void RenderingEngine::Render(float theta) const { const float distance = 10; const vec3 target(0, -0.15, 0); const vec3 up(0, 1, 0); vec3 eye(0, -0.15, distance * 2); mat4 view = mat4::LookAt(eye, target, up); glUseProgram(m_simple.Program); glUniformMatrix4fv(m_simple.Uniforms.Modelview, 1, 0, view.Pointer()); glDepthFunc(GL_ALWAYS); glBindTexture(GL_TEXTURE_2D, m_textures.Metal); RenderDrawable(m_quad, m_simple); eye = vec3(0, 0, distance); view = mat4::LookAt(eye, target, up); const mat4 model = mat4::RotateY(theta * 180.0f / 3.14f); const mat3 model3x3 = model.ToMat3(); const mat4 modelview = model * view; vec4 eyeWorldSpace(0, 0, -10, 1); vec4 eyeObjectSpace = model * eyeWorldSpace; glUseProgram(m_cubemap.Program); glUniform3fv(m_cubemap.Uniforms.EyePosition, 1, eyeObjectSpace.Pointer()); glUniformMatrix4fv(m_cubemap.Uniforms.Modelview, 1, 0, modelview.Pointer()); glUniformMatrix3fv(m_cubemap.Uniforms.Model, 1, 0, model3x3.Pointer()); glBindTexture(GL_TEXTURE_CUBE_MAP, m_textures.Cubemap); glEnableVertexAttribArray(m_cubemap.Attributes.Normal); glDepthFunc(GL_LESS); RenderDrawable(m_kleinBottle, m_cubemap); }
void RenderingEngine::Render(float theta) const { glViewport(0, 0, m_size.x, m_size.y); glEnable(GL_DEPTH_TEST); // Set the render target to the full size offscreen buffer. glBindTexture(GL_TEXTURE_2D, m_textures.TombWindow); glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffers.Scene); glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers.SceneColor); // Blit the background texture. glUseProgram(m_blitting.Program); glUniform1f(m_blitting.Uniforms.Threshold, 0); glDepthFunc(GL_ALWAYS); RenderDrawable(m_quad, m_blitting); // Set the light position. glUseProgram(m_lighting.Program); vec4 lightPosition(0.25, 0.25, 1, 0); glUniform3fv(m_lighting.Uniforms.LightPosition, 1, lightPosition.Pointer()); // Set the model-view transform. const float distance = 10; const vec3 target(0, -0.15, 0); const vec3 up(0, 1, 0); const vec3 eye = vec3(0, 0, distance); const mat4 view = mat4::LookAt(eye, target, up); const mat4 model = mat4::RotateY(theta * 180.0f / 3.14f); const mat4 modelview = model * view; glUniformMatrix4fv(m_lighting.Uniforms.Modelview, 1, 0, modelview.Pointer()); // Set the normal matrix. mat3 normalMatrix = modelview.ToMat3(); glUniformMatrix3fv(m_lighting.Uniforms.NormalMatrix, 1, 0, normalMatrix.Pointer()); // Render the Klein Bottle. glDepthFunc(GL_LESS); glEnableVertexAttribArray(m_lighting.Attributes.Normal); RenderDrawable(m_kleinBottle, m_lighting); // Set up OpenGL for rendering full-screen quads. glUseProgram(m_blitting.Program); glUniform1f(m_blitting.Uniforms.Threshold, 0.85); glDisable(GL_DEPTH_TEST); // Downsample the rendered scene. int w = m_size.x, h = m_size.y; for (int i = 0; i < OffscreenCount; ++i, w >>= 1, h >>= 1) { glViewport(0, 0, w, h); glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffers.Offscreen[i]); glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers.OffscreenColor[i]); glBindTexture(GL_TEXTURE_2D, i ? m_textures.Offscreen[i - 1] : m_textures.Scene); RenderDrawable(m_quad, m_blitting); glUniform1f(m_blitting.Uniforms.Threshold, 0); } // Accumulate the downsampled buffers onto the backbuffer. glUniform1f(m_blitting.Uniforms.Threshold, 0); glViewport(0, 0, m_size.x, m_size.y); glEnable(GL_BLEND); glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffers.Offscreen[0]); glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers.OffscreenColor[0]); for (int i = 0; i < OffscreenCount; ++i) { glBindTexture(GL_TEXTURE_2D, m_textures.Offscreen[i]); RenderDrawable(m_quad, m_blitting); } // Blit the full-color buffer onto the backbuffer. glDisable(GL_BLEND); glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffers.Backbuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers.BackbufferColor); glBindTexture(GL_TEXTURE_2D, m_textures.Scene); RenderDrawable(m_quad, m_blitting); // Add the bloom texture onto the backbuffer. glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, m_textures.Offscreen[0]); RenderDrawable(m_quad, m_blitting); glDisable(GL_BLEND); }