Skip to content

Commit

Permalink
UPBGE: Fix default frame buffer object restored when creating an off …
Browse files Browse the repository at this point in the history
…screen.

Previously when an off screen was created the default frame buffer object
was restored because the constructor function assumed that no frame buffer
object was bound before.

To fix this issue in the OffScreens class in the OpenGL rasterizer, we store
the current off screen index before create an off screen and then restore
this off screen after the creation if its index is not -1.
Also the RestoreScreen (previously named RestoreScreenFrameBuffer) now set
the current off screen index to -1 for the check explained above.

An other bug noticed was for blit off screen just after theirs creation.
Indeed an off screen just created doesn't have a valid draw/read buffer state
which failed the blit. To fix this issue we set the draw/read buffer in the
blit function as for simple bind function.
  • Loading branch information
panzergame committed Aug 24, 2016
1 parent 6df1e38 commit 1f23323
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 10 deletions.
3 changes: 3 additions & 0 deletions source/blender/gpu/intern/gpu_framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,9 @@ void GPU_offscreen_blit(GPUOffScreen *srcofs, GPUOffScreen *dstofs)
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, srcofs->fb->object);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dstofs->fb->object);

glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);

int height = min_ff(GPU_offscreen_height(srcofs), GPU_offscreen_height(dstofs));
int width = min_ff(GPU_offscreen_width(srcofs), GPU_offscreen_width(dstofs));

Expand Down
2 changes: 0 additions & 2 deletions source/gameengine/Rasterizer/RAS_IRasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,6 @@ class RAS_IRasterizer
virtual void UpdateOffScreens(RAS_ICanvas *canvas) = 0;
/// Bind the off screen at the given index.
virtual void BindOffScreen(unsigned short index) = 0;
/// Unbind the off screen at the given index.
virtual void RestoreScreenFrameBuffer() = 0;

/** Draw off screen without set viewport.
* Used to copy the frame buffer object to another.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ RAS_OpenGLRasterizer::OffScreens::~OffScreens()

GPUOffScreen *RAS_OpenGLRasterizer::OffScreens::GetOffScreen(unsigned short index)
{
const short lastIndex = m_currentIndex;

if (!m_offScreens[index]) {
// The offscreen need to be created now.

Expand Down Expand Up @@ -247,8 +249,16 @@ GPUOffScreen *RAS_OpenGLRasterizer::OffScreens::GetOffScreen(unsigned short inde
break;
}
}

/* Creating an off screen restore the default frame buffer object.
* We have to rebind the last off screen. */
if (lastIndex != -1) {
Bind(lastIndex);
}
}

BLI_assert(lastIndex == m_currentIndex);

return m_offScreens[index];
}

Expand Down Expand Up @@ -304,6 +314,13 @@ inline void RAS_OpenGLRasterizer::OffScreens::Bind(unsigned short index)
m_currentIndex = index;
}

inline void RAS_OpenGLRasterizer::OffScreens::RestoreScreen()
{
GPU_framebuffer_restore();

m_currentIndex = -1;
}

inline void RAS_OpenGLRasterizer::OffScreens::Blit(unsigned short srcindex, unsigned short dstindex)
{
GPU_offscreen_blit(GetOffScreen(srcindex), GetOffScreen(dstindex));
Expand Down Expand Up @@ -854,11 +871,6 @@ void RAS_OpenGLRasterizer::BindOffScreen(unsigned short index)
m_offScreens.Bind(index);
}

void RAS_OpenGLRasterizer::RestoreScreenFrameBuffer()
{
GPU_framebuffer_restore();
}

void RAS_OpenGLRasterizer::DrawOffScreen(unsigned short srcindex, unsigned short dstindex)
{
if (m_offScreens.GetSamples(srcindex) == 0) {
Expand Down Expand Up @@ -894,7 +906,7 @@ void RAS_OpenGLRasterizer::DrawOffScreen(RAS_ICanvas *canvas, unsigned short ind

SetDepthFunc(RAS_ALWAYS);

RestoreScreenFrameBuffer();
m_offScreens.RestoreScreen();
DrawOffScreen(index, 0);

SetDepthFunc(RAS_LEQUAL);
Expand All @@ -920,7 +932,7 @@ void RAS_OpenGLRasterizer::DrawStereoOffScreen(RAS_ICanvas *canvas, unsigned sho

SetDepthFunc(RAS_ALWAYS);

RestoreScreenFrameBuffer();
m_offScreens.RestoreScreen();

if (m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED) {
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_STEREO_STIPPLE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer

void Update(RAS_ICanvas *canvas);
void Bind(unsigned short index);
void RestoreScreen();
/// NOTE: This function has the side effect to leave the destination off screen bound.
void Blit(unsigned short srcindex, unsigned short dstindex);
void BindTexture(unsigned short index, unsigned short slot, OffScreen type);
Expand Down Expand Up @@ -247,7 +248,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer

virtual void UpdateOffScreens(RAS_ICanvas *canvas);
virtual void BindOffScreen(unsigned short index);
virtual void RestoreScreenFrameBuffer();
virtual void DrawOffScreen(unsigned short srcindex, unsigned short dstindex);
virtual void DrawOffScreen(RAS_ICanvas *canvas, unsigned short index);
virtual void DrawStereoOffScreen(RAS_ICanvas *canvas, unsigned short lefteyeindex, unsigned short righteyeindex);
Expand Down

0 comments on commit 1f23323

Please sign in to comment.