Advertisement
Guest User

Untitled

a guest
Sep 21st, 2014
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.92 KB | None | 0 0
  1. //on linux or mingw: g++ demo.cpp -lglut -lGLEW -DGL3_PROTOTYPES
  2. // modified to use GLM library from [url]http://pheatt.emporia.edu/courses/2005/cs410f05/hand14/hand14.htm[/url]
  3. // modified to use camera at begining of MODELVIEW Transformations, not in the Projection Transform! see [url]http://www.sjbaker.org/steve/omniv/projection_abuse.html[/url]
  4. #include <GL/glew.h>     // great opengl extensions helper
  5. #include <GL/gl3.h>
  6. #include <GL/freeglut.h> // use of opengl 3.0 context requires freeglut from svn!
  7.  
  8. #include <glm/glm.h> //OpenGL Mathematics (GLM).  A C++ mathematics library for 3D graphics.
  9. #include <glm/glmext.h>
  10. #include <glm/GLM_VIRTREV_address.h> // gives helper function address(X) instead of using &amp;X[0][0]
  11. namespace glm
  12. {
  13.           // read glm/gtx/transform.h for function prototypes
  14.           using GLM_GTX_transform;
  15.           using GLM_GTX_transform2; // for lookAt
  16.           using GLM_GTX_matrix_projection;
  17. }
  18. using namespace glm;
  19.  
  20. #include <cstdio>
  21. #include <cmath>
  22. #include <iostream>
  23. #include <iomanip>
  24. #include <sstream>
  25. #include <stack>
  26. #include <cstring>
  27. #include <cassert>
  28.  
  29. namespace global {
  30.   int theta = 0;
  31.   int   phi = 0;
  32.   GLfloat ratio = 1.0;
  33.   int width = 512;
  34.   int height = 512;
  35. };
  36.  
  37. class CustomGraphicsPipeline
  38. {
  39.             GLuint shader_id;
  40.       std::stack<mat4> glm_ProjectionMatrix; //cpu-side
  41.             GLint  glm_ProjectionMatrix_id; //cpu-side hook to shader uniform
  42.       std::stack<mat4> glm_ModelViewMatrix; //cpu-side
  43.             GLint  glm_ModelViewMatrix_id; //cpu-side hook to shader uniform
  44.             GLuint vao_id[2]; // vertex array object hook id
  45.             GLuint vao_elementcount[2]; // number of attribute elements in vao ie number of vertices
  46.             GLuint vao_primitivetype[2]; // type [GL_LINE_LOOP|GL_TRIANGLES|etc]
  47.         public:
  48.             CustomGraphicsPipeline() :
  49.        shader_id(NULL),
  50.        glm_ProjectionMatrix_id(NULL),
  51.        glm_ModelViewMatrix_id(NULL)
  52.       {
  53.        glm_ProjectionMatrix.push( mat4(1.0f) ); // identity matrix
  54.        glm_ModelViewMatrix.push( mat4(1.0f) ), // identity matrix
  55.        vao_id[0]=NULL;
  56.        vao_id[1]=NULL;
  57.        vao_elementcount[0]=0;
  58.        vao_elementcount[1]=0;
  59.        vao_primitivetype[0] = GL_LINE_LOOP;
  60.        vao_primitivetype[1] = GL_TRIANGLES;
  61.       }
  62.             ~CustomGraphicsPipeline() {}
  63.  
  64.       bool Init()                                       // All Setup For OpenGL Goes Here
  65.       {
  66.         GLint ret = true; // optimistic return value upon completion of execution
  67.  
  68.         std::cout << "GL_VERSION: " << glGetString(GL_VERSION) << std::endl;
  69.         std::cout << "GL_EXTENSIONS: " << glGetString(GL_EXTENSIONS) << std::endl;
  70.         std::cout << "GL_RENDERER: " << glGetString(GL_RENDERER) << std::endl;
  71.         std::cout << "GL_VENDOR: " << glGetString(GL_VENDOR) << std::endl;
  72.         std::cout << "GLU_VERSION: " << gluGetString(GLU_VERSION) << std::endl;
  73.         std::cout << "GLU_EXTENSIONS: " << gluGetString(GLU_EXTENSIONS) << std::endl;
  74.         std::cout << "GLUT_API_VERSION: " << GLUT_API_VERSION << std::endl;
  75. #ifdef GLUT_XLIB_IMPLEMENTATION
  76.         std::cout << "GLUT_XLIB_IMPLEMENTATION: " << GLUT_XLIB_IMPLEMENTATION << std::endl;
  77. #endif
  78.         std::cout << "press t,T to rotate camera theta" << std::endl;
  79.         std::cout << "press p,P to rotate camera phi" << std::endl;
  80.  
  81.         glEnable(GL_DEPTH_TEST);
  82.         glClearColor(0.2f, 0.2f, 0.2f, 0.5f);
  83.  
  84.       //Datas destioned for video memory, can be local (and lost after bound to GPU!).
  85.         GLfloat vertices0[] = { // dgl_Vertex
  86.           1.0, -1.0, 0.0, 1.0, // xyzw
  87.          -1.0, -1.0, 0.0, 1.0,
  88.           0.0,  1.0, 0.0, 1.0
  89.         };
  90.         size_t Nbytes_vertices0=sizeof(vertices0);
  91.  
  92.         GLfloat colors0[] = { // dgl_Color
  93.           0.0, 0.0, 1.0, 1.0, //rgba
  94.           0.0, 1.0, 0.0, 1.0,
  95.           1.0, 0.0, 0.0, 1.0
  96.         };
  97.         size_t Nbytes_colors0=sizeof(colors0);
  98.  
  99.         GLfloat vertices1[] = { // dgl_Vertex
  100.           0.5, -0.5, 0.0, 1.0, // xyzw
  101.          -0.5, -0.5, 0.0, 1.0,
  102.           0.0,  0.5, 0.0, 1.0
  103.         };
  104.         size_t Nbytes_vertices1=sizeof(vertices1);
  105.  
  106.         GLfloat colors1[] = { // dgl_Color
  107.           0.0, 0.0, 1.0, 1.0, //rgba
  108.           0.0, 1.0, 0.0, 1.0,
  109.           1.0, 0.0, 0.0, 1.0
  110.         };
  111.         size_t Nbytes_colors1=sizeof(colors1);
  112.  
  113.         const GLchar *g_vertexShader[] = {"#version 130\n",
  114.          "uniform mat4 glm_ProjectionMatrix;\n", // replaces deprecated gl_ProjectionMatrix see [url]http://www.lighthouse3d.com/opengl/glsl/index.php?minimal[/url]
  115.          "uniform mat4 glm_ModelViewMatrix;\n", // replaces deprecated gl_ModelViewMatrix
  116.          "in         vec4 dgl_Vertex;\n", // replaces deprecated gl_Vertex
  117.          "in         vec4 dgl_Color;\n", // replaces deprecated gl_Color
  118.          "invariant out vec4 Color;\n", // to fragment shader
  119.          "void main(void)\n",
  120.          "{\n",
  121.          "  Color = dgl_Color;\n",
  122.          "  gl_Position = glm_ProjectionMatrix*glm_ModelViewMatrix*dgl_Vertex;\n", // replaces deprecated ftransform() see [url]http://www.songho.ca/opengl/gl_transform.html[/url]
  123.          "}\n"
  124.         };
  125.  
  126.         const GLchar *g_fragmentShader[] = {"#version 130\n",
  127.          "invariant in vec4 Color;\n", // from vertex shader
  128.          "out  vec4 dgl_FragColor;\n", // replaces deprecated gl_FragColor
  129.          "void main(void)\n",
  130.          "{\n",
  131.          "  dgl_FragColor = Color;\n", // gl_FragColor is deprecated
  132.          "}\n"
  133.         };
  134.  
  135.       // compile Vertex shader
  136.         GLuint m_vxShaderId = glCreateShader(GL_VERTEX_SHADER);
  137.         GLsizei nlines_vx = sizeof(g_vertexShader)/sizeof(const GLchar*);
  138.         glShaderSource(m_vxShaderId, nlines_vx, (const GLchar**)g_vertexShader, NULL);
  139.         glCompileShader(m_vxShaderId);
  140.         CheckShader(m_vxShaderId, GL_COMPILE_STATUS, &amp;ret, "unable to compile the vertex shader!");
  141.  
  142.       // compile Fragment shader
  143.         GLuint m_fgShaderId = glCreateShader(GL_FRAGMENT_SHADER);
  144.         GLsizei nlines_fg = sizeof(g_fragmentShader)/sizeof(const GLchar*);
  145.         glShaderSource(m_fgShaderId, nlines_fg, (const GLchar**)g_fragmentShader, NULL);
  146.         glCompileShader(m_fgShaderId);
  147.         CheckShader(m_fgShaderId, GL_COMPILE_STATUS, &amp;ret, "unable to compile the fragment shader!");
  148.  
  149.       // link shaders
  150.         shader_id = glCreateProgram();
  151.         glAttachShader(shader_id, m_vxShaderId);
  152.         glAttachShader(shader_id, m_fgShaderId);
  153.         glLinkProgram(shader_id);
  154.         CheckShader(shader_id, GL_LINK_STATUS, &amp;ret, "unable to link the program!");
  155.  
  156.       //hooks from CPU to GPU
  157.         //define Uniform hooks
  158.         glm_ProjectionMatrix_id = glGetUniformLocation(shader_id, "glm_ProjectionMatrix");
  159.         glm_ModelViewMatrix_id = glGetUniformLocation(shader_id, "glm_ModelViewMatrix");
  160.  
  161.         //guard that all attributes have same number of elements
  162.         assert(Nbytes_vertices0/4/sizeof(GLfloat)==Nbytes_colors0/4/sizeof(GLfloat));
  163.         vao_elementcount[0]=Nbytes_vertices0/4/sizeof(GLfloat); // number of elements for first VAO
  164.         assert(Nbytes_vertices1/4/sizeof(GLfloat)==Nbytes_colors1/4/sizeof(GLfloat));
  165.         vao_elementcount[1]=Nbytes_vertices1/4/sizeof(GLfloat); // number of elements for second VAO
  166.  
  167.         //create and define vertex array objects
  168.         glGenVertexArrays(2, &amp;vao_id[0]); // vao_id[#] will be referenced in Draw()
  169.         defineVertexArrayObject(vao_id[0],Nbytes_vertices0,4,GL_FLOAT,vertices0,colors0); //VertexAttribArray: vertices0, colors0
  170.         defineVertexArrayObject(vao_id[1],Nbytes_vertices1,4,GL_FLOAT,vertices1,colors1); //VertexAttribArray: vertices1, colors1
  171.  
  172.       // finally, use the shader for rendering
  173.         glUseProgram(shader_id);            // select the shaders program
  174.  
  175.         return ret;                                     // Initialization Went OK?
  176.       }
  177.  
  178.       void defineVertexArrayObject(GLuint vaoId, size_t Nbytes, GLint size, GLenum type, GLfloat *vertices, GLfloat *colors)
  179.       {
  180.         //enable vertex array object to be defined
  181.         glBindVertexArray(vaoId);
  182.  
  183.         //generate VBO foreach 'in'; dgl_Vertex and dgl_Color
  184.         GLuint m_vboId[2];
  185.         glGenBuffers(2, &amp;m_vboId[0]);
  186.  
  187.         //"in        vec4 dgl_Vertex;",
  188.         glBindBuffer(GL_ARRAY_BUFFER, m_vboId[0] ); // enable the 1st VBO
  189.         glBufferData(GL_ARRAY_BUFFER, Nbytes, vertices, GL_STATIC_DRAW); // fill the VBO with vertices data
  190.         const GLuint index_mPosition = glGetAttribLocation(shader_id,"dgl_Vertex"); // get ID for "dgl_Vertex"
  191.         glVertexAttribPointer(index_mPosition, size, type, GL_FALSE, 0, 0); // VBO point to the "dgl_Vertex" attribute
  192.         glEnableVertexAttribArray(index_mPosition);     // enable VBO vertex attribute ("dgl_Vertex")
  193.  
  194.         //"in        vec4 dgl_Color;",
  195.         glBindBuffer(GL_ARRAY_BUFFER, m_vboId[1]);  // enable the 2nd VBO
  196.         glBufferData(GL_ARRAY_BUFFER, Nbytes , colors, GL_STATIC_DRAW); // fill the 2nd VBO with colors data
  197.         const GLuint index_mcolor = glGetAttribLocation(shader_id,"dgl_Color"); // get ID for "dgl_Color"
  198.         glVertexAttribPointer(index_mcolor, size, type, GL_FALSE, 0, 0); // VBO point to the "dgl_Color" attribute
  199.         glEnableVertexAttribArray(index_mcolor);        // enable VBO vertex attribute ("dgl_Color")
  200.       }
  201.  
  202.       void CheckShader(GLuint id, GLuint type, GLint *ret, const char *onfail)
  203.       {
  204.        //Check if something is wrong with the shader
  205.        switch(type) {
  206.        case(GL_COMPILE_STATUS):
  207.          glGetShaderiv(id, type, ret);
  208.          if(*ret == false){
  209.           int infologLength =  0;
  210.           glGetShaderiv(id, GL_INFO_LOG_LENGTH, &amp;infologLength);
  211.           GLchar buffer[infologLength];
  212.           GLsizei charsWritten = 0;
  213.           std::cout << onfail << std::endl;
  214.           glGetShaderInfoLog(id, infologLength, &amp;charsWritten, buffer);
  215.           std::cout << buffer << std::endl;
  216.          }
  217.          break;
  218.        case(GL_LINK_STATUS):
  219.          glGetProgramiv(id, type, ret);
  220.          if(*ret == false){
  221.           int infologLength =  0;
  222.           glGetProgramiv(id, GL_INFO_LOG_LENGTH, &amp;infologLength);
  223.           GLchar buffer[infologLength];
  224.           GLsizei charsWritten = 0;
  225.           std::cout << onfail << std::endl;
  226.           glGetProgramInfoLog(id, infologLength, &amp;charsWritten, buffer);
  227.           std::cout << buffer << std::endl;
  228.          }
  229.        default:
  230.          break;
  231.        };
  232.       }
  233.  
  234.       void Draw_vao(size_t index)
  235.       {
  236.         glBindVertexArray(vao_id[index]);       // select the vertex array object:vao_id[index] by definiton using vertices_index,colors_index
  237.         glDrawArrays(vao_primitivetype[index], 0, vao_elementcount[index]); // draw the array (at the speed of light)
  238.       }
  239.  
  240.       void Draw()                                   // Here's Where We Do All The Drawing
  241.       {
  242.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  243.  
  244.         glUniformMatrix4fv(glm_ProjectionMatrix_id, 1, false, &amp;glm_ProjectionMatrix.top()[0][0] );  // set the rotation/translation/scale matrix
  245.         //glUniformMatrix4fv(glm_ProjectionMatrix_id, 1, false, address(glm_ProjectionMatrix.top()) );  // set the rotation/translation/scale matrix
  246.  
  247.         {
  248.         glm_ModelViewMatrix.push(glm_ModelViewMatrix.top());
  249.         //glm_ModelViewMatrix.top() *= translate(       vec3(0.5, 0.5, 0.0) );
  250.         glm_ModelViewMatrix.top() *=    rotate(45.0f, vec3(0.0, 0.0, 1.0) );
  251.         glm_ModelViewMatrix.top() *=     scale(       vec3(0.2, 0.2, 0.2) );
  252.  
  253.         glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, &amp;glm_ModelViewMatrix.top()[0][0] );    // set the rotation/translation/scale matrix
  254.         //glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, address(glm_ModelViewMatrix.top()) );    // set the rotation/translation/scale matrix
  255.  
  256.         Draw_vao(0);
  257.  
  258.         glm_ModelViewMatrix.pop();
  259.         }
  260.  
  261.         {
  262.         glm_ModelViewMatrix.push(glm_ModelViewMatrix.top());
  263.         glm_ModelViewMatrix.top() *= translate(       vec3(0.0, 0.0, 0.25) );
  264.         //glm_ModelViewMatrix.top() *=    rotate(45.0f, vec3(1.0, 1.0, 0.0) );
  265.         glm_ModelViewMatrix.top() *=     scale(       vec3(0.2, 0.2, 0.2) );
  266.  
  267.         glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, &amp;glm_ModelViewMatrix.top()[0][0] );    // set the rotation/translation/scale matrix
  268.         //glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, address(glm_ModelViewMatrix.top()) );    // set the rotation/translation/scale matrix
  269.  
  270.         Draw_vao(1);
  271.  
  272.         glm_ModelViewMatrix.pop();
  273.         }
  274.       }
  275.  
  276.       bool Reshape(GLfloat ratio)
  277.       {
  278.           //glMatrixMode(GL_PROJECTION);
  279.           glm_ProjectionMatrix.top() = mat4(1.0); //glLoadIdentity
  280.           glm_ProjectionMatrix.top() *= perspective(20.0f,ratio,1.0f,3.0f);
  281.             //glLoadMatrixf(address(glm_ProjectionMatrix.top()));
  282.           glUniformMatrix4fv(glm_ProjectionMatrix_id, 1, false, &amp;glm_ProjectionMatrix.top()[0][0] );    // set the rotation/translation/scale matrix
  283.       }
  284.  
  285.       bool SetCamera(GLfloat theta, GLfloat phi)
  286.       {
  287.         //////////////
  288.           // Set the camera view.
  289.           static const double radianFactor = acos(0.0) / 90.0;
  290.           float r = 1.0f*2.0; // approx. want half way between near + far (see perspective)
  291.           float eyeX = r * sin(theta * radianFactor) * cos(phi * radianFactor);
  292.           float eyeY = r * sin(theta * radianFactor) * sin(phi * radianFactor);
  293.           float eyeZ = r * cos(radianFactor * theta);
  294.  
  295.           float centerX = 0, centerY = 0, centerZ = 0;
  296.           float upX = 0, upY = 1.0f, upZ = 0;
  297.  
  298.           //glMatrixMode(GL_MODELVIEW);
  299.           glm_ModelViewMatrix.top() = mat4(1.0); // LoadIdentity
  300.           glm_ModelViewMatrix.top() *= lookAt( vec3(eyeX, eyeY, eyeZ), vec3(centerX, centerY, centerZ), vec3(upX, upY, upZ));
  301.             //glLoadMatrixf(address(glm_ModelViewMatrix.top()));
  302.           glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, &amp;glm_ModelViewMatrix.top()[0][0] );
  303.  
  304.         return true;
  305.       }
  306. };
  307.  
  308. // GLOBAL ///////////////////////////////////////////////////////////
  309. CustomGraphicsPipeline Scene;
  310. /////////////////////////////////////////////////////////////////////
  311.  
  312. static void timer(int dt_msec)
  313. {
  314.   static GLfloat time_msec = 0.0;
  315.   time_msec += dt_msec; // absolute time
  316.  
  317.   Scene.SetCamera(global::theta, global::phi);
  318.  
  319.     glutPostRedisplay();
  320.     glutTimerFunc(30,timer,30); // come back in 30msec
  321. }
  322.  
  323. static void display(void)
  324. {
  325.     Scene.Draw();
  326.   glutSwapBuffers();
  327. }
  328.  
  329. static void reshape(int w, int h)
  330. {
  331.     // Set the viewport to be the entire window
  332.     glViewport(0, 0, w, h);
  333.  
  334.     // Prevent a divide by zero, when window is too short
  335.     if(h == 0) h = 1;
  336.  
  337.     global::width = w;
  338.     global::height = h;
  339.     global::ratio = 1.0 * w / h;
  340.  
  341.     Scene.Reshape(global::ratio);
  342. }
  343.  
  344. static void keyboard(unsigned char k, int x, int y)
  345. {
  346.     switch (k) {
  347.             case 't' : global::theta++; if(global::theta > 360) global::theta = 1; break;
  348.             case 'p' : global::phi++; if(global::phi > 360) global::phi = 1; break;
  349.             case 'T' : global::theta--; if(global::theta < 0) global::theta = 359; break;
  350.             case 'P' : global::phi--; if(global::phi < 0) global::phi = 359; break;
  351.             case  27 : exit(0); break;
  352.     }
  353. }
  354.  
  355. int main( int argc, char *argv[] )
  356. {
  357.    glutInit( &amp;argc, argv );
  358.    //opengl 3.0 with freeglut requires to install latest version from svn
  359.    //but not necessary to actually get openGL context since code will run anyhow.
  360.    //glutInitContextVersion( 3, 0 ); // freeglut is so cool! get openGL 3.0 context
  361.    //glutInitContextFlags( int flags )
  362.    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
  363.    glutInitWindowSize(global::width, global::height);
  364.    glutCreateWindow("demo opengl 3.0 matrix transformations");
  365.  
  366.    glewInit();
  367.  
  368.    assert( Scene.Init() ); // bail if scene initialization fails
  369.  
  370.    glutTimerFunc(0,timer,0);
  371.    glutDisplayFunc(display);
  372.    glutReshapeFunc(reshape);
  373.    glutKeyboardFunc(keyboard);
  374.  
  375.    glutMainLoop();
  376.  
  377.    return 0;
  378. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement