83 lines
2.6 KiB
C++
83 lines
2.6 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
------------------------------------------------------------------------------*/
|
|
|
|
|
|
#include "gpu/gpu_renderer.h"
|
|
#include "gpu/gpu_geometry.h"
|
|
#include "gpu/gpu_draw_context.h"
|
|
#include "core/renderer_environment_interface.h"
|
|
#include "core/camera.h"
|
|
#include "core/light.h"
|
|
|
|
using namespace GS::GPU;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Renderer::RenderGBufferPass(const GS::Stack <RenderPrimitive *> &display_lists)
|
|
{
|
|
SetCurrentFBO(buffer_fbo);
|
|
Clear(0, 0, 0, 0);
|
|
|
|
DrawContext dc(DrawContext::Deferred, DrawContext::Base, MaterialShader::DS_GBufferMRT4);
|
|
DrawList(display_lists, dc);
|
|
}
|
|
void Renderer::RenderDeferredLightPass(const GS::Stack <RenderPrimitive *> &)
|
|
{
|
|
SetCurrentFBO(resolve_fbo);
|
|
|
|
DrawContext dc(DrawContext::Deferred, DrawContext::Light);
|
|
|
|
// Clear to ambient.
|
|
EnableDepthWrite(false);
|
|
RenderFullscreenQuad(*ambient_program, viewport.GetWidth() / (float)dimensions.x, viewport.GetHeight() / (float)dimensions.y);
|
|
EnableDepthWrite(true);
|
|
|
|
// For each light in frustum, render affected primitives with a light specific shader.
|
|
SetBlendFunc(BlendOne, BlendOne);
|
|
|
|
List <Core::Light *> light_list;
|
|
environment_interface->GetLightsInFrustum(view_item->GetMatrix().GetRow(3), frustum, light_list);
|
|
|
|
ListForeachPtr(Core::Light *, l, light_list)
|
|
{
|
|
// Render shadow map.
|
|
if (gpu_config.enable_shadow && l->shadow == Core::Light::Shadow_Map)
|
|
{
|
|
if (PrepareShadowMap(*l, true)) // TODO move to job
|
|
RenderShadowMap(*l);
|
|
|
|
SetCurrentFBO(resolve_fbo);
|
|
SetBlendFunc(BlendOne, BlendOne);
|
|
}
|
|
|
|
// Compose light.
|
|
EnableDepthWrite(false);
|
|
EnableBlending(true);
|
|
|
|
switch (l->model)
|
|
{
|
|
case Core::Light::Model_Point: RenderPointLight(*l, dc); break;
|
|
case Core::Light::Model_Linear: RenderLinearLight(*l, dc); break;
|
|
case Core::Light::Model_Spot: RenderSpotLight(*l, dc); break;
|
|
}
|
|
|
|
EnableBlending(false);
|
|
EnableDepthWrite(true);
|
|
stats.light_processed++;
|
|
}
|
|
|
|
SetBlendFunc(BlendSrcAlpha, BlendOneMinusSrcAlpha);
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Renderer::RenderListDeferred(const GS::Stack <RenderPrimitive *> &display_lists)
|
|
{
|
|
RenderGBufferPass(display_lists);
|
|
if (environment_interface)
|
|
RenderDeferredLightPass(display_lists);
|
|
}
|
|
//------------------------------------------------------------------------------
|