Ejemplo n.º 1
0
void DrawShader::drawTextureShader(bool isReflection, Shader& shader, const std::vector<Drawable>& drawables,
      const glm::mat4& viewMatrix, const glm::vec3& sunDir, float sunIntensity, 
      int lightning, const FrameBufferObject& reflection_fbo) {

   shader.sendUniform(Uniform::PROJECTION, uniforms, gProjectionMatrix);
   shader.sendUniform(Uniform::VIEW, uniforms, viewMatrix);

   shader.sendUniform(Uniform::LIGHTNING, uniforms, lightning);
   SendSun(shader, uniforms, sunIntensity, sunDir);

   for (auto& drawable : drawables) {
      if (drawable.draw_template.shader_type == ShaderType::TEXTURE ||
          drawable.draw_template.shader_type == ShaderType::DEFERRED) { 
         {
         // Per-Drawable Texture Shader Setup
            //SendHeightMap(shader, drawable);
            SendBones(shader, drawable);
            SendTexture(shader, drawable);

            if (!isReflection && drawable.draw_template.effects.count(EffectType::IS_WATER)) {
               shader.sendUniform(Uniform::IS_WATER, uniforms, 1);
               shader.sendUniform(Uniform::REFLECTION_TEXTURE, uniforms, reflection_fbo.texture_slot());  
               reflection_fbo.texture().enable(texture_cache_);
            }
            else
               shader.sendUniform(Uniform::IS_WATER, uniforms, 0);

            drawable.draw_template.material.sendMaterial(shader, uniforms);
         }
         if (!drawable.draw_template.effects.count(EffectType::IS_WATER) || !isReflection)
            drawModelTransforms(shader, drawable, viewMatrix, true, uniforms);
      }
   }
}
Ejemplo n.º 2
0
void DrawShader::SendShadow(Shader& shader, const UniformLocationMap& uniforms,
         const FrameBufferObject& shadow_map_fbo_,
         const glm::vec3& deerPos, const glm::vec3& sunDir) {
      shadow_map_fbo_.texture().enable(texture_cache_);
      shader.sendUniform(Uniform::HAS_SHADOWS, uniforms, 1);
      shader.sendUniform(Uniform::SHADOW_MAP_TEXTURE, uniforms, shadow_map_fbo_.texture_slot());
      SendInverseShadow(shader, uniforms, sunDir, deerPos);
}
Ejemplo n.º 3
0
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;
      }
   }
}