void TextRenderer:: render_fps(RenderContext const& ctx, FrameBufferObject& target, float application_fps, float rendering_fps) const { target.bind(ctx); math::mat4 fs_projection = scm::math::make_ortho_matrix( 0.0f, static_cast<float>(target.width()), 0.0f, static_cast<float>(target.height()), -1.0f, 1.0f); text_renderer_->projection_matrix(fs_projection); frame_counter_text_->text_string("Application FPS: " + string_utils::to_string(application_fps) + "\nRendering FPS: " + string_utils::to_string(rendering_fps)); math::vec2i text_ur = math::vec2i(40, target.height() - frame_counter_text_->text_bounding_box().y + 10); text_renderer_->draw_outlined( ctx.render_context, text_ur, frame_counter_text_); target.unbind(ctx); }
void DrawShader::drawModelTransforms( Shader& shader, const Drawable& drawable, const glm::mat4& view, const FrameBufferObject& deferred_diffuse_fbo, const FrameBufferObject& deferred_position_fbo, const FrameBufferObject& deferred_normal_fbo, bool needsModel, const UniformLocationMap& uniforms) { for(const auto& instance : drawable.draw_instances) { if (instance.material) { instance.material->sendMaterial(shader, uniforms); } const auto model_view = view * instance.model_transform; shader.sendUniform(Uniform::MODEL_VIEW_PROJECTION, uniforms, gProjectionMatrix * model_view); SendModelAndNormal(shader, uniforms, model_view, instance.model_transform, needsModel); for (int i = 0; i < LAST_DEFERRED; ++i) { const auto deferred_type(static_cast<DeferredType>(i)); switch (deferred_type) { case DEFERRED_DIFFUSE: deferred_diffuse_fbo.bind(); break; case DEFERRED_POSITION: deferred_position_fbo.bind(); break; case DEFERRED_NORMAL: deferred_normal_fbo.bind(); break; default: break; } shader.sendUniform(Uniform::OUTPUT_SHADER_TYPE, uniforms, i); shader.drawMesh(drawable.draw_template.mesh); } } }
FrameBufferObject::Binder::Binder( const FrameBufferObject& fbo ) : m_fbo( fbo ) { KVS_ASSERT( fbo.isCreated() ); fbo.bind(); }
void DrawShader::Draw(glm::vec3 flowerFade, const FrameBufferObject& shadow_map_fbo_, const FrameBufferObject& reflection_fbo, const FrameBufferObject& deferred_diffuse_fbo_, const FrameBufferObject& deferred_position_fbo_, const FrameBufferObject& deferred_normal_fbo_, const vector<CulledDrawable>& culledDrawables, const glm::mat4& viewMatrix, int useBlinnPhong, const glm::vec3& deerPos, const glm::vec3& sunDir, float sunIntensity, int lightning) { glm::mat4 curView; //For deferred shading. for(auto& shader_pair : shaders.getMap()) { Shader& shader = shader_pair.second; shader.use(); switch (shader_pair.first) { case ShaderType::SHADOW: if(printCurrentShaderName) printf("Shadow\n"); { const auto shadow_view = glm::lookAt(sunDir + deerPos, deerPos, glm::vec3(0.0, 1.0, 0.0)); const auto view_projection = kShadowProjection * shadow_view; // Shadow Culling. Frustum frustum(view_projection); const auto shadow_drawables = frustum.cullShadowDrawables(culledDrawables); if(!debug) { shadow_map_fbo_.bind(); glClear(GL_DEPTH_BUFFER_BIT); } { glPolygonMode(GL_FRONT, GL_FILL); const auto drawables = Drawable::fromCulledDrawables(shadow_drawables, CullType::VIEW_CULLING); for (auto& drawable : drawables) { SendBones(shader, drawable); if (drawable.draw_template.effects.count(EffectType::CASTS_SHADOW)) { SendTexture(shader, drawable); for(auto& instance : drawable.draw_instances) { shader.sendUniform(Uniform::MODEL_VIEW_PROJECTION, uniforms, view_projection * instance.model_transform); shader.sendUniform(Uniform::MODEL, uniforms, instance.model_transform); shader.drawMesh(drawable.draw_template.mesh); } } } } if(!debug) { glBindFramebuffer(GL_FRAMEBUFFER, 0); shadow_map_fbo_.texture().enable(texture_cache_); } } break; case ShaderType::REFLECTION: if (!gReflections) break; { reflection_fbo.bind(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // Cheap hack: just use view culling. auto drawables = Drawable::fromCulledDrawables(culledDrawables, CullType::VIEW_CULLING); // scale everything across the ground. const auto scale = glm::scale(glm::mat4(), glm::vec3(1, -1, 1)); for (std::vector<Drawable>::iterator iter = drawables.begin(); iter != drawables.end();) { // Cheap hack to get rid of the ground plane. DEADLINE // APPROACHES. if (iter->draw_template.height_map) { iter = drawables.erase(iter); } else { for (auto& instance : iter->draw_instances) { instance.model_transform = scale * instance.model_transform; } ++iter; } } const auto reflectSunDir = glm::vec3(scale * glm::vec4(sunDir, 0)); shader.sendUniform(Uniform::HAS_SHADOWS, uniforms, 0); shader.sendUniform(Uniform::USE_BLINN_PHONG, uniforms, useBlinnPhong); glFrontFace(GL_CW); drawTextureShader(true, shader, drawables, viewMatrix, reflectSunDir, sunIntensity, lightning, reflection_fbo); glFrontFace(GL_CCW); } break; case ShaderType::TEXTURE: if (!useTextureShader) break; if(printCurrentShaderName) printf("Texture\n"); glBindFramebuffer(GL_FRAMEBUFFER, 0); { const auto drawables = Drawable::fromCulledDrawables(culledDrawables, CullType::VIEW_CULLING); shader.sendUniform(Uniform::USE_BLINN_PHONG, uniforms, useBlinnPhong); SendShadow(shader, uniforms, shadow_map_fbo_, deerPos, sunDir); SendScreenSize(shader, uniforms); drawTextureShader(false, shader, drawables, viewMatrix, sunDir, sunIntensity, lightning, reflection_fbo); } break; case ShaderType::SKYBOX: if(printCurrentShaderName) printf("Skybox\n"); shader.sendUniform(Uniform::PROJECTION, uniforms, gProjectionMatrix); for (auto& drawable : culledDrawables) { if (drawable.draw_template.shader_type == ShaderType::SKYBOX) { /* doesn't use drawModelTransforms because no normals */ for(const auto& instance : drawable.draw_instances) { shader.sendUniform(Uniform::TEXTURE, uniforms, (*drawable.draw_template.texture).texture_slot()); (*drawable.draw_template.texture).enable(texture_cache_); if (drawable.draw_template.effects.count(EffectType::IS_TITLE_SCREEN)) { shader.sendUniform(Uniform::IS_TITLE_SCREEN, uniforms, 1); curView = glm::lookAt( glm::vec3(2.0f, 0.f,0.0f),glm::vec3(0.f, 0.f, 0.f),glm::vec3( 0.0f, 1.0f, 0.0f ) ); } else { shader.sendUniform(Uniform::IS_TITLE_SCREEN, uniforms, 0); curView = viewMatrix; } shader.sendUniform(Uniform::MODEL_VIEW, uniforms, curView * instance.instance.model_transform); shader.drawMesh(drawable.draw_template.mesh); } } } break; case ShaderType::DEFERRED: if (useTextureShader) break; if(printCurrentShaderName) printf("Deferred\n"); for (size_t i = 0; i < LAST_DEFERRED; ++i) { DeferredType deferred_type = static_cast<DeferredType>(i); switch (deferred_type) { case DEFERRED_DIFFUSE: deferred_diffuse_fbo_.bind(); break; case DEFERRED_POSITION: deferred_position_fbo_.bind(); break; case DEFERRED_NORMAL: deferred_normal_fbo_.bind(); break; default: break; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } SendShadow(shader, uniforms, shadow_map_fbo_, deerPos, sunDir); for (auto& drawable : culledDrawables) { Drawable newDrawable = Drawable::fromCulledDrawable(drawable, CullType::VIEW_CULLING); if (newDrawable.draw_template.shader_type == ShaderType::DEFERRED) { if (drawable.draw_template.effects.count(EffectType::IS_FLOWER)) shader.sendUniform(Uniform::FLOWER_FADE, uniforms, glm::vec3(1.0f)); else shader.sendUniform(Uniform::FLOWER_FADE, uniforms, flowerFade); newDrawable.draw_template.material.sendMaterial(shader, uniforms); //SendHeightMap(shader, newDrawable); SendBones(shader, newDrawable); SendTexture(shader, newDrawable); { const int vary_material = drawable.draw_template.effects.count(EffectType::VARY_MATERIAL); shader.sendUniform(Uniform::VARY_MATERIAL, uniforms, vary_material); } drawModelTransforms(shader, newDrawable, viewMatrix, deferred_diffuse_fbo_, deferred_position_fbo_, deferred_normal_fbo_, true, uniforms); } } glBindFramebuffer(GL_FRAMEBUFFER, 0); break; case ShaderType::FINAL_LIGHT_PASS: if (useTextureShader) break; glm::mat4 lookAt = glm::lookAt( glm::vec3(2.0f, 0.f,0.0f),glm::vec3(0.f, 0.f, 0.f),glm::vec3( 0.0f, 1.0f, 0.0f ) ); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); deferred_diffuse_fbo_.texture().enable(texture_cache_); shader.sendUniform(Uniform::FINAL_PASS_DIFFUSE_TEXTURE, uniforms, deferred_diffuse_fbo_.texture_slot()); deferred_position_fbo_.texture().enable(texture_cache_); shader.sendUniform(Uniform::FINAL_PASS_POSITION_TEXTURE, uniforms, deferred_position_fbo_.texture_slot()); deferred_normal_fbo_.texture().enable(texture_cache_); shader.sendUniform(Uniform::FINAL_PASS_NORMAL_TEXTURE, uniforms, deferred_normal_fbo_.texture_slot()); SendSun(shader, uniforms, sunIntensity, sunDir); shader.sendUniform(Uniform::PROJECTION, uniforms, gProjectionMatrix); SendScreenSize(shader, uniforms); shader.sendUniform(Uniform::LIGHTNING, uniforms, lightning); for (auto& drawable : culledDrawables) { Drawable newDrawable = Drawable::fromCulledDrawable(drawable, CullType::VIEW_CULLING); if(newDrawable.draw_template.shader_type == ShaderType::FINAL_LIGHT_PASS) { if (drawable.draw_template.effects.count(EffectType::IS_WATER)) { shader.sendUniform(Uniform::IS_WATER, uniforms, 1); shader.sendUniform(Uniform::TEXTURE, uniforms, reflection_fbo.texture_slot()); reflection_fbo.texture().enable(texture_cache_); } else shader.sendUniform(Uniform::IS_WATER, uniforms, 0); shader.sendUniform(Uniform::IS_FIREFLY, uniforms, 0); if (drawable.draw_template.effects.count(EffectType::IS_GOD_RAY)) { shader.sendUniform(Uniform::IS_GOD_RAY, uniforms, 1); if(drawable.draw_template.effects.count(EffectType::IS_FIREFLY)) shader.sendUniform(Uniform::IS_FIREFLY, uniforms, 1); curView = viewMatrix; } else if(drawable.draw_template.effects.count(EffectType::IS_WATER)) { curView = viewMatrix; } else { shader.sendUniform(Uniform::IS_GOD_RAY, uniforms, 0); curView = lookAt; } for(const auto& instance : drawable.draw_instances) { if (drawable.draw_template.effects.count(EffectType::IS_GOD_RAY)) { glm::vec3 ray_pos = glm::vec3(instance.instance.model_transform * glm::vec4(0,0,0,1)); shader.sendUniform(Uniform::GOD_RAY_CENTER, uniforms, ray_pos); } shader.sendUniform(Uniform::MODEL, uniforms, instance.instance.model_transform); shader.sendUniform(Uniform::VIEW, uniforms, curView); shader.sendUniform(Uniform::NORMAL, uniforms, glm::transpose(glm::inverse(curView * instance.instance.model_transform))); shader.drawMesh(drawable.draw_template.mesh); } } } break; } } }