22 #include "precompiled.h"
241 float boundInc = 16.0f;
255 CVector3D shift = (ShadowBound[1] + ShadowBound[0]) * -0.5;
264 scale.
X = 2.0 / scale.
X;
265 scale.
Y = 2.0 / scale.
Y;
266 scale.
Z = 2.0 / scale.
Z;
286 float texscalez = scale.
Z * 0.5f;
290 lightToTex.
_11 = texscalex;
291 lightToTex.
_14 = (offsetX - ShadowBound[0].X) * texscalex;
292 lightToTex.
_22 = texscaley;
293 lightToTex.
_24 = (offsetY - ShadowBound[0].Y) * texscaley;
294 lightToTex.
_33 = texscalez;
295 lightToTex.
_34 = -ShadowBound[0].Z * texscalez;
296 lightToTex.
_44 = 1.0;
325 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &
SavedViewFBO);
347 const char* formatname;
351 case 16: formatname =
"DEPTH_COMPONENT16";
break;
352 case 24: formatname =
"DEPTH_COMPONENT24";
break;
353 case 32: formatname =
"DEPTH_COMPONENT32";
break;
354 default: formatname =
"DEPTH_COMPONENT";
break;
357 LOGMESSAGE(L
"Creating shadow texture (size %dx%d) (format = %hs)",
365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
368 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
369 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
Width,
Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
378 format = GL_DEPTH_COMPONENT;
382 case 16: format = GL_DEPTH_COMPONENT16;
break;
383 case 24: format = GL_DEPTH_COMPONENT24;
break;
384 case 32: format = GL_DEPTH_COMPONENT32;
break;
385 default: format = GL_DEPTH_COMPONENT;
break;
389 glTexImage2D(GL_TEXTURE_2D, 0, format,
Width,
Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
393 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
394 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
399 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
400 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
403 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
404 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
405 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
408 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
415 glBindTexture(GL_TEXTURE_2D, 0);
416 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
Framebuffer);
418 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D,
Texture, 0);
422 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
DummyTexture, 0);
427 #warning TODO: figure out whether the glDrawBuffer/glReadBuffer stuff is needed, since it is not supported by GLES
429 glDrawBuffer(GL_NONE);
434 glReadBuffer(GL_NONE);
439 GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
441 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
SavedViewFBO);
443 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
445 LOGWARNING(L
"Framebuffer object incomplete: 0x%04X", status);
467 glBindTexture(GL_TEXTURE_2D, 0);
468 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
m->
Framebuffer);
473 PROFILE(
"clear depth texture");
477 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
478 glColorMask(0,0,0,0);
492 glMatrixMode(GL_PROJECTION);
494 glMatrixMode(GL_MODELVIEW);
498 glEnable(GL_SCISSOR_TEST);
507 glDisable(GL_SCISSOR_TEST);
518 glColorMask(1,1,1,1);
574 shaderTech->BeginPass();
578 glDisable(GL_CULL_FACE);
584 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
585 shader->Uniform(str_color, 0.0f, 0.0f, 1.0f, 0.25f);
589 shader->Uniform(str_color, 0.0f, 0.0f, 1.0f, 1.0f);
593 float shadowLineVerts[] = {
606 shader->VertexPointer(3, GL_FLOAT, 0, shadowLineVerts);
607 shader->AssertPointersBound();
608 glDrawArrays(GL_LINES, 0, 8);
610 shaderTech->EndPass();
619 glMultMatrixf(&InvTexTransform.
_11);
622 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
623 glColor4ub(255,0,0,64);
625 glVertex3f(0.0, 0.0, 0.0);
626 glVertex3f(1.0, 0.0, 0.0);
627 glVertex3f(1.0, 1.0, 0.0);
628 glVertex3f(0.0, 1.0, 0.0);
632 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
635 glVertex3f(0.0, 0.0, 0.0);
636 glVertex3f(1.0, 0.0, 0.0);
637 glVertex3f(1.0, 1.0, 0.0);
638 glVertex3f(0.0, 1.0, 0.0);
640 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
644 glEnable(GL_CULL_FACE);
652 glDisable(GL_DEPTH_TEST);
656 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
660 texTech->BeginPass();
664 texShader->BindTexture(str_tex,
m->
Texture);
676 texShader->VertexPointer(2, GL_FLOAT, 0, boxVerts);
677 texShader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, boxUV);
678 texShader->AssertPointersBound();
679 glDrawArrays(GL_TRIANGLES, 0, 6);
685 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
688 glEnable(GL_DEPTH_TEST);
void Transform(const CMatrix3D &m, CBoundingBoxAligned &result) const
Transforms these bounds according to the specified transformation matrix m, and writes the axis-align...
void RenderOutline(CShaderProgramPtr &shader) const
Render: Render the outline of the bound object as lines.
CMatrix3D GetDefaultGuiMatrix()
void SetDepthTextureBits(int bits)
SetDepthTextureBits: Sets the number of bits to use for depth textures when enabled.
int GetDepthTextureBits() const
GetDepthTextureBits: Return the number of bits to use for depth textures when enabled.
void SetupFrame(const CCamera &camera, const CVector3D &lightdir)
SetupFrame: Configure light space for the given camera and light direction, create the shadow texture...
void AddShadowedBound(const CBoundingBoxAligned &bounds)
AddShadowedBound: Add the bounding box of an object that has to be shadowed.
Struct ShadowMapInternals: Internal data for the ShadowMap implementation.
float Dot(const CVector3D &vector) const
const CFrustum & GetFrustum() const
CVector3D Cross(const CVector3D &vector) const
GLuint GetTexture() const
GetTexture: Retrieve the OpenGL texture object name that contains the shadow map. ...
shared_ptr< CShaderTechnique > CShaderTechniquePtr
int GetWidth() const
GetWidth: Return the width of the depth texture.
T round_up_to_pow2(T x)
round up to next larger power of two.
CMatrix3D & GetOrientation()
void CalcShadowMatrices()
void RenderDebugTexture()
Visualize shadow map texture to help in debugging.
void IntersectFrustumConservative(const CFrustum &frustum)
IntersectFrustumConservative: Approximate the intersection of this bounds object with the given frust...
CMatrix3D LightProjection
T bits(T num, size_t lo_idx, size_t hi_idx)
extract the value of bits hi_idx:lo_idx within num
void BeginRender()
BeginRender: Set OpenGL state for rendering into the shadow map texture.
const CMatrix3D & GetTextureMatrix() const
GetTextureMatrix: Retrieve the world-space to shadow map texture coordinates transformation matrix...
void UpdateFrustum(const CBoundingBoxAligned &scissor=CBoundingBoxAligned(CVector3D(-1.0f,-1.0f,-1.0f), CVector3D(1.0f, 1.0f, 1.0f)))
void RenderDebugBounds()
Visualize shadow mapping calculations to help in debugging and optimal shadow map usage...
void GetInverse(CMatrix3D &dst) const
void RecreateTexture()
RecreateTexture: Destroy the current shadow texture and force creation of a new one.
void ogl_WarnIfError()
raise a warning (break into the debugger) if an OpenGL error is pending.
CBoundingBoxAligned ShadowBound
CMatrix3D InvLightTransform
CVector3D GetTranslation() const
void EndRender()
EndRender: Finish rendering into the shadow map.
void Render(CShaderProgramPtr &shader) const
Render: Render the surfaces of the bound object as triangles.
shared_ptr< CShaderProgram > CShaderProgramPtr
int GetHeight() const
GetHeight: Return the height of the depth texture.
void SetProjection(float nearp, float farp, float fov)