So I've recently tried to add Vertex Buffer Object Matrix transformation to an OpenGL engine I'm working on. I could go about this by applying the matrix to a copy of each vertex individually, but this would take a lot of CPU resources, so I am trying to implement transformation natively using OpenGL. This code works:
/// <summary>
/// Sets up the required OpenGL settings so as to create the necessary environment for the models to work (must be called on a thread on which an OpenGL context is set up, preferably on the thread on which the model was loaded).
/// </summary>
public static void Setup(Size viewPort, ref Matrix4 camera) {
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix();
if (!(viewPort.Width == 0 || viewPort.Height == 0)) {
Matrix4 matrix;
Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver3F, (float) viewPort.Width / viewPort.Height, 0.01F, long.MaxValue, out matrix);
GL.LoadMatrix(ref matrix);
}
GL.MatrixMode(MatrixMode.Modelview);
GL.PushMatrix();
Camera = camera;
GL.LoadMatrix(ref Camera);
GL.Enable(EnableCap.DepthTest);
GL.Enable(EnableCap.Lighting);
}
/// <summary>
/// Renders the model (must be called on a thread on which an OpenGL context is set up, preferably on the thread on which the model was loaded).
/// </summary>
public override void Render() {
if (IsVisible) {
/*Matrix4 matrix = Matrix4.CreateTranslation(location);
GL.MultMatrix(ref matrix);*/
if (Cull)
GL.Enable(EnableCap.CullFace);
else
GL.Disable(EnableCap.CullFace);
texture.Bind();
if (DataBuffer == 0) {
GL.GenBuffers(1, out DataBuffer);
GL.BindBuffer(BufferTarget.ArrayBuffer, DataBuffer);
GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, BufferSize, BufferData, Optimization);
} else {
GL.BindBuffer(BufferTarget.ArrayBuffer, DataBuffer);
if (UpdateFrame) {
GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, BufferSize, BufferData, Optimization);
UpdateFrame = false;
}
}
IndexBuffer.Bind();
GL.VertexPointer(3, VertexPointerType.Float, Vertex.SizeOfVertex, IntPtr.Zero);
GL.TexCoordPointer(2, TexCoordPointerType.Float, Vertex.SizeOfVertex, TexturePointer);
GL.NormalPointer(NormalPointerType.Float, Vertex.SizeOfVertex, NormalPointer);
GL.DrawElements(BeginMode.Triangles, IndexBuffer.Count, IndexBuffer.Format, IntPtr.Zero);
GL.Disable(EnableCap.CullFace);
//GL.LoadMatrix(ref Camera);
}
}
/// <summary>
/// Resets the OpenGL settings set by calling Setup().
/// </summary>
public static void Reset() {
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix();
}
First Setup() is called to set up the projection matrix, then several meshes are rendered using the Render() method, then Reset() is called at the end to restore the matrices before I swap the buffers to the window.
However, when I comment out the commented lines in order to apply a simple translation matrix, I only get flickers all over the window. I tried using GL.Push() and GL.Pop() at the beginning and end of the Render() method, but to no avail. I also tried using GL.LoadIdentity() first and GL.MatrixMode(MatrixMode.Projection), but still no success.
Can anyone be kind enough to point out the mistake in my code please?