// 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) } }
func initTrans() { if transCreated { accum.Delete() revealage.Delete() transFramebuffer.Delete() fbColor.Delete() fbDepth.Delete() mainFramebuffer.Delete() } transCreated = true transFramebuffer = gl.NewFramebuffer() transFramebuffer.Bind() accum = gl.CreateTexture() accum.Bind(gl.Texture2D) accum.Image2DEx(0, lastWidth, lastHeight, gl.RGBA16F, gl.RGBA, gl.Float, nil) accum.Parameter(gl.TextureMinFilter, gl.Linear) accum.Parameter(gl.TextureMagFilter, gl.Linear) transFramebuffer.Texture2D(gl.ColorAttachment0, gl.Texture2D, accum, 0) revealage = gl.CreateTexture() revealage.Bind(gl.Texture2D) revealage.Image2DEx(0, lastWidth, lastHeight, gl.R16F, gl.Red, gl.Float, nil) revealage.Parameter(gl.TextureMinFilter, gl.Linear) revealage.Parameter(gl.TextureMagFilter, gl.Linear) transFramebuffer.Texture2D(gl.ColorAttachment1, gl.Texture2D, revealage, 0) transDepth = gl.CreateTexture() transDepth.Bind(gl.Texture2D) transDepth.Image2DEx(0, lastWidth, lastHeight, gl.DepthComponent24, gl.DepthComponent, gl.UnsignedByte, nil) transDepth.Parameter(gl.TextureMinFilter, gl.Linear) transDepth.Parameter(gl.TextureMagFilter, gl.Linear) transFramebuffer.Texture2D(gl.DepthAttachment, gl.Texture2D, transDepth, 0) chunkProgramT.Use() gl.BindFragDataLocation(chunkProgramT, 0, "accum") gl.BindFragDataLocation(chunkProgramT, 1, "revealage") gl.DrawBuffers([]gl.Attachment{ gl.ColorAttachment0, gl.ColorAttachment1, }) mainFramebuffer = gl.NewFramebuffer() mainFramebuffer.Bind() fbColor = gl.CreateTexture() fbColor.Bind(gl.Texture2DMultisample) fbColor.Image2DSample(rSamples.Value(), lastWidth, lastHeight, gl.RGBA8, false) mainFramebuffer.Texture2D(gl.ColorAttachment0, gl.Texture2DMultisample, fbColor, 0) fbDepth = gl.CreateTexture() fbDepth.Bind(gl.Texture2DMultisample) fbDepth.Image2DSample(rSamples.Value(), lastWidth, lastHeight, gl.DepthComponent24, false) mainFramebuffer.Texture2D(gl.DepthAttachment, gl.Texture2DMultisample, fbDepth, 0) gl.UnbindFramebuffer() transState.program = CreateProgram(vertexTrans, fragmentTrans) transState.shader = &transShader{} InitStruct(transState.shader, transState.program) transState.array = gl.CreateVertexArray() transState.array.Bind() transState.buffer = gl.CreateBuffer() transState.buffer.Bind(gl.ArrayBuffer) data := builder.New() for _, f := range []float32{-1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1} { data.Float(f) } transState.buffer.Data(data.Data(), gl.StaticDraw) transState.shader.Position.Enable() transState.shader.Position.Pointer(2, gl.Float, false, 8, 0) }