flopoloco's picture

Index Draws - My code does not work

Hi 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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Your vertex shader looks rather strange.

What doesn't work?

flopoloco's picture

Here's a crash log (but does not say anything specific).

Problem signature:
  Problem Event Name:	APPCRASH
  Application Name:	OpenTKIndexedDraws.exe
  Application Version:	1.0.4055.7458
  Application Timestamp:	4d4f5424
  Fault Module Name:	nvoglv32.DLL
  Fault Module Version:	8.17.12.6658
  Fault Module Timestamp:	4d27c3d6
  Exception Code:	c0000005
  Exception Offset:	006fd184
  OS Version:	6.1.7600.2.0.0.256.1
  Locale ID:	1032
  Additional Information 1:	0a9e
  Additional Information 2:	0a9e372d3b4ad19135b953a78882e789
  Additional Information 3:	0a9e
  Additional Information 4:	0a9e372d3b4ad19135b953a78882e789
 
Read our privacy statement online:
  http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409
 
If the online privacy statement is not available, please read our privacy statement offline:
  C:\Windows\system32\en-US\erofflps.txt

Fiddler, does it work on your machine?
(Maybe I will have to update my nVidia drivers).