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