diff options
-rw-r--r-- | vbo.c | 64 |
1 files changed, 48 insertions, 16 deletions
@@ -34,6 +34,7 @@ typedef struct gltpoint int program_running = 1; SDL_Surface *screen; GLuint buffer_objects[3]; +GLuint buffer_objects2[3]; /* few light arrays */ const GLfloat fNoLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -57,25 +58,28 @@ static void setup_glew(void); static void setup_opengl(void); /* we have a separate buffer objects for vertex data, attributes, and indices - * gl*Pointer gets assiociated with currently binded buffer * interleaved arrays improve cache performance, the key is locality + * for simplicity, vertex is composed of 3 components and texcoord of 2 components */ static int gltGenVBOInterleaved(GLuint *bufferobjects, float *vert_arr, float *texcoord_arr, float *norm_arr, unsigned char *color_arr, - unsigned short *indices_arr, size_t points_n, size_t indices_n) + unsigned short *indices_arr, GLsizeiptr points_n, GLsizeiptr indices_n) { - /* skip error checks for now */ + if (!bufferobjects || !vert_arr || !texcoord_arr || !norm_arr || !color_arr || + !indices_arr || !points_n || !indices_n) + return -1; /* create an interleaved data structure, is it worth the cpu time? */ - size_t attrib_buff_sz = ((points_n * (3+2) * sizeof(GLfloat)) + - (points_n * 3 * sizeof(GLubyte))); + GLsizeiptr attrib_buff_sz = ((points_n * (3+2) * sizeof(GLfloat)) + + (points_n * 3 * sizeof(GLubyte))); if ((attrib_buff_sz % sizeof(gltpoint_t)) != 0) { - fprintf(stderr, "gltGenVBOInterleaved: fatal, gltpoint_t appears to be padded!\n"); - exit(-1); + fprintf(stderr, "%s: fatal, gltpoint_t appears to be padded!\n", __FUNCTION__); + return -1; } + /* I call point a vbo slice */ size_t slices_n = attrib_buff_sz / sizeof(gltpoint_t); gltpoint_t *gltpoints_arr = (gltpoint_t *) malloc(attrib_buff_sz); @@ -83,7 +87,7 @@ static int gltGenVBOInterleaved(GLuint *bufferobjects, float *vert_arr, { fprintf(stderr, "%s failed, %s:%d\n", __FUNCTION__, __FILE__, __LINE__); perror("malloc"); - exit(-1); + return -1; } /* build interleaved data structure, may not be cache friendly */ @@ -119,7 +123,7 @@ static int gltGenVBOInterleaved(GLuint *bufferobjects, float *vert_arr, return 0; } -static int gltDrawVBOInterleaved(GLuint *bufferobjects, size_t indices_n) +static int gltDrawVBOInterleaved(GLuint *bufferobjects, size_t indices_n, GLenum mode) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); @@ -139,7 +143,7 @@ static int gltDrawVBOInterleaved(GLuint *bufferobjects, size_t indices_n) /* indices data */ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferobjects[2]); - glDrawElements(GL_TRIANGLES, indices_n, GL_UNSIGNED_SHORT, 0); + glDrawElements(mode, indices_n, GL_UNSIGNED_SHORT, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); @@ -343,7 +347,8 @@ static void render(void) glPushMatrix(); /* draw vbo */ glTranslatef(0.0f, 0.0f, -4.0f); - gltDrawVBOInterleaved(buffer_objects, 3); + gltDrawVBOInterleaved(buffer_objects, 3, GL_TRIANGLES); + gltDrawVBOInterleaved(buffer_objects2, 4, GL_QUADS); glPopMatrix(); } /* restore the matrix state */ @@ -361,7 +366,7 @@ static void setup_sdl(void) exit(-1); } atexit(SDL_Quit); - SDL_WM_SetCaption("SDL", NULL); + SDL_WM_SetCaption("VBO", NULL); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); @@ -413,10 +418,10 @@ int main(int argc, char **argv) setup_opengl(); gltErrorCheck(); - /* setup a vbo */ + /* setup a triangle */ float vert_arr[9] = { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.66f, 0.0f }; + 0.5f, 0.83f, 0.0f }; float norm_arr[9] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, @@ -432,8 +437,35 @@ int main(int argc, char **argv) unsigned short indices_arr[3] = { 0, 1, 2 }; - gltGenVBOInterleaved(buffer_objects, vert_arr, texcoord_arr, norm_arr, color_arr, - indices_arr, 3, 3); + gltGenVBOInterleaved(buffer_objects, vert_arr, texcoord_arr, norm_arr, + color_arr, indices_arr, 3, 3); + gltErrorCheck(); + + /* setup a rectangle, notice the ccw winding */ + float vert_arr2[12] = { -0.5f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, + -1.0f, 0.0f, 0.0f, + -0.5f, 0.0f, 0.0f }; + + float norm_arr2[12] = { 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f }; + + float texcoord_arr2[8] = { 0.5f, 0.0f, + 0.0f, 0.0f, + 0.0f, 1.0f, + 0.5f, 1.0f }; + + unsigned char color_arr2[12] = { 255, 0, 0, + 0, 255, 0, + 0, 0, 255, + 255, 0, 255 }; + + unsigned short indices_arr2[4] = { 0, 1, 2, 3 }; + + gltGenVBOInterleaved(buffer_objects2, vert_arr2, texcoord_arr2, norm_arr2, + color_arr2, indices_arr2, 4, 4); gltErrorCheck(); while (program_running) |