예제 #1
0
파일: render.go 프로젝트: num5/steven
func renderBuffer(ch *ChunkBuffer, po position, fr direction.Type, delta float64) {
	if ch == nil {
		return
	}
	rQueue.Append(renderRequest{ch, po, fr})

	slidy := slidyChunks.Value()

	for !rQueue.Empty() {
		req := rQueue.Take()
		if req.chunk.renderedOn == frameID {
			continue
		}
		req.chunk.renderedOn = frameID

		aabb := vmath.NewAABB(
			-float32((req.pos.X<<4)+16), -float32((req.pos.Y<<4)+16), float32((req.pos.Z<<4)),
			-float32((req.pos.X<<4)), -float32((req.pos.Y<<4)), float32((req.pos.Z<<4)+16),
		).Grow(1, 1, 1)
		if !frustum.IsAABBInside(aabb) {
			continue
		}
		renderOrder = append(renderOrder, req.chunk)

		req.chunk.Rendered = true

		if slidy {
			dx := req.pos.X - int(Camera.X)>>4
			dz := req.pos.Z - int(Camera.Z)>>4

			if req.chunk.progress < 1 && dx*dx+dz*dz > 6*6 {
				req.chunk.progress += delta * 0.015
			} else {
				req.chunk.progress = 1
			}
		} else {
			req.chunk.progress = 1
		}

		if req.chunk.count != 0 && req.chunk.buffer.IsValid() {
			shaderChunk.Offset.Int3(req.chunk.X, req.chunk.Y*4096-req.chunk.Y*int(4096*(1-req.chunk.progress)), req.chunk.Z)

			req.chunk.array.Bind()
			gl.DrawElements(gl.Triangles, req.chunk.count, elementBufferType, 0)
		}

		for _, dir := range direction.Values {
			c := req.chunk.neighborChunks[dir]
			if dir != req.from && c != nil && c.renderedOn != frameID &&
				(req.from == direction.Invalid || (req.chunk.IsVisible(req.from, dir) && validDirs[dir])) {
				ox, oy, oz := dir.Offset()
				pos := position{req.pos.X + ox, req.pos.Y + oy, req.pos.Z + oz}
				rQueue.Append(renderRequest{c, pos, dir.Opposite()})
			}
		}
	}
}
예제 #2
0
파일: model.go 프로젝트: num5/steven
func drawModels() {
	if len(modelState.models) == 0 {
		return
	}
	m := 4
	if modelState.indexType == gl.UnsignedShort {
		m = 2
	}

	gl.Enable(gl.Blend)

	offsetBuf := make([]uintptr, 10)

	for _, c := range modelState.models {
		c.program.Use()
		c.shader.Texture.Int(0)
		c.shader.PerspectiveMatrix.Matrix4(&perspectiveMatrix)
		c.shader.CameraMatrix.Matrix4(&cameraMatrix)
		c.shader.SkyOffset.Float(SkyOffset)
		c.shader.LightLevel.Float(LightLevel)
		gl.BlendFunc(c.blendS, c.blendD)
		for _, mdl := range c.models {
			if mdl.Radius != 0 && !frustum.IsSphereInside(mdl.X, mdl.Y, mdl.Z, mdl.Radius) {
				continue
			}
			mdl.array.Bind()
			c.shader.Lighting.Float2(mdl.BlockLight, mdl.SkyLight)
			if len(mdl.counts) > 1 {
				copy(offsetBuf, mdl.offsets)
				for i := range mdl.offsets {
					offsetBuf[i] *= uintptr(m)
				}
				c.shader.ModelMatrix.Matrix4Multi(mdl.Matrix)
				c.shader.ColorMul.FloatMutliRaw(mdl.Colors, len(mdl.Colors))
				gl.MultiDrawElements(gl.Triangles, mdl.counts, modelState.indexType, offsetBuf[:len(mdl.offsets)])
			} else {
				c.shader.ModelMatrix.Matrix4Multi(mdl.Matrix)
				c.shader.ColorMul.FloatMutliRaw(mdl.Colors, len(mdl.Colors))
				gl.DrawElements(gl.Triangles, int(mdl.counts[0]), modelState.indexType, int(mdl.offsets[0])*m)
			}
		}
	}

	gl.Disable(gl.Blend)
}
예제 #3
0
파일: render.go 프로젝트: suedadam/steven
func renderBuffer(ch *ChunkBuffer, po position, fr direction.Type) {
	if ch == nil {
		return
	}
	rQueue.Append(renderRequest{ch, po, fr})
itQueue:
	for !rQueue.Empty() {
		req := rQueue.Take()
		if req.chunk.renderedOn == frameID {
			continue itQueue
		}
		aabb := vmath.NewAABB(
			-float32((req.pos.X<<4)+16), -float32((req.pos.Y<<4)+16), float32((req.pos.Z<<4)),
			-float32((req.pos.X<<4)), -float32((req.pos.Y<<4)), float32((req.pos.Z<<4)+16),
		).Grow(1, 1, 1)
		if !frustum.IsAABBInside(aabb) {
			req.chunk.renderedOn = frameID
			continue itQueue
		}
		req.chunk.renderedOn = frameID
		renderOrder = append(renderOrder, req.chunk)

		if req.chunk.count != 0 && req.chunk.buffer.IsValid() {
			shaderChunk.Offset.Int3(req.chunk.X, req.chunk.Y, req.chunk.Z)

			req.chunk.array.Bind()
			gl.DrawElements(gl.Triangles, req.chunk.count, elementBufferType, 0)
		}

		for _, dir := range direction.Values {
			c := req.chunk.neighborChunks[dir]
			if dir != req.from && c != nil && c.renderedOn != frameID &&
				(req.from == direction.Invalid || (req.chunk.IsVisible(req.from, dir) && validDirs[dir])) {
				ox, oy, oz := dir.Offset()
				pos := position{req.pos.X + ox, req.pos.Y + oy, req.pos.Z + oz}
				rQueue.Append(renderRequest{c, pos, dir.Opposite()})
			}
		}
	}
}
예제 #4
0
파일: ui.go 프로젝트: num5/steven
func drawUI() {
	// Prevent clipping with the world
	gl.Clear(gl.DepthBufferBit)
	gl.DepthFunc(gl.LessOrEqual)
	gl.Enable(gl.Blend)

	uiState.program.Use()
	uiState.shader.Texture.Int(0)
	if uiState.count > 0 {
		uiState.array.Bind()
		if uiState.maxIndex < uiState.count {
			var data []byte
			data, uiState.indexType = genElementBuffer(uiState.count)
			uiState.indexBuffer.Bind(gl.ElementArrayBuffer)
			uiState.indexBuffer.Data(data, gl.DynamicDraw)
			uiState.maxIndex = uiState.count
		}

		uiState.shader.ScreenSize.Float2(float32(lastWidth), float32(lastHeight))

		uiState.buffer.Bind(gl.ArrayBuffer)
		if len(uiState.data) > uiState.prevSize {
			uiState.prevSize = len(uiState.data)
			uiState.buffer.Data(uiState.data, gl.StreamDraw)
		} else {
			target := uiState.buffer.Map(gl.WriteOnly, len(uiState.data))
			copy(target, uiState.data)
			uiState.buffer.Unmap()
		}
		gl.DrawElements(gl.Triangles, uiState.count, uiState.indexType, 0)
	}
	gl.Disable(gl.Blend)
	gl.DepthFunc(gl.LessOrEqual)
	uiState.count = 0
	uiState.data = uiState.data[:0]
}
예제 #5
0
파일: render.go 프로젝트: num5/steven
// Draw draws a single frame
func Draw(width, height int, delta float64) {
	tickAnimatedTextures(delta)
	frameID++
sync:
	for {
		select {
		case f := <-syncChan:
			f()
		default:
			break sync
		}
	}

	// Only update the viewport if the window was resized
	if lastHeight != height || lastWidth != width || lastFOV != FOV.Value() {
		lastWidth = width
		lastHeight = height
		lastFOV = FOV.Value()

		perspectiveMatrix = mgl32.Perspective(
			(math.Pi/180)*float32(lastFOV),
			float32(width)/float32(height),
			0.1,
			500.0,
		)
		gl.Viewport(0, 0, width, height)
		frustum.SetPerspective(
			(math.Pi/180)*float32(lastFOV),
			float32(width)/float32(height),
			0.1,
			500.0,
		)
		initTrans()
	}

	mainFramebuffer.Bind()
	gl.Enable(gl.Multisample)

	gl.ActiveTexture(0)
	glTexture.Bind(gl.Texture2DArray)

	gl.ClearColor(ClearColour.R, ClearColour.G, ClearColour.B, 1.0)
	gl.Clear(gl.ColorBufferBit | gl.DepthBufferBit)

	chunkProgram.Use()

	viewVector = mgl32.Vec3{
		float32(math.Cos(Camera.Yaw-math.Pi/2) * -math.Cos(Camera.Pitch)),
		float32(-math.Sin(Camera.Pitch)),
		float32(-math.Sin(Camera.Yaw-math.Pi/2) * -math.Cos(Camera.Pitch)),
	}
	cam := mgl32.Vec3{-float32(Camera.X), -float32(Camera.Y), float32(Camera.Z)}
	cameraMatrix = mgl32.LookAtV(
		cam,
		cam.Add(mgl32.Vec3{-viewVector.X(), -viewVector.Y(), viewVector.Z()}),
		mgl32.Vec3{0, -1, 0},
	)
	cameraMatrix = cameraMatrix.Mul4(mgl32.Scale3D(-1.0, 1.0, 1.0))

	frustum.SetCamera(
		cam,
		cam.Add(mgl32.Vec3{-viewVector.X(), -viewVector.Y(), viewVector.Z()}),
		mgl32.Vec3{0, -1, 0},
	)

	shaderChunk.PerspectiveMatrix.Matrix4(&perspectiveMatrix)
	shaderChunk.CameraMatrix.Matrix4(&cameraMatrix)
	shaderChunk.Texture.Int(0)
	shaderChunk.LightLevel.Float(LightLevel)
	shaderChunk.SkyOffset.Float(SkyOffset)

	chunkPos := position{
		X: int(Camera.X) >> 4,
		Y: int(Camera.Y) >> 4,
		Z: int(Camera.Z) >> 4,
	}
	nearestBuffer = buffers[chunkPos]

	for _, dir := range direction.Values {
		validDirs[dir] = viewVector.Dot(dir.AsVec()) > -0.8
	}

	renderOrder = renderOrder[:0]
	renderBuffer(nearestBuffer, chunkPos, direction.Invalid, delta)

	drawLines()
	drawModels()
	clouds.tick(delta)

	chunkProgramT.Use()
	shaderChunkT.PerspectiveMatrix.Matrix4(&perspectiveMatrix)
	shaderChunkT.CameraMatrix.Matrix4(&cameraMatrix)
	shaderChunkT.Texture.Int(0)
	shaderChunkT.LightLevel.Float(LightLevel)
	shaderChunkT.SkyOffset.Float(SkyOffset)

	// Copy the depth buffer
	mainFramebuffer.BindRead()
	transFramebuffer.BindDraw()
	gl.BlitFramebuffer(
		0, 0, lastWidth, lastHeight,
		0, 0, lastWidth, lastHeight,
		gl.DepthBufferBit, gl.Nearest,
	)

	gl.Enable(gl.Blend)
	gl.DepthMask(false)
	transFramebuffer.Bind()
	gl.ClearColor(0, 0, 0, 1)
	gl.Clear(gl.ColorBufferBit)
	gl.ClearBuffer(gl.Color, 0, []float32{0, 0, 0, 1})
	gl.ClearBuffer(gl.Color, 1, []float32{0, 0, 0, 0})
	gl.BlendFuncSeparate(gl.OneFactor, gl.OneFactor, gl.ZeroFactor, gl.OneMinusSrcAlpha)
	for _, chunk := range renderOrder {
		if chunk.countT > 0 && chunk.bufferT.IsValid() {
			shaderChunkT.Offset.Int3(chunk.X, chunk.Y*4096-chunk.Y*int(4096*(1-chunk.progress)), chunk.Z)

			chunk.arrayT.Bind()
			gl.DrawElements(gl.Triangles, chunk.countT, elementBufferType, 0)
		}
	}

	gl.UnbindFramebuffer()
	gl.Disable(gl.DepthTest)
	gl.Clear(gl.ColorBufferBit)
	gl.Disable(gl.Blend)

	transDraw()

	gl.Enable(gl.DepthTest)
	gl.DepthMask(true)
	gl.BlendFunc(gl.SrcAlpha, gl.OneMinusSrcAlpha)
	gl.Disable(gl.Multisample)

	drawUI()

	if debugFramebuffers.Value() {
		gl.Enable(gl.Multisample)
		blitBuffers()
		gl.Disable(gl.Multisample)
	}
}