Guest User

petafile

a guest
Feb 22nd, 2010
1,051
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //compiled with g++ -o vboEx -g main.cpp -lglut -lGLEW
  2.  
  3. #include <stdlib.h>
  4. #include <GL/glew.h>
  5. #include <GL/glut.h>
  6.  
  7. // Location/Normals
  8. #define X_POS 0
  9. #define Y_POS 1
  10. #define Z_POS 2
  11.  
  12. // Texture Coordinates
  13. #define U_POS 0
  14. #define V_POS 1
  15.  
  16. // Colours
  17. #define R_POS 0
  18. #define G_POS 1
  19. #define B_POS 2
  20. #define A_POS 3
  21.  
  22. // Vertex structure
  23. typedef struct
  24. {
  25.     GLfloat location[3];
  26.     GLfloat tex[2];
  27.     GLfloat normal[3];
  28.     GLfloat colour[4];
  29.     GLubyte padding[16];
  30. } Vertex;
  31.  
  32. // A helper macro to get a position
  33. #define BUFFER_OFFSET(i) ((char *)NULL + (i))
  34.  
  35. // GLUT functions
  36. void renderScene();
  37. void changeSize(int w, int h);
  38. void processNormalKeys(unsigned char key, int x, int y);
  39.  
  40. // VBO functions
  41. void initVBO();
  42.  
  43. // Other functions
  44. void buildCube();
  45.  
  46. // Globals - typically these would be in classes,
  47. // but in this simple example, I'm using globals
  48. Vertex verts[24]; // We're making a cube, 6 faces * 4 verticies per face
  49. GLubyte index[36]; // 2 Triangles per face (possible to use quads, but they're being phased out of OpenGL3, so we're using triangles instead)
  50. GLuint vboID; // Vertex Buffer Object ID
  51. GLuint indexVBOID; // Index Buffer Object ID
  52. float angle = 0.0; // Just for display rotation
  53.  
  54. int main (int argc, char * argv[])
  55. {
  56.     glutInit(&argc, argv);
  57.     glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
  58.     glutInitWindowPosition(100, 100);
  59.     glutInitWindowSize(320, 320);
  60.     glutCreateWindow("VBO Example");
  61.     glutDisplayFunc(renderScene);
  62.     glutIdleFunc(renderScene);
  63.     glutReshapeFunc(changeSize);
  64.     glutKeyboardFunc(processNormalKeys);
  65.     glEnable(GL_DEPTH_TEST);
  66.     buildCube();
  67.     initVBO();
  68.     glutMainLoop();
  69.     return 0;
  70. }
  71.  
  72. void renderScene()
  73. {
  74.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  75.     glPushMatrix();
  76.     glRotatef(angle, 1.0, 1.0, 1.0);
  77.  
  78.     // Bind our buffers much like we would for texturing
  79.     glBindBuffer(GL_ARRAY_BUFFER, vboID);
  80.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBOID);
  81.    
  82.     // Set the state of what we are drawing (I don't think order matters here, but I like to do it in the same
  83.     // order I set the pointers
  84.     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  85.     glEnableClientState(GL_COLOR_ARRAY);
  86.     glEnableClientState(GL_NORMAL_ARRAY);
  87.     glEnableClientState(GL_VERTEX_ARRAY);
  88.    
  89.     // Resetup our pointers.  This doesn't reinitialise any data, only how we walk through it
  90.     glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));
  91.     glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(20));
  92.     glColorPointer(4, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(32));
  93.     glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
  94.    
  95.     // Actually do our drawing, parameters are Primative (Triangles, Quads, Triangle Fans etc), Elements to
  96.     // draw, Type of each element, Start Offset
  97.     glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
  98.    
  99.     // Disable our client state back to normal drawing
  100.     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  101.     glDisableClientState(GL_COLOR_ARRAY);
  102.     glDisableClientState(GL_NORMAL_ARRAY);
  103.     glDisableClientState(GL_VERTEX_ARRAY);
  104.    
  105.     glPopMatrix();
  106.     glutSwapBuffers();
  107.     angle += 0.01;
  108. }
  109.  
  110. void changeSize(int w, int h)
  111. {
  112.     if (h == 0) // Prevent divide by zero
  113.         h = 1;
  114.    
  115.     float ratio = 1.0 * w / h;
  116.    
  117.     glMatrixMode(GL_PROJECTION);
  118.     glLoadIdentity();
  119.    
  120.     glViewport(0, 0, w, h);
  121.    
  122.     gluPerspective(45, ratio, 1, 1000);
  123.     glMatrixMode(GL_MODELVIEW);
  124.     glLoadIdentity();
  125.     gluLookAt(0.0, 0.0, 5.0,
  126.               0.0, 0.0, -1.0,
  127.               0.0, 1.0, 0.0);
  128.    
  129. }
  130.  
  131. void processNormalKeys(unsigned char key, int x, int y)
  132. {
  133.     if (key == 27)
  134.         exit(0);
  135. }
  136.  
  137. void initVBO()
  138. {
  139.     glGenBuffers(1, &vboID); // Create the buffer ID, this is basically the same as generating texture ID's
  140.     glBindBuffer(GL_ARRAY_BUFFER, vboID); // Bind the buffer (vertex array data)
  141.    
  142.     // Allocate space.  We could pass the mesh in here (where the NULL is), but it's actually faster to do it as a
  143.     // seperate step.  We also define it as GL_STATIC_DRAW which means we set the data once, and never
  144.     // update it.  This is not a strict rule code wise, but gives hints to the driver as to where to store the data
  145.     glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * 24, NULL, GL_STATIC_DRAW);
  146.     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex) * 24, verts);
  147.    
  148.     // Set the pointers to our data.  Except for the normal value (which always has a size of 3), we must pass
  149.     // the size of the individual component.  ie. A vertex has 3 points (x, y, z), texture coordinates have 2 (u, v) etc.
  150.     // Basically the arguments are (ignore the first one for the normal pointer), Size (many components to
  151.     // read), Type (what data type is it), Stride (how far to move forward - in bytes - per vertex) and Offset
  152.     // (where in the buffer to start reading the data - in bytes)
  153.    
  154.     // Make sure you put glVertexPointer at the end as there is a lot of work that goes on behind the scenes
  155.     // with it, and if it's set at the start, it has to do all that work for each gl*Pointer call, rather than once at
  156.     // the end.
  157.     glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));
  158.     glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(20));
  159.     glColorPointer(4, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(32));
  160.     glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
  161.    
  162.     // When we get here, all the vertex data is effectively on the card
  163.    
  164.     glGenBuffers(1, &indexVBOID); // Generate buffer
  165.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBOID); // Bind the element array buffer
  166.     // Upload the index array, this can be done the same way as above (with NULL as the data, then a
  167.     // glBufferSubData call, but doing it all at once for convenience) 
  168.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLubyte), index, GL_STATIC_DRAW);
  169. }
  170.  
  171. void buildCube()
  172. {
  173.     // Ugh, ugly code this
  174.    
  175.     // Top
  176.     verts[0].location[X_POS]    = 1;    verts[0].location[Y_POS]    = 1;    verts[0].location[Z_POS]    = -1;
  177.     verts[0].normal[X_POS]      = 0;    verts[0].normal[Y_POS]      = 1;    verts[0].normal[Z_POS]      = 0;
  178.     verts[0].tex[U_POS]         = 0;    verts[0].tex[V_POS] = 0;
  179.    
  180.     verts[1].location[X_POS]    = -1;   verts[1].location[Y_POS]    = 1;    verts[1].location[Z_POS]    = -1;
  181.     verts[1].normal[X_POS]      = 0;    verts[1].normal[Y_POS]      = 1;    verts[1].normal[Z_POS]      = 0;
  182.     verts[1].tex[U_POS]         = 0;    verts[1].tex[V_POS] = 1;
  183.    
  184.     verts[2].location[X_POS]    = -1;   verts[2].location[Y_POS]    = 1;    verts[2].location[Z_POS]    = 1;
  185.     verts[2].normal[X_POS]      = 0;    verts[2].normal[Y_POS]      = 1;    verts[2].normal[Z_POS]      = 0;
  186.     verts[2].tex[U_POS]         = 1;    verts[2].tex[V_POS] = 1;
  187.    
  188.     verts[3].location[X_POS]    = 1;    verts[3].location[Y_POS]    = 1;    verts[3].location[Z_POS]    = 1;
  189.     verts[3].normal[X_POS]      = 0;    verts[3].normal[Y_POS]      = 1;    verts[3].normal[Z_POS]      = 0;
  190.     verts[3].tex[U_POS]         = 1;    verts[3].tex[V_POS] = 0;
  191.    
  192.     // Bottom
  193.     verts[4].location[X_POS]    = 1;    verts[4].location[Y_POS]    = -1;   verts[4].location[Z_POS]    = 1;
  194.     verts[4].normal[X_POS]      = 0;    verts[4].normal[Y_POS]      = -1;   verts[4].normal[Z_POS]      = 0;
  195.     verts[4].tex[U_POS]         = 0;    verts[4].tex[V_POS] = 0;
  196.    
  197.     verts[5].location[X_POS]    = -1;   verts[5].location[Y_POS]    = -1;   verts[5].location[Z_POS]    = 1;
  198.     verts[5].normal[X_POS]      = 0;    verts[5].normal[Y_POS]      = -1;   verts[5].normal[Z_POS]      = 0;
  199.     verts[5].tex[U_POS]         = 0;    verts[5].tex[V_POS] = 1;
  200.    
  201.     verts[6].location[X_POS]    = -1;   verts[6].location[Y_POS]    = -1;   verts[6].location[Z_POS]    = -1;
  202.     verts[6].normal[X_POS]      = 0;    verts[6].normal[Y_POS]      = -1;   verts[6].normal[Z_POS]      = 0;
  203.     verts[6].tex[U_POS]         = 1;    verts[6].tex[V_POS] = 1;
  204.    
  205.     verts[7].location[X_POS]    = 1;    verts[7].location[Y_POS]    = -1;   verts[7].location[Z_POS]    = -1;
  206.     verts[7].normal[X_POS]      = 0;    verts[7].normal[Y_POS]      = -1;   verts[7].normal[Z_POS]      = 0;
  207.     verts[7].tex[U_POS]         = 1;    verts[7].tex[V_POS] = 0;
  208.    
  209.     // Front
  210.     verts[8].location[X_POS]    = 1;    verts[8].location[Y_POS]    = 1;    verts[8].location[Z_POS]    = 1;
  211.     verts[8].normal[X_POS]      = 0;    verts[8].normal[Y_POS]      = 0;    verts[8].normal[Z_POS]      = 1;
  212.     verts[8].tex[U_POS]         = 0;    verts[8].tex[V_POS] = 0;
  213.    
  214.     verts[9].location[X_POS]    = -1;   verts[9].location[Y_POS]    = 1;    verts[9].location[Z_POS]    = 1;
  215.     verts[9].normal[X_POS]      = 0;    verts[9].normal[Y_POS]      = 0;    verts[9].normal[Z_POS]      = 1;
  216.     verts[9].tex[U_POS]         = 0;    verts[9].tex[V_POS] = 1;
  217.    
  218.     verts[10].location[X_POS]   = -1;   verts[10].location[Y_POS]   = -1;   verts[10].location[Z_POS]   = 1;
  219.     verts[10].normal[X_POS]     = 0;    verts[10].normal[Y_POS]     = 0;    verts[10].normal[Z_POS]     = 1;
  220.     verts[10].tex[U_POS]        = 1;    verts[10].tex[V_POS]        = 1;
  221.    
  222.     verts[11].location[X_POS]   = 1;    verts[11].location[Y_POS]   = -1;   verts[11].location[Z_POS]   = 1;
  223.     verts[11].normal[X_POS]     = 0;    verts[11].normal[Y_POS]     = 0;    verts[11].normal[Z_POS]     = 1;
  224.     verts[11].tex[U_POS]        = 1;    verts[11].tex[V_POS]        = 0;
  225.  
  226.     // Back
  227.     verts[12].location[X_POS]   = 1;    verts[12].location[Y_POS]   = -1;   verts[12].location[Z_POS]   = -1;
  228.     verts[12].normal[X_POS]     = 0;    verts[12].normal[Y_POS]     = 0;    verts[12].normal[Z_POS]     = -1;
  229.     verts[12].tex[U_POS]        = 0;    verts[12].tex[V_POS]        = 0;
  230.    
  231.     verts[13].location[X_POS]   = -1;   verts[13].location[Y_POS]   = -1;   verts[13].location[Z_POS]   = -1;
  232.     verts[13].normal[X_POS]     = 0;    verts[13].normal[Y_POS]     = 0;    verts[13].normal[Z_POS]     = -1;
  233.     verts[13].tex[U_POS]        = 0;    verts[13].tex[V_POS]        = 1;
  234.    
  235.     verts[14].location[X_POS]   = -1;   verts[14].location[Y_POS]   = 1;    verts[14].location[Z_POS]   = -1;
  236.     verts[14].normal[X_POS]     = 0;    verts[14].normal[Y_POS]     = 0;    verts[14].normal[Z_POS]     = -1;
  237.     verts[14].tex[U_POS]        = 1;    verts[14].tex[V_POS]        = 1;
  238.    
  239.     verts[15].location[X_POS]   = 1;    verts[15].location[Y_POS]   = 1;    verts[15].location[Z_POS]   = -1;
  240.     verts[15].normal[X_POS]     = 0;    verts[15].normal[Y_POS]     = 0;    verts[15].normal[Z_POS]     = -1;
  241.     verts[15].tex[U_POS]        = 1;    verts[15].tex[V_POS]        = 0;
  242.  
  243.     // Left
  244.     verts[16].location[X_POS]   = -1;   verts[16].location[Y_POS]   = 1;    verts[16].location[Z_POS]   = 1;
  245.     verts[16].normal[X_POS]     = -1;   verts[16].normal[Y_POS]     = 0;    verts[16].normal[Z_POS]     = 0;
  246.     verts[16].tex[U_POS]        = 0;    verts[16].tex[V_POS]        = 0;
  247.    
  248.     verts[17].location[X_POS]   = -1;   verts[17].location[Y_POS]   = 1;    verts[17].location[Z_POS]   = -1;
  249.     verts[17].normal[X_POS]     = -1;   verts[17].normal[Y_POS]     = 0;    verts[17].normal[Z_POS]     = 0;
  250.     verts[17].tex[U_POS]        = 0;    verts[17].tex[V_POS]        = 1;
  251.    
  252.     verts[18].location[X_POS]   = -1;   verts[18].location[Y_POS]   = -1;   verts[18].location[Z_POS]   = -1;
  253.     verts[18].normal[X_POS]     = -1;   verts[18].normal[Y_POS]     = 0;    verts[18].normal[Z_POS]     = 0;
  254.     verts[18].tex[U_POS]        = 1;    verts[18].tex[V_POS]        = 1;
  255.    
  256.     verts[19].location[X_POS]   = -1;   verts[19].location[Y_POS]   = -1;   verts[19].location[Z_POS]   = 1;
  257.     verts[19].normal[X_POS]     = -1;   verts[19].normal[Y_POS]     = 0;    verts[19].normal[Z_POS]     = 0;
  258.     verts[19].tex[U_POS]        = 1;    verts[19].tex[V_POS]        = 0;
  259.  
  260.     // Right
  261.     verts[20].location[X_POS]   = 1;    verts[20].location[Y_POS]   = 1;    verts[20].location[Z_POS]   = -1;
  262.     verts[20].normal[X_POS]     = 1;    verts[20].normal[Y_POS]     = 0;    verts[20].normal[Z_POS]     = 0;
  263.     verts[20].tex[U_POS]        = 0;    verts[20].tex[V_POS]        = 0;
  264.    
  265.     verts[21].location[X_POS]   = 1;    verts[21].location[Y_POS]   = 1;    verts[21].location[Z_POS]   = 1;
  266.     verts[21].normal[X_POS]     = 1;    verts[21].normal[Y_POS]     = 0;    verts[21].normal[Z_POS]     = 0;
  267.     verts[21].tex[U_POS]        = 0;    verts[21].tex[V_POS]        = 1;
  268.    
  269.     verts[22].location[X_POS]   = 1;    verts[22].location[Y_POS]   = -1;   verts[22].location[Z_POS]   = 1;
  270.     verts[22].normal[X_POS]     = 1;    verts[22].normal[Y_POS]     = 0;    verts[22].normal[Z_POS]     = 0;
  271.     verts[22].tex[U_POS]        = 1;    verts[22].tex[V_POS]        = 1;
  272.    
  273.     verts[23].location[X_POS]   = 1;    verts[23].location[Y_POS]   = -1;   verts[23].location[Z_POS]   = -1;
  274.     verts[23].normal[X_POS]     = 1;    verts[23].normal[Y_POS]     = 0;    verts[23].normal[Z_POS]     = 0;
  275.     verts[23].tex[U_POS]        = 1;    verts[23].tex[V_POS]        = 0;
  276.    
  277.     // Colours
  278.     for (int i = 0; i < 24; i++)
  279.     {
  280.         verts[i].colour[R_POS] = 1.0;
  281.         verts[i].colour[G_POS] = 1.0;
  282.         verts[i].colour[B_POS] = 1.0;
  283.         verts[i].colour[A_POS] = 1.0;
  284.     }
  285.    
  286.     // Index Array (define our triangles)
  287.     // A Face looks like (numbers are the array index number of the vertex)
  288.     // 1      2
  289.     // +------+
  290.     // |      |
  291.     // |      |
  292.     // +------+
  293.     // 0      3
  294.     index[0] = 0;   index[1] = 1;   index[2] = 2;
  295.     index[3] = 2;   index[4] = 3;   index[5] = 0;
  296.    
  297.     index[6] = 4;   index[7] = 5;   index[8] = 6;
  298.     index[9] = 6;   index[10] = 7;  index[11] = 4;
  299.    
  300.     index[12] = 8;  index[13] = 9;  index[14] = 10;
  301.     index[15] = 10; index[16] = 11; index[17] = 8;
  302.    
  303.     index[18] = 12; index[19] = 13; index[20] = 14;
  304.     index[21] = 14; index[22] = 15; index[23] = 12;
  305.    
  306.     index[24] = 16; index[25] = 17; index[26] = 18;
  307.     index[27] = 18; index[28] = 19; index[29] = 16;
  308.    
  309.     index[30] = 20; index[31] = 21; index[32] = 22;
  310.     index[33] = 22; index[34] = 23; index[35] = 20;
  311.    
  312. }
  313.  
RAW Paste Data