use vertex buffer objects to speed up voxel rendering

This commit is contained in:
Stephen Birarda 2013-03-06 13:56:11 -08:00
parent 0fbb534566
commit e16cd4ffc3
3 changed files with 40 additions and 10 deletions

View file

@ -9,7 +9,7 @@
#include "VoxelSystem.h" #include "VoxelSystem.h"
const float MAX_UNIT_ANY_AXIS = 20.0f; const float MAX_UNIT_ANY_AXIS = 20.0f;
const float CUBE_WIDTH = 0.05f; const float CUBE_WIDTH = 0.005f;
const int VERTICES_PER_VOXEL = 8; const int VERTICES_PER_VOXEL = 8;
const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL;
const int INDICES_PER_VOXEL = 3 * 12; const int INDICES_PER_VOXEL = 3 * 12;
@ -47,10 +47,10 @@ void VoxelSystem::init(int numberOfRandomVoxels) {
voxelsRendered = numberOfRandomVoxels; voxelsRendered = numberOfRandomVoxels;
// there are 3 points for each vertices, 24 vertices in each cube // there are 3 points for each vertices, 24 vertices in each cube
verticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * numberOfRandomVoxels]; GLfloat *verticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * numberOfRandomVoxels];
// there are 12 triangles in each cube, with three indices for each triangle // there are 12 triangles in each cube, with three indices for each triangle
indicesArray = new GLuint[INDICES_PER_VOXEL * numberOfRandomVoxels]; GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * numberOfRandomVoxels];
// new seed based on time now so voxels are different each time // new seed based on time now so voxels are different each time
srand((unsigned)time(0)); srand((unsigned)time(0));
@ -81,6 +81,27 @@ void VoxelSystem::init(int numberOfRandomVoxels) {
} }
} }
// generate new VBO for the verticesArray
glGenBuffers(1, &vboVerticesID);
// bind VBO in order to use
glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
// upload data to VBO
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * numberOfRandomVoxels, verticesArray, GL_STATIC_DRAW);
// generate new VBO for the indicesArray
glGenBuffers(1, &vboIndicesID);
// bind VBO in order to use
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
// upload data to VBO
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numberOfRandomVoxels * INDICES_PER_VOXEL * sizeof(GLuint), indicesArray, GL_STATIC_DRAW);
// delete the verticesArray, indicesArray
delete[] verticesArray;
delete[] indicesArray;
} }
// //
@ -184,14 +205,23 @@ int VoxelSystem::render(Voxel * voxel, float scale, glm::vec3 * distance) {
} }
void VoxelSystem::render() { void VoxelSystem::render() {
glEnableClientState(GL_VERTEX_ARRAY); // bind VBOs for vertices and indices array
glVertexPointer(3, GL_FLOAT, 0, verticesArray); glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
// draw a cube // draw the cubes
glDrawElements(GL_TRIANGLES, 36 * voxelsRendered, GL_UNSIGNED_INT, indicesArray); glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawElements(GL_TRIANGLES, 36 * voxelsRendered, GL_UNSIGNED_INT, 0);
// deactivate vertex arrays after drawing // deactivate vertex arrays after drawing
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
// bind with 0 to switch back to normal operation
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }
void VoxelSystem::simulate(float deltaTime) { void VoxelSystem::simulate(float deltaTime) {

View file

@ -35,8 +35,8 @@ public:
Voxel * root; Voxel * root;
private: private:
int voxelsRendered; int voxelsRendered;
GLfloat *verticesArray; GLuint vboVerticesID;
GLuint *indicesArray; GLuint vboIndicesID;
}; };
#endif #endif

View file

@ -319,7 +319,7 @@ void initDisplay(void)
void init(void) void init(void)
{ {
voxels.init(50000); voxels.init(200000);
myHead.setRenderYaw(start_yaw); myHead.setRenderYaw(start_yaw);