Beispiel #1
0
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}
	}()
}
Beispiel #2
0
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}
	}()
}