func (cs *chunkSection) build(complete chan<- buildPos) { ox, oy, oz := (cs.chunk.X<<4)-2, (cs.Y<<4)-2, (cs.chunk.Z<<4)-2 bs := getPooledSnapshot(ox, oy, oz) // Make relative bs.x = -2 bs.y = -2 bs.z = -2 go func() { bO := getBuilder() bT := getBuilder() bO.Reset() bT.Reset() bOI := new(int) bTI := new(int) r := rand.New(rand.NewSource(int64(cs.chunk.X) | (int64(cs.chunk.Z) << 32))) for y := 0; y < 16; y++ { for x := 0; x < 16; x++ { for z := 0; z < 16; z++ { bl := bs.block(x, y, z) if !bl.Renderable() { // Use one step of the rng so that // if a block is placed in an empty // location is variant doesn't change r.Int() continue } // Liquids can't be represented by the model system // due to the number of possible states they have if l, ok := bl.(*blockLiquid); ok { if bl.IsTranslucent() { l.renderLiquid(bs, x, y, z, bT, bTI) } else { l.renderLiquid(bs, x, y, z, bO, bOI) } r.Int() // See the comment above for non-renderable blocks continue } // The random generator is used to select a 'random' variant // which is constant for that position. if variant := bl.Models().selectModel(r); variant != nil { if bl.IsTranslucent() { variant.Render(x, y, z, bs, bT, bTI) } else { variant.Render(x, y, z, bs, bO, bOI) } } } } } // Update culling information cullBits := buildCullBits(bs) snapshotPool.Put(bs) // Upload the buffers on the render goroutine render.Sync(func() { if cs.Buffer != nil { cs.Buffer.Upload(bO.Data(), *bOI, cullBits) cs.Buffer.UploadTrans(bT.Data(), *bTI) } putBuilder(bO) putBuilder(bT) }) // Free up the builder complete <- buildPos{cs.chunk.X, cs.Y, cs.chunk.Z} }() }
func (cs *chunkSection) build(complete chan<- buildPos) { ox, oy, oz := (cs.chunk.X<<4)-2, (cs.Y<<4)-2, (cs.chunk.Z<<4)-2 bs := getPooledSnapshot(ox, oy, oz) // Make relative bs.x = -2 bs.y = -2 bs.z = -2 go func() { bO := builderPool.Get().([]chunkVertex)[:0] bT := builderPool.Get().([]chunkVertex)[:0] bOI := new(int) bTI := new(int) r := rand.New(rand.NewSource(int64(cs.chunk.X) | (int64(cs.chunk.Z) << 32))) for y := 0; y < 16; y++ { for x := 0; x < 16; x++ { for z := 0; z < 16; z++ { bl := bs.block(x, y, z) if !bl.Renderable() { // Use one step of the rng so that // if a block is placed in an empty // location is variant doesn't change r.Int() continue } bI := bOI // Translucent models need special handling if bl.IsTranslucent() { bI = bTI } // Liquids can't be represented by the model system // due to the number of possible states they have if l, ok := bl.(*blockLiquid); ok { if bl.IsTranslucent() { bT = l.renderLiquid(bs, x, y, z, bT, bI) } else { bO = l.renderLiquid(bs, x, y, z, bO, bI) } r.Int() // See the comment above for air continue } // The random generator is used to select a 'random' variant // which is constant for that position. if variant := bl.Models().selectModel(r); variant != nil { if bl.IsTranslucent() { bT = variant.Render(x, y, z, bs, bT, bI) } else { bO = variant.Render(x, y, z, bs, bO, bI) } } } } } // Update culling information cullBits := buildCullBits(bs) snapshotPool.Put(bs) // Upload the buffers on the render goroutine render.Sync(func() { if cs.Buffer != nil { var data, dataT []byte if len(bO) > 0 { size := len(bO) * int(unsafe.Sizeof(bO[0])) data = (*[1 << 28]byte)(unsafe.Pointer(&bO[0]))[:size] } if len(bT) > 0 { size := len(bT) * int(unsafe.Sizeof(bT[0])) dataT = (*[1 << 28]byte)(unsafe.Pointer(&bT[0]))[:size] } cs.Buffer.Upload(data, *bOI, cullBits) cs.Buffer.UploadTrans(dataT, *bTI) } builderPool.Put(bO) builderPool.Put(bT) }) // Free up the builder complete <- buildPos{cs.chunk.X, cs.Y, cs.chunk.Z} }() }