forked from 0ad/0ad
#Use EXT_framebuffer_object when available
* noframebufferobject configuration in system.cfg can be used to disable EXT_fbo (in case drivers are flaky etc.) * shadow texture size now honours the OpenGL maximum texture size as reported by the implementation This was SVN commit r3693.
This commit is contained in:
parent
12b214bf27
commit
8fd256c458
@ -24,6 +24,7 @@
|
||||
; System settings:
|
||||
|
||||
novbo=false
|
||||
noframebufferobject=false
|
||||
shadows=true
|
||||
vsync=false
|
||||
|
||||
|
@ -57,6 +57,25 @@ FUNC2(void, glCompressedTexSubImage2DARB, glCompressedTexSubImage2D, "1.3", (GLe
|
||||
FUNC2(void, glCompressedTexSubImage1DARB, glCompressedTexSubImage1D, "1.3", (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid*))
|
||||
FUNC2(void, glGetCompressedTexImageARB, glGetCompressedTexImage, "1.3", (GLenum, GLint, GLvoid*))
|
||||
|
||||
// GL_EXT_framebuffer_object
|
||||
FUNC(GLboolean, glIsRenderbufferEXT, (GLuint renderbuffer))
|
||||
FUNC(void, glBindRenderbufferEXT, (GLenum target, GLuint renderbuffer))
|
||||
FUNC(void, glDeleteRenderbuffersEXT, (GLsizei n, const GLuint *renderbuffers))
|
||||
FUNC(void, glGenRenderbuffersEXT, (GLsizei n, GLuint *renderbuffers))
|
||||
FUNC(void, glRenderbufferStorageEXT, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height))
|
||||
FUNC(void, glGetRenderbufferParameterivEXT, (GLenum target, GLenum pname, GLint *params))
|
||||
FUNC(GLboolean, glIsFramebufferEXT, (GLuint framebuffer))
|
||||
FUNC(void, glBindFramebufferEXT, (GLenum target, GLuint framebuffer))
|
||||
FUNC(void, glDeleteFramebuffersEXT, (GLsizei n, const GLuint *framebuffers))
|
||||
FUNC(void, glGenFramebuffersEXT, (GLsizei n, GLuint *framebuffers))
|
||||
FUNC(GLenum, glCheckFramebufferStatusEXT, (GLenum target))
|
||||
FUNC(void, glFramebufferTexture1DEXT, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level))
|
||||
FUNC(void, glFramebufferTexture2DEXT, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level))
|
||||
FUNC(void, glFramebufferTexture3DEXT, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset))
|
||||
FUNC(void, glFramebufferRenderbufferEXT, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer))
|
||||
FUNC(void, glGetFramebufferAttachmentParameterivEXT, (GLenum target, GLenum attachment, GLenum pname, GLint *params))
|
||||
FUNC(void, glGenerateMipmapEXT, (GLenum target))
|
||||
|
||||
// GL_ARB_shader_objects
|
||||
FUNC2(void, glDeleteObjectARB, glDeleteObject, "2.0", (GLhandleARB obj))
|
||||
FUNC2(GLhandleARB, glGetHandleARB, glGetHandle, "2.0", (GLenum pname))
|
||||
|
@ -264,7 +264,8 @@ static void dump_gl_error(GLenum err)
|
||||
E(GL_STACK_OVERFLOW)
|
||||
E(GL_STACK_UNDERFLOW)
|
||||
E(GL_OUT_OF_MEMORY)
|
||||
default:;
|
||||
E(GL_INVALID_FRAMEBUFFER_OPERATION_EXT)
|
||||
default: debug_printf("GL error: %04f\n", err); break;
|
||||
}
|
||||
#undef E
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ CStr g_ActiveProfile = "default";
|
||||
// flag to disable extended GL extensions until fix found - specifically, crashes
|
||||
// using VBOs on laptop Radeon cards
|
||||
bool g_NoGLVBO=false;
|
||||
// disable FBO extension in case the driver is flaky
|
||||
bool g_NoGLFramebufferObject = false;
|
||||
// flag to switch on shadows
|
||||
bool g_Shadows=false;
|
||||
// flag to switch off pbuffers
|
||||
@ -69,6 +71,7 @@ static void LoadGlobals()
|
||||
|
||||
CFG_GET_USER_VAL("vsync", Bool, g_VSync);
|
||||
CFG_GET_USER_VAL("novbo", Bool, g_NoGLVBO);
|
||||
CFG_GET_USER_VAL("noframebufferobject", Bool, g_NoGLFramebufferObject);
|
||||
CFG_GET_USER_VAL("shadows", Bool, g_Shadows);
|
||||
CFG_GET_USER_VAL("renderpath", String, g_RenderPath);
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
// flag to disable extended GL extensions until fix found - specifically, crashes
|
||||
// using VBOs on laptop Radeon cards
|
||||
extern bool g_NoGLVBO;
|
||||
// disable FBO extension in case the driver is flaky
|
||||
extern bool g_NoGLFramebufferObject;
|
||||
// flag to switch on shadows
|
||||
extern bool g_Shadows;
|
||||
// flag to switch off pbuffers
|
||||
|
@ -643,6 +643,7 @@ static void InitRenderer()
|
||||
|
||||
// set renderer options from command line options - NOVBO must be set before opening the renderer
|
||||
g_Renderer.SetOptionBool(CRenderer::OPT_NOVBO,g_NoGLVBO);
|
||||
g_Renderer.SetOptionBool(CRenderer::OPT_NOFRAMEBUFFEROBJECT,g_NoGLFramebufferObject);
|
||||
g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS,g_Shadows);
|
||||
g_Renderer.SetOptionBool(CRenderer::OPT_NOPBUFFER,g_NoPBuffer);
|
||||
g_Renderer.SetRenderPath(CRenderer::GetRenderPathByName(g_RenderPath));
|
||||
|
@ -294,18 +294,104 @@ CRenderer::CRenderer()
|
||||
m_FastNormals = true;
|
||||
m_DisplayFrustum = false;
|
||||
m_DisableCopyShadow = false;
|
||||
m_FastPlayerColor = true;
|
||||
|
||||
m_VertexShader = 0;
|
||||
|
||||
m_Options.m_NoVBO=false;
|
||||
m_Options.m_NoFramebufferObject = false;
|
||||
m_Options.m_Shadows=true;
|
||||
m_Options.m_ShadowColor=RGBAColor(0.4f,0.4f,0.4f,1.0f);
|
||||
m_Options.m_RenderPath = RP_DEFAULT;
|
||||
|
||||
m_ShadowZBias = 0.001f;
|
||||
|
||||
for (uint i=0;i<MaxTextureUnits;i++) {
|
||||
m_ActiveTextures[i]=0;
|
||||
}
|
||||
|
||||
ONCE( ScriptingInit(); );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// CRenderer destructor
|
||||
CRenderer::~CRenderer()
|
||||
{
|
||||
// model rendering
|
||||
for(int vertexType = 0; vertexType < NumVertexTypes; ++vertexType)
|
||||
{
|
||||
delete m->Model.pal_NormalFF[vertexType];
|
||||
delete m->Model.pal_PlayerFF[vertexType];
|
||||
delete m->Model.pal_TranspFF[vertexType];
|
||||
delete m->Model.pal_NormalHWLit[vertexType];
|
||||
delete m->Model.pal_PlayerHWLit[vertexType];
|
||||
delete m->Model.pal_TranspHWLit[vertexType];
|
||||
delete m->Model.pal_NormalInstancing[vertexType];
|
||||
delete m->Model.pal_PlayerInstancing[vertexType];
|
||||
}
|
||||
delete m->Model.pal_TranspSortAll;
|
||||
|
||||
// general
|
||||
delete m_VertexShader;
|
||||
m_VertexShader = 0;
|
||||
|
||||
CParticleEngine::GetInstance()->cleanup();
|
||||
|
||||
// we no longer UnloadAlphaMaps / UnloadWaterTextures here -
|
||||
// that is the responsibility of the module that asked for
|
||||
// them to be loaded (i.e. CGameView).
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// EnumCaps: build card cap bits
|
||||
void CRenderer::EnumCaps()
|
||||
{
|
||||
// assume support for nothing
|
||||
m_Caps.m_VBO=false;
|
||||
m_Caps.m_TextureBorderClamp=false;
|
||||
m_Caps.m_GenerateMipmaps=false;
|
||||
m_Caps.m_VertexShader=false;
|
||||
m_Caps.m_DepthTextureShadows = false;
|
||||
m_Caps.m_FramebufferObject = false;
|
||||
|
||||
// now start querying extensions
|
||||
if (!m_Options.m_NoVBO) {
|
||||
if (oglHaveExtension("GL_ARB_vertex_buffer_object")) {
|
||||
m_Caps.m_VBO=true;
|
||||
}
|
||||
}
|
||||
if (oglHaveExtension("GL_ARB_texture_border_clamp")) {
|
||||
m_Caps.m_TextureBorderClamp=true;
|
||||
}
|
||||
if (oglHaveExtension("GL_SGIS_generate_mipmap")) {
|
||||
m_Caps.m_GenerateMipmaps=true;
|
||||
}
|
||||
if (0 == oglHaveExtensions(0, "GL_ARB_shader_objects", "GL_ARB_shading_language_100", 0))
|
||||
{
|
||||
if (oglHaveExtension("GL_ARB_vertex_shader"))
|
||||
m_Caps.m_VertexShader=true;
|
||||
}
|
||||
|
||||
if (0 == oglHaveExtensions(0, "GL_ARB_shadow", "GL_ARB_depth_texture", 0)) {
|
||||
// According to Delphi3d.net, all relevant graphics chips that support depth textures
|
||||
// (i.e. Geforce3+, Radeon9500+, even i915) also have >= 4 TMUs, so this restriction
|
||||
// isn't actually a restriction, and it helps with integrating depth texture
|
||||
// shadows into rendering paths.
|
||||
if (ogl_max_tex_units >= 4)
|
||||
m_Caps.m_DepthTextureShadows = true;
|
||||
}
|
||||
if (!m_Options.m_NoFramebufferObject)
|
||||
{
|
||||
if (oglHaveExtension("GL_EXT_framebuffer_object"))
|
||||
m_Caps.m_FramebufferObject = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CRenderer::Open(int width, int height, int depth)
|
||||
{
|
||||
// Must query card capabilities before creating renderers that depend
|
||||
// on card capabilities.
|
||||
EnumCaps();
|
||||
@ -375,88 +461,12 @@ CRenderer::CRenderer()
|
||||
m->Model.ModTransparentShadow = RenderModifierPtr(new TransparentShadowRenderModifier);
|
||||
m->Model.ModTransparentDepthShadow = RenderModifierPtr(new TransparentDepthShadowModifier);
|
||||
|
||||
m_ShadowZBias = 0.001f;
|
||||
|
||||
// Particle engine
|
||||
CParticleEngine::GetInstance()->initParticleSystem();
|
||||
CEmitter *pEmitter = new CDefaultEmitter(1000, -1);
|
||||
CParticleEngine::GetInstance()->addEmitter(pEmitter);
|
||||
|
||||
ONCE( ScriptingInit(); );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// CRenderer destructor
|
||||
CRenderer::~CRenderer()
|
||||
{
|
||||
// model rendering
|
||||
for(int vertexType = 0; vertexType < NumVertexTypes; ++vertexType)
|
||||
{
|
||||
delete m->Model.pal_NormalFF[vertexType];
|
||||
delete m->Model.pal_PlayerFF[vertexType];
|
||||
delete m->Model.pal_TranspFF[vertexType];
|
||||
delete m->Model.pal_NormalHWLit[vertexType];
|
||||
delete m->Model.pal_PlayerHWLit[vertexType];
|
||||
delete m->Model.pal_TranspHWLit[vertexType];
|
||||
delete m->Model.pal_NormalInstancing[vertexType];
|
||||
delete m->Model.pal_PlayerInstancing[vertexType];
|
||||
}
|
||||
delete m->Model.pal_TranspSortAll;
|
||||
|
||||
// general
|
||||
delete m_VertexShader;
|
||||
m_VertexShader = 0;
|
||||
|
||||
CParticleEngine::GetInstance()->cleanup();
|
||||
|
||||
// we no longer UnloadAlphaMaps / UnloadWaterTextures here -
|
||||
// that is the responsibility of the module that asked for
|
||||
// them to be loaded (i.e. CGameView).
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// EnumCaps: build card cap bits
|
||||
void CRenderer::EnumCaps()
|
||||
{
|
||||
// assume support for nothing
|
||||
m_Caps.m_VBO=false;
|
||||
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) {
|
||||
if (oglHaveExtension("GL_ARB_vertex_buffer_object")) {
|
||||
m_Caps.m_VBO=true;
|
||||
}
|
||||
}
|
||||
if (oglHaveExtension("GL_ARB_texture_border_clamp")) {
|
||||
m_Caps.m_TextureBorderClamp=true;
|
||||
}
|
||||
if (oglHaveExtension("GL_SGIS_generate_mipmap")) {
|
||||
m_Caps.m_GenerateMipmaps=true;
|
||||
}
|
||||
if (0 == oglHaveExtensions(0, "GL_ARB_shader_objects", "GL_ARB_shading_language_100", 0))
|
||||
{
|
||||
if (oglHaveExtension("GL_ARB_vertex_shader"))
|
||||
m_Caps.m_VertexShader=true;
|
||||
}
|
||||
|
||||
if (0 == oglHaveExtensions(0, "GL_ARB_shadow", "GL_ARB_depth_texture", 0)) {
|
||||
// According to Delphi3d.net, all relevant graphics chips that support depth textures
|
||||
// (i.e. Geforce3+, Radeon9500+, even i915) also have >= 4 TMUs, so this restriction
|
||||
// isn't actually a restriction, and it helps with integrating depth texture
|
||||
// shadows into rendering paths.
|
||||
if (ogl_max_tex_units >= 4)
|
||||
m_Caps.m_DepthTextureShadows = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CRenderer::Open(int width, int height, int depth)
|
||||
{
|
||||
// Dimensions
|
||||
m_Width = width;
|
||||
m_Height = height;
|
||||
m_Depth = depth;
|
||||
@ -505,6 +515,9 @@ void CRenderer::SetOptionBool(enum Option opt,bool value)
|
||||
case OPT_NOVBO:
|
||||
m_Options.m_NoVBO=value;
|
||||
break;
|
||||
case OPT_NOFRAMEBUFFEROBJECT:
|
||||
m_Options.m_NoFramebufferObject=value;
|
||||
break;
|
||||
case OPT_SHADOWS:
|
||||
m_Options.m_Shadows=value;
|
||||
break;
|
||||
@ -524,6 +537,8 @@ bool CRenderer::GetOptionBool(enum Option opt) const
|
||||
switch (opt) {
|
||||
case OPT_NOVBO:
|
||||
return m_Options.m_NoVBO;
|
||||
case OPT_NOFRAMEBUFFEROBJECT:
|
||||
return m_Options.m_NoFramebufferObject;
|
||||
case OPT_SHADOWS:
|
||||
return m_Options.m_Shadows;
|
||||
default:
|
||||
|
@ -88,6 +88,7 @@ public:
|
||||
enum { MaxTextureUnits=16 };
|
||||
enum Option {
|
||||
OPT_NOVBO,
|
||||
OPT_NOFRAMEBUFFEROBJECT,
|
||||
OPT_NOPBUFFER,
|
||||
OPT_SHADOWS,
|
||||
OPT_SHADOWCOLOR,
|
||||
@ -134,6 +135,7 @@ public:
|
||||
// renderer options
|
||||
struct Options {
|
||||
bool m_NoVBO;
|
||||
bool m_NoFramebufferObject;
|
||||
bool m_Shadows;
|
||||
RGBAColor m_ShadowColor;
|
||||
float m_LodBias;
|
||||
@ -146,6 +148,7 @@ public:
|
||||
bool m_GenerateMipmaps;
|
||||
bool m_VertexShader;
|
||||
bool m_DepthTextureShadows;
|
||||
bool m_FramebufferObject;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -37,10 +37,15 @@ struct ShadowMapInternals
|
||||
bool UseDepthTexture;
|
||||
// bit depth for the depth texture, if used
|
||||
int DepthTextureBits;
|
||||
// if non-zero, we're using EXT_framebuffer_object for shadow rendering,
|
||||
// and this is the framebuffer
|
||||
GLuint Framebuffer;
|
||||
// handle of shadow map
|
||||
GLuint Texture;
|
||||
// width, height of shadow map
|
||||
u32 Width, Height;
|
||||
// used width, height of shadow map
|
||||
u32 EffectiveWidth, EffectiveHeight;
|
||||
// transform light space into projected light space
|
||||
// in projected light space, the shadowbound box occupies the [-1..1] cube
|
||||
// calculated on BeginRender, after the final shadow bounds are known
|
||||
@ -67,9 +72,12 @@ struct ShadowMapInternals
|
||||
ShadowMap::ShadowMap()
|
||||
{
|
||||
m = new ShadowMapInternals;
|
||||
m->Framebuffer = 0;
|
||||
m->Texture = 0;
|
||||
m->Width = 0;
|
||||
m->Height = 0;
|
||||
m->EffectiveWidth = 0;
|
||||
m->EffectiveHeight = 0;
|
||||
m->UseDepthTexture = false;
|
||||
m->DepthTextureBits = 16;
|
||||
}
|
||||
@ -79,12 +87,14 @@ ShadowMap::~ShadowMap()
|
||||
{
|
||||
if (m->Texture)
|
||||
glDeleteTextures(1, &m->Texture);
|
||||
if (m->Framebuffer)
|
||||
pglDeleteFramebuffersEXT(1, &m->Framebuffer);
|
||||
|
||||
delete m;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SetCameraAndLight: camera and light direction for this frame
|
||||
// SetupFrame: camera and light direction for this frame
|
||||
void ShadowMap::SetupFrame(const CCamera& camera, const CVector3D& lightdir)
|
||||
{
|
||||
if (!m->Texture)
|
||||
@ -184,8 +194,8 @@ void ShadowMapInternals::CalcShadowMatrices()
|
||||
// Calculate texture matrix by creating the clip space to texture coordinate matrix
|
||||
// and then concatenating all matrices that have been calculated so far
|
||||
CMatrix3D lightToTex;
|
||||
float texscalex = (float)renderer.GetWidth() / (float)Width;
|
||||
float texscaley = (float)renderer.GetHeight() / (float)Height;
|
||||
float texscalex = (float)EffectiveWidth / (float)Width;
|
||||
float texscaley = (float)EffectiveHeight / (float)Height;
|
||||
float texscalez = 1.0;
|
||||
|
||||
texscalex = texscalex / (ShadowBound[1].X - ShadowBound[0].X);
|
||||
@ -210,14 +220,42 @@ void ShadowMapInternals::CalcShadowMatrices()
|
||||
// Create the shadow map
|
||||
void ShadowMapInternals::CreateTexture()
|
||||
{
|
||||
// Cleanup
|
||||
if (Texture)
|
||||
{
|
||||
glDeleteTextures(1, &Texture);
|
||||
Texture = 0;
|
||||
}
|
||||
if (Framebuffer)
|
||||
{
|
||||
pglDeleteFramebuffersEXT(1, &Framebuffer);
|
||||
Framebuffer = 0;
|
||||
}
|
||||
|
||||
// Prepare FBO if available
|
||||
// Note: luminance is not an RGB format, so a luminance texture cannot be used
|
||||
// as a color buffer
|
||||
if (UseDepthTexture && g_Renderer.GetCapabilities().m_FramebufferObject)
|
||||
{
|
||||
pglGenFramebuffersEXT(1, &Framebuffer);
|
||||
}
|
||||
|
||||
// get shadow map size as next power of two up from view width and height
|
||||
Width = g_Renderer.GetWidth();
|
||||
Width = RoundUpToPowerOf2(Width);
|
||||
Width = std::min(RoundUpToPowerOf2(Width), ogl_max_tex_size);
|
||||
Height = g_Renderer.GetHeight();
|
||||
Height = RoundUpToPowerOf2(Height);
|
||||
Height = std::min(RoundUpToPowerOf2(Height), ogl_max_tex_size);
|
||||
|
||||
if (Framebuffer)
|
||||
{
|
||||
EffectiveWidth = Width;
|
||||
EffectiveHeight = Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
EffectiveWidth = std::min(Width, (u32)g_Renderer.GetWidth());
|
||||
EffectiveHeight = std::min(Height, (u32)g_Renderer.GetHeight());
|
||||
}
|
||||
|
||||
const char* formatname = "LUMINANCE";
|
||||
|
||||
@ -231,8 +269,8 @@ void ShadowMapInternals::CreateTexture()
|
||||
}
|
||||
}
|
||||
|
||||
LOG(NORMAL, LOG_CATEGORY, "Creating shadow texture (size %ix%i) (format = %s)",
|
||||
Width, Height, formatname);
|
||||
LOG(NORMAL, LOG_CATEGORY, "Creating shadow texture (size %ix%i) (format = %s)%s",
|
||||
Width, Height, formatname, Framebuffer ? " (using EXT_framebuffer_object)" : "");
|
||||
|
||||
// create texture object
|
||||
glGenTextures(1, &Texture);
|
||||
@ -274,6 +312,35 @@ void ShadowMapInternals::CreateTexture()
|
||||
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);
|
||||
|
||||
// bind to framebuffer object
|
||||
if (Framebuffer)
|
||||
{
|
||||
debug_assert(UseDepthTexture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Framebuffer);
|
||||
|
||||
pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
||||
GL_TEXTURE_2D, Texture, 0);
|
||||
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
|
||||
GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
LOG(WARNING, LOG_CATEGORY, "Framebuffer object incomplete: %04f", status);
|
||||
|
||||
pglDeleteFramebuffersEXT(1, &Framebuffer);
|
||||
Framebuffer = 0;
|
||||
EffectiveWidth = std::min(Width, (u32)g_Renderer.GetWidth());
|
||||
EffectiveHeight = std::min(Height, (u32)g_Renderer.GetHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -283,27 +350,29 @@ void ShadowMap::BeginRender()
|
||||
{
|
||||
// HACK HACK: this depends in non-obvious ways on the behaviour of the caller
|
||||
|
||||
CRenderer& renderer = g_Renderer;
|
||||
int renderWidth = renderer.GetWidth();
|
||||
int renderHeight = renderer.GetHeight();
|
||||
|
||||
// Calc remaining shadow matrices
|
||||
m->CalcShadowMatrices();
|
||||
|
||||
if (m->Framebuffer)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m->Framebuffer);
|
||||
}
|
||||
|
||||
// clear buffers
|
||||
if (m->UseDepthTexture)
|
||||
{
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
glClear(GL_DEPTH_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);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// setup viewport
|
||||
glViewport(0, 0, renderWidth, renderHeight);
|
||||
glViewport(0, 0, m->EffectiveWidth, m->EffectiveHeight);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
@ -314,7 +383,7 @@ void ShadowMap::BeginRender()
|
||||
glLoadMatrixf(&m->LightTransform._11);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(1,1, renderWidth-2, renderHeight-2);
|
||||
glScissor(1,1, m->EffectiveWidth-2, m->EffectiveHeight-2);
|
||||
}
|
||||
|
||||
|
||||
@ -325,11 +394,20 @@ void ShadowMap::EndRender()
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
// copy result into shadow map texture
|
||||
if (!g_Renderer.GetDisableCopyShadow())
|
||||
if (m->Framebuffer)
|
||||
{
|
||||
g_Renderer.BindTexture(0, m->Texture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, g_Renderer.GetWidth(), g_Renderer.GetHeight());
|
||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!g_Renderer.GetDisableCopyShadow())
|
||||
{
|
||||
g_Renderer.BindTexture(0, m->Texture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, g_Renderer.GetWidth(), g_Renderer.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
glViewport(0, 0, g_Renderer.GetWidth(), g_Renderer.GetHeight());
|
||||
|
||||
if (m->UseDepthTexture)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user