// Now, we start initializing OpenGL. protected override void OnLoad() { // This will be the color of the background after we clear it, in normalized colors. // Normalized colors are mapped on a range of 0.0 to 1.0, with 0.0 representing black, and 1.0 representing // the largest possible value for that channel. // This is a deep green. GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f); GL.Enable(EnableCap.DepthTest); // We need to send our vertices over to the graphics card so OpenGL can use them. // To do this, we need to create what's called a Vertex Buffer Object (VBO). // These allow you to upload a bunch of data to a buffer, and send the buffer to the graphics card. // This effectively sends all the vertices at the same time. // First, we need to create a buffer. This function returns a handle to it, but as of right now, it's empty. ObjParser objParser = new ObjParser(); obj = objParser.GetVBOs(null, "Shaders\\denhouse1.obj"); //obj = objParser.GetVBOs(null, "Shaders\\cube.obj"); int vsize = obj[0].Length; float[] vArray = new float[vsize / 4]; //Copy source array data to floatArray (convert bytes to floats) System.Buffer.BlockCopy(obj[0], 0, vArray, 0, (int)vsize); int tsize = obj[1].Length; float[] tArray = new float[tsize / 4]; //Copy source array data to floatArray (convert bytes to floats) System.Buffer.BlockCopy(obj[1], 0, tArray, 0, (int)tsize); int rFloatSize = vsize / 4 + tsize / 4; float[] rArray = new float[rFloatSize]; uint[] ind = new uint[rFloatSize / 5]; int vcount = 0; int tcount = 0; uint indCount = 0; for (int i = 0; i < rFloatSize; i += 5) { rArray[i + 0] = vArray[vcount + 0]; rArray[i + 1] = vArray[vcount + 1]; rArray[i + 2] = vArray[vcount + 2]; rArray[i + 3] = tArray[tcount + 0]; rArray[i + 4] = tArray[tcount + 1]; vcount += 3; tcount += 2; ind[indCount] = indCount; indCount++; } // shader.frag has been modified yet again, take a look at it as well. _shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag"); _shader.Use(); //Vertexes -------------------------------- _vertexArrayObject = GL.GenVertexArray(); GL.BindVertexArray(_vertexArrayObject); _vertexBufferObject = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferObject); GL.BufferData(BufferTarget.ArrayBuffer, rFloatSize * sizeof(float), rArray, BufferUsageHint.StaticDraw); _elementBufferObject = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _elementBufferObject); GL.BufferData(BufferTarget.ElementArrayBuffer, rFloatSize / 5 * sizeof(uint), ind, BufferUsageHint.StaticDraw); // The shaders have been modified to include the texture coordinates, check them out after finishing the OnLoad function. _shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag"); _shader.Use(); // Because there's now 5 floats between the start of the first vertex and the start of the second, // we modify this from 3 * sizeof(float) to 5 * sizeof(float). // This will now pass the new vertex array to the buffer. var vertexLocation = _shader.GetAttribLocation("aPosition"); GL.EnableVertexAttribArray(vertexLocation); GL.VertexAttribPointer(vertexLocation, 3, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0); // Next, we also setup texture coordinates. It works in much the same way. // We add an offset of 3, since the first vertex coordinate comes after the first vertex // and change the amount of data to 2 because there's only 2 floats for vertex coordinates var texCoordLocation = _shader.GetAttribLocation("aTexCoord"); GL.EnableVertexAttribArray(texCoordLocation); GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float)); //_texture = Texture.LoadFromFile("Shaders/den_housetextutre.png"); _texture = Texture.LoadFromFile("Shaders/housetex1.png"); //_texture = Texture.LoadFromFile("Shaders/skin.png"); // Texture units are explained in Texture.cs, at the Use function. // First texture goes in texture unit 0. _texture.Use(TextureUnit.Texture0); _camera = new Camera(Vector3.UnitZ * 3, Size.X / (float)Size.Y); // Setup is now complete! Now we move to the OnRenderFrame function to finally draw the triangle. base.OnLoad(); }