Voxel engine to draw cubes

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












I am an amateur in OpenGl and for this reason I am seeking to learn only modern OpenGl the 4.x stuff. Once I had completed basic tutorials (rotating cubes, for example) I decided I would try and create a voxel-based program dealing solely with cubes. The goals of this program was to be fast, use limited CPU power and memory, and be dynamic so the map size can change and blocks will only be drawn if in the array it says the block is filled.



I have one VBO with the vertices and indexes of a cube built out of triangles. At the beginning of the render function I tell OpenGl the shaders to use and then bind the VBO; once that is complete I execute a loop.



Draw Cube Loop:



//The letter_max are the dimensions of the matrix created to store the voxel status in
// The method I use for getting and setting entries in the map are very efficient so I have not included it in this example
for(int z = -(z_max / 2); z < z_max - (z_max / 2); z++)

for(int y = -(y_max / 2); y < y_max - (y_max / 2); y++)

for(int x = -(x_max / 2); x < x_max - (x_max / 2); x++)

DrawCube(x, y, z);





Cube.c



#include "include/Project.h"

void CreateCube()

const Vertex VERTICES[8] =

-.5f, -.5f, .5f, 1 , 0, 0, 1, 1 ,
-.5f, .5f, .5f, 1 , 1, 0, 0, 1 ,
.5f, .5f, .5f, 1 , 0, 1, 0, 1 ,
.5f, -.5f, .5f, 1 , 1, 1, 0, 1 ,
-.5f, -.5f, -.5f, 1 , 1, 1, 1, 1 ,
-.5f, .5f, -.5f, 1 , 1, 0, 0, 1 ,
.5f, .5f, -.5f, 1 , 1, 0, 1, 1 ,
.5f, -.5f, -.5f, 1 , 0, 0, 1, 1
;

const GLuint INDICES[36] =

0,2,1, 0,3,2,
4,3,0, 4,7,3,
4,1,5, 4,0,1,
3,6,2, 3,7,6,
1,6,5, 1,2,6,
7,5,6, 7,4,5
;

ShaderIds[0] = glCreateProgram();
ExitOnGLError("ERROR: Could not create the shader program");

ShaderIds[1] = LoadShader("FragmentShader.glsl", GL_FRAGMENT_SHADER);
ShaderIds[2] = LoadShader("VertexShader.glsl", GL_VERTEX_SHADER);
glAttachShader(ShaderIds[0], ShaderIds[1]);
glAttachShader(ShaderIds[0], ShaderIds[2]);

glLinkProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not link the shader program");

ModelMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ModelMatrix");
ViewMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ViewMatrix");
ProjectionMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ProjectionMatrix");
ExitOnGLError("ERROR: Could not get shader uniform locations");

glGenVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not generate the VAO");
glBindVertexArray(BufferIds[0]);
ExitOnGLError("ERROR: Could not bind the VAO");

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
ExitOnGLError("ERROR: Could not enable vertex attributes");

glGenBuffers(2, &BufferIds[1]);
ExitOnGLError("ERROR: Could not generate the buffer objects");

glBindBuffer(GL_ARRAY_BUFFER, BufferIds[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the VBO to the VAO");

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)sizeof(VERTICES[0].Position));
ExitOnGLError("ERROR: Could not set VAO attributes");

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferIds[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the IBO to the VAO");

glBindVertexArray(0);


void DestroyCube()

glDetachShader(ShaderIds[0], ShaderIds[1]);
glDetachShader(ShaderIds[0], ShaderIds[2]);
glDeleteShader(ShaderIds[1]);
glDeleteShader(ShaderIds[2]);
glDeleteProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not destroy the shaders");

glDeleteBuffers(2, &BufferIds[1]);
glDeleteVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not destroy the buffer objects");


void DrawCube(float x, float y, float z)

ModelMatrix = IDENTITY_MATRIX;

TranslateMatrix(&ModelMatrix, x, y, z);
TranslateMatrix(&ModelMatrix, MainCamera.x, MainCamera.y, MainCamera.z);

glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, ModelMatrix.m);
glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, ViewMatrix.m);
ExitOnGLError("ERROR: Could not set the shader uniforms");


glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)0);
ExitOnGLError("ERROR: Could not draw the cube");



Here is a link to the github repository with the complete code.



The vertex shader only handles rotation and transformation of vertices and the fragment shader only deals with colour - they are not expensive to run so they are not the bottleneck.



How can this code be improved to render more efficiently and take full advantage of modern OpenGL features to decrease overhead?



P.S.
I am not looking for a book or a tool or an off-site resource as an answer. I have used backface culling and the OpenGL depth test to try and improve speed, however they haven't made a dramatic difference - it is still taking ~50ms to render a frame and that is too much for a voxel grid of 32*32*32.







share|improve this question





















  • Code does not compile . Best to post compilable code.
    – chux
    Jan 5 at 20:32










  • Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
    – Sam Onela
    Jan 5 at 21:08










  • @chux I have edited the question and added a link to my github repo with all of the code.
    – Oliver Strong
    Jan 5 at 22:14
















up vote
2
down vote

favorite












I am an amateur in OpenGl and for this reason I am seeking to learn only modern OpenGl the 4.x stuff. Once I had completed basic tutorials (rotating cubes, for example) I decided I would try and create a voxel-based program dealing solely with cubes. The goals of this program was to be fast, use limited CPU power and memory, and be dynamic so the map size can change and blocks will only be drawn if in the array it says the block is filled.



I have one VBO with the vertices and indexes of a cube built out of triangles. At the beginning of the render function I tell OpenGl the shaders to use and then bind the VBO; once that is complete I execute a loop.



Draw Cube Loop:



//The letter_max are the dimensions of the matrix created to store the voxel status in
// The method I use for getting and setting entries in the map are very efficient so I have not included it in this example
for(int z = -(z_max / 2); z < z_max - (z_max / 2); z++)

for(int y = -(y_max / 2); y < y_max - (y_max / 2); y++)

for(int x = -(x_max / 2); x < x_max - (x_max / 2); x++)

DrawCube(x, y, z);





Cube.c



#include "include/Project.h"

void CreateCube()

const Vertex VERTICES[8] =

-.5f, -.5f, .5f, 1 , 0, 0, 1, 1 ,
-.5f, .5f, .5f, 1 , 1, 0, 0, 1 ,
.5f, .5f, .5f, 1 , 0, 1, 0, 1 ,
.5f, -.5f, .5f, 1 , 1, 1, 0, 1 ,
-.5f, -.5f, -.5f, 1 , 1, 1, 1, 1 ,
-.5f, .5f, -.5f, 1 , 1, 0, 0, 1 ,
.5f, .5f, -.5f, 1 , 1, 0, 1, 1 ,
.5f, -.5f, -.5f, 1 , 0, 0, 1, 1
;

const GLuint INDICES[36] =

0,2,1, 0,3,2,
4,3,0, 4,7,3,
4,1,5, 4,0,1,
3,6,2, 3,7,6,
1,6,5, 1,2,6,
7,5,6, 7,4,5
;

ShaderIds[0] = glCreateProgram();
ExitOnGLError("ERROR: Could not create the shader program");

ShaderIds[1] = LoadShader("FragmentShader.glsl", GL_FRAGMENT_SHADER);
ShaderIds[2] = LoadShader("VertexShader.glsl", GL_VERTEX_SHADER);
glAttachShader(ShaderIds[0], ShaderIds[1]);
glAttachShader(ShaderIds[0], ShaderIds[2]);

glLinkProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not link the shader program");

ModelMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ModelMatrix");
ViewMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ViewMatrix");
ProjectionMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ProjectionMatrix");
ExitOnGLError("ERROR: Could not get shader uniform locations");

glGenVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not generate the VAO");
glBindVertexArray(BufferIds[0]);
ExitOnGLError("ERROR: Could not bind the VAO");

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
ExitOnGLError("ERROR: Could not enable vertex attributes");

glGenBuffers(2, &BufferIds[1]);
ExitOnGLError("ERROR: Could not generate the buffer objects");

glBindBuffer(GL_ARRAY_BUFFER, BufferIds[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the VBO to the VAO");

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)sizeof(VERTICES[0].Position));
ExitOnGLError("ERROR: Could not set VAO attributes");

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferIds[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the IBO to the VAO");

glBindVertexArray(0);


void DestroyCube()

glDetachShader(ShaderIds[0], ShaderIds[1]);
glDetachShader(ShaderIds[0], ShaderIds[2]);
glDeleteShader(ShaderIds[1]);
glDeleteShader(ShaderIds[2]);
glDeleteProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not destroy the shaders");

glDeleteBuffers(2, &BufferIds[1]);
glDeleteVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not destroy the buffer objects");


void DrawCube(float x, float y, float z)

ModelMatrix = IDENTITY_MATRIX;

TranslateMatrix(&ModelMatrix, x, y, z);
TranslateMatrix(&ModelMatrix, MainCamera.x, MainCamera.y, MainCamera.z);

glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, ModelMatrix.m);
glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, ViewMatrix.m);
ExitOnGLError("ERROR: Could not set the shader uniforms");


glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)0);
ExitOnGLError("ERROR: Could not draw the cube");



Here is a link to the github repository with the complete code.



The vertex shader only handles rotation and transformation of vertices and the fragment shader only deals with colour - they are not expensive to run so they are not the bottleneck.



How can this code be improved to render more efficiently and take full advantage of modern OpenGL features to decrease overhead?



P.S.
I am not looking for a book or a tool or an off-site resource as an answer. I have used backface culling and the OpenGL depth test to try and improve speed, however they haven't made a dramatic difference - it is still taking ~50ms to render a frame and that is too much for a voxel grid of 32*32*32.







share|improve this question





















  • Code does not compile . Best to post compilable code.
    – chux
    Jan 5 at 20:32










  • Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
    – Sam Onela
    Jan 5 at 21:08










  • @chux I have edited the question and added a link to my github repo with all of the code.
    – Oliver Strong
    Jan 5 at 22:14












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I am an amateur in OpenGl and for this reason I am seeking to learn only modern OpenGl the 4.x stuff. Once I had completed basic tutorials (rotating cubes, for example) I decided I would try and create a voxel-based program dealing solely with cubes. The goals of this program was to be fast, use limited CPU power and memory, and be dynamic so the map size can change and blocks will only be drawn if in the array it says the block is filled.



I have one VBO with the vertices and indexes of a cube built out of triangles. At the beginning of the render function I tell OpenGl the shaders to use and then bind the VBO; once that is complete I execute a loop.



Draw Cube Loop:



//The letter_max are the dimensions of the matrix created to store the voxel status in
// The method I use for getting and setting entries in the map are very efficient so I have not included it in this example
for(int z = -(z_max / 2); z < z_max - (z_max / 2); z++)

for(int y = -(y_max / 2); y < y_max - (y_max / 2); y++)

for(int x = -(x_max / 2); x < x_max - (x_max / 2); x++)

DrawCube(x, y, z);





Cube.c



#include "include/Project.h"

void CreateCube()

const Vertex VERTICES[8] =

-.5f, -.5f, .5f, 1 , 0, 0, 1, 1 ,
-.5f, .5f, .5f, 1 , 1, 0, 0, 1 ,
.5f, .5f, .5f, 1 , 0, 1, 0, 1 ,
.5f, -.5f, .5f, 1 , 1, 1, 0, 1 ,
-.5f, -.5f, -.5f, 1 , 1, 1, 1, 1 ,
-.5f, .5f, -.5f, 1 , 1, 0, 0, 1 ,
.5f, .5f, -.5f, 1 , 1, 0, 1, 1 ,
.5f, -.5f, -.5f, 1 , 0, 0, 1, 1
;

const GLuint INDICES[36] =

0,2,1, 0,3,2,
4,3,0, 4,7,3,
4,1,5, 4,0,1,
3,6,2, 3,7,6,
1,6,5, 1,2,6,
7,5,6, 7,4,5
;

ShaderIds[0] = glCreateProgram();
ExitOnGLError("ERROR: Could not create the shader program");

ShaderIds[1] = LoadShader("FragmentShader.glsl", GL_FRAGMENT_SHADER);
ShaderIds[2] = LoadShader("VertexShader.glsl", GL_VERTEX_SHADER);
glAttachShader(ShaderIds[0], ShaderIds[1]);
glAttachShader(ShaderIds[0], ShaderIds[2]);

glLinkProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not link the shader program");

ModelMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ModelMatrix");
ViewMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ViewMatrix");
ProjectionMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ProjectionMatrix");
ExitOnGLError("ERROR: Could not get shader uniform locations");

glGenVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not generate the VAO");
glBindVertexArray(BufferIds[0]);
ExitOnGLError("ERROR: Could not bind the VAO");

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
ExitOnGLError("ERROR: Could not enable vertex attributes");

glGenBuffers(2, &BufferIds[1]);
ExitOnGLError("ERROR: Could not generate the buffer objects");

glBindBuffer(GL_ARRAY_BUFFER, BufferIds[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the VBO to the VAO");

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)sizeof(VERTICES[0].Position));
ExitOnGLError("ERROR: Could not set VAO attributes");

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferIds[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the IBO to the VAO");

glBindVertexArray(0);


void DestroyCube()

glDetachShader(ShaderIds[0], ShaderIds[1]);
glDetachShader(ShaderIds[0], ShaderIds[2]);
glDeleteShader(ShaderIds[1]);
glDeleteShader(ShaderIds[2]);
glDeleteProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not destroy the shaders");

glDeleteBuffers(2, &BufferIds[1]);
glDeleteVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not destroy the buffer objects");


void DrawCube(float x, float y, float z)

ModelMatrix = IDENTITY_MATRIX;

TranslateMatrix(&ModelMatrix, x, y, z);
TranslateMatrix(&ModelMatrix, MainCamera.x, MainCamera.y, MainCamera.z);

glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, ModelMatrix.m);
glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, ViewMatrix.m);
ExitOnGLError("ERROR: Could not set the shader uniforms");


glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)0);
ExitOnGLError("ERROR: Could not draw the cube");



Here is a link to the github repository with the complete code.



The vertex shader only handles rotation and transformation of vertices and the fragment shader only deals with colour - they are not expensive to run so they are not the bottleneck.



How can this code be improved to render more efficiently and take full advantage of modern OpenGL features to decrease overhead?



P.S.
I am not looking for a book or a tool or an off-site resource as an answer. I have used backface culling and the OpenGL depth test to try and improve speed, however they haven't made a dramatic difference - it is still taking ~50ms to render a frame and that is too much for a voxel grid of 32*32*32.







share|improve this question













I am an amateur in OpenGl and for this reason I am seeking to learn only modern OpenGl the 4.x stuff. Once I had completed basic tutorials (rotating cubes, for example) I decided I would try and create a voxel-based program dealing solely with cubes. The goals of this program was to be fast, use limited CPU power and memory, and be dynamic so the map size can change and blocks will only be drawn if in the array it says the block is filled.



I have one VBO with the vertices and indexes of a cube built out of triangles. At the beginning of the render function I tell OpenGl the shaders to use and then bind the VBO; once that is complete I execute a loop.



Draw Cube Loop:



//The letter_max are the dimensions of the matrix created to store the voxel status in
// The method I use for getting and setting entries in the map are very efficient so I have not included it in this example
for(int z = -(z_max / 2); z < z_max - (z_max / 2); z++)

for(int y = -(y_max / 2); y < y_max - (y_max / 2); y++)

for(int x = -(x_max / 2); x < x_max - (x_max / 2); x++)

DrawCube(x, y, z);





Cube.c



#include "include/Project.h"

void CreateCube()

const Vertex VERTICES[8] =

-.5f, -.5f, .5f, 1 , 0, 0, 1, 1 ,
-.5f, .5f, .5f, 1 , 1, 0, 0, 1 ,
.5f, .5f, .5f, 1 , 0, 1, 0, 1 ,
.5f, -.5f, .5f, 1 , 1, 1, 0, 1 ,
-.5f, -.5f, -.5f, 1 , 1, 1, 1, 1 ,
-.5f, .5f, -.5f, 1 , 1, 0, 0, 1 ,
.5f, .5f, -.5f, 1 , 1, 0, 1, 1 ,
.5f, -.5f, -.5f, 1 , 0, 0, 1, 1
;

const GLuint INDICES[36] =

0,2,1, 0,3,2,
4,3,0, 4,7,3,
4,1,5, 4,0,1,
3,6,2, 3,7,6,
1,6,5, 1,2,6,
7,5,6, 7,4,5
;

ShaderIds[0] = glCreateProgram();
ExitOnGLError("ERROR: Could not create the shader program");

ShaderIds[1] = LoadShader("FragmentShader.glsl", GL_FRAGMENT_SHADER);
ShaderIds[2] = LoadShader("VertexShader.glsl", GL_VERTEX_SHADER);
glAttachShader(ShaderIds[0], ShaderIds[1]);
glAttachShader(ShaderIds[0], ShaderIds[2]);

glLinkProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not link the shader program");

ModelMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ModelMatrix");
ViewMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ViewMatrix");
ProjectionMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ProjectionMatrix");
ExitOnGLError("ERROR: Could not get shader uniform locations");

glGenVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not generate the VAO");
glBindVertexArray(BufferIds[0]);
ExitOnGLError("ERROR: Could not bind the VAO");

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
ExitOnGLError("ERROR: Could not enable vertex attributes");

glGenBuffers(2, &BufferIds[1]);
ExitOnGLError("ERROR: Could not generate the buffer objects");

glBindBuffer(GL_ARRAY_BUFFER, BufferIds[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the VBO to the VAO");

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)sizeof(VERTICES[0].Position));
ExitOnGLError("ERROR: Could not set VAO attributes");

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferIds[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the IBO to the VAO");

glBindVertexArray(0);


void DestroyCube()

glDetachShader(ShaderIds[0], ShaderIds[1]);
glDetachShader(ShaderIds[0], ShaderIds[2]);
glDeleteShader(ShaderIds[1]);
glDeleteShader(ShaderIds[2]);
glDeleteProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not destroy the shaders");

glDeleteBuffers(2, &BufferIds[1]);
glDeleteVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not destroy the buffer objects");


void DrawCube(float x, float y, float z)

ModelMatrix = IDENTITY_MATRIX;

TranslateMatrix(&ModelMatrix, x, y, z);
TranslateMatrix(&ModelMatrix, MainCamera.x, MainCamera.y, MainCamera.z);

glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, ModelMatrix.m);
glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, ViewMatrix.m);
ExitOnGLError("ERROR: Could not set the shader uniforms");


glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)0);
ExitOnGLError("ERROR: Could not draw the cube");



Here is a link to the github repository with the complete code.



The vertex shader only handles rotation and transformation of vertices and the fragment shader only deals with colour - they are not expensive to run so they are not the bottleneck.



How can this code be improved to render more efficiently and take full advantage of modern OpenGL features to decrease overhead?



P.S.
I am not looking for a book or a tool or an off-site resource as an answer. I have used backface culling and the OpenGL depth test to try and improve speed, however they haven't made a dramatic difference - it is still taking ~50ms to render a frame and that is too much for a voxel grid of 32*32*32.









share|improve this question












share|improve this question




share|improve this question








edited Jan 5 at 22:12
























asked Jan 4 at 8:24









Oliver Strong

113




113











  • Code does not compile . Best to post compilable code.
    – chux
    Jan 5 at 20:32










  • Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
    – Sam Onela
    Jan 5 at 21:08










  • @chux I have edited the question and added a link to my github repo with all of the code.
    – Oliver Strong
    Jan 5 at 22:14
















  • Code does not compile . Best to post compilable code.
    – chux
    Jan 5 at 20:32










  • Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
    – Sam Onela
    Jan 5 at 21:08










  • @chux I have edited the question and added a link to my github repo with all of the code.
    – Oliver Strong
    Jan 5 at 22:14















Code does not compile . Best to post compilable code.
– chux
Jan 5 at 20:32




Code does not compile . Best to post compilable code.
– chux
Jan 5 at 20:32












Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
– Sam Onela
Jan 5 at 21:08




Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate.
– Sam Onela
Jan 5 at 21:08












@chux I have edited the question and added a link to my github repo with all of the code.
– Oliver Strong
Jan 5 at 22:14




@chux I have edited the question and added a link to my github repo with all of the code.
– Oliver Strong
Jan 5 at 22:14










1 Answer
1






active

oldest

votes

















up vote
4
down vote













Your question is very broad and without enough code to do anything else than speculate. Regardless, I will venture an answer based on speculation. I believe that how to best improve your performance has actually nothing to do with OpenGL but rather how you render your scene.



Or to be more specific, how to not render parts of the scene. To me it seems as if you're rendering every cube in your voxel grid, even if they are covered by other cubes and thus not visible at all. You need to process your voxel grid to mark voxels that are concealed as not visible and simply not draw them.



Next you should consider not drawing sides of your cube that are covered by another cube.



Eventually you will get to a point where traversing the grid to find what to render is the most expensive part of your render loop. And at that point you need to start considering to split your voxel grid into larger chunks that can be individually processed into a single vbo mesh that you can render in one call instead of a call for every cube.



As always when dealing with performance, measure at every step and profile your code to see where the time is spent.






share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184258%2fvoxel-engine-to-draw-cubes%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    down vote













    Your question is very broad and without enough code to do anything else than speculate. Regardless, I will venture an answer based on speculation. I believe that how to best improve your performance has actually nothing to do with OpenGL but rather how you render your scene.



    Or to be more specific, how to not render parts of the scene. To me it seems as if you're rendering every cube in your voxel grid, even if they are covered by other cubes and thus not visible at all. You need to process your voxel grid to mark voxels that are concealed as not visible and simply not draw them.



    Next you should consider not drawing sides of your cube that are covered by another cube.



    Eventually you will get to a point where traversing the grid to find what to render is the most expensive part of your render loop. And at that point you need to start considering to split your voxel grid into larger chunks that can be individually processed into a single vbo mesh that you can render in one call instead of a call for every cube.



    As always when dealing with performance, measure at every step and profile your code to see where the time is spent.






    share|improve this answer

























      up vote
      4
      down vote













      Your question is very broad and without enough code to do anything else than speculate. Regardless, I will venture an answer based on speculation. I believe that how to best improve your performance has actually nothing to do with OpenGL but rather how you render your scene.



      Or to be more specific, how to not render parts of the scene. To me it seems as if you're rendering every cube in your voxel grid, even if they are covered by other cubes and thus not visible at all. You need to process your voxel grid to mark voxels that are concealed as not visible and simply not draw them.



      Next you should consider not drawing sides of your cube that are covered by another cube.



      Eventually you will get to a point where traversing the grid to find what to render is the most expensive part of your render loop. And at that point you need to start considering to split your voxel grid into larger chunks that can be individually processed into a single vbo mesh that you can render in one call instead of a call for every cube.



      As always when dealing with performance, measure at every step and profile your code to see where the time is spent.






      share|improve this answer























        up vote
        4
        down vote










        up vote
        4
        down vote









        Your question is very broad and without enough code to do anything else than speculate. Regardless, I will venture an answer based on speculation. I believe that how to best improve your performance has actually nothing to do with OpenGL but rather how you render your scene.



        Or to be more specific, how to not render parts of the scene. To me it seems as if you're rendering every cube in your voxel grid, even if they are covered by other cubes and thus not visible at all. You need to process your voxel grid to mark voxels that are concealed as not visible and simply not draw them.



        Next you should consider not drawing sides of your cube that are covered by another cube.



        Eventually you will get to a point where traversing the grid to find what to render is the most expensive part of your render loop. And at that point you need to start considering to split your voxel grid into larger chunks that can be individually processed into a single vbo mesh that you can render in one call instead of a call for every cube.



        As always when dealing with performance, measure at every step and profile your code to see where the time is spent.






        share|improve this answer













        Your question is very broad and without enough code to do anything else than speculate. Regardless, I will venture an answer based on speculation. I believe that how to best improve your performance has actually nothing to do with OpenGL but rather how you render your scene.



        Or to be more specific, how to not render parts of the scene. To me it seems as if you're rendering every cube in your voxel grid, even if they are covered by other cubes and thus not visible at all. You need to process your voxel grid to mark voxels that are concealed as not visible and simply not draw them.



        Next you should consider not drawing sides of your cube that are covered by another cube.



        Eventually you will get to a point where traversing the grid to find what to render is the most expensive part of your render loop. And at that point you need to start considering to split your voxel grid into larger chunks that can be individually processed into a single vbo mesh that you can render in one call instead of a call for every cube.



        As always when dealing with performance, measure at every step and profile your code to see where the time is spent.







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jan 4 at 12:18









        Emily L.

        11k12372




        11k12372






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184258%2fvoxel-engine-to-draw-cubes%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Greedy Best First Search implementation in Rust

            Function to Return a JSON Like Objects Using VBA Collections and Arrays

            C++11 CLH Lock Implementation