
Index Draws - My code does not work
Posted Monday, 7 February, 2011 - 02:13 by flopoloco inHi there I try to port some example to OpenTK.
Here's the original C++ code
http://ogldev.atspace.org/www/tutorial10/tutorial10.html
/* Copyright 2010 Etay Meiri This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Tutorial 10 - Indexed draws */ #include <stdio.h> #include <string.h> #include <assert.h> #include <math.h> #include <GL/glew.h> #include <GL/freeglut.h> #include "math_3d.h" GLuint VBO; GLuint IBO; GLuint gWorldLocation; static const char* pVS = " \n\ #version 330 \n\ \n\ layout (location = 0) in vec3 Position; \n\ \n\ uniform mat4 gWorld; \n\ \n\ out vec4 Color; \n\ \n\ void main() \n\ { \n\ gl_Position = gWorld * vec4(Position, 1.0); \n\ Color = vec4(clamp(Position, 0.0, 1.0), 1.0); \n\ }"; static const char* pFS = " \n\ #version 330 \n\ \n\ in vec4 Color; \n\ \n\ out vec4 FragColor; \n\ \n\ void main() \n\ { \n\ FragColor = Color; \n\ }"; static void RenderSceneCB() { glClear(GL_COLOR_BUFFER_BIT); static float Scale = 0.0f; Scale += 0.001f; Matrix4f World; World.m[0][0] = cosf(Scale); World.m[0][1] = 0.0f; World.m[0][2] = -sinf(Scale); World.m[0][3] = 0.0f; World.m[1][0] = 0.0; World.m[1][1] = 1.0f; World.m[1][2] = 0.0f ; World.m[1][3] = 0.0f; World.m[2][0] = sinf(Scale); World.m[2][1] = 0.0f; World.m[2][2] = cosf(Scale) ; World.m[2][3] = 0.0f; World.m[3][0] = 0.0f; World.m[3][1] = 0.0f; World.m[3][2] = 0.0f ; World.m[3][3] = 1.0f; glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, &World.m[0][0]); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glutSwapBuffers(); } static void InitializeGlutCallbacks() { glutDisplayFunc(RenderSceneCB); glutIdleFunc(RenderSceneCB); } static void CreateVertexBuffer() { Vector3f Vertices[4]; Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f); Vertices[1] = Vector3f(0.0f, -1.0f, 1.0f); Vertices[2] = Vector3f(1.0f, -1.0f, 0.0f); Vertices[3] = Vector3f(0.0f, 1.0f, 0.0f); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); } static void CreateIndexBuffer() { unsigned int Indices[] = { 0, 3, 1, 1, 3, 2, 2, 3, 0, 0, 2, 1 }; glGenBuffers(1, &IBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); } static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType) { GLuint ShaderObj = glCreateShader(ShaderType); if (ShaderObj == 0) { fprintf(stderr, "Error creating shader type %d\n", ShaderType); exit(0); } const GLchar* p[1]; p[0] = pShaderText; GLint Lengths[1]; Lengths[0]= strlen(pShaderText); glShaderSource(ShaderObj, 1, p, Lengths); glCompileShader(ShaderObj); GLint success; glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success); if (!success) { GLchar InfoLog[1024]; glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog); fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog); exit(1); } glAttachShader(ShaderProgram, ShaderObj); } static void CompileShaders() { GLuint ShaderProgram = glCreateProgram(); if (ShaderProgram == 0) { fprintf(stderr, "Error creating shader program\n"); exit(1); } AddShader(ShaderProgram, pVS, GL_VERTEX_SHADER); AddShader(ShaderProgram, pFS, GL_FRAGMENT_SHADER); GLint Success = 0; GLchar ErrorLog[1024] = { 0 }; glLinkProgram(ShaderProgram); glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success); if (Success == 0) { glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog); exit(1); } glValidateProgram(ShaderProgram); glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success); if (!Success) { glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog); exit(1); } glUseProgram(ShaderProgram); gWorldLocation = glGetUniformLocation(ShaderProgram, "gWorld"); assert(gWorldLocation != 0xFFFFFFFF); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA); glutInitWindowSize(1024, 768); glutInitWindowPosition(100, 100); glutCreateWindow("Tutorial 10"); InitializeGlutCallbacks(); // Must be done after glut is initialized! GLenum res = glewInit(); if (res != GLEW_OK) { fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res)); return 1; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); CreateVertexBuffer(); CreateIndexBuffer(); CompileShaders(); glutMainLoop(); return 0; }
And Here's my C# OpenTK version.
using System; using System.Drawing; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace OpenTKIndexedDraws { class Program : GameWindow { string vertexShaderSource = @" #version 330 layout (location = 0) in vec3 Position; void main() { gl_Position = vec4(Position.x, Position.y, Position.z, 1.0); }"; string fragmentShaderSource = @" #version 330 out vec4 FragColor; void main() { FragColor = vec4(1.0, 1.0, 1.0, 1.0); }"; int vbo, ibo; int shaderProgramHandle, vertexShaderHandle, fragmentShaderHandle; Vector3[] vertices; int[] indices; void CreateVertexBuffer() { vertices = new Vector3[] { new Vector3(-1.0f, -1.0f, 1.0f), new Vector3( 1.0f, -1.0f, 1.0f), new Vector3( 1.0f, 1.0f, 1.0f), new Vector3(-1.0f, 1.0f, 1.0f), new Vector3(-1.0f, -1.0f, -1.0f), new Vector3( 1.0f, -1.0f, -1.0f), new Vector3( 1.0f, 1.0f, -1.0f), new Vector3(-1.0f, 1.0f, -1.0f) }; GL.GenBuffers(1, out vbo); GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, new IntPtr(vertices.Length * Vector3.SizeInBytes), vertices, BufferUsageHint.StaticDraw); } void CreateIndexBuffer() { indices = new int[] { 0, 1, 2, 2, 3, 0, 3, 2, 6, 6, 7, 3, 7, 6, 5, 5, 4, 7, 4, 0, 3, 3, 7, 4, 0, 1, 5, 5, 4, 0, 1, 5, 6, 6, 2, 1 }; GL.GenBuffers(1, out ibo); GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo); GL.BufferData<int>(BufferTarget.ElementArrayBuffer, new IntPtr(indices.Length * sizeof(int)), indices, BufferUsageHint.StaticDraw); } void CreateShaders() { shaderProgramHandle = GL.CreateProgram(); vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader); fragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(vertexShaderHandle, vertexShaderSource); GL.ShaderSource(fragmentShaderHandle, fragmentShaderSource); GL.CompileShader(vertexShaderHandle); GL.CompileShader(fragmentShaderHandle); Console.WriteLine(GL.GetShaderInfoLog(vertexShaderHandle)); Console.WriteLine(GL.GetShaderInfoLog(fragmentShaderHandle)); GL.AttachShader(shaderProgramHandle, vertexShaderHandle); GL.AttachShader(shaderProgramHandle, fragmentShaderHandle); GL.LinkProgram(shaderProgramHandle); Console.WriteLine(GL.GetProgramInfoLog(shaderProgramHandle)); GL.UseProgram(shaderProgramHandle); } protected override void OnLoad(EventArgs e) { GL.ClearColor(Color.Brown); CreateVertexBuffer(); CreateIndexBuffer(); CreateShaders(); } protected override void OnRenderFrame(FrameEventArgs e) { GL.Clear(ClearBufferMask.ColorBufferBit); GL.EnableVertexAttribArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GL.VertexAttribPointer(0, vertices.Length, VertexAttribPointerType.Float, false, 0, 0); GL.BindBuffer(BufferTarget.ArrayBuffer, ibo); GL.DrawElements(BeginMode.Triangles, indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero); GL.DisableVertexAttribArray(0); SwapBuffers(); } public static void Main() { using (Program p = new Program()) { p.Run(60); } } } }
Do you know what's going on? Is there any OpenTK workarounds need to be done?
P.S: Most of the code is derived from this example http://www.opentk.com/node/2293 because I want to focus only on "indexed" draws.


Comments
Re: Index Draws - My code does not work
Your vertex shader looks rather strange.
What doesn't work?
Re: Index Draws - My code does not work
Here's a crash log (but does not say anything specific).
Fiddler, does it work on your machine?
(Maybe I will have to update my nVidia drivers).