Skip to content

Commit

Permalink
Renderer|Models: Use an alternative depth buffer for 3D psprites
Browse files Browse the repository at this point in the history
It is unacceptable to clear the depth buffer for 3D psprites as that
would remove the depth information required for flare occlusion.

Now 3D psprites use their own, separate depth buffer.

Todo: Clean this up.
  • Loading branch information
skyjake committed Dec 3, 2013
1 parent 3b66512 commit 9e012a9
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 4 deletions.
35 changes: 31 additions & 4 deletions doomsday/client/src/render/sprite.cpp
Expand Up @@ -39,9 +39,12 @@
#include "resource/sprites.h"

#include "render/vissprite.h"

#include "render/sprite.h"

#include <de/GLState>
#include <de/GLTarget>
#include <de/GLTexture>

using namespace de;

void Rend_RenderSprite(rendspriteparams_t const *params);
Expand Down Expand Up @@ -104,9 +107,15 @@ void Rend_Draw3DPlayerSprites()
// Setup the modelview matrix.
Rend_ModelViewMatrix(false /* don't apply view angle rotation */);

// Clear Z buffer. This will prevent the psprites from being clipped
// by nearby polygons.
glClear(GL_DEPTH_BUFFER_BIT);
bool zBufferHasBeenSetUp = false;

/// @todo Set up an easier API for switching depth buffer temporarily

GLTarget &target = GLState::current().target();
GLTexture *originalDepth = target.attachedTexture(GLTarget::DepthStencil);
DENG2_ASSERT(originalDepth != 0);

static GLTexture localDepth;

rendmodelparams_t parm;
for(int i = 0; i < DDMAXPSPRITES; ++i)
Expand All @@ -115,9 +124,27 @@ void Rend_Draw3DPlayerSprites()

if(spr->type != VPSPR_MODEL) continue; // Not used.

if(!zBufferHasBeenSetUp)
{
// Resize the local depth buffer to match target size.
if(localDepth.size() != target.size())
{
localDepth.setDepthStencilContent(target.size());
}
target.replaceAttachment(GLTarget::DepthStencil, localDepth);
target.clear(GLTarget::DepthStencil);
zBufferHasBeenSetUp = true;
}

setupModelParamsForVisPSprite(&parm, spr);
Rend_RenderModel(&parm);
}

// Restore the old depth/stencil buffer.
if(zBufferHasBeenSetUp)
{
target.replaceAttachment(GLTarget::DepthStencil, *originalDepth);
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions doomsday/client/src/ui/clientwindow.cpp
Expand Up @@ -819,6 +819,8 @@ void ClientWindow::drawGameContentToTexture(GLTexture &texture)
DENG_ASSERT_IN_MAIN_THREAD();
DENG_ASSERT_GL_CONTEXT_ACTIVE();

/// @todo Use GLFramebuffer

GLTarget offscreen(texture, GLTarget::DepthStencil);
GLState::push()
.setTarget(offscreen)
Expand Down
8 changes: 8 additions & 0 deletions doomsday/libgui/include/de/gui/gltarget.h
Expand Up @@ -183,6 +183,14 @@ class LIBGUI_PUBLIC GLTarget : public Asset
*/
GLTexture *attachedTexture(Flags const &attachment) const;

/**
* Replaces a currently attached texture with another.
*
* @param attachment Which attachment.
* @param texture New texture to use as the attachment.
*/
void replaceAttachment(Flags const &attachment, GLTexture &texture);

/**
* Sets the subregion inside the render target where scissor and viewport
* will be scaled into. Scissor and viewport can still be defined as if the
Expand Down
31 changes: 31 additions & 0 deletions doomsday/libgui/src/gltarget.cpp
Expand Up @@ -62,6 +62,18 @@ DENG2_OBSERVES(Asset, Deletion)
return ColorBuffer; // should not be reached
}

static GLenum flagsToGLAttachment(Flags const &flags)
{
DENG2_ASSERT(!flags.testFlag(ColorDepth));
DENG2_ASSERT(!flags.testFlag(ColorDepthStencil));

return flags == Color? GL_COLOR_ATTACHMENT0 :
flags == Depth? GL_DEPTH_ATTACHMENT :
flags == Stencil? GL_STENCIL_ATTACHMENT :
GL_DEPTH_STENCIL_ATTACHMENT;
}


GLuint fbo;
GLuint renderBufs[MAX_ATTACHMENTS];
GLTexture *bufTextures[MAX_ATTACHMENTS];
Expand Down Expand Up @@ -253,6 +265,18 @@ DENG2_OBSERVES(Asset, Deletion)
allocRenderBuffers();
}

void replace(GLenum attachment, GLTexture &newTexture)
{
DENG2_ASSERT(self.isReady()); // must already be inited
DENG2_ASSERT(bufTextures[attachmentToId(attachment)] != 0); // must have an attachment already

glBindFramebuffer(GL_FRAMEBUFFER, fbo);
attachTexture(newTexture, attachment);

// Restore previous target.
GLState::current().target().glBind();
}

void validate()
{
if(isDefault())
Expand Down Expand Up @@ -462,6 +486,13 @@ GLTexture *GLTarget::attachedTexture(Flags const &attachment) const
return d->bufferTexture(attachment);
}

void GLTarget::replaceAttachment(Flags const &attachment, GLTexture &texture)
{
DENG2_ASSERT(!d->isDefault());

d->replace(d->flagsToGLAttachment(attachment), texture);
}

GLuint GLTarget::glName() const
{
return d->fbo;
Expand Down

0 comments on commit 9e012a9

Please sign in to comment.