public void Render() { gl.Enable(Capability.DepthTest); gl.Clear(Buffers.Color | Buffers.Depth); shaderProgram.Use(gl); gl.BindVertexArray(vertexArray); gl.BindBuffer(BufferTarget.Array, vertexBuffer); gl.ActiveTexture(TextureUnit.Texture0); gl.BindTexture(TextureTarget.Texture2d, texture); chunkPool.Update(); var count = chunkPool.Uninitialized.Count; foreach (var c in chunkPool.Disposed) { if (count > 0) { var(x, y, z) = chunkPool.Uninitialized[count - 1]; chunkPool.Uninitialized.RemoveAt(count - 1); chunkPool.AddInsideRange(InitializeChunk(x, y, z, c)); count--; } else { break; } } foreach (var(x, y, z) in chunkPool.Uninitialized) { chunkPool.AddInsideRange(InitializeChunk(x, y, z, new Chunk <bool>())); } foreach (var c in chunkPool.InsideRange) { if (frustum.SphereInFrustum(new Vector3(c.X * 16 + 8, c.Y * 16 + 8, c.Z * 16 + 8), chunkRadius) == FrustumIntersection.Outside) { continue; } index = 0; int vertexCount = 0; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { for (int k = 0; k < 16; k++) { if (c[i, j, k]) { vertexCount += GenerateCubeFaces(c, i, j, k, vertexCount); } } } } vertexCount += FlushVertices(vertexCount, index); if (vertexCount > 0) { gl.DrawArrays(DrawMode.Triangles, 0, vertexCount); } } gl.Disable(Capability.DepthTest); }
internal unsafe Scene(GraphicsLibrary graphicsLibrary) { gl = graphicsLibrary; camera = new Camera(); gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); shaderProgram = new ShaderProgram(gl, @" layout(location = 0) in vec3 vPosition; layout(location = 1) in vec2 vTexCoord; layout(location = 2) in vec3 vNormal; out vec2 fTexCoord; out vec3 fNormal; uniform mat4 view; uniform mat4 proj; void main() { gl_Position = proj * view * vec4(vPosition, 1.0); fTexCoord = vTexCoord; fNormal = vNormal; } ", @" in vec2 fTexCoord; in vec3 fNormal; out vec4 outColor; uniform sampler2D tex; uniform vec3 lightingDirection; void main() { vec3 norm = normalize(fNormal); float diff = max(dot(norm, normalize(lightingDirection)), 0.0); vec3 diffuse = (diff + vec3(0.7)) * vec3(1.0); outColor = texture(tex, fTexCoord) * vec4(diffuse, 1.0); } " ); const uint position = 0; const uint texCoord = 1; const uint normal = 2; uint h; gl.GenVertexArrays(1, &h); vertexArray = h; gl.BindVertexArray(vertexArray); gl.GenBuffers(1, &h); vertexBuffer = h; gl.BindBuffer(BufferTarget.Array, vertexBuffer); gl.BufferData(BufferTarget.Array, IntPtr.Zero + 8 * sizeof(float) * 16 * 16 * 16 * 36, IntPtr.Zero, BufferUsage.DynamicDraw); var stride = sizeof(float) * 8; gl.EnableVertexAttribArray(position); gl.VertexAttribPointer(position, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero); gl.EnableVertexAttribArray(texCoord); gl.VertexAttribPointer(texCoord, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 3 * sizeof(float)); gl.EnableVertexAttribArray(normal); gl.VertexAttribPointer(normal, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 5 * sizeof(float)); shaderProgram.Use(gl); viewUniform = shaderProgram.GetUniformLocation(gl, "view"); var proj = shaderProgram.GetUniformLocation(gl, "proj"); var tex = shaderProgram.GetUniformLocation(gl, "tex"); gl.Uniform1i(tex, 0); var lightingDirection = shaderProgram.GetUniformLocation(gl, "lightingDirection"); gl.Uniform3f(lightingDirection, (float)Math.Cos(Math.PI / 4), 0.3f, (float)Math.Sin(Math.PI / 4)); var fieldOfView = (float)(Math.PI / 4); // 45 degrees var aspectRatio = 1.3f; var nearDistance = 1f; var farDistance = 200f; frustum.SetPerspectiveFieldOfView(fieldOfView, aspectRatio, nearDistance, farDistance); var mat = Matrix4x4.CreatePerspectiveFieldOfView(fieldOfView, aspectRatio, nearDistance, farDistance); shaderProgram.UniformMatrix(gl, proj, mat); camera.Position = new Vector3(0f, 40f, 0f); camera.Yaw = 115; camera.Pitch = -20; camera.UpdateVectors(); shaderProgram.UniformMatrix(gl, viewUniform, camera.GetViewMatrix()); frustum.SetLookAt(camera.Position, camera.Position + camera.Front, camera.Up); chunkPool.Height = 2; chunkPool.MaxDistance = 7; }