I’ve been working on this for a couple of days now and I just can’t see what I’m doing wrong. I took some code that draws a square from two triangles and tried to simply add an index buffer object and everything just stopped rendering.
main.c
/*
* This example shows an example of setting up the projection matrix to enable control over 3d rendering.
* I also added an index to cut down on the vertices.
*
* This project includes two shader files: vs.glsl and fs.glsl
*
*/
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <math.h>
#define TRUE 1
#define FALSE 0
#define SCREEN_WIDTH 640.0
#define SCREEN_HEIGHT 480.0
#define IDENTITY_MATRIX4 { 1.0, 0.0, 0.0, 0.0,\
0.0, 1.0, 0.0, 0.0,\
0.0, 0.0, 1.0, 0.0,\
0.0, 0.0, 0.0, 1.0 }
typedef enum {
X_AXIS,
Y_AXIS,
Z_AXIS
} AXIS;
/* our loadShader function */
GLuint loadShader(const char *strShaderFile, GLenum type)
{
char shaderSource[4096];
char inChar;
FILE *shaderFile;
int i = 0;
shaderFile = fopen(strShaderFile, "r");
while(fscanf(shaderFile, "%c", &inChar) > 0)
{
shaderSource[i++] = inChar; /* load the file's characters into an array */
}
shaderSource[i-1] = '\0'; /* set the last character to NULL for future parsing. */
fclose(shaderFile);
puts(shaderSource); /* print the source to test loading */
GLuint shader = glCreateShader(type);
const char *ss = shaderSource;
glShaderSource(shader, 1, &ss, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE)
{
printf("Shader Compile error!
");
}
else
{
printf("Shader compiled successfully!
");
}
return shader;
}
/* our matrix math functions
*
*/
/* Multiply 4x4 matrix m1 by 4x4 matrix m2 and store the result in m1 */
void multiply4x4(GLfloat *m1, GLfloat *m2)
{
GLfloat temp[16];
int x,y;
for (x=0; x < 4; x++)
{
for(y=0; y < 4; y++)
{
temp[y + (x*4)] = (m1[x*4] * m2[y]) +
(m1[(x*4)+1] * m2[y+4]) +
(m1[(x*4)+2] * m2[y+8]) +
(m1[(x*4)+3] * m2[y+12]);
}
}
memcpy(m1, temp, sizeof(GLfloat) << 4);
}
/* Generate a perspective view matrix using a field of view angle fov,
* window aspect ratio, near and far clipping planes */
void perspective(GLfloat *matrix, GLfloat fov, GLfloat aspect, GLfloat nearz, GLfloat farz)
{
GLfloat range;
range = tan(fov * 0.00872664625) * nearz; /* 0.00872664625 = PI/360 */
memset(matrix, 0, sizeof(GLfloat) * 16);
matrix[0] = (2 * nearz) / ((range * aspect) - (-range * aspect));
matrix[5] = (2 * nearz) / (2 * range);
matrix[10] = -(farz + nearz) / (farz - nearz);
matrix[11] = -1;
matrix[14] = -(2 * farz * nearz) / (farz - nearz);
}
/* Perform translation operations on a matrix */
void translate(GLfloat *matrix, GLfloat x, GLfloat y, GLfloat z)
{
GLfloat newmatrix[16] = IDENTITY_MATRIX4;
newmatrix[12] = x;
newmatrix[13] = y;
newmatrix[14] = z;
multiply4x4(matrix, newmatrix);
}
/* Rotate a matrix by an angle on a X, Y, or Z axis */
void rotate(GLfloat *matrix, GLfloat angle, AXIS axis)
{
const GLfloat d2r = 0.0174532925199; /* PI / 180 */
const int cos1[3] = { 5, 0, 0 };
const int cos2[3] = { 10, 10, 5 };
const int sin1[3] = { 6, 2, 1 };
const int sin2[3] = { 9, 8, 4 };
GLfloat newmatrix[16] = IDENTITY_MATRIX4;
newmatrix[cos1[axis]] = cos(d2r * angle);
newmatrix[sin1[axis]] = -sin(d2r * angle);
newmatrix[sin2[axis]] = -newmatrix[sin1[axis]];
newmatrix[cos2[axis]] = newmatrix[cos1[axis]];
multiply4x4(matrix, newmatrix);
}
/*
* end math functions
*/
int main(int argc, char *argv[])
{
/* first let's initialize SDL */
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("Could not initialize SDL!: %s", SDL_GetError());
return 1;
}
/* create an event handler for the keyboard */
SDL_Event(event);
/* Now let's create our window */
SDL_Window *window = SDL_CreateWindow("two triangles with index! - perspective",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
/* because of OpenGL we will need to create the OpenGL context */
SDL_GLContext glContext = SDL_GL_CreateContext(window);
/* and test */
if(glContext == NULL)
{
printf("Unable to create OpenGL context: %s
", SDL_GetError());
return 1;
}
/* vsync */
SDL_GL_SetSwapInterval(1);
/* Next make the window current */
SDL_GL_MakeCurrent(window, glContext);
/* and make sure we specify a GL version */
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
printf("OpenGL version: %s
", glGetString(GL_VERSION));
/* Enable depth testing and which type of test we will do */
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
/* create our matrices for projection, model, and identity */
GLfloat projectionMatrix[16];
GLfloat modelMatrix[16];
const float identityMatrix[16] = IDENTITY_MATRIX4;
/* great, the SDL setup is done so we can start
* setting up the program.
* Let's define some variables.
*/
GLuint vao; /* our vertex array object */
GLuint vbo; /* our vertex buffer object */
GLuint ibo; /* our index buffer object */
GLuint programID; /* the program we will use to render the triangle */
/* lets create some vertices
*
* (-1,1)[0] (1,1)[3]
* *-------*
* | /|
* | / |
* | / |
* | / |
* | / |
* | / |
* |/ |
* *-------*
* (-1,-1)[1] (1,-1)[2]
*/
/* old
GLfloat vertexData[] = {
-1.0f, 1.0f, 0.0f,
-1.0f,-1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f,-1.0f, 0.0f,
1.0f,-1.0f, 0.0f
};
*/
/* new! */
GLfloat vertices[] = {
-1.0, 1.0, 0.0,
1.0,-1.0, 0.0,
1.0,-1.0, 0.0,
1.0, 1.0, 0.0
};
/* our index for the shared vertices */
GLuint indices[] = {
0, 1, 3,
3, 1, 2
};
/* let's load our shaders */
GLuint vertexShader;
GLuint fragmentShader;
GLuint linked; /* for testing if the shaders linked correctly. */
vertexShader = loadShader("vs.glsl", GL_VERTEX_SHADER); /* loadShader has been previously defined. */
fragmentShader = loadShader("fs.glsl", GL_FRAGMENT_SHADER);
/* activate our shader program. */
programID = glCreateProgram();
glAttachShader(programID, vertexShader);
glAttachShader(programID, fragmentShader);
glBindAttribLocation(programID, 0, "in_Position");
glLinkProgram(programID);
glGetProgramiv(programID, GL_LINK_STATUS, &linked);
glUseProgram(programID);
/* generate our objects */
glGenVertexArrays(1, &vao); /* generate array using previously defined "vao" variable as id storage */
glBindVertexArray(vao); /* bind the array for use */
glGenBuffers(1, &vbo); /* generate Vertex Buffer Objext and store id in "vbo" */
glBindBuffer(GL_ARRAY_BUFFER, vbo); /* bind it for use */
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); /* store our vertex data "vertexData" into our vbo */
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices), NULL); /* specify how to use the vertex data */
if(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
{
printf("Framebuffer ok!
");
}
else
{
printf("Error creating fremebuffer!
");
glDeleteVertexArrays(&vao);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
glEnableVertexAttribArray(0); /* connect to the 0 attibute of the vertex shader */
glGenBuffers(1, &ibo); /* generate the index buffer object */
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); /* bind it for definition */
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); /* the definition */
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); /* unbind the ibo */
glBindBuffer(GL_ARRAY_BUFFER, 0); /* unbind the vbo */
glBindVertexArray(0); /* unbind the vao */
/* now that the vbo and vao are defined and populated we may proceed to drawing stuff! */
unsigned short int running = TRUE;
glClearColor(0.2, 0.2, 0.2, 1); /* background */
/* our projection matrix with 45 degree FOV, a width to height ratio , and view .1 to 100 in front of us */
perspective(projectionMatrix, 45.0, SCREEN_WIDTH/SCREEN_HEIGHT, 0.1, 100);
/* degree will be used to rotate our object */
unsigned short int degree = 0;
int z = -1; /* used for controlling the z axis */
while(running)
{
/* check for keyboard events */
if(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
running = FALSE;
else if(event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE )
running = FALSE;
else if(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_UP)
z--;
else if(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_DOWN)
z++;
}
/* move the identity matrix into model matrix, move it back 5 */
memcpy(modelMatrix, identityMatrix, sizeof(GLfloat)*16);
rotate(modelMatrix, (GLfloat)degree * 1.0, Y_AXIS);
translate(modelMatrix, 0, 0, z);
if( degree > 360 )
{
degree = 0;
}
else
{
degree++;
}
/* multiply our model matrix and our projection matrix, results are stored in modelMatrix */
multiply4x4(modelMatrix, projectionMatrix);
/* bind our model matrix to mvpMatrix in our shader program */
glUniformMatrix4fv(glGetUniformLocation(programID, "mvpMatrix"), 1, GL_FALSE, modelMatrix);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* clear the color buffer and depth buffer after each frame with the background color */
/* lets draw the triangle! */
glBindVertexArray(vao); /* bind the vao we want to work with ("vao" in this case) */
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (GLvoid*)0); /* draw a triangle! */
//printf("glError: %i
", glGetError());
glBindVertexArray(0); /* now unbind it */
/* SDL2 */
SDL_GL_SwapWindow(window); /* this swaps the video memory to the window allowing us to see it */
SDL_Delay(20); /* It's very important to allow some cpu to go to other processes on the computer, SDL_Delay does just that. */
}
/* cleanup */
glUseProgram(0);
glDisableVertexAttribArray(0);
glDetachShader(programID, vertexShader);
glDetachShader(programID, fragmentShader);
glDeleteProgram(programID);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteBuffers(1, &ibo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
SDL_GL_DeleteContext(glContext);
SDL_DestroyWindow(window);
SDL_Quit();
return 0; /* end our program */
}
vs.glsl
#version 130
in vec3 in_Position;
//mvp matrix is the result of multiplying the model, view, and projection matrices
uniform mat4 mvpMatrix;
void main()
{
// multiply the mvpMatrix by the vertex to obtain our final vertex position
gl_Position = mvpMatrix * vec4(in_Position, 1.0);
}
fs.glsl
#version 130
out vec4 outputColor;
void main()
{
outputColor = vec4(1.0, 0.7, 0.0, 1.0);
}
It also may be my old laptop since it’s running linux.
Any help would be appreciated!