//This is my orthographic projection window with two viewports, one looking down the x and one down the z axis. void renderAxis() { vec3 position; glClearColor(0.4f, 0.4f, 0.4f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(globals.program2); //left side X-axis glViewport( (int)(.1*globals.windowHalfWidth2), (int)(.1*globals.windowHeight2), (int)(.8*globals.windowHalfWidth2), (int)(.8*globals.windowHeight2) ); //Question //set view matrix with camera looking down x-axis glUniformMatrix4fv(globals.viewUniform2, 1, GL_FALSE, glm::value_ptr(globals.viewX)); //draw ships, save time and only draw one row, since in ortho proj we don't see anything behind since it's a parallel proj float coord[] = { -60.0f, -20.0f, 20.0f, 60.0f }; for(int i = 0; i < 4; i++) { position = vec3( 20.0f, 0.0f, coord[i]); ship.render(position, globals.vaoSphere2, globals.vaoCylinder2, globals.worldUniform2, globals.fragColorUniform2); } //draw sphere glPolygonMode(GL_FRONT, GL_LINE); glPolygonMode(GL_BACK, GL_LINE); //update uniforms mat4 temp(1.0f); temp[3] = vec4(-80.0f, 0.0f, 0.0f, 1.0f); glUniformMatrix4fv(globals.worldUniform2, 1, GL_FALSE, glm::value_ptr(temp)); vec4 color(1.0f, 1.0f, 1.0f, 1.0f); glUniform4fv(globals.fragColorUniform2, 1, glm::value_ptr(color)); glBindVertexArray(globals.vaoSphere3); glDrawElements(GL_TRIANGLES, globals.elementSphere3.size(), GL_UNSIGNED_SHORT, 0); //reset this so other objects get filled in glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_FILL); glBindVertexArray(0); //right side Z-axis glViewport( (int)(.1*globals.windowHalfWidth2 + globals.windowHalfWidth2), (int)(.1*globals.windowHeight2), (int)(.8*globals.windowHalfWidth2), (int)(.8*globals.windowHeight2)); glUniformMatrix4fv(globals.viewUniform2, 1, GL_FALSE, glm::value_ptr(globals.viewZ)); for(int i = 0; i < 4; i++) { position = vec3( coord[i], 0.0f, 20.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); } //draw sphere glPolygonMode(GL_FRONT, GL_LINE); glPolygonMode(GL_BACK, GL_LINE); //update uniforms temp[3] = vec4(0.0f, 0.0f, -80.0f, 1.0f); glUniformMatrix4fv(globals.worldUniform2, 1, GL_FALSE, glm::value_ptr(temp)); color = vec4(1.0f, 1.0f, 1.0f, 1.0f); glUniform4fv(globals.fragColorUniform2, 1, glm::value_ptr(color)); glBindVertexArray(globals.vaoSphere3); glDrawElements(GL_TRIANGLES, globals.elementSphere3.size(), GL_UNSIGNED_SHORT, 0); glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_FILL); glBindVertexArray(0); glUseProgram(0); //draw frustum glUseProgram(globals.program3); glBindVertexArray(globals.vaoFrustum); //set uniforms that will be used by the frustum shader program mat4 world(1.0f); glUniformMatrix4fv(globals.worldUniform, 1, GL_FALSE, glm::value_ptr(world)); //world glUniformMatrix4fv(globals.viewUniform, 1, GL_FALSE, glm::value_ptr(globals.viewX)); //view glUniformMatrix4fv(globals.projUniform, 1, GL_FALSE, glm::value_ptr(globals.orthoProj)); //proj mat4 inverse = CalcViewMatrix(globals.camera.camPosition, globals.camera.camTarget, globals.camera.upDirection); inverse = glm::inverse(inverse); glUniformMatrix4fv(globals.inverseViewUniform, 1, GL_FALSE, glm::value_ptr(inverse)); // view inverse inverse = glm::inverse(globals.perspProj); glUniformMatrix4fv(globals.inverseProjUniform, 1, GL_FALSE, glm::value_ptr(inverse)); //proj inverse //use same two viewports for drawing the frustum. I do this separately because I have a particular shader program and didn't want to switch back and forth. //left side X-axis glViewport( (int)(.1*globals.windowHalfWidth2), (int)(.1*globals.windowHeight2), (int)(.8*globals.windowHalfWidth2), (int)(.8*globals.windowHeight2) ); glPointSize(10.0f); glDrawElements(GL_LINES, 48, GL_UNSIGNED_SHORT, (GLvoid*)0); //right side Z-axis glUniformMatrix4fv(globals.viewUniform, 1, GL_FALSE, glm::value_ptr(globals.viewZ)); //view glViewport( (int)(.1*globals.windowHalfWidth2 + globals.windowHalfWidth2), (int)(.1*globals.windowHeight2), (int)(.8*globals.windowHalfWidth2), (int)(.8*globals.windowHeight2)); glDrawElements(GL_LINES, 48, GL_UNSIGNED_SHORT, (GLvoid*)0); glBindVertexArray(0); glUseProgram(0); //draw text glViewport(0, 0, 400, 400); const unsigned char string1[] = "Options: w - wireframe mode, m - antialiasing, t - textures"; vec3 temp2(-80.0f, -30.0f, 0.0f); drawText(string1, temp2); const unsigned char string2[] = "X - A X I S"; temp2 = vec3(-80.0f, -40.0f, 0.0f); drawText(string2, temp2); glViewport(700, 0, 800, 400); const unsigned char string3[] = "Z - A X I S"; temp2 = vec3(-80.0f, -40.0f, 0.0f); drawText(string3, temp2); glutSwapBuffers(); glutPostRedisplay(); }
//This is my perspective window render fuction void renderFPS() { //enable options //msaa if(globals.msaaEnable) { glEnable(GL_MULTISAMPLE_ARB); } else { glDisable(GL_MULTISAMPLE_ARB); } //wireframe mode if(globals.wireframeEnable) { glPolygonMode(GL_FRONT, GL_LINE); glPolygonMode(GL_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_FILL); } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //get current view matrix from camera class mat4 view = CalcViewMatrix(globals.camera.camPosition, globals.camera.camTarget, globals.camera.upDirection); glUseProgram(globals.program1); //get view matrix from camera glUniformMatrix4fv(globals.viewUniform1, 1, GL_FALSE, glm::value_ptr(view)); //for this project, each ship is going to be the same, could either add method or parameter to pass in a "world" matrix //or a scale/rotation matrix to alter each ship individually //draw ships passing in the postion it should be placed float coord[] = { -60.0f, -20.0f, 20.0f, 60.0f }; //used to place ships vec3 position; for(int i = 0; i < 4; i++) { position = vec3( coord[i], 0.0f, -60.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); position = vec3( coord[i], 0.0f, -20.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); position = vec3( coord[i], 0.0f, 20.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); position = vec3( coord[i], 0.0f, 60.0f); ship.render(position, globals.vaoSphere1, globals.vaoCylinder1, globals.worldUniform1, globals.fragColorUniform1); } glUseProgram(0); //I have this as an option since for this project we wanted to demonstrate the frustum and so I can't see all of the textured floor so I can //turn it on and off. if(globals.textureOn) { //draw textured floor glUseProgram(globals.programT); glBindVertexArray(globals.vaoT); glUniformMatrix4fv(globals.viewTUniform, 1, GL_FALSE, glm::value_ptr(view)); //view mat4 world(1.0f); world[3] = vec4(0.0f, -19.0f, 0.0f, 1.0f); //translate world[0].x = world[2].z = 100.0f; //scale glUniformMatrix4fv(globals.worldTUniform, 1, GL_FALSE, glm::value_ptr(world)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, globals.texture); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (GLubyte*)0); glBindVertexArray(0); glUseProgram(0); } //draw text glViewport(0, 0, 400, 400); //do this so that text gets rendered to same area in window and doesn't change due to resizing const unsigned char string1[] = "Options: w - wireframe mode, m - antialiasing, t - textures"; vec3 temp(-80.0f, -30.0f, 0.0f); drawText(string1, temp); const unsigned char string2[] = "PERSPECTIVE VIEW"; temp = vec3(-80.0f, -40.0f, 0.0f); drawText(string2, temp); glViewport(0, 0, globals.windowWidth1, globals.windowHeight1); //reset viewport back to entire screen glutSwapBuffers(); glutPostRedisplay(); }