#ifndef __RENDERENGINE #define __RENDERENGINE #include "GLHelper.h" #include "WorldState.h" #include "glm/gtc/matrix_transform.hpp" class RenderEngine { public: RenderEngine() { initialized = false; } ~RenderEngine() { if(initialized) { glDeleteVertexArrays(1, &clockArray); } } void display(WorldState const & world) { if(!initialized) init(world.getModel()); Model const & model = world.getModel(); float time = world.getCurrentTime(); //clear the old frame glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); checkGLError("clear"); //use shader glUseProgram(clockProg); //TODO upload transformation matrices to control the clock //to build the clock: //create the vertices in Model, display here //use the tick object 12 times with different rotations //use a transform to rotate the large hand clockwise //use a transform to rotate the small hand clockwise at 1/12 the large hand rate //TODO handle the qwer transforms //apply the z rotation before the y rotation //figure out the rest of the transform order glUniform1f(timeSlot, time); checkGLError("uniform"); //draw model glBindVertexArray(clockArray); //glDrawArrays(GL_LINE_LOOP, model.getObjectStart(0), model.getObjectSize(0)); glm::mat4 rot = glm::rotate(glm::mat4(1.0f), time, glm::vec3(0,0,1)); glUniformMatrix4fv(transformSlot, 1, GL_FALSE, &rot[0][0]); glDrawArrays(GL_LINES, model.getObjectStart(1), model.getObjectSize(1)); glm::mat4 ident = glm::mat4(1.0f); glUniformMatrix4fv(transformSlot, 1, GL_FALSE, &ident[0][0]); glDrawArrays(GL_LINES, model.getObjectStart(2), model.getObjectSize(2)); glm::mat4 trans = glm::translate(glm::mat4(1.0f), glm::vec3(time*0.1, time*0.1, 0)); glm::mat4 funny = rot * trans; glUniformMatrix4fv(transformSlot, 1, GL_FALSE, &funny[0][0]); glDrawArrays(GL_LINES, model.getObjectStart(3), model.getObjectSize(3)); checkGLError("draw"); //cleanup glBindVertexArray(0); glUseProgram(0); checkGLError("render"); } private: bool initialized; GLuint clockProg; GLuint clockArray; GLint timeSlot; GLint transformSlot; void setupShader() { char const * vertPath = "Shaders/simple.vert"; char const * redPath = "Shaders/simple.frag"; clockProg = ShaderManager::shaderFromFile(&vertPath, &redPath, 1, 1); checkGLError("shader"); } void setupBuffers(Model const & model) { GLint positionSlot; GLint colorSlot; GLuint positionBuffer; GLuint colorBuffer; positionSlot = glGetAttribLocation(clockProg, "pos"); colorSlot = glGetAttribLocation(clockProg, "color"); timeSlot = glGetUniformLocation(clockProg, "time"); transformSlot = glGetUniformLocation(clockProg, "T"); glGenVertexArrays(1, &clockArray); glBindVertexArray(clockArray); glGenBuffers(1, &positionBuffer); glBindBuffer(GL_ARRAY_BUFFER, positionBuffer); glBufferData(GL_ARRAY_BUFFER, model.getPositionBytes(), model.getPositions(), GL_STATIC_DRAW); glEnableVertexAttribArray(positionSlot); glVertexAttribPointer(positionSlot, 2, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Do the same thing for the color data glGenBuffers(1, &colorBuffer); glBindBuffer(GL_ARRAY_BUFFER, colorBuffer); glBufferData(GL_ARRAY_BUFFER, model.getColorBytes(), model.getColors(), GL_STATIC_DRAW); glEnableVertexAttribArray(colorSlot); glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); checkGLError("setup"); } float initLoader() { float ver = 0.0f; #ifdef GLEW glewExperimental = GL_TRUE; GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); } fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); if (GLEW_VERSION_1_1) { ver = 1.1f; } if (GLEW_VERSION_1_2) { ver = 1.2f; } if (GLEW_VERSION_1_3) { ver = 1.3f; } if (GLEW_VERSION_1_4) { ver = 1.4f; } if (GLEW_VERSION_1_5) { ver = 1.5f; } if (GLEW_VERSION_2_0) { ver = 2.0f; } if (GLEW_VERSION_2_1) { ver = 2.1f; } if (GLEW_VERSION_3_0) { ver = 3.0f; } if (GLEW_VERSION_3_1) { ver = 3.1f; } if (GLEW_VERSION_3_2) { ver = 3.2f; } if (GLEW_VERSION_3_3) { ver = 3.3f; } if (GLEW_VERSION_4_0) { ver = 4.0f; } if (GLEW_VERSION_4_1) { ver = 4.1f; } if (GLEW_VERSION_4_2) { ver = 4.2f; } if (GLEW_VERSION_4_3) { ver = 4.3f; } if (GLEW_VERSION_4_4) { ver = 4.4f; } if (GLEW_VERSION_4_5) { ver = 4.5f; } #endif #ifdef GL3W if (gl3wInit()) { fprintf(stderr, "failed to initialize OpenGL\n"); } if (gl3wIsSupported(1, 1)) { ver = 1.1f; } if (gl3wIsSupported(1, 2)) { ver = 1.2f; } if (gl3wIsSupported(1, 3)) { ver = 1.3f; } if (gl3wIsSupported(1, 4)) { ver = 1.4f; } if (gl3wIsSupported(1, 5)) { ver = 1.5f; } if (gl3wIsSupported(2, 0)) { ver = 2.0f; } if (gl3wIsSupported(2, 1)) { ver = 2.1f; } if (gl3wIsSupported(3, 0)) { ver = 3.0f; } if (gl3wIsSupported(3, 1)) { ver = 3.1f; } if (gl3wIsSupported(3, 2)) { ver = 3.2f; } if (gl3wIsSupported(3, 3)) { ver = 3.3f; } if (gl3wIsSupported(4, 0)) { ver = 4.0f; } if (gl3wIsSupported(4, 1)) { ver = 4.1f; } if (gl3wIsSupported(4, 2)) { ver = 4.2f; } if (gl3wIsSupported(4, 3)) { ver = 4.3f; } if (gl3wIsSupported(4, 4)) { ver = 4.4f; } if (gl3wIsSupported(4, 5)) { ver = 4.5f; } #endif return ver; } void init(Model const & model) { initialized = true; float ver = initLoader(); if( ver < 1.0f ) { printf("OpenGL is not supported.\n"); exit(1); } printf("OpenGL version %.1f is supported.\n", ver); //setup all shader parts setupShader(); //setup buffers setupBuffers(model); } }; #endif