
Polygons Not Drawn According to Index and Vertex Data
Posted Sunday, 6 February, 2011 - 11:05 by GraysonPeddie inHi, everyone. My name is Grayson Peddie and I am brand new to the forum and I am transitioning away from Managed DirectX 1.1 to 2.0 to XNA and then to OpenTK, since I'd like to try out developing for OpenGL with OpenTK.
So, since this is my first post, I am having a problem with my code. Note that I am used to creating vertex and index buffer for a simple cube and with OpenTK/OpenGL, it's taking me a while to figure out what's going on but then I couldn't figure out my problem.
First, I'm going to preset you with my code with the following images.:
ushort[] indicesVboData = new ushort[]{ 0, 1, 2, 2, 3, 0, // Front 3, 2, 5, 5, 4, 3, // Top 1, 6, 5, 5, 2, 1, // Right 7, 6, 5, 5, 4, 7, // Back 7, 6, 1, 1, 0, 7, // Bottom 7, 0, 3, 3, 4, 7}; // Left
ushort[] indicesVboData = new ushort[]{ 0, 1, 2, 2, 3, 0, // Front 3, 2, 5, 5, 4, 3, // Top 1, 6, 5, 5, 2, 1, // Right 7, 6, 5, 5, 4, 7, // Back 7, 6, 1, 1, 0, 7/*, // Bottom 7, 0, 3, 3, 4, 7*/}; // Left
ushort[] indicesVboData = new ushort[]{ 0, 1, 2, 2, 3, 0, // Front 3, 2, 5, 5, 4, 3/*, // Top 1, 6, 5, 5, 2, 1, // Right 7, 6, 5, 5, 4, 7, // Back 7, 6, 1, 1, 0, 7, // Bottom 7, 0, 3, 3, 4, 7*/}; // Left
ushort[] indicesVboData = new ushort[]{ 0, 1, 2, 2, 3, 0/*, // Front 3, 2, 5, 5, 4, 3, // Top 1, 6, 5, 5, 2, 1, // Right 7, 6, 5, 5, 4, 7, // Back 7, 6, 1, 1, 0, 7, // Bottom 7, 0, 3, 3, 4, 7*/}; // Left
So, my question is, can anyone please tell me what's going on with my code as seen below?
using System; using System.Diagnostics; using System.IO; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace HelloOpenGL { class MainGame : GameWindow { string vertexShaderSource, fragmentShaderSource; int vertexShaderHandle, fragmentShaderHandle, shaderProgramHandle, worldMatrixLocation, viewMatrixLocation, projectionMatrixLocation; int vboHandle, indicesVboHandle; Vector3[] cubePositionData = new Vector3[]{ new Vector3(-0.5f, -0.5f, 0.5f), new Vector3( 0.5f, -0.5f, 0.5f), new Vector3( 0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, -0.5f), new Vector3( 0.5f, 0.5f, -0.5f), new Vector3( 0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, -0.5f)}; Vector3[] cubeNormalData = new Vector3[]{ new Vector3( 0.0f, 0.0f, 1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector3(-1.0f, 0.0f, 0.0f)}; VertexPositionNormal[] verts; Matrix4 matProjection, matView, matWorld; ushort[] indicesVboData = new ushort[]{ 0, 1, 2, 2, 3, 0, // Front 3, 2, 5, 5, 4, 3, // Top 1, 6, 5, 5, 2, 1, // Right 7, 6, 5, 5, 4, 7, // Back 7, 6, 1, 1, 0, 7/*, // Bottom 7, 0, 3, 3, 4, 7*/}; // Left public MainGame() : base(1280, 720, new GraphicsMode(new ColorFormat(32)), "Hello OpenGL!", 0, DisplayDevice.Default, 3, 1, GraphicsContextFlags.Debug) { } protected override void OnLoad(EventArgs e) { base.OnLoad(e); verts = new VertexPositionNormal[]{ new VertexPositionNormal(cubePositionData[0], cubeNormalData[0]), new VertexPositionNormal(cubePositionData[1], cubeNormalData[0]), new VertexPositionNormal(cubePositionData[2], cubeNormalData[0]), new VertexPositionNormal(cubePositionData[3], cubeNormalData[0]), new VertexPositionNormal(cubePositionData[3], cubeNormalData[1]), new VertexPositionNormal(cubePositionData[2], cubeNormalData[1]), new VertexPositionNormal(cubePositionData[5], cubeNormalData[1]), new VertexPositionNormal(cubePositionData[4], cubeNormalData[1]), new VertexPositionNormal(cubePositionData[1], cubeNormalData[2]), new VertexPositionNormal(cubePositionData[6], cubeNormalData[2]), new VertexPositionNormal(cubePositionData[5], cubeNormalData[2]), new VertexPositionNormal(cubePositionData[2], cubeNormalData[2]), new VertexPositionNormal(cubePositionData[6], cubeNormalData[3]), new VertexPositionNormal(cubePositionData[7], cubeNormalData[3]), new VertexPositionNormal(cubePositionData[4], cubeNormalData[3]), new VertexPositionNormal(cubePositionData[5], cubeNormalData[3]), new VertexPositionNormal(cubePositionData[7], cubeNormalData[4]), new VertexPositionNormal(cubePositionData[6], cubeNormalData[4]), new VertexPositionNormal(cubePositionData[1], cubeNormalData[4]), new VertexPositionNormal(cubePositionData[0], cubeNormalData[4]), new VertexPositionNormal(cubePositionData[7], cubeNormalData[5]), new VertexPositionNormal(cubePositionData[0], cubeNormalData[5]), new VertexPositionNormal(cubePositionData[3], cubeNormalData[5]), new VertexPositionNormal(cubePositionData[4], cubeNormalData[5])}; vertexShaderSource = ReadFileToString("Shaders\\main.vert"); fragmentShaderSource = ReadFileToString("Shaders\\main.frag"); CreateShaders(); CreateProgram(); GL.UseProgram(shaderProgramHandle); QueryMatrixLocations(); float aspectRatio = (float)(ClientSize.Width) / (float)(ClientSize.Height); SetProjectionMatrix(Matrix4.CreatePerspectiveFieldOfView( ((float)(Math.PI) / 180.0f) * 45.0f, aspectRatio, 1.0f, 20.0f)); SetViewMatrix(Matrix4.CreateRotationX(0.5f) * Matrix4.CreateTranslation(0, 0, -8)); GL.GenBuffers(1, out vboHandle); GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandle); GL.BufferData<VertexPositionNormal>(BufferTarget.ArrayBuffer, new IntPtr(verts.Length * VertexPositionNormal.SizeInBytes), verts, BufferUsageHint.StaticDraw); LoadVertexType(0, "vertexPosition"); LoadVertexType(1, "vertexNormal"); indicesVboHandle = LoadIndexer(); GL.Enable(EnableCap.DepthTest); GL.ClearColor(Color4.Black); Keyboard.KeyDown += new EventHandler<OpenTK.Input.KeyboardKeyEventArgs>(Keyboard_KeyDown); this.WindowBorder = OpenTK.WindowBorder.Fixed; } private string ReadFileToString(string fileName) { // This is for loading two files (main.vert and main.frag for vertex and // fragment shader. Nothing relevant. } private void CreateShaders() { vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader); GL.ShaderSource(vertexShaderHandle, vertexShaderSource); GL.CompileShader(vertexShaderHandle); Console.WriteLine(GL.GetShaderInfoLog(vertexShaderHandle)); fragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(fragmentShaderHandle, fragmentShaderSource); GL.CompileShader(fragmentShaderHandle); Console.WriteLine(GL.GetShaderInfoLog(fragmentShaderHandle)); } private void CreateProgram() { shaderProgramHandle = GL.CreateProgram(); GL.AttachShader(shaderProgramHandle, vertexShaderHandle); GL.AttachShader(shaderProgramHandle, fragmentShaderHandle); GL.LinkProgram(shaderProgramHandle); Console.WriteLine(GL.GetProgramInfoLog(shaderProgramHandle)); } private void QueryMatrixLocations() { projectionMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "projection_matrix"); viewMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "view_matrix"); worldMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "world_matrix"); } private void SetWorldMatrix(Matrix4 matrix) { matWorld = matrix; GL.UniformMatrix4(worldMatrixLocation, false, ref matWorld); } private void SetViewMatrix(Matrix4 matrix) { matView = matrix; GL.UniformMatrix4(viewMatrixLocation, false, ref matView); } private void SetProjectionMatrix(Matrix4 matrix) { matProjection = matrix; GL.UniformMatrix4(projectionMatrixLocation, false, ref matProjection); } private void LoadVertexType(int index, string type) { GL.EnableVertexAttribArray(index); GL.BindAttribLocation(shaderProgramHandle, index, type); GL.VertexAttribPointer(index, 3, VertexAttribPointerType.Float, false, VertexPositionNormal.SizeInBytes, 0); } private int LoadIndexer() { int handle; GL.GenBuffers( 1, out handle ); GL.BindBuffer( BufferTarget.ElementArrayBuffer, handle ); GL.BufferData<ushort>( BufferTarget.ElementArrayBuffer, new IntPtr( indicesVboData.Length * sizeof(ushort) ), indicesVboData, BufferUsageHint.StaticDraw ); return handle; } void Keyboard_KeyDown(object sender, OpenTK.Input.KeyboardKeyEventArgs e) { switch (e.Key) { case OpenTK.Input.Key.Escape: Exit(); break; } } protected override void OnUpdateFrame(FrameEventArgs e) { } float rotateY = 0; protected override void OnRenderFrame(FrameEventArgs e) { GL.Viewport(0, 0, this.Width, this.Height); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); matWorld = Matrix4.CreateTranslation(0, 0, 0); SetViewMatrix(matView); SetWorldMatrix(Matrix4.CreateRotationY((float)e.Time + rotateY) * Matrix4.CreateTranslation(0, 0, 0)); GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandle); GL.VertexPointer(3, VertexPointerType.Float, 0, 0); GL.NormalPointer(NormalPointerType.Float, 0, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, indicesVboHandle); GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.NormalArray); GL.EnableClientState(ArrayCap.IndexArray); GL.DrawElements(BeginMode.Triangles, indicesVboData.Length, DrawElementsType.UnsignedShort, 0); GL.DisableClientState(ArrayCap.VertexArray); GL.DisableClientState(ArrayCap.NormalArray); GL.DisableClientState(ArrayCap.IndexArray); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); rotateY += (float)Math.PI / 360.0f; GL.Flush(); SwapBuffers(); } } }
Here's my struct of VertexPositionNormal.
namespace HelloOpenGL { public struct VertexPositionNormal { public Vector3 position, normal; public VertexPositionNormal(float x, float y, float z, float nx, float ny, float nz) { position = new Vector3(x, y, z); normal = new Vector3(nx, ny, nz); } public VertexPositionNormal(Vector3 position, Vector3 normal) { this.position = position; this.normal = normal; } public static int SizeInBytes { get { return sizeof(float) * 6; } } } }
Here's the visual of how the vertices are numbered:






Comments
Re: Polygons Not Drawn According to Index and Vertex Data
One thing that stands out is that your winding order is incorrect - compare, for instance, your front and back faces. OpenGL (and D3D) use the winding order to distinguish between the front and back face of a polygon, following the right-hand rule.
Re: Polygons Not Drawn According to Index and Vertex Data
Well, what about this winding order from this website:
http://www.opentk.com/node/1039
What I have is here:
I'm only seeing 5 out of 12 polygons
Re: Polygons Not Drawn According to Index and Vertex Data
I'm only seeing 5 out of 12 polygons
Why did you change the front face indices? If you want to reproduce the working example, stick to the exact data.
Re: Polygons Not Drawn According to Index and Vertex Data
Well, I was going to modify it and that code above works the same as the example.
Re: Polygons Not Drawn According to Index and Vertex Data
Can't follow you. Check the examples in the OpenTK example browser, the OpenGL 3.x example uses indexed drawing based on what you referenced. See if that works out of the box.
Re: Polygons Not Drawn According to Index and Vertex Data
What they said
Re: Polygons Not Drawn According to Index and Vertex Data
Hi, guys. I finally got my cube rendered properly. It seems you'll need to have 24 vertices instead of 8 if you're going to have 4 vertices per side of the cube, since this will allow you to have individual control of texture coordinates and normals.
I apologize if anyone is not following me here.