static void Main(string[] args) { Glut.glutInit(); Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH | Glut.GLUT_MULTISAMPLE); Glut.glutInitWindowSize(width, height); int window = Glut.glutCreateWindow("VoxelEngine"); Console.WriteLine("OpenGL Version: {0}", Gl.Version()); Console.WriteLine("Loading shaders..."); orthoShader = LoadShader("ortho_vs", "ortho_fs"); if (orthoShader == null) { Glut.glutHideWindow(); Console.WriteLine("Error loading shaders."); Console.ReadKey(true); return; } Console.WriteLine("Loaded shaders successfully."); Console.WriteLine("Creating Glut Window..."); Glut.glutIdleFunc(OnRenderFrame); Glut.glutDisplayFunc(OnDisplay); Glut.glutCloseFunc(OnClose); Glut.glutKeyboardFunc(OnKeyboardDown); Glut.glutKeyboardUpFunc(OnKeyboardUp); Glut.glutMouseFunc(OnMouse); Glut.glutMotionFunc(OnMove); Glut.glutReshapeFunc(OnReshape); Glut.glutMouseWheelFunc(OnMouseWheel); Glut.glutPassiveMotionFunc(OnPassiveMove); gizmo = new Gizmo(); camera = new Camera(new Vector3(0, 48, 0), Quaternion.Identity); testViewMatrix = camera.ViewMatrix; VoxelChunkManager.Instance.projectionMatrix = Matrix4.CreatePerspectiveFieldOfView(fov, aspect, near, far); float nearTop = near * (float)Math.Tan(fov / 2f); float nearBottom = -nearTop; float nearRight = nearTop * aspect; float nearLeft = -nearRight; float farTop = far * (float)Math.Tan(fov / 2f); float farBottom = -farTop; float farRight = farTop * aspect; float farLeft = -farRight; frustumVertices = new VBO<Vector3>(new Vector3[] { new Vector3(nearLeft, nearTop, -near),new Vector3(nearRight, nearTop, -near),new Vector3(nearRight, nearBottom, -near),new Vector3(nearLeft, nearBottom, -near), new Vector3(farLeft, farTop, -far),new Vector3(farRight, farTop, -far),new Vector3(farRight, farBottom, -far),new Vector3(farLeft, farBottom, -far) }); frustumIndices = new VBO<int>(new int[] { 0, 1, 2, 3, 4, 5, 1, 0, 1, 5, 6, 2, 4, 0, 3, 7, 5, 4, 7, 6, 6, 7, 3, 2 }, BufferTarget.ElementArrayBuffer); int radius = 2; for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { VoxelChunkManager.Instance.LoadChunk(i, j); } } //screenQuad = Geometry.CreateQuad(orthoShader, new Vector2(-0.5, 0.5), new Vector2(1, 1), new Vector2(0, 0), new Vector2(1, 1)); //fbo = new FBO(new System.Drawing.Size(width, height), // new FramebufferAttachment[] { // FramebufferAttachment.ColorAttachment0Ext }, // PixelInternalFormat.Rgb8, true); Gl.Enable(EnableCap.DepthTest); Gl.Enable(EnableCap.CullFace); Gl.FrontFace(FrontFaceDirection.Cw); Gl.CullFace(CullFaceMode.Back); //Gl.Enable(EnableCap.Multisample); Gl.ClearColor(0.53f, 0.8f, 0.92f, 1); font = new BMFont("font24.fnt", "font24.png"); fontProgram = new ShaderProgram(BMFont.FontVertexSource, BMFont.FontFragmentSource); fontProgram.Use(); fontProgram["ortho_matrix"].SetValue(Matrix4.CreateOrthographic(width, height, 0, 1000)); fontProgram["color"].SetValue(new Vector3(1, 1, 1)); information = font.CreateString(fontProgram, ""); watch = System.Diagnostics.Stopwatch.StartNew(); Console.WriteLine("Entering main loop..."); Glut.glutMainLoop(); }
private static void OnRenderFrame() { watch.Stop(); float deltaTime = (float)watch.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency; watch.Restart(); System.Threading.Thread.Sleep((int)(Math.Max(0f, 16f - deltaTime))); timeElapsed += deltaTime; fpsCounter++; if (timeElapsed >= 1.0f) { fps = fpsCounter; fpsCounter = 0; timeElapsed -= 1.0f; Glut.glutSetWindowTitle(string.Format("VoxelEngine {0}fps", fps)); } //Gl.PolygonMode(MaterialFace.FrontAndBack, wireframe ? PolygonMode.Line : PolygonMode.Fill); //fbo.Enable(); Vector3 tomove = Vector3.Zero; if (moveforward) tomove.z -= 1f; if (movebackward) tomove.z += 1f; if (moveleft) tomove.x -= 1f; if (moveright) tomove.x += 1f; if (moveup) tomove.y += 1f; if (movedown) tomove.y -= 1f; tomove = tomove.Normalize(); camera.MoveRelative(tomove * deltaTime * moveSpeed * (speedmod ? speedMultiplier : 1f)); VoxelChunkManager.Instance.Update(); Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); Gl.Viewport(0, 0, width, height); //Gl.Disable(EnableCap.CullFace); //Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); //Cube.Shader.Use(); //Cube.Shader["projectionMatrix"].SetValue(VoxelChunkManager.Instance.projectionMatrix); //Cube.Shader["viewMatrix"].SetValue(camera.ViewMatrix); //Cube.Shader["modelMatrix"].SetValue(testOrientation.Matrix4);// *Matrix4.CreateTranslation(testPos)); //Gl.BindBufferToShaderAttribute(frustumVertices, Cube.Shader, "vertexPosition"); //Gl.BindBufferToShaderAttribute(Cube.Colors("FFFFFF"), Cube.Shader, "vertexColor"); //Gl.BindBuffer(frustumIndices); //Gl.DrawElements(BeginMode.Quads, frustumIndices.Count, DrawElementsType.UnsignedInt, IntPtr.Zero); float xs = (mouseX / (float)(width)) * 2f - 1f; float ys = (-mouseY / (float)(height)) * 2f + 1f; float nearHeight = near * (float)Math.Tan(fov / 2f); Vector3 ray = testOrientation * new Vector3(xs * nearHeight * aspect, ys * nearHeight, -near); //Vector3 pos = camera.Position + ray.Normalize() * 10f; //Cube.Render(VoxelChunkManager.Instance.projectionMatrix, camera.ViewMatrix, Matrix4.CreateTranslation(pos - new Vector3(0.5, 0.5, 0.5)), "000000"); float maxpickdist = 30f; Vector3 dir = ray.Normalize(); Vector3 start = new Vector3(0, 48, 0); Vector3 stop = new Vector3(15, 58, 20); Vector3 delta = stop - start; float errorY = 0f, errorZ = 0f; ; float deltaerrorY = Math.Abs(delta.y / delta.x), deltaerrorZ = Math.Abs(delta.z / delta.x); int startx = (int)Math.Floor(start.x); int y = (int)Math.Floor(start.y); int z = (int)Math.Floor(start.z); int stopx = (int)Math.Floor(stop.x); int stopy = (int)Math.Floor(stop.y); int chunkX = startx / VoxelChunkManager.ChunkWidth; int chunkZ = (int)Math.Floor(start.z) / VoxelChunkManager.ChunkDepth; for (int x = (int)Math.Floor(start.x); x <= stopx; x++) { chunkX = x / VoxelChunkManager.ChunkWidth; Cube.Render(VoxelChunkManager.Instance.projectionMatrix, camera.ViewMatrix, Matrix4.CreateTranslation(new Vector3(x, y, z)), "000000"); errorY += deltaerrorY; errorZ += deltaerrorZ; while(errorY >= 0.5f) { //Cube.Render(VoxelChunkManager.Instance.projectionMatrix, camera.ViewMatrix, Matrix4.CreateTranslation(new Vector3(x, y, z)), "000000"); y += Math.Sign(delta.y); errorY -= 1.0f; } //while (errorZ >= 0.5f) //{ // //Cube.Render(VoxelChunkManager.Instance.projectionMatrix, camera.ViewMatrix, Matrix4.CreateTranslation(new Vector3(x, y, z)), "000000"); // z += Math.Sign(delta.z); // chunkZ = z / VoxelChunkManager.ChunkDepth; // if (VoxelChunkManager.Instance.ChunkMeshed(chunkX, chunkZ) && y >= 0) // errorZ -= 1.0f; //} //if (y >= (int)Math.Floor(stop.y) && z >= (int)Math.Floor(stop.z)) // break; } VoxelChunkManager.Instance.viewMatrix = camera.ViewMatrix; VoxelChunkManager.Instance.Render(camera.ViewMatrix, wireframe); Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); gizmo.Render(new Vector3(0, 0, 0), camera.ViewMatrix); information?.Dispose(); information = font.CreateString(fontProgram, string.Format("FPS: {0} Culling: {1} Vertices: {2} Chunks: {3}/{4} x: {5:0.000} y: {6:0.000} pos: {7}", fps, culling ? "on" : "off", VoxelChunkManager.Instance.VertexCount, VoxelChunkManager.Instance.RenderedChunkCount, VoxelChunkManager.Instance.ChunkCount, xs, ys, camera.Position)); information.Position = new Vector2(-width / 2 + 10, height / 2 - font.Height - 10); //if (wireframe) //{ // Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); // Gl.BindBufferToShaderAttribute(lineColorVBO, program, "vertexColor"); // Gl.DrawElements(BeginMode.Triangles, chunk.Indices.Count, DrawElementsType.UnsignedInt, IntPtr.Zero); //} //fbo.Disable(); //orthoShader.Use(); //Gl.BindTexture(TextureTarget.Texture2D, fbo.TextureID[0]); //screenQuad.Draw(); //bind the font program as well as the font texture fontProgram.Use(); Gl.BindTexture(font.FontTexture); Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); Gl.Disable(EnableCap.CullFace); Gl.Viewport(10, height - height / 2 - 10, width / 2, height / 2); information.Draw(); Glut.glutSwapBuffers(); }