/* Called by GLUT whenever the window needs to be redrawn. This * function should not be called directly by the programmer. Instead, * we can call glutPostRedisplay() to request that GLUT call display() * at some point. */ void display() { /* If we are using DGR, send or receive data to keep multiple * processes/computers synchronized. */ dgr_update(); /* Render the scene once for each viewport. Frequently one * viewport will fill the entire screen. However, this loop will * run twice for HMDs (once for the left eye and once for the * right. */ viewmat_begin_frame(); for(int viewportID=0; viewportID<viewmat_num_viewports(); viewportID++) { viewmat_begin_eye(viewportID); /* Where is the viewport that we are drawing onto and what is its size? */ int viewport[4]; // x,y of lower left corner, width, height viewmat_get_viewport(viewport, viewportID); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); /* Clear the current viewport. Without glScissor(), glClear() * clears the entire screen. We could call glClear() before * this viewport loop---but on order for all variations of * this code to work (Oculus support, etc), we can only draw * after viewmat_begin_eye(). */ glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); glEnable(GL_SCISSOR_TEST); glClearColor(.2,.2,.2,0); // set clear color to grey glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // turn on depth testing kuhl_errorcheck(); /* Turn on blending (note, if you are using transparent textures, the transparency may not look correct unless you draw further items before closer items. This program always draws the geometry in the same order.). */ glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); /* Get the view or camera matrix; update the frustum values if needed. */ float viewMat[16], perspective[16]; viewmat_get(viewMat, perspective, viewportID); /* Calculate an angle to rotate the * object. glutGet(GLUT_ELAPSED_TIME) is the number of * milliseconds since glutInit() was called. */ int count = glutGet(GLUT_ELAPSED_TIME) % 10000; // get a counter that repeats every 10 seconds float angle = count / 10000.0 * 360; // rotate 360 degrees every 10 seconds /* Make sure all computers/processes use the same angle */ dgr_setget("angle", &angle, sizeof(GLfloat)); /* Create a 4x4 rotation matrix based on the angle we computed. */ float rotateMat[16]; mat4f_rotateAxis_new(rotateMat, angle, 0,1,0); /* Create a scale matrix. */ float scaleMatrix[16]; mat4f_scale_new(scaleMatrix, 3, 3, 3); // Modelview = (viewMatrix * scaleMatrix) * rotationMatrix float modelview[16]; mat4f_mult_mat4f_new(modelview, viewMat, scaleMatrix); mat4f_mult_mat4f_new(modelview, modelview, rotateMat); kuhl_errorcheck(); glUseProgram(program); kuhl_errorcheck(); /* Send the perspective projection matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, // number of 4x4 float matrices 0, // transpose perspective); // value /* Send the modelview matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, // number of 4x4 float matrices 0, // transpose modelview); // value kuhl_errorcheck(); /* Draw the geometry using the matrices that we sent to the * vertex programs immediately above */ kuhl_geometry_draw(&triangle); } // finish viewport loop viewmat_end_frame(); /* Check for errors. If there are errors, consider adding more * calls to kuhl_errorcheck() in your code. */ kuhl_errorcheck(); /* Ask GLUT to call display() again. We shouldn't call display() * ourselves recursively because it will not leave time for GLUT * to call other callback functions for when a key is pressed, the * window is resized, etc. */ glutPostRedisplay(); }
void display() { /* If we are using DGR, send or receive data to keep multiple * processes/computers synchronized. */ dgr_update(); /* Get current frames per second calculations. */ float fps = kuhl_getfps(&fps_state); if(dgr_is_enabled() == 0 || dgr_is_master()) { // If DGR is being used, only display dgr counter if we are // the master process. // Check if FPS value was just updated by kuhl_getfps() if(fps_state.frame == 0) { char label[1024]; snprintf(label, 1024, "FPS: %0.1f", fps); /* Delete old label if it exists */ if(fpsLabel != 0) glDeleteTextures(1, &fpsLabel); /* Make a new label */ float labelColor[3] = { 1,1,1 }; float labelBg[4] = { 0,0,0,.3 }; /* Change the last parameter (point size) to adjust the * size of the texture that the text is rendered in to. */ fpsLabelAspectRatio = kuhl_make_label(label, &fpsLabel, labelColor, labelBg, 24); if(fpsLabel != 0) kuhl_geometry_texture(&labelQuad, fpsLabel, "tex", 1); } } /* Ensure the slaves use the same render style as the master * process. */ dgr_setget("style", &renderStyle, sizeof(int)); /* Render the scene once for each viewport. Frequently one * viewport will fill the entire screen. However, this loop will * run twice for HMDs (once for the left eye and once for the * right. */ viewmat_begin_frame(); for(int viewportID=0; viewportID<viewmat_num_viewports(); viewportID++) { viewmat_begin_eye(viewportID); /* Where is the viewport that we are drawing onto and what is its size? */ int viewport[4]; // x,y of lower left corner, width, height viewmat_get_viewport(viewport, viewportID); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); /* Clear the current viewport. Without glScissor(), glClear() * clears the entire screen. We could call glClear() before * this viewport loop---but on order for all variations of * this code to work (Oculus support, etc), we can only draw * after viewmat_begin_eye(). */ glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); glEnable(GL_SCISSOR_TEST); glClearColor(.2,.2,.2,0); // set clear color to grey glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // turn on depth testing kuhl_errorcheck(); /* Turn on blending (note, if you are using transparent textures, the transparency may not look correct unless you draw further items before closer items.). */ glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); /* Get the view or camera matrix; update the frustum values if needed. */ float viewMat[16], perspective[16]; viewmat_get(viewMat, perspective, viewportID); glUseProgram(program); kuhl_errorcheck(); /* Send the perspective projection matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, // number of 4x4 float matrices 0, // transpose perspective); // value float modelMat[16]; get_model_matrix(modelMat); float modelview[16]; mat4f_mult_mat4f_new(modelview, viewMat, modelMat); // modelview = view * model /* Send the modelview matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, // number of 4x4 float matrices 0, // transpose modelview); // value glUniform1i(kuhl_get_uniform("renderStyle"), renderStyle); // Copy far plane value into vertex program so we can render depth buffer. float f[6]; // left, right, bottom, top, near>0, far>0 projmat_get_frustum(f, viewport[2], viewport[3]); glUniform1f(kuhl_get_uniform("farPlane"), f[5]); kuhl_errorcheck(); kuhl_geometry_draw(modelgeom); /* Draw the model */ kuhl_errorcheck(); if(showOrigin) { /* Save current line width */ GLfloat origLineWidth; glGetFloatv(GL_LINE_WIDTH, &origLineWidth); glLineWidth(4); // make lines thick /* Object coordinate system origin */ kuhl_geometry_draw(origingeom); /* Draw the origin marker */ /* World coordinate origin */ mat4f_copy(modelview, viewMat); glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, // number of 4x4 float matrices 0, // transpose modelview); // value kuhl_geometry_draw(origingeom); /* Draw the origin marker */ /* Restore line width */ glLineWidth(origLineWidth); } if(dgr_is_enabled() == 0 || dgr_is_master()) { /* The shape of the frames per second quad depends on the * aspect ratio of the label texture and the aspect ratio of * the window (because we are placing the quad in normalized * device coordinates). */ int windowWidth, windowHeight; viewmat_window_size(&windowWidth, &windowHeight); float windowAspect = windowWidth / (float)windowHeight; float stretchLabel[16]; mat4f_scale_new(stretchLabel, 1/8.0 * fpsLabelAspectRatio / windowAspect, 1/8.0, 1); /* Position label in the upper left corner of the screen */ float transLabel[16]; mat4f_translate_new(transLabel, -.9, .8, 0); mat4f_mult_mat4f_new(modelview, transLabel, stretchLabel); glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, 0, modelview); /* Make sure we don't use a projection matrix */ float identity[16]; mat4f_identity(identity); glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, 0, identity); /* Don't use depth testing and make sure we use the texture * rendering style */ glDisable(GL_DEPTH_TEST); glUniform1i(kuhl_get_uniform("renderStyle"), 1); kuhl_geometry_draw(&labelQuad); /* Draw the quad */ glEnable(GL_DEPTH_TEST); kuhl_errorcheck(); } glUseProgram(0); // stop using a GLSL program. } // finish viewport loop viewmat_end_frame(); /* Update the model for the next frame based on the time. We * convert the time to seconds and then use mod to cause the * animation to repeat. */ int time = glutGet(GLUT_ELAPSED_TIME); dgr_setget("time", &time, sizeof(int)); kuhl_update_model(modelgeom, 0, ((time%10000)/1000.0)); /* Check for errors. If there are errors, consider adding more * calls to kuhl_errorcheck() in your code. */ kuhl_errorcheck(); //kuhl_video_record("videoout", 30); /* Ask GLUT to call display() again. We shouldn't call display() * ourselves recursively because it will not leave time for GLUT * to call other callback functions for when a key is pressed, the * window is resized, etc. */ glutPostRedisplay(); }
/* Called by GLUT whenever the window needs to be redrawn. This * function should not be called directly by the programmer. Instead, * we can call glutPostRedisplay() to request that GLUT call display() * at some point. */ void display() { /* If we are using DGR, send or receive data to keep multiple * processes/computers synchronized. */ dgr_update(); /* Render the scene once for each viewport. Frequently one * viewport will fill the entire screen. However, this loop will * run twice for HMDs (once for the left eye and once for the * right.) */ viewmat_begin_frame(); for(int viewportID=0; viewportID<viewmat_num_viewports(); viewportID++) { viewmat_begin_eye(viewportID); /* Where is the viewport that we are drawing onto and what is its size? */ int viewport[4]; // x,y of lower left corner, width, height viewmat_get_viewport(viewport, viewportID); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); /* Clear the current viewport. Without glScissor(), glClear() * clears the entire screen. We could call glClear() before * this viewport loop---but on order for all variations of * this code to work (Oculus support, etc), we can only draw * after viewmat_begin_eye(). */ glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); glEnable(GL_SCISSOR_TEST); glClearColor(.2,.2,.2,0); // set clear color to grey glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // turn on depth testing kuhl_errorcheck(); /* Get the view or camera matrix; update the frustum values if needed. */ float viewMat[16], perspective[16]; viewmat_get(viewMat, perspective, viewportID); /* Calculate an angle to rotate the * object. glutGet(GLUT_ELAPSED_TIME) is the number of * milliseconds since glutInit() was called. */ int count = glutGet(GLUT_ELAPSED_TIME) % 10000; // get a counter that repeats every 10 seconds float angle = count / 10000.0 * 360; // rotate 360 degrees every 10 seconds /* Make sure all computers/processes use the same angle */ dgr_setget("angle", &angle, sizeof(GLfloat)); /* Create a 4x4 rotation matrix based on the angle we computed. */ float rotateMat[16]; mat4f_rotateAxis_new(rotateMat, angle, 0,1,0); /* Create a scale matrix. */ float scaleMatrix[16]; mat4f_scale_new(scaleMatrix, 3, 3, 3); // Modelview = (viewMatrix * scaleMatrix) * rotationMatrix float modelview[16]; mat4f_mult_mat4f_new(modelview, viewMat, scaleMatrix); mat4f_mult_mat4f_new(modelview, modelview, rotateMat); kuhl_errorcheck(); glUseProgram(program); kuhl_errorcheck(); /* Send the perspective projection matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, // number of 4x4 float matrices 0, // transpose perspective); // value /* Send the modelview matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, // number of 4x4 float matrices 0, // transpose modelview); // value kuhl_errorcheck(); /* Draw the geometry using the matrices that we sent to the * vertex programs immediately above. Use the stencil buffer * to keep track of which object appears on top. */ if(viewportID == 0) glEnable(GL_STENCIL_TEST); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilFunc(GL_ALWAYS, 1, -1); kuhl_geometry_draw(&triangle); glStencilFunc(GL_ALWAYS, 2, -1); kuhl_geometry_draw(&quad); glDisable(GL_STENCIL_TEST); /* If we have multiple viewports, only draw cursor in the * first viewport. */ if(viewportID == 0) { /* Draw the cursor in normalized device coordinates. Don't * use any matrices. */ float identity[16]; mat4f_identity(identity); glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, 0, identity); glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, 0, identity); /* Disable depth testing so the cursor isn't occluded by * anything. */ glDisable(GL_DEPTH_TEST); kuhl_geometry_draw(&cursor); glEnable(GL_DEPTH_TEST); /* When we render images on the Oculus, we are rendering * into a multisampled framebuffer object, and we can't * read from the multisample FBO until we have blitted it * into a normal FBO. Here, we get the blitted FBO for the * *previous* frame. */ GLint fb =viewmat_get_blitted_framebuffer(viewportID); glBindFramebuffer(GL_FRAMEBUFFER, fb); GLuint stencilVal = 0; kuhl_errorcheck(); glReadPixels(viewport[0]+viewport[2]/2, viewport[1]+viewport[3]/2, 1,1, // get data for 1x1 area (i.e., a pixel) GL_STENCIL_INDEX, // query the stencil buffer GL_UNSIGNED_INT, &stencilVal); kuhl_errorcheck(); if(stencilVal == 1) printf("Cursor is on triangle.\n"); else if(stencilVal == 2) printf("Cursor is on quad.\n"); else printf("Cursor isn't on anything.\n"); } glUseProgram(0); // stop using a GLSL program. } // finish viewport loop viewmat_end_frame(); /* Check for errors. If there are errors, consider adding more * calls to kuhl_errorcheck() in your code. */ kuhl_errorcheck(); /* Ask GLUT to call display() again. We shouldn't call display() * ourselves recursively because it will not leave time for GLUT * to call other callback functions for when a key is pressed, the * window is resized, etc. */ glutPostRedisplay(); }
/* Called by GLUT whenever the window needs to be redrawn. This * function should not be called directly by the programmer. Instead, * we can call glutPostRedisplay() to request that GLUT call display() * at some point. */ void display() { /* If we are using DGR, send or receive data to keep multiple * processes/computers synchronized. */ dgr_update(); /* Render the scene once for each viewport. Frequently one * viewport will fill the entire screen. However, this loop will * run twice for HMDs (once for the left eye and once for the * right. */ viewmat_begin_frame(); for(int viewportID=0; viewportID<viewmat_num_viewports(); viewportID++) { viewmat_begin_eye(viewportID); /* Where is the viewport that we are drawing onto and what is its size? */ int viewport[4]; // x,y of lower left corner, width, height viewmat_get_viewport(viewport, viewportID); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); /* Clear the current viewport. Without glScissor(), glClear() * clears the entire screen. We could call glClear() before * this viewport loop---but on order for all variations of * this code to work (Oculus support, etc), we can only draw * after viewmat_begin_eye(). */ glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); glEnable(GL_SCISSOR_TEST); glClearColor(.2,.2,.2,0); // set clear color to grey glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // turn on depth testing kuhl_errorcheck(); /* Turn on blending (note, if you are using transparent textures, the transparency may not look correct unless you draw further items before closer items. This program always draws the geometry in the same order.). */ glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); /* Get the view or camera matrix; update the frustum values if needed. */ float viewMat[16], perspective[16]; viewmat_eye eye = viewmat_get(viewMat, perspective, viewportID); /* Always put camera at origin (no translation, no * interpupillary distance). */ float noTranslation[4] = {0,0,0,1}; mat4f_setColumn(viewMat, noTranslation, 3); // last column /* Create a scale matrix. */ float scaleMatrix[16]; mat4f_scale_new(scaleMatrix, 20, 20, 20); // Modelview = (viewMatrix * scaleMatrix) * rotationMatrix float modelview[16]; mat4f_mult_mat4f_new(modelview, viewMat, scaleMatrix); kuhl_errorcheck(); glUseProgram(program); kuhl_errorcheck(); /* Send the perspective projection matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, // number of 4x4 float matrices 0, // transpose perspective); // value /* Send the modelview matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, // number of 4x4 float matrices 0, // transpose modelview); // value kuhl_errorcheck(); if(texIdLeft != 0 && texIdRight != 0) // cylinder { /* Draw the cylinder with the appropriate texture */ if(eye == VIEWMAT_EYE_RIGHT) kuhl_geometry_texture(&cylinder, texIdRight, "tex", KG_WARN); else kuhl_geometry_texture(&cylinder, texIdLeft, "tex", KG_WARN); kuhl_geometry_draw(&cylinder); } else // cubemap { if(eye == VIEWMAT_EYE_RIGHT) setupCubemap(cubemapRightTex, quad, modelview); else setupCubemap(cubemapLeftTex, quad, modelview); } } // finish viewport loop viewmat_end_frame(); /* Check for errors. If there are errors, consider adding more * calls to kuhl_errorcheck() in your code. */ kuhl_errorcheck(); /* Ask GLUT to call display() again. We shouldn't call display() * ourselves recursively because it will not leave time for GLUT * to call other callback functions for when a key is pressed, the * window is resized, etc. */ glutPostRedisplay(); static int fps_state_init = 0; static kuhl_fps_state fps_state; if(fps_state_init == 0) { kuhl_getfps_init(&fps_state); fps_state_init = 1; } float fps = kuhl_getfps(&fps_state); if(fps_state.frame == 0) msg(INFO, "fps: %6.1f\n", fps); }
/* Called by GLUT whenever the window needs to be redrawn. This * function should not be called directly by the programmer. Instead, * we can call glutPostRedisplay() to request that GLUT call display() * at some point. */ void display() { /* If we are using DGR, send or receive data to keep multiple * processes/computers synchronized. */ dgr_update(); /* Render the scene once for each viewport. Frequently one * viewport will fill the entire screen. However, this loop will * run twice for HMDs (once for the left eye and once for the * right. */ viewmat_begin_frame(); for(int viewportID=0; viewportID<viewmat_num_viewports(); viewportID++) { viewmat_begin_eye(viewportID); /* Where is the viewport that we are drawing onto and what is its size? */ int viewport[4]; // x,y of lower left corner, width, height viewmat_get_viewport(viewport, viewportID); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); /* Clear the current viewport. Without glScissor(), glClear() * clears the entire screen. We could call glClear() before * this viewport loop---but on order for all variations of * this code to work (Oculus support, etc), we can only draw * after viewmat_begin_eye(). */ glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); glEnable(GL_SCISSOR_TEST); glClearColor(.2,.2,.2,0); // set clear color to grey glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // turn on depth testing kuhl_errorcheck(); /* Get the view or camera matrix; update the frustum values if needed. */ float viewMat[16], perspective[16]; viewmat_get(viewMat, perspective, viewportID); /* Calculate an angle to rotate the * object. glutGet(GLUT_ELAPSED_TIME) is the number of * milliseconds since glutInit() was called. */ int count = glutGet(GLUT_ELAPSED_TIME) % 10000; // get a counter that repeats every 10 seconds float angle = count / 10000.0 * 360; // rotate 360 degrees every 10 seconds /* Make sure all computers/processes use the same angle */ dgr_setget("angle", &angle, sizeof(GLfloat)); /* Create a 4x4 rotation matrix based on the angle we computed. */ float rotateMat[16]; mat4f_rotateAxis_new(rotateMat, angle, 0,1,0); /* Create a scale matrix. */ float scaleMatrix[16]; mat4f_scale_new(scaleMatrix, 3, 3, 3); // Modelview = (viewMatrix * scaleMatrix) * rotationMatrix float modelview[16]; mat4f_mult_mat4f_new(modelview, viewMat, scaleMatrix); mat4f_mult_mat4f_new(modelview, modelview, rotateMat); kuhl_errorcheck(); glUseProgram(program); kuhl_errorcheck(); /* Send the perspective projection matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, // number of 4x4 float matrices 0, // transpose perspective); // value /* Send the modelview matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, // number of 4x4 float matrices 0, // transpose modelview); // value kuhl_errorcheck(); /* Setup prerender directly to texture once (and reuse the * framebuffer object for subsequent draw commands). */ if(prerenderFrameBuffer == 0) { #if USE_MSAA==1 /* Generate a MSAA framebuffer + texture */ GLuint prerenderTexIDAA; prerenderFrameBufferAA = kuhl_gen_framebuffer_msaa(viewport[2], viewport[3], &prerenderTexIDAA, NULL, 16); #endif prerenderFrameBuffer = kuhl_gen_framebuffer(viewport[2], viewport[3], &prerenderTexID, NULL); /* Apply the texture to our geometry and draw the quad. */ kuhl_geometry_texture(&prerendQuad, prerenderTexID, "tex", 1); } /* Switch to framebuffer and set the OpenGL viewport to cover * the entire framebuffer. */ #if USE_MSAA==1 glBindFramebuffer(GL_FRAMEBUFFER, prerenderFrameBufferAA); #else glBindFramebuffer(GL_FRAMEBUFFER, prerenderFrameBuffer); #endif glViewport(0,0,viewport[2], viewport[3]); kuhl_errorcheck(); /* Clear the framebuffer and the depth buffer. */ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); /* Draw the geometry using the matrices that we sent to the * vertex programs immediately above */ kuhl_geometry_draw(&triangle); kuhl_geometry_draw(&quad); /* Stop rendering to texture */ glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(0); kuhl_errorcheck(); #if USE_MSAA==1 /* Copy the MSAA framebuffer into the normal framebuffer */ glBindFramebuffer(GL_READ_FRAMEBUFFER, prerenderFrameBufferAA); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prerenderFrameBuffer); glBlitFramebuffer(0,0,viewport[2],viewport[3], 0,0,viewport[2],viewport[3], GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_READ_FRAMEBUFFER,0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0); kuhl_errorcheck(); #endif /* Set up the viewport to draw on the screen */ glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); kuhl_geometry_draw(&prerendQuad); } // finish viewport loop viewmat_end_frame(); /* Check for errors. If there are errors, consider adding more * calls to kuhl_errorcheck() in your code. */ kuhl_errorcheck(); /* Ask GLUT to call display() again. We shouldn't call display() * ourselves recursively because it will not leave time for GLUT * to call other callback functions for when a key is pressed, the * window is resized, etc. */ glutPostRedisplay(); }
/** Called by GLUT whenever the window needs to be redrawn. This * function should not be called directly by the programmer. Instead, * we can call glutPostRedisplay() to request that GLUT call display() * at some point. */ void display() { /* If we are using DGR, send or receive data to keep multiple * processes/computers synchronized. */ dgr_update(); /* Get current frames per second calculations. */ float fps = kuhl_getfps(&fps_state); if(dgr_is_enabled() == 0 || dgr_is_master()) { // If DGR is being used, only display dgr counter if we are // the master process. // Check if FPS value was just updated by kuhl_getfps() if(fps_state.frame == 0) msg(INFO, "FPS: %0.1f", fps); } /* Render the scene once for each viewport. Frequently one * viewport will fill the entire screen. However, this loop will * run twice for HMDs (once for the left eye and once for the * right. */ viewmat_begin_frame(); for(int viewportID=0; viewportID<viewmat_num_viewports(); viewportID++) { viewmat_begin_eye(viewportID); /* Where is the viewport that we are drawing onto and what is its size? */ int viewport[4]; // x,y of lower left corner, width, height viewmat_get_viewport(viewport, viewportID); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); /* Clear the current viewport. Without glScissor(), glClear() * clears the entire screen. We could call glClear() before * this viewport loop---but on order for all variations of * this code to work (Oculus support, etc), we can only draw * after viewmat_begin_eye(). */ glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); glEnable(GL_SCISSOR_TEST); glClearColor(.2,.2,.2,0); // set clear color to grey glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // turn on depth testing kuhl_errorcheck(); /* Turn on blending (note, if you are using transparent textures, the transparency may not look correct unless you draw further items before closer items.). */ glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); /* Get the view or camera matrix; update the frustum values if needed. */ float viewMat[16], perspective[16]; viewmat_get(viewMat, perspective, viewportID); glUseProgram(program); kuhl_errorcheck(); /* Send the perspective projection matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, // number of 4x4 float matrices 0, // transpose perspective); // value for(int i=1; i<global_argc; i++) drawObject(i, viewMat); glUseProgram(0); // stop using a GLSL program. } // finish viewport loop viewmat_end_frame(); /* Update the model for the next frame based on the time. We * convert the time to seconds and then use mod to cause the * animation to repeat. */ int time = glutGet(GLUT_ELAPSED_TIME); dgr_setget("time", &time, sizeof(int)); kuhl_update_model(modelgeom, 0, ((time%10000)/1000.0)); /* Check for errors. If there are errors, consider adding more * calls to kuhl_errorcheck() in your code. */ kuhl_errorcheck(); //kuhl_video_record("videoout", 30); /* Ask GLUT to call display() again. We shouldn't call display() * ourselves recursively because it will not leave time for GLUT * to call other callback functions for when a key is pressed, the * window is resized, etc. */ glutPostRedisplay(); }
/* Called by GLUT whenever the window needs to be redrawn. This * function should not be called directly by the programmer. Instead, * we can call glutPostRedisplay() to request that GLUT call display() * at some point. */ void display() { /* If we are using DGR, send or receive data to keep multiple * processes/computers synchronized. */ dgr_update(); dgr_setget("style", &renderStyle, sizeof(int)); /* Render the scene once for each viewport. Frequently one * viewport will fill the entire screen. However, this loop will * run twice for HMDs (once for the left eye and once for the * right. */ viewmat_begin_frame(); for(int viewportID=0; viewportID<viewmat_num_viewports(); viewportID++) { viewmat_begin_eye(viewportID); /* Where is the viewport that we are drawing onto and what is its size? */ int viewport[4]; // x,y of lower left corner, width, height viewmat_get_viewport(viewport, viewportID); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); /* Clear the current viewport. Without glScissor(), glClear() * clears the entire screen. We could call glClear() before * this viewport loop---but on order for all variations of * this code to work (Oculus support, etc), we can only draw * after viewmat_begin_eye(). */ glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); glEnable(GL_SCISSOR_TEST); glClearColor(.2,.2,.2,0); // set clear color to grey glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // turn on depth testing kuhl_errorcheck(); /* Turn on blending (note, if you are using transparent textures, the transparency may not look correct unless you draw further items before closer items.). */ glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); /* Get the view or camera matrix; update the frustum values if needed. */ float viewMat[16], perspective[16]; viewmat_get(viewMat, perspective, viewportID); glUseProgram(program); kuhl_errorcheck(); /* Send the perspective projection matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, // number of 4x4 float matrices 0, // transpose perspective); // value float modelMat[16]; get_model_matrix(modelMat); float modelview[16]; mat4f_mult_mat4f_new(modelview, viewMat, modelMat); // modelview = view * model /* Send the modelview matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, // number of 4x4 float matrices 0, // transpose modelview); // value glUniform1i(kuhl_get_uniform("renderStyle"), renderStyle); // Copy far plane value into vertex program so we can render depth buffer. float f[6]; // left, right, bottom, top, near>0, far>0 projmat_get_frustum(f, viewport[2], viewport[3]); glUniform1f(kuhl_get_uniform("farPlane"), f[5]); kuhl_errorcheck(); kuhl_limitfps(60); update(); kuhl_geometry_draw(modelgeom); /* Draw the model */ kuhl_errorcheck(); glUseProgram(0); // stop using a GLSL program. } // finish viewport loop viewmat_end_frame(); /* Check for errors. If there are errors, consider adding more * calls to kuhl_errorcheck() in your code. */ kuhl_errorcheck(); // kuhl_video_record("videoout", 30); /* Ask GLUT to call display() again. We shouldn't call display() * ourselves recursively because it will not leave time for GLUT * to call other callback functions for when a key is pressed, the * window is resized, etc. */ glutPostRedisplay(); }