Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //on linux or mingw: g++ demo.cpp -lglut -lGLEW -DGL3_PROTOTYPES
- // modified to use GLM library from [url]http://pheatt.emporia.edu/courses/2005/cs410f05/hand14/hand14.htm[/url]
- // 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]
- #include <GL/glew.h> // great opengl extensions helper
- #include <GL/gl3.h>
- #include <GL/freeglut.h> // use of opengl 3.0 context requires freeglut from svn!
- #include <glm/glm.h> //OpenGL Mathematics (GLM). A C++ mathematics library for 3D graphics.
- #include <glm/glmext.h>
- #include <glm/GLM_VIRTREV_address.h> // gives helper function address(X) instead of using &X[0][0]
- namespace glm
- {
- // read glm/gtx/transform.h for function prototypes
- using GLM_GTX_transform;
- using GLM_GTX_transform2; // for lookAt
- using GLM_GTX_matrix_projection;
- }
- using namespace glm;
- #include <cstdio>
- #include <cmath>
- #include <iostream>
- #include <iomanip>
- #include <sstream>
- #include <stack>
- #include <cstring>
- #include <cassert>
- namespace global {
- int theta = 0;
- int phi = 0;
- GLfloat ratio = 1.0;
- int width = 512;
- int height = 512;
- };
- class CustomGraphicsPipeline
- {
- GLuint shader_id;
- std::stack<mat4> glm_ProjectionMatrix; //cpu-side
- GLint glm_ProjectionMatrix_id; //cpu-side hook to shader uniform
- std::stack<mat4> glm_ModelViewMatrix; //cpu-side
- GLint glm_ModelViewMatrix_id; //cpu-side hook to shader uniform
- GLuint vao_id[2]; // vertex array object hook id
- GLuint vao_elementcount[2]; // number of attribute elements in vao ie number of vertices
- GLuint vao_primitivetype[2]; // type [GL_LINE_LOOP|GL_TRIANGLES|etc]
- public:
- CustomGraphicsPipeline() :
- shader_id(NULL),
- glm_ProjectionMatrix_id(NULL),
- glm_ModelViewMatrix_id(NULL)
- {
- glm_ProjectionMatrix.push( mat4(1.0f) ); // identity matrix
- glm_ModelViewMatrix.push( mat4(1.0f) ), // identity matrix
- vao_id[0]=NULL;
- vao_id[1]=NULL;
- vao_elementcount[0]=0;
- vao_elementcount[1]=0;
- vao_primitivetype[0] = GL_LINE_LOOP;
- vao_primitivetype[1] = GL_TRIANGLES;
- }
- ~CustomGraphicsPipeline() {}
- bool Init() // All Setup For OpenGL Goes Here
- {
- GLint ret = true; // optimistic return value upon completion of execution
- std::cout << "GL_VERSION: " << glGetString(GL_VERSION) << std::endl;
- std::cout << "GL_EXTENSIONS: " << glGetString(GL_EXTENSIONS) << std::endl;
- std::cout << "GL_RENDERER: " << glGetString(GL_RENDERER) << std::endl;
- std::cout << "GL_VENDOR: " << glGetString(GL_VENDOR) << std::endl;
- std::cout << "GLU_VERSION: " << gluGetString(GLU_VERSION) << std::endl;
- std::cout << "GLU_EXTENSIONS: " << gluGetString(GLU_EXTENSIONS) << std::endl;
- std::cout << "GLUT_API_VERSION: " << GLUT_API_VERSION << std::endl;
- #ifdef GLUT_XLIB_IMPLEMENTATION
- std::cout << "GLUT_XLIB_IMPLEMENTATION: " << GLUT_XLIB_IMPLEMENTATION << std::endl;
- #endif
- std::cout << "press t,T to rotate camera theta" << std::endl;
- std::cout << "press p,P to rotate camera phi" << std::endl;
- glEnable(GL_DEPTH_TEST);
- glClearColor(0.2f, 0.2f, 0.2f, 0.5f);
- //Datas destioned for video memory, can be local (and lost after bound to GPU!).
- GLfloat vertices0[] = { // dgl_Vertex
- 1.0, -1.0, 0.0, 1.0, // xyzw
- -1.0, -1.0, 0.0, 1.0,
- 0.0, 1.0, 0.0, 1.0
- };
- size_t Nbytes_vertices0=sizeof(vertices0);
- GLfloat colors0[] = { // dgl_Color
- 0.0, 0.0, 1.0, 1.0, //rgba
- 0.0, 1.0, 0.0, 1.0,
- 1.0, 0.0, 0.0, 1.0
- };
- size_t Nbytes_colors0=sizeof(colors0);
- GLfloat vertices1[] = { // dgl_Vertex
- 0.5, -0.5, 0.0, 1.0, // xyzw
- -0.5, -0.5, 0.0, 1.0,
- 0.0, 0.5, 0.0, 1.0
- };
- size_t Nbytes_vertices1=sizeof(vertices1);
- GLfloat colors1[] = { // dgl_Color
- 0.0, 0.0, 1.0, 1.0, //rgba
- 0.0, 1.0, 0.0, 1.0,
- 1.0, 0.0, 0.0, 1.0
- };
- size_t Nbytes_colors1=sizeof(colors1);
- const GLchar *g_vertexShader[] = {"#version 130\n",
- "uniform mat4 glm_ProjectionMatrix;\n", // replaces deprecated gl_ProjectionMatrix see [url]http://www.lighthouse3d.com/opengl/glsl/index.php?minimal[/url]
- "uniform mat4 glm_ModelViewMatrix;\n", // replaces deprecated gl_ModelViewMatrix
- "in vec4 dgl_Vertex;\n", // replaces deprecated gl_Vertex
- "in vec4 dgl_Color;\n", // replaces deprecated gl_Color
- "invariant out vec4 Color;\n", // to fragment shader
- "void main(void)\n",
- "{\n",
- " Color = dgl_Color;\n",
- " gl_Position = glm_ProjectionMatrix*glm_ModelViewMatrix*dgl_Vertex;\n", // replaces deprecated ftransform() see [url]http://www.songho.ca/opengl/gl_transform.html[/url]
- "}\n"
- };
- const GLchar *g_fragmentShader[] = {"#version 130\n",
- "invariant in vec4 Color;\n", // from vertex shader
- "out vec4 dgl_FragColor;\n", // replaces deprecated gl_FragColor
- "void main(void)\n",
- "{\n",
- " dgl_FragColor = Color;\n", // gl_FragColor is deprecated
- "}\n"
- };
- // compile Vertex shader
- GLuint m_vxShaderId = glCreateShader(GL_VERTEX_SHADER);
- GLsizei nlines_vx = sizeof(g_vertexShader)/sizeof(const GLchar*);
- glShaderSource(m_vxShaderId, nlines_vx, (const GLchar**)g_vertexShader, NULL);
- glCompileShader(m_vxShaderId);
- CheckShader(m_vxShaderId, GL_COMPILE_STATUS, &ret, "unable to compile the vertex shader!");
- // compile Fragment shader
- GLuint m_fgShaderId = glCreateShader(GL_FRAGMENT_SHADER);
- GLsizei nlines_fg = sizeof(g_fragmentShader)/sizeof(const GLchar*);
- glShaderSource(m_fgShaderId, nlines_fg, (const GLchar**)g_fragmentShader, NULL);
- glCompileShader(m_fgShaderId);
- CheckShader(m_fgShaderId, GL_COMPILE_STATUS, &ret, "unable to compile the fragment shader!");
- // link shaders
- shader_id = glCreateProgram();
- glAttachShader(shader_id, m_vxShaderId);
- glAttachShader(shader_id, m_fgShaderId);
- glLinkProgram(shader_id);
- CheckShader(shader_id, GL_LINK_STATUS, &ret, "unable to link the program!");
- //hooks from CPU to GPU
- //define Uniform hooks
- glm_ProjectionMatrix_id = glGetUniformLocation(shader_id, "glm_ProjectionMatrix");
- glm_ModelViewMatrix_id = glGetUniformLocation(shader_id, "glm_ModelViewMatrix");
- //guard that all attributes have same number of elements
- assert(Nbytes_vertices0/4/sizeof(GLfloat)==Nbytes_colors0/4/sizeof(GLfloat));
- vao_elementcount[0]=Nbytes_vertices0/4/sizeof(GLfloat); // number of elements for first VAO
- assert(Nbytes_vertices1/4/sizeof(GLfloat)==Nbytes_colors1/4/sizeof(GLfloat));
- vao_elementcount[1]=Nbytes_vertices1/4/sizeof(GLfloat); // number of elements for second VAO
- //create and define vertex array objects
- glGenVertexArrays(2, &vao_id[0]); // vao_id[#] will be referenced in Draw()
- defineVertexArrayObject(vao_id[0],Nbytes_vertices0,4,GL_FLOAT,vertices0,colors0); //VertexAttribArray: vertices0, colors0
- defineVertexArrayObject(vao_id[1],Nbytes_vertices1,4,GL_FLOAT,vertices1,colors1); //VertexAttribArray: vertices1, colors1
- // finally, use the shader for rendering
- glUseProgram(shader_id); // select the shaders program
- return ret; // Initialization Went OK?
- }
- void defineVertexArrayObject(GLuint vaoId, size_t Nbytes, GLint size, GLenum type, GLfloat *vertices, GLfloat *colors)
- {
- //enable vertex array object to be defined
- glBindVertexArray(vaoId);
- //generate VBO foreach 'in'; dgl_Vertex and dgl_Color
- GLuint m_vboId[2];
- glGenBuffers(2, &m_vboId[0]);
- //"in vec4 dgl_Vertex;",
- glBindBuffer(GL_ARRAY_BUFFER, m_vboId[0] ); // enable the 1st VBO
- glBufferData(GL_ARRAY_BUFFER, Nbytes, vertices, GL_STATIC_DRAW); // fill the VBO with vertices data
- const GLuint index_mPosition = glGetAttribLocation(shader_id,"dgl_Vertex"); // get ID for "dgl_Vertex"
- glVertexAttribPointer(index_mPosition, size, type, GL_FALSE, 0, 0); // VBO point to the "dgl_Vertex" attribute
- glEnableVertexAttribArray(index_mPosition); // enable VBO vertex attribute ("dgl_Vertex")
- //"in vec4 dgl_Color;",
- glBindBuffer(GL_ARRAY_BUFFER, m_vboId[1]); // enable the 2nd VBO
- glBufferData(GL_ARRAY_BUFFER, Nbytes , colors, GL_STATIC_DRAW); // fill the 2nd VBO with colors data
- const GLuint index_mcolor = glGetAttribLocation(shader_id,"dgl_Color"); // get ID for "dgl_Color"
- glVertexAttribPointer(index_mcolor, size, type, GL_FALSE, 0, 0); // VBO point to the "dgl_Color" attribute
- glEnableVertexAttribArray(index_mcolor); // enable VBO vertex attribute ("dgl_Color")
- }
- void CheckShader(GLuint id, GLuint type, GLint *ret, const char *onfail)
- {
- //Check if something is wrong with the shader
- switch(type) {
- case(GL_COMPILE_STATUS):
- glGetShaderiv(id, type, ret);
- if(*ret == false){
- int infologLength = 0;
- glGetShaderiv(id, GL_INFO_LOG_LENGTH, &infologLength);
- GLchar buffer[infologLength];
- GLsizei charsWritten = 0;
- std::cout << onfail << std::endl;
- glGetShaderInfoLog(id, infologLength, &charsWritten, buffer);
- std::cout << buffer << std::endl;
- }
- break;
- case(GL_LINK_STATUS):
- glGetProgramiv(id, type, ret);
- if(*ret == false){
- int infologLength = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infologLength);
- GLchar buffer[infologLength];
- GLsizei charsWritten = 0;
- std::cout << onfail << std::endl;
- glGetProgramInfoLog(id, infologLength, &charsWritten, buffer);
- std::cout << buffer << std::endl;
- }
- default:
- break;
- };
- }
- void Draw_vao(size_t index)
- {
- glBindVertexArray(vao_id[index]); // select the vertex array object:vao_id[index] by definiton using vertices_index,colors_index
- glDrawArrays(vao_primitivetype[index], 0, vao_elementcount[index]); // draw the array (at the speed of light)
- }
- void Draw() // Here's Where We Do All The Drawing
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- glUniformMatrix4fv(glm_ProjectionMatrix_id, 1, false, &glm_ProjectionMatrix.top()[0][0] ); // set the rotation/translation/scale matrix
- //glUniformMatrix4fv(glm_ProjectionMatrix_id, 1, false, address(glm_ProjectionMatrix.top()) ); // set the rotation/translation/scale matrix
- {
- glm_ModelViewMatrix.push(glm_ModelViewMatrix.top());
- //glm_ModelViewMatrix.top() *= translate( vec3(0.5, 0.5, 0.0) );
- glm_ModelViewMatrix.top() *= rotate(45.0f, vec3(0.0, 0.0, 1.0) );
- glm_ModelViewMatrix.top() *= scale( vec3(0.2, 0.2, 0.2) );
- glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, &glm_ModelViewMatrix.top()[0][0] ); // set the rotation/translation/scale matrix
- //glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, address(glm_ModelViewMatrix.top()) ); // set the rotation/translation/scale matrix
- Draw_vao(0);
- glm_ModelViewMatrix.pop();
- }
- {
- glm_ModelViewMatrix.push(glm_ModelViewMatrix.top());
- glm_ModelViewMatrix.top() *= translate( vec3(0.0, 0.0, 0.25) );
- //glm_ModelViewMatrix.top() *= rotate(45.0f, vec3(1.0, 1.0, 0.0) );
- glm_ModelViewMatrix.top() *= scale( vec3(0.2, 0.2, 0.2) );
- glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, &glm_ModelViewMatrix.top()[0][0] ); // set the rotation/translation/scale matrix
- //glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, address(glm_ModelViewMatrix.top()) ); // set the rotation/translation/scale matrix
- Draw_vao(1);
- glm_ModelViewMatrix.pop();
- }
- }
- bool Reshape(GLfloat ratio)
- {
- //glMatrixMode(GL_PROJECTION);
- glm_ProjectionMatrix.top() = mat4(1.0); //glLoadIdentity
- glm_ProjectionMatrix.top() *= perspective(20.0f,ratio,1.0f,3.0f);
- //glLoadMatrixf(address(glm_ProjectionMatrix.top()));
- glUniformMatrix4fv(glm_ProjectionMatrix_id, 1, false, &glm_ProjectionMatrix.top()[0][0] ); // set the rotation/translation/scale matrix
- }
- bool SetCamera(GLfloat theta, GLfloat phi)
- {
- //////////////
- // Set the camera view.
- static const double radianFactor = acos(0.0) / 90.0;
- float r = 1.0f*2.0; // approx. want half way between near + far (see perspective)
- float eyeX = r * sin(theta * radianFactor) * cos(phi * radianFactor);
- float eyeY = r * sin(theta * radianFactor) * sin(phi * radianFactor);
- float eyeZ = r * cos(radianFactor * theta);
- float centerX = 0, centerY = 0, centerZ = 0;
- float upX = 0, upY = 1.0f, upZ = 0;
- //glMatrixMode(GL_MODELVIEW);
- glm_ModelViewMatrix.top() = mat4(1.0); // LoadIdentity
- glm_ModelViewMatrix.top() *= lookAt( vec3(eyeX, eyeY, eyeZ), vec3(centerX, centerY, centerZ), vec3(upX, upY, upZ));
- //glLoadMatrixf(address(glm_ModelViewMatrix.top()));
- glUniformMatrix4fv(glm_ModelViewMatrix_id, 1, false, &glm_ModelViewMatrix.top()[0][0] );
- return true;
- }
- };
- // GLOBAL ///////////////////////////////////////////////////////////
- CustomGraphicsPipeline Scene;
- /////////////////////////////////////////////////////////////////////
- static void timer(int dt_msec)
- {
- static GLfloat time_msec = 0.0;
- time_msec += dt_msec; // absolute time
- Scene.SetCamera(global::theta, global::phi);
- glutPostRedisplay();
- glutTimerFunc(30,timer,30); // come back in 30msec
- }
- static void display(void)
- {
- Scene.Draw();
- glutSwapBuffers();
- }
- static void reshape(int w, int h)
- {
- // Set the viewport to be the entire window
- glViewport(0, 0, w, h);
- // Prevent a divide by zero, when window is too short
- if(h == 0) h = 1;
- global::width = w;
- global::height = h;
- global::ratio = 1.0 * w / h;
- Scene.Reshape(global::ratio);
- }
- static void keyboard(unsigned char k, int x, int y)
- {
- switch (k) {
- case 't' : global::theta++; if(global::theta > 360) global::theta = 1; break;
- case 'p' : global::phi++; if(global::phi > 360) global::phi = 1; break;
- case 'T' : global::theta--; if(global::theta < 0) global::theta = 359; break;
- case 'P' : global::phi--; if(global::phi < 0) global::phi = 359; break;
- case 27 : exit(0); break;
- }
- }
- int main( int argc, char *argv[] )
- {
- glutInit( &argc, argv );
- //opengl 3.0 with freeglut requires to install latest version from svn
- //but not necessary to actually get openGL context since code will run anyhow.
- //glutInitContextVersion( 3, 0 ); // freeglut is so cool! get openGL 3.0 context
- //glutInitContextFlags( int flags )
- glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
- glutInitWindowSize(global::width, global::height);
- glutCreateWindow("demo opengl 3.0 matrix transformations");
- glewInit();
- assert( Scene.Init() ); // bail if scene initialization fails
- glutTimerFunc(0,timer,0);
- glutDisplayFunc(display);
- glutReshapeFunc(reshape);
- glutKeyboardFunc(keyboard);
- glutMainLoop();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement