forked from 0ad/0ad
Shadow rendering can use depth textures, as a preparation for
self-shadowing and shadows on models in general. Usage of depth textures can be toggled using ?renderer.useDepthTexture = true/false in the JavaScript console. This was SVN commit r3495.
This commit is contained in:
parent
58da2342c2
commit
9f055eddb0
@ -9,7 +9,7 @@
|
||||
#include "precompiled.h"
|
||||
#include "ParticleEngine.h"
|
||||
#include "ogl.h"
|
||||
#include "renderer.h"
|
||||
#include "Renderer.h"
|
||||
|
||||
CParticleEngine *CParticleEngine::m_pInstance = 0;
|
||||
CParticleEngine::CParticleEngine(void)
|
||||
@ -59,7 +59,7 @@ CParticleEngine *CParticleEngine::GetInstance(void)
|
||||
}
|
||||
|
||||
void CParticleEngine::DeleteInstance()
|
||||
{
|
||||
{
|
||||
if (m_pInstance)
|
||||
delete m_pInstance;
|
||||
m_pInstance = 0;
|
||||
@ -158,7 +158,7 @@ void CParticleEngine::updateEmitters()
|
||||
{
|
||||
// store a pointer to the next node
|
||||
tEmitterNode *pTemp = temp->next;
|
||||
|
||||
|
||||
// check for the head
|
||||
if(!temp->prev)
|
||||
m_pHead = pTemp;
|
||||
@ -166,7 +166,7 @@ void CParticleEngine::updateEmitters()
|
||||
// forward the previous's pointer
|
||||
temp->prev->next = pTemp;
|
||||
|
||||
// if there is any next one,
|
||||
// if there is any next one,
|
||||
if(pTemp)
|
||||
// fix the backwards pointer
|
||||
pTemp->prev = temp->prev;
|
||||
@ -214,7 +214,7 @@ void CParticleEngine::destroyAllEmitters(bool fade)
|
||||
{
|
||||
// store a pointer to the next node
|
||||
tEmitterNode *pTemp = temp->next;
|
||||
|
||||
|
||||
// check for the head
|
||||
if(!temp->prev)
|
||||
m_pHead = pTemp;
|
||||
@ -222,7 +222,7 @@ void CParticleEngine::destroyAllEmitters(bool fade)
|
||||
// forward the previous's pointer
|
||||
temp->prev->next = pTemp;
|
||||
|
||||
// if there is any next one,
|
||||
// if there is any next one,
|
||||
if(pTemp)
|
||||
// fix the backwards pointer
|
||||
pTemp->prev = temp->prev;
|
||||
|
@ -252,6 +252,7 @@ CRenderer::CRenderer()
|
||||
// Must query card capabilities before creating renderers that depend
|
||||
// on card capabilities.
|
||||
EnumCaps();
|
||||
m->shadow->SetUseDepthTexture(true);
|
||||
|
||||
m_VertexShader = new RenderPathVertexShader;
|
||||
if (!m_VertexShader->Init())
|
||||
@ -301,6 +302,7 @@ CRenderer::CRenderer()
|
||||
m_Models.ModSolidColor = RenderModifierPtr(new SolidColorRenderModifier);
|
||||
m_Models.ModTransparent = RenderModifierPtr(new TransparentRenderModifier);
|
||||
m_Models.ModTransparentShadow = RenderModifierPtr(new TransparentShadowRenderModifier);
|
||||
m_Models.ModTransparentDepthShadow = RenderModifierPtr(new TransparentDepthShadowModifier);
|
||||
|
||||
CEmitter *pEmitter = new CDefaultEmitter(1000, -1);
|
||||
CParticleEngine::GetInstance()->addEmitter(pEmitter);
|
||||
@ -343,6 +345,7 @@ void CRenderer::EnumCaps()
|
||||
m_Caps.m_TextureBorderClamp=false;
|
||||
m_Caps.m_GenerateMipmaps=false;
|
||||
m_Caps.m_VertexShader=false;
|
||||
m_Caps.m_DepthTextureShadows = false;
|
||||
|
||||
// now start querying extensions
|
||||
if (!m_Options.m_NoVBO) {
|
||||
@ -361,6 +364,9 @@ void CRenderer::EnumCaps()
|
||||
if (oglHaveExtension("GL_ARB_vertex_shader"))
|
||||
m_Caps.m_VertexShader=true;
|
||||
}
|
||||
if (0 == oglHaveExtensions(0, "GL_ARB_shadow", "GL_ARB_depth_texture", 0)) {
|
||||
m_Caps.m_DepthTextureShadows = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -591,8 +597,6 @@ void CRenderer::BeginFrame()
|
||||
}
|
||||
|
||||
// init per frame stuff
|
||||
m_ShadowRendered=false;
|
||||
|
||||
m->shadow->SetupFrame(m_CullCamera, m_LightEnv->m_SunDir);
|
||||
}
|
||||
|
||||
@ -612,7 +616,6 @@ void CRenderer::RenderShadowMap()
|
||||
|
||||
m->shadow->BeginRender();
|
||||
|
||||
// TODO HACK fold this into ShadowMap
|
||||
glColor4fv(m_Options.m_ShadowColor);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
@ -627,37 +630,24 @@ void CRenderer::RenderShadowMap()
|
||||
m_Models.NormalInstancing->Render(m_Models.ModSolidColor, MODELFLAG_CASTSHADOWS);
|
||||
if (m_Models.PlayerInstancing)
|
||||
m_Models.PlayerInstancing->Render(m_Models.ModSolidColor, MODELFLAG_CASTSHADOWS);
|
||||
m_Models.TranspFF->Render(m_Models.ModTransparentShadow, MODELFLAG_CASTSHADOWS);
|
||||
|
||||
RenderModifierPtr transparentShadows = m_Models.ModTransparentShadow;
|
||||
|
||||
if (m->shadow->GetUseDepthTexture())
|
||||
transparentShadows = m_Models.ModTransparentDepthShadow;
|
||||
|
||||
m_Models.TranspFF->Render(transparentShadows, MODELFLAG_CASTSHADOWS);
|
||||
if (m_Models.TranspHWLit)
|
||||
m_Models.TranspHWLit->Render(m_Models.ModTransparentShadow, MODELFLAG_CASTSHADOWS);
|
||||
m_Models.TranspSortAll->Render(m_Models.ModTransparentShadow, MODELFLAG_CASTSHADOWS);
|
||||
m_Models.TranspHWLit->Render(transparentShadows, MODELFLAG_CASTSHADOWS);
|
||||
m_Models.TranspSortAll->Render(transparentShadows, MODELFLAG_CASTSHADOWS);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glColor3f(1.0f,1.0f,1.0f);
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
||||
m->shadow->EndRender();
|
||||
}
|
||||
|
||||
//TODO: Fold into TerrainRenderer
|
||||
void CRenderer::ApplyShadowMap()
|
||||
{
|
||||
PROFILE( "applying shadows" );
|
||||
|
||||
const CMatrix3D& texturematrix = m->shadow->GetTextureMatrix();
|
||||
GLuint shadowmap = m->shadow->GetTexture();
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(&texturematrix._11);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
m->terrainRenderer->ApplyShadowMap(shadowmap);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void CRenderer::RenderPatches()
|
||||
{
|
||||
PROFILE(" render patches ");
|
||||
@ -670,7 +660,7 @@ void CRenderer::RenderPatches()
|
||||
|
||||
// render all the patches, including blend pass
|
||||
MICROLOG(L"render patch submissions");
|
||||
m->terrainRenderer->RenderTerrain();
|
||||
m->terrainRenderer->RenderTerrain(m_Options.m_Shadows ? m->shadow : 0, m_Options.m_ShadowColor);
|
||||
|
||||
if (m_TerrainRenderMode==WIREFRAME) {
|
||||
// switch wireframe off again
|
||||
@ -804,16 +794,15 @@ void CRenderer::FlushFrame()
|
||||
m->terrainRenderer->PrepareForRendering();
|
||||
PROFILE_END("prepare terrain");
|
||||
|
||||
if (!m_ShadowRendered) {
|
||||
if (m_Options.m_Shadows) {
|
||||
MICROLOG(L"render shadows");
|
||||
RenderShadowMap();
|
||||
}
|
||||
// clear buffers
|
||||
glClearColor(m_ClearColor[0],m_ClearColor[1],m_ClearColor[2],m_ClearColor[3]);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
if (m_Options.m_Shadows) {
|
||||
MICROLOG(L"render shadows");
|
||||
RenderShadowMap();
|
||||
}
|
||||
|
||||
// clear buffers
|
||||
glClearColor(m_ClearColor[0],m_ClearColor[1],m_ClearColor[2],m_ClearColor[3]);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
oglCheck();
|
||||
|
||||
// render submitted patches and models
|
||||
@ -825,13 +814,6 @@ void CRenderer::FlushFrame()
|
||||
RenderModels();
|
||||
oglCheck();
|
||||
|
||||
if (m_Options.m_Shadows && !m_ShadowRendered) {
|
||||
MICROLOG(L"apply shadows");
|
||||
ApplyShadowMap();
|
||||
oglCheck();
|
||||
}
|
||||
m_ShadowRendered=true;
|
||||
|
||||
// call on the transparency renderer to render all the transparent stuff
|
||||
MICROLOG(L"render transparent");
|
||||
RenderTransparentModels();
|
||||
@ -1284,10 +1266,26 @@ void CRenderer::JSI_SetRenderPath(JSContext* ctx, jsval newval)
|
||||
SetRenderPath(GetRenderPathByName(name));
|
||||
}
|
||||
|
||||
jsval CRenderer::JSI_GetUseDepthTexture(JSContext*)
|
||||
{
|
||||
return ToJSVal(m->shadow->GetUseDepthTexture());
|
||||
}
|
||||
|
||||
void CRenderer::JSI_SetUseDepthTexture(JSContext* ctx, jsval newval)
|
||||
{
|
||||
bool depthTexture;
|
||||
|
||||
if (!ToPrimitive(ctx, newval, depthTexture))
|
||||
return;
|
||||
|
||||
m->shadow->SetUseDepthTexture(depthTexture);
|
||||
}
|
||||
|
||||
void CRenderer::ScriptingInit()
|
||||
{
|
||||
AddProperty(L"fastPlayerColor", &CRenderer::JSI_GetFastPlayerColor, &CRenderer::JSI_SetFastPlayerColor);
|
||||
AddProperty(L"renderpath", &CRenderer::JSI_GetRenderPath, &CRenderer::JSI_SetRenderPath);
|
||||
AddProperty(L"useDepthTexture", &CRenderer::JSI_GetUseDepthTexture, &CRenderer::JSI_SetUseDepthTexture);
|
||||
AddProperty(L"sortAllTransparent", &CRenderer::m_SortAllTransparent);
|
||||
AddProperty(L"fastNormals", &CRenderer::m_FastNormals);
|
||||
AddProperty(L"displayFrustum", &CRenderer::m_DisplayFrustum);
|
||||
|
@ -140,6 +140,14 @@ public:
|
||||
RenderPath m_RenderPath;
|
||||
} m_Options;
|
||||
|
||||
struct Caps {
|
||||
bool m_VBO;
|
||||
bool m_TextureBorderClamp;
|
||||
bool m_GenerateMipmaps;
|
||||
bool m_VertexShader;
|
||||
bool m_DepthTextureShadows;
|
||||
};
|
||||
|
||||
public:
|
||||
// constructor, destructor
|
||||
CRenderer();
|
||||
@ -280,6 +288,13 @@ public:
|
||||
*/
|
||||
void SetFastPlayerColor(bool fast);
|
||||
|
||||
/**
|
||||
* GetCapabilities: Return which OpenGL capabilities are available and enabled.
|
||||
*
|
||||
* @return capabilities structure
|
||||
*/
|
||||
const Caps& GetCapabilities() const { return m_Caps; }
|
||||
|
||||
protected:
|
||||
friend struct CRendererInternals;
|
||||
friend class CVertexBuffer;
|
||||
@ -298,6 +313,8 @@ protected:
|
||||
void JSI_SetFastPlayerColor(JSContext* ctx, jsval newval);
|
||||
jsval JSI_GetRenderPath(JSContext*);
|
||||
void JSI_SetRenderPath(JSContext* ctx, jsval newval);
|
||||
jsval JSI_GetUseDepthTexture(JSContext*);
|
||||
void JSI_SetUseDepthTexture(JSContext* ctx, jsval newval);
|
||||
static void ScriptingInit();
|
||||
|
||||
// patch rendering stuff
|
||||
@ -309,7 +326,6 @@ protected:
|
||||
|
||||
// shadow rendering stuff
|
||||
void RenderShadowMap();
|
||||
void ApplyShadowMap();
|
||||
|
||||
// debugging
|
||||
void DisplayFrustum();
|
||||
@ -358,19 +374,12 @@ protected:
|
||||
CSHCoeffs m_SHCoeffsTerrain;
|
||||
// ogl_tex handle of composite alpha map (all the alpha maps packed into one texture)
|
||||
Handle m_hCompositeAlphaMap;
|
||||
// per-frame flag: has the shadow map been rendered this frame?
|
||||
bool m_ShadowRendered;
|
||||
// coordinates of each (untransformed) alpha map within the packed texture
|
||||
struct {
|
||||
float u0,u1,v0,v1;
|
||||
} m_AlphaMapCoords[NumAlphaMaps];
|
||||
// card capabilities
|
||||
struct Caps {
|
||||
bool m_VBO;
|
||||
bool m_TextureBorderClamp;
|
||||
bool m_GenerateMipmaps;
|
||||
bool m_VertexShader;
|
||||
} m_Caps;
|
||||
Caps m_Caps;
|
||||
// build card cap bits
|
||||
void EnumCaps();
|
||||
// per-frame renderer stats
|
||||
@ -439,6 +448,7 @@ protected:
|
||||
RenderModifierPtr ModSolidColor;
|
||||
RenderModifierPtr ModTransparent;
|
||||
RenderModifierPtr ModTransparentShadow;
|
||||
RenderModifierPtr ModTransparentDepthShadow;
|
||||
} m_Models;
|
||||
};
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ogl.h"
|
||||
#include "CLogger.h"
|
||||
|
||||
#include "graphics/LightEnv.h"
|
||||
|
||||
@ -21,6 +22,8 @@
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/ShadowMap.h"
|
||||
|
||||
#define LOG_CATEGORY "graphics"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ShadowMap implementation
|
||||
@ -30,6 +33,8 @@
|
||||
*/
|
||||
struct ShadowMapInternals
|
||||
{
|
||||
// whether we're using depth texture or luminance map
|
||||
bool UseDepthTexture;
|
||||
// handle of shadow map
|
||||
GLuint Texture;
|
||||
// width, height of shadow map
|
||||
@ -61,6 +66,9 @@ ShadowMap::ShadowMap()
|
||||
{
|
||||
m = new ShadowMapInternals;
|
||||
m->Texture = 0;
|
||||
m->Width = 0;
|
||||
m->Height = 0;
|
||||
m->UseDepthTexture = false;
|
||||
}
|
||||
|
||||
|
||||
@ -203,21 +211,36 @@ void ShadowMapInternals::CreateTexture()
|
||||
Height = g_Renderer.GetHeight();
|
||||
Height = RoundUpToPowerOf2(Height);
|
||||
|
||||
LOG(NORMAL, LOG_CATEGORY, "Creating shadow texture (size %ix%i) (format = %s)",
|
||||
Width, Height, UseDepthTexture ? "DEPTH_COMPONENT" : "LUMINANCE");
|
||||
|
||||
// create texture object
|
||||
glGenTextures(1, &Texture);
|
||||
g_Renderer.BindTexture(0, Texture);
|
||||
|
||||
u32 size = Width*Height;
|
||||
u32* buf=new u32[size];
|
||||
for (uint i=0;i<size;i++) buf[i]=0x00ffffff;
|
||||
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,Width,Height,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
|
||||
delete[] buf;
|
||||
|
||||
if (UseDepthTexture)
|
||||
{
|
||||
float* buf = new float[size];
|
||||
for(uint i = 0; i < size; i++) buf[i] = 1.0;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, Width, Height, 0,
|
||||
GL_DEPTH_COMPONENT, GL_FLOAT, buf);
|
||||
delete[] buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32* buf=new u32[size];
|
||||
for (uint i=0;i<size;i++) buf[i]=0x00ffffff;
|
||||
glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE8,Width,Height,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
// set texture parameters
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
|
||||
@ -235,8 +258,16 @@ void ShadowMap::BeginRender()
|
||||
m->CalcShadowMatrices();
|
||||
|
||||
// clear buffers
|
||||
glClearColor(1,1,1,0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
if (m->UseDepthTexture)
|
||||
{
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
glColorMask(0,0,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearColor(1,1,1,0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// setup viewport
|
||||
glViewport(0, 0, renderWidth, renderHeight);
|
||||
@ -264,6 +295,11 @@ void ShadowMap::EndRender()
|
||||
g_Renderer.BindTexture(0, m->Texture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, g_Renderer.GetWidth(), g_Renderer.GetHeight());
|
||||
|
||||
if (m->UseDepthTexture)
|
||||
{
|
||||
glColorMask(1,1,1,1);
|
||||
}
|
||||
|
||||
// restore matrix stack
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
@ -285,6 +321,38 @@ const CMatrix3D& ShadowMap::GetTextureMatrix()
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Using depth textures vs. a simple luminance map
|
||||
bool ShadowMap::GetUseDepthTexture()
|
||||
{
|
||||
return m->UseDepthTexture;
|
||||
}
|
||||
|
||||
void ShadowMap::SetUseDepthTexture(bool depthTexture)
|
||||
{
|
||||
if (depthTexture)
|
||||
{
|
||||
if (!g_Renderer.GetCapabilities().m_DepthTextureShadows)
|
||||
{
|
||||
LOG(WARNING, LOG_CATEGORY, "Depth textures are not supported by your graphics card/driver. Fallback to luminance map (no self-shadowing)!");
|
||||
depthTexture = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (depthTexture != m->UseDepthTexture)
|
||||
{
|
||||
if (m->Texture)
|
||||
{
|
||||
glDeleteTextures(1, &m->Texture);
|
||||
m->Texture = 0;
|
||||
}
|
||||
m->Width = m->Height = 0;
|
||||
|
||||
m->UseDepthTexture = depthTexture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// RenderDebugDisplay: debug visualizations
|
||||
// - blue: objects in shadow
|
||||
@ -363,6 +431,11 @@ void ShadowMap::RenderDebugDisplay()
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
g_Renderer.BindTexture(0, m->Texture);
|
||||
if (m->UseDepthTexture)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
|
||||
|
@ -25,7 +25,9 @@ struct ShadowMapInternals;
|
||||
* The class will automatically generate a texture the first time the shadow map is rendered into.
|
||||
* The texture will not be resized afterwards.
|
||||
*
|
||||
* @todo use depth textures for self-shadowing
|
||||
* Can use a simple luminance map to store shadows (no self-shadowing possible) or
|
||||
* depth textures (with self-shadowing). Default is to use a luminance map, use SetUseDepthTexture
|
||||
* to override the default.
|
||||
*/
|
||||
class ShadowMap
|
||||
{
|
||||
@ -33,6 +35,28 @@ public:
|
||||
ShadowMap();
|
||||
~ShadowMap();
|
||||
|
||||
/**
|
||||
* GetUseDepthTexture: Return whether rendering uses a depth texture (instead of
|
||||
* a luminance texture).
|
||||
*
|
||||
* Note that this value may be changed automatically based on OpenGL capabilities.
|
||||
* It is guarantueed that it stays constant after SetupFrame until the end of the
|
||||
* frame or the next call to SetUseDepthTexture.
|
||||
*
|
||||
* @return whether shadow rendering uses depth textures
|
||||
*/
|
||||
bool GetUseDepthTexture();
|
||||
|
||||
/**
|
||||
* SetUseDepthTexture: Set whether shadowing should use depth textures.
|
||||
* Note that even passing @c true for depthTexture does not actually guarantuee that
|
||||
* depth textures will be used (mostly due to OpenGL capabilities). See the comment
|
||||
* for GetUseDepthTexture.
|
||||
*
|
||||
* @param depthTexture whether shadow rendering should use depth textures
|
||||
*/
|
||||
void SetUseDepthTexture(bool depthTexture);
|
||||
|
||||
/**
|
||||
* SetupFrame: Configure light space for the given camera and light direction,
|
||||
* create the shadow texture if necessary, etc.
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "renderer/PatchRData.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/ShadowMap.h"
|
||||
#include "renderer/TerrainRenderer.h"
|
||||
#include "renderer/WaterManager.h"
|
||||
|
||||
@ -56,6 +57,9 @@ struct TerrainRendererInternals
|
||||
* @todo Merge this list with CPatchRData list
|
||||
*/
|
||||
std::vector<CPatch*> visiblePatches;
|
||||
|
||||
// Helper functions
|
||||
void ApplyShadowMap(ShadowMap* shadow, const RGBAColor& shadowColor);
|
||||
};
|
||||
|
||||
|
||||
@ -124,7 +128,7 @@ bool TerrainRenderer::HaveSubmissions()
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Full-featured terrain rendering with blending and everything
|
||||
void TerrainRenderer::RenderTerrain()
|
||||
void TerrainRenderer::RenderTerrain(ShadowMap* shadow, const RGBAColor& shadowColor)
|
||||
{
|
||||
debug_assert(m->phase == Phase_Render);
|
||||
|
||||
@ -157,7 +161,7 @@ void TerrainRenderer::RenderTerrain()
|
||||
CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData();
|
||||
patchdata->RenderBase();
|
||||
}
|
||||
|
||||
|
||||
// render blends
|
||||
// switch on the composite alpha map texture
|
||||
(void)ogl_tex_bind(g_Renderer.m_hCompositeAlphaMap, 1);
|
||||
@ -197,7 +201,7 @@ void TerrainRenderer::RenderTerrain()
|
||||
pglClientActiveTextureARB(GL_TEXTURE1);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
g_Renderer.BindTexture(1,0);
|
||||
|
||||
|
||||
pglClientActiveTextureARB(GL_TEXTURE0);
|
||||
pglActiveTextureARB(GL_TEXTURE0);
|
||||
|
||||
@ -205,6 +209,12 @@ void TerrainRenderer::RenderTerrain()
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
// Now render shadows as a second pass
|
||||
if (shadow)
|
||||
{
|
||||
m->ApplyShadowMap(shadow, shadowColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -368,35 +378,71 @@ void TerrainRenderer::RenderWater()
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void TerrainRenderer::ApplyShadowMap(GLuint shadowmaphandle)
|
||||
// ApplyShadowMap: add luminance map shadows after rendering the
|
||||
// actual terrain
|
||||
void TerrainRendererInternals::ApplyShadowMap(ShadowMap* shadow, const RGBAColor& shadowColor)
|
||||
{
|
||||
debug_assert(m->phase == Phase_Render);
|
||||
debug_assert(phase == Phase_Render);
|
||||
|
||||
g_Renderer.BindTexture(0, shadowmaphandle);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
const CMatrix3D& texturematrix = shadow->GetTextureMatrix();
|
||||
GLuint shadowmap = shadow->GetTexture();
|
||||
|
||||
glColor3f(1,1,1);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(&texturematrix._11);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
g_Renderer.BindTexture(0, shadowmap);
|
||||
if (shadow->GetUseDepthTexture())
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_ONE_MINUS_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
glColor4fv(shadowColor);
|
||||
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
glColor3f(1,1,1);
|
||||
glBlendFunc(GL_DST_COLOR,GL_ZERO);
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_DST_COLOR,GL_ZERO);
|
||||
glDepthMask(0);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
for (uint i = 0; i < m->visiblePatches.size(); ++i)
|
||||
for (uint i = 0; i < visiblePatches.size(); ++i)
|
||||
{
|
||||
CPatchRData* patchdata = (CPatchRData*)m->visiblePatches[i]->GetRenderData();
|
||||
CPatchRData* patchdata = (CPatchRData*)visiblePatches[i]->GetRenderData();
|
||||
patchdata->RenderStreams(STREAM_POS|STREAM_POSTOUV0);
|
||||
}
|
||||
|
||||
glDepthMask(1);
|
||||
glDisable(GL_BLEND);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define TERRAINRENDERER_H
|
||||
|
||||
class CPatch;
|
||||
class ShadowMap;
|
||||
class WaterManager;
|
||||
|
||||
struct TerrainRendererInternals;
|
||||
@ -69,8 +70,11 @@ public:
|
||||
*
|
||||
* preconditions : PrepareForRendering must have been called this
|
||||
* frame before calling RenderTerrain.
|
||||
*
|
||||
* @param shadow a prepared shadow map, in case rendering with shadows is enabled
|
||||
* @param shadowColor color of shadows
|
||||
*/
|
||||
void RenderTerrain();
|
||||
void RenderTerrain(ShadowMap* shadow, const RGBAColor& shadowColor);
|
||||
|
||||
/**
|
||||
* RenderPatches: Render all patches un-textured as polygons.
|
||||
@ -97,14 +101,6 @@ public:
|
||||
*/
|
||||
void RenderWater();
|
||||
|
||||
/**
|
||||
* ApplyShadowMap: transition measure during refactoring
|
||||
*
|
||||
* @todo fix this
|
||||
* @deprecated
|
||||
*/
|
||||
void ApplyShadowMap(GLuint handle);
|
||||
|
||||
private:
|
||||
TerrainRendererInternals* m;
|
||||
};
|
||||
|
@ -659,3 +659,53 @@ void TransparentShadowRenderModifier::PrepareModel(uint UNUSED(pass), CModel* UN
|
||||
{
|
||||
// No per-model setup necessary
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TransparentDepthShadowModifier implementation
|
||||
|
||||
TransparentDepthShadowModifier::TransparentDepthShadowModifier()
|
||||
{
|
||||
}
|
||||
|
||||
TransparentDepthShadowModifier::~TransparentDepthShadowModifier()
|
||||
{
|
||||
}
|
||||
|
||||
u32 TransparentDepthShadowModifier::BeginPass(uint pass)
|
||||
{
|
||||
debug_assert(pass == 0);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.4);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
// Set the proper LOD bias
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias);
|
||||
|
||||
return STREAM_POS|STREAM_UV0;
|
||||
}
|
||||
|
||||
bool TransparentDepthShadowModifier::EndPass(uint UNUSED(pass))
|
||||
{
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TransparentDepthShadowModifier::PrepareTexture(uint UNUSED(pass), CTexture* texture)
|
||||
{
|
||||
g_Renderer.SetTexture(0, texture);
|
||||
}
|
||||
|
||||
void TransparentDepthShadowModifier::PrepareModel(uint UNUSED(pass), CModel* UNUSED(model))
|
||||
{
|
||||
// No per-model setup necessary
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ struct PolygonSortModelRendererInternals;
|
||||
/**
|
||||
* Class PolygonSortModelRenderer: Render animated models using only
|
||||
* OpenGL fixed function, sorting polygons from back to front.
|
||||
*
|
||||
*
|
||||
* This ModelVertexRenderer should only be used with SortModelRenderer.
|
||||
* However, SortModelRenderer can be used with other ModelVertexRenderers
|
||||
* than this one.
|
||||
@ -55,12 +55,12 @@ struct SortModelRendererInternals;
|
||||
/**
|
||||
* Class SortModelRenderer: Render models back-to-front from the
|
||||
* camera's point of view.
|
||||
*
|
||||
*
|
||||
* This is less efficient than batched model renderers, but
|
||||
* necessary for transparent models.
|
||||
*
|
||||
*
|
||||
* TransparencyRenderer can be used with any ModelVertexRenderer.
|
||||
*
|
||||
*
|
||||
* Use this renderer together with TransparentRenderModifier and
|
||||
* TransparentShadowRenderModifier to achieve transparency.
|
||||
*/
|
||||
@ -69,7 +69,7 @@ class SortModelRenderer : public ModelRenderer
|
||||
public:
|
||||
SortModelRenderer(ModelVertexRendererPtr vertexrenderer);
|
||||
~SortModelRenderer();
|
||||
|
||||
|
||||
// Transparency renderer implementation
|
||||
void Submit(CModel* model);
|
||||
void PrepareModels();
|
||||
@ -101,8 +101,8 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Class TransparentShadowRenderModifier: Use for shadow rendering of
|
||||
* transparent models.
|
||||
* Class TransparentShadowRenderModifier: Use to render shadow data for
|
||||
* transparent models into a luminance map.
|
||||
*/
|
||||
class TransparentShadowRenderModifier : public RenderModifier
|
||||
{
|
||||
@ -117,4 +117,22 @@ public:
|
||||
void PrepareModel(uint pass, CModel* model);
|
||||
};
|
||||
|
||||
/**
|
||||
* Class TransparentDepthShadowModifier: Use to render shadow data for
|
||||
* transparent models into a depth texture: Writes into the depth buffer,
|
||||
* color data is undefined.
|
||||
*/
|
||||
class TransparentDepthShadowModifier : public RenderModifier
|
||||
{
|
||||
public:
|
||||
TransparentDepthShadowModifier();
|
||||
~TransparentDepthShadowModifier();
|
||||
|
||||
// Implementation
|
||||
u32 BeginPass(uint pass);
|
||||
bool EndPass(uint pass);
|
||||
void PrepareTexture(uint pass, CTexture* texture);
|
||||
void PrepareModel(uint pass, CModel* model);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user