public void DeActivate() { Gl.BindBuffer(BufferTarget.Array, 0); Gl.CheckForError(); Gl.BindVertexArray(0); Gl.CheckForError(); }
public void Activate() { Gl.ActiveTexture(ActiveTextureTarget.Texture0); Gl.CheckForError(); Gl.BindTexture(TextureTarget.Texture2D, textureObject); Gl.CheckForError(); }
public void Activate() { // Remember, GL_ARRAY_BUFFER binding is **NOT** part of the VAO's state! Gl.BindBuffer(BufferTarget.Array, (uint)vertexArrayObject); Gl.CheckForError(); Gl.BindVertexArray((uint)vertexArrayObject); Gl.CheckForError(); }
public void Draw(mat4 perspective, mat4 view, float state) { // Enable texture if applicable Texture?.Activate(); //vec3 renderPosition = (Position * state) + (PreviousPosition * (1 - state)); vec3 renderPosition = (Position); // Model matrix mat4 scaleMatrix = mat4.Scale(Scale); mat4 translationMatrix = mat4.Translate(renderPosition.x, renderPosition.y, renderPosition.z); mat4 rotationMatrix = Orientation.ToMat4; mat4 modelMatrix = translationMatrix * rotationMatrix * scaleMatrix; // Transfer to shader uniforms int modelLocation = Gl.UniformLocation(Material.ProgramObject, "model"); Gl.CheckForError(); Gl.UniformMatrix4(modelLocation, 0, modelMatrix.ToArray()); Gl.CheckForError(); int projectionLocation = Gl.UniformLocation(Material.ProgramObject, "projection"); Gl.CheckForError(); Gl.UniformMatrix4(projectionLocation, 0, perspective.ToArray()); Gl.CheckForError(); int viewLocation = Gl.UniformLocation(Material.ProgramObject, "view"); Gl.CheckForError(); Gl.UniformMatrix4(viewLocation, 0, view.ToArray()); Gl.CheckForError(); // Turn on fragment color usage int colorBoolLocation = Gl.UniformLocation(Material.ProgramObject, "isTexture"); Gl.Uniform1(colorBoolLocation, 0); Gl.CheckForError(); // Set user defined color int userColorLocation = Gl.UniformLocation(Material.ProgramObject, "userColor"); Gl.Uniform3(userColorLocation, new float[] { UserColor.X, UserColor.Y, UserColor.Z }); Gl.CheckForError(); Gl.DrawElements(DrawMode.Triangles, (uint)Vertices.Count, DrawType.UnsignedInt, IntPtr.Zero); Gl.CheckForError(); }
public Texture(string filepath) { // Load Image Bitmap bitmap = new Bitmap(filepath); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); // Texture settings uint[] generatedTextures = new uint[1]; Gl.GenTextures(1, generatedTextures); Gl.CheckForError(); textureObject = generatedTextures[0]; Gl.BindTexture(TextureTarget.Texture2D, textureObject); Gl.CheckForError(); Gl.TexParameter((int)TextureTarget.Texture2D, (int)TextureParameter.TextureWrapS, (int)TextureParameterWrapMode.MirroredRepeat); Gl.CheckForError(); Gl.TexParameter((int)TextureTarget.Texture2D, (int)TextureParameter.TextureWrapT, (int)TextureParameterWrapMode.MirroredRepeat); Gl.CheckForError(); // TODO: Read up on wtf min + mag filters do, THEY MADE MY TEXTURE WORK! Gl.TexParameter((int)TextureTarget.Texture2D, (int)TextureParameter.TextureMinFilter, (float)TextureParameterMinifyingMode.Linear); Gl.CheckForError(); Gl.TexParameter((int)TextureTarget.Texture2D, (int)TextureParameter.TextureMagFilter, (float)TextureParameterMinifyingMode.Linear); Gl.CheckForError(); // TODO: Read up on pixel store. Texture wouldn't render without this setting Gl.PixelStore((int)PixelStoreParameter.UnpackAlignment, 1); Gl.CheckForError(); // Upload texture data Gl.TexImage2D(TextureTarget.Texture2D, 0, InternalPixelFormat.RGB, (uint)bitmap.Width, (uint)bitmap.Height, 0, GLFWSharpie.PixelFormat.RGB, PixelType.UnsignedByte, bitmapData.Scan0); Gl.CheckForError(); // TODO. Wtf does mipmap do? Texture wouldn't show without it! Gl.BindTexture(TextureTarget.Texture2D, 0); Gl.CheckForError(); bitmap.UnlockBits(bitmapData); }
public Shader(string filepath, ShaderType shaderType) { string shaderFileContent = File.ReadAllText(filepath); if (string.IsNullOrEmpty(shaderFileContent)) { throw new ShaderException("The specified shader file was empty."); } // Create shader object ShaderObject = Gl.CreateShader(shaderType); Gl.CheckForError(); // Set shader source code Gl.ShaderSource(ShaderObject, 1, new string[] { shaderFileContent }, IntPtr.Zero); Gl.CheckForError(); // Compile shader source code Gl.CompileShader(ShaderObject); Gl.CheckForError(); // Check shader compilation status int shaderCompilationStatus = 0; Gl.GetShader(ShaderObject, ShaderParameter.CompileStatus, out shaderCompilationStatus); if (shaderCompilationStatus == 0) { // Get shader info length int shaderInfoLenght = 0; Gl.GetShader(ShaderObject, ShaderParameter.InfoLogLength, out shaderInfoLenght); // Get shader info text uint actualShaderInfoLength = 0; StringBuilder shaderInfo = new StringBuilder(shaderInfoLenght); Gl.GetShaderInfoLog(ShaderObject, (uint)shaderInfoLenght, out actualShaderInfoLength, shaderInfo); throw new ShaderException($"Shader failed to compile with the following error: {shaderInfo.ToString()}"); } }
static void Main(string[] args) { // Initialize GLFW int result = Glfw.Init(); if (result == 0) { Console.WriteLine("Failed to initialize GLFW"); return; } // Display GLFW version initialized Console.WriteLine("GLFW Version: " + Marshal.PtrToStringAnsi(Glfw.GetVersionString())); // Set window creation hints Glfw.WindowHint((int)GlfwWindowHint.ContextVersionMajor, 3); Glfw.WindowHint((int)GlfwWindowHint.ContextVersionMinor, 2); // Create window IntPtr windowHandle = Glfw.CreateWindow(800, 600, "Seacow Engine", IntPtr.Zero, IntPtr.Zero); // Make the window's context current Glfw.MakeContextCurrent(windowHandle); // Display context information int majorVersion = Glfw.GetWindowAttrib(windowHandle, (int)GlfwWindowHint.ContextVersionMajor); int minorVersion = Glfw.GetWindowAttrib(windowHandle, (int)GlfwWindowHint.ContextVersionMinor); Console.WriteLine("OpenGL Major Version: " + majorVersion); Console.WriteLine("OpenGL Minor Version: " + minorVersion); // Set GLFW input callback Glfw.SetKeyCallback(windowHandle, Marshal.GetFunctionPointerForDelegate(callback)); // Own init stuff Renderer myRenderer = new Renderer(); Shader myVertexShader = new Shader("Data/Shaders/Vertex.Shader", ShaderType.VertexShader); Shader myFragmentShader = new Shader("Data/Shaders/Fragment.Shader", ShaderType.FragmentShader); Material mySimpleMaterial = new Material(new List <Shader>() { myVertexShader, myFragmentShader }); // Load texture Texture dirtTexture = new Texture("Data/Textures/simpleTex.bmp"); // Load sphere ObjLoader experimentalLoader = new ObjLoader("Data/Models/sphere/textureSphere.obj"); ModelData experimentalModelData = experimentalLoader.LoadModel(); ObjWeaver objWeave = new ObjWeaver(); var weavedModelData = objWeave.WeaveModelData(experimentalModelData); // Load box ObjLoader boxLoader = new ObjLoader("Data/Models/Box/simpleBox.obj"); ModelData boxModelData = boxLoader.LoadModel(); ObjWeaver boxModelDataWeaver = new ObjWeaver(); var weavedBoxModelData = boxModelDataWeaver.WeaveModelData(boxModelData); // Create sphere mySphere = new Mesh( weavedModelData.weavedVertexData, weavedModelData.indexes.Select(i => (uint)i).ToList(), mySimpleMaterial, dirtTexture); mySphere.Scale = 0.1f; mySphere.Position = new vec3(0.3f, 1.0f, 0.0f); mySimpleMaterial.Activate(); // Create box Mesh myBox = new Mesh( weavedBoxModelData.weavedVertexData, weavedBoxModelData.indexes.Select(i => (uint)i).ToList(), mySimpleMaterial ); myBox.Position = vec3.UnitX * 1; myBox.Scale = 0.5f; myBox.UserColor = new Vector3(0.0f, 0.0f, 1.0f); // Create indicator sphere indicatorSphere = new Mesh( weavedModelData.weavedVertexData, weavedModelData.indexes.Select(i => (uint)i).ToList(), mySimpleMaterial ); indicatorSphere.UserColor = new Vector3(1.0f, 0.0f, 0.0f); indicatorSphere.Scale = 0.1f; // Add objects to world myRenderer.WorldMeshes.Add(mySphere); myRenderer.WorldMeshes.Add(myBox); //myRenderer.WorldMeshes.Add(indicatorSphere); // ** Do all sorts of fun collision stuff! :D :D ** Aabb colBox = new Aabb(new Vector3(0.5f, -0.5f, -0.5f), new Vector3(1.5f, 0.5f, 0.5f)); Vector3 circlePoint = new Vector3(mySphere.Position.x, mySphere.Position.y, mySphere.Position.z); // Enable depth testing Gl.Enable((uint)Capability.DepthTest); Gl.CheckForError(); const double dt = 0.01; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); double currentTime = stopwatch.ElapsedMilliseconds / 1000.0f; double accumulator = 0.0; while (Glfw.WindowShouldClose(windowHandle) == 0) { // Timer stuff double newTime = stopwatch.ElapsedMilliseconds / 1000.0f; double frameTime = newTime - currentTime; currentTime = newTime; accumulator += frameTime; int counter = 0; // Fixed timestep while (accumulator >= dt) { Sphere theSphere = new Sphere(new Vector3(mySphere.Position.x, mySphere.Position.y, mySphere.Position.z), 0.1f); var colResult = IntersectionDetector.TestSphereAgainstAabb(theSphere, colBox); if (colResult) { Console.WriteLine("COLLISION"); } //Integrate(dt); accumulator -= dt; } // Rendering Gl.ClearColor(0.39f, 0.58f, 0.92f, 0.0f); Gl.CheckForError(); Gl.Clear((int)ColorBit.ColorBuffer | (int)ColorBit.DepthBuffer); Gl.CheckForError(); myRenderer.Render((float)(accumulator / dt)); Glfw.SwapBuffers(windowHandle); Glfw.PollEvents(); } Glfw.Terminate(); }
public void DeActivate() { Gl.UseProgram(0); Gl.CheckForError(); }
public void Activate() { Gl.UseProgram(ProgramObject); Gl.CheckForError(); }
public Mesh(List <float> vertices, List <uint> indices, Material material) { this.vertices = vertices; this.indices = indices; Material = material; Orientation = quat.Identity; Position = vec3.Zero; Scale = 1.0f; UserColor = new Vector3(1.0f, 1.0f, 1.0f); /* * A VAO (Vertex Array Object) stores state needed to supply vertex data from the application * To the vertex shader during what is called the "vertex fetch" stage. * * This state includes the buffer object bound when the VAO was active, * And other vertex array related states, such as glEnableVertexAttribArray and * glVertexAttribPointer. * * In order for a vertex attribute to be used, it must be manually enabled! * * In the OpenGL core profile, it is required to use a VAO. * * Also, remember that the actual VBO is NOT a part of the VAO state!!!! Which would * Totally make sense, but is not the case. So remember to actually bind the relevant * VBO when you bind your VAO! */ uint[] generatedVertexArray = new uint[1]; Gl.GenVertexArrays(2, generatedVertexArray); Gl.CheckForError(); vertexArrayObject = (int)generatedVertexArray[0]; // Bind the vertex array Gl.BindVertexArray((uint)vertexArrayObject); Gl.CheckForError(); // Generate a vertex buffer object to store vertex data for the mesh uint[] generatedVBOs = new uint[1]; Gl.GenBuffers(1, generatedVBOs); Gl.CheckForError(); var vertexBufferObject = (int)generatedVBOs[0]; // Bind the vertex buffer object to store vertex data for the mesh Gl.BindBuffer(BufferTarget.Array, (uint)vertexBufferObject); Gl.CheckForError(); /* Enable vertex attribute at location 0 and 1 in the vertex shader * Location 0 = Vertex Buffer Object * Location 1 = Texture Coordinates * */ Gl.EnableVertexAttribArray(0); Gl.CheckForError(); Gl.EnableVertexAttribArray(1); Gl.CheckForError(); // Specif vertex buffer layout Gl.VertexAttribPointer(0, 3, VertexAttribPointerDataType.Float, 0, sizeof(float) * 5, (IntPtr)0); Gl.CheckForError(); Gl.VertexAttribPointer(1, 2, VertexAttribPointerDataType.Float, 0, sizeof(float) * 5, (IntPtr)(sizeof(float) * 3)); Gl.CheckForError(); // Upload vertex data Gl.BufferData(BufferTarget.Array, (vertices.Count * sizeof(float)), vertices.ToArray(), BufferUsageHint.StaticDraw); Gl.CheckForError(); /* * Element buffer objects are used for indexed rendering. * Indexed rendering can help overcome the problem of having duplicate * Vertices when rendering more complex meshes. * The way it works is that you have a VBO of vertices that your model consists of. * In this VBO, htere will be no overlapping/duplicated vertices. * * Instead, you then complement this VBO with an EBO. The EBO is simply an array of * Indices, each consecutive 3 indices representing one triangle. Each index is an * Index into the vertex elements of the VBO. * * This way, you can specify exactly which vertices to use for each triangle. * More importantly, you can reuse vertices for different triangles! * This gives major benefits in the reduction of vertices send to the GPU! * * The VAO also saves state related to GL_ELEMENT_ARRAY_BUFFER, which is the * Buffer target used for indexes for the vertex array */ uint[] elemBuffers = new uint[1]; Gl.GenBuffers(1, elemBuffers); Gl.CheckForError(); var elementBufferObject = elemBuffers[0]; // Bind buffer Gl.BindBuffer(BufferTarget.ElementArray, elementBufferObject); Gl.CheckForError(); // Upload index data Gl.BufferData(BufferTarget.ElementArray, (sizeof(uint) * indices.Count), indices.ToArray(), BufferUsageHint.StaticDraw); Gl.CheckForError(); // Clean up OpenGL state by unbinding Gl.BindVertexArray(0); Gl.CheckForError(); Gl.BindBuffer(BufferTarget.Array, 0); Gl.CheckForError(); Gl.BindBuffer(BufferTarget.ElementArray, 0); Gl.CheckForError(); }