From 4f5827605f8321015b9eec1570eaaaad76351c3e Mon Sep 17 00:00:00 2001 From: skyjake Date: Fri, 25 Oct 2013 13:01:58 +0300 Subject: [PATCH] API|GL: Public GL API now uses GLState for scissor; added push/pop state This commit fixes scissor-related issues when drawing stuff via the public GL API (e.g., game automap). The public GL API now internally uses GLState to set the scissor box. This fixes a GL state update conflict between legacy code and libgui based code. The public GL API now also has functions for pushing and popping GLState. The version number of the public GL API was incremented; old API is no longer supported. --- doomsday/api/api_gl.h | 16 +++--- doomsday/api/apis.h | 3 +- doomsday/client/src/gl/dgl_common.cpp | 53 ++++++++++---------- doomsday/client/src/gl/gl_draw.cpp | 27 ++++++---- doomsday/plugins/common/include/hu_automap.h | 4 +- doomsday/plugins/common/src/hu_automap.c | 24 +++++---- 6 files changed, 69 insertions(+), 58 deletions(-) diff --git a/doomsday/api/api_gl.h b/doomsday/api/api_gl.h index 228e36a43a..06c43f43b0 100644 --- a/doomsday/api/api_gl.h +++ b/doomsday/api/api_gl.h @@ -222,8 +222,8 @@ typedef struct { int availWidth, availHeight; boolean alignHorizontal; /// @c false: align vertically instead. float scaleFactor; - int scissorState; - RectRaw scissorRegion; + //int scissorState; + //RectRaw scissorRegion; } dgl_borderedprojectionstate_t; DENG_API_TYPEDEF(GL) @@ -232,6 +232,8 @@ DENG_API_TYPEDEF(GL) int (*Enable)(int cap); void (*Disable)(int cap); + void (*PushState)(void); + void (*PopState)(void); boolean (*GetIntegerv)(int name, int* vec); int (*GetInteger)(int name); @@ -242,11 +244,6 @@ DENG_API_TYPEDEF(GL) void (*Ortho)(float left, float top, float right, float bottom, float znear, float zfar); - /** - * Retrieve the current dimensions of the viewport scissor region. - */ - void (*Scissor)(RectRaw* rect); - /** * Change the current viewport scissor region. * @@ -256,7 +253,7 @@ DENG_API_TYPEDEF(GL) * @param rect Geometry of the new scissor region. Coordinates are * in viewport space. */ - void (*SetScissor)(const RectRaw* rect); + void (*SetScissor)(RectRaw const *rect); void (*SetScissor2)(int x, int y, int width, int height); void (*MatrixMode)(int mode); @@ -349,6 +346,8 @@ DENG_API_T(GL); #ifndef DENG_NO_API_MACROS_GL #define DGL_Enable _api_GL.Enable #define DGL_Disable _api_GL.Disable +#define DGL_PushState _api_GL.PushState +#define DGL_PopState _api_GL.PopState #define DGL_GetIntegerv _api_GL.GetIntegerv #define DGL_GetInteger _api_GL.GetInteger #define DGL_SetInteger _api_GL.SetInteger @@ -356,7 +355,6 @@ DENG_API_T(GL); #define DGL_GetFloat _api_GL.GetFloat #define DGL_SetFloat _api_GL.SetFloat #define DGL_Ortho _api_GL.Ortho -#define DGL_Scissor _api_GL.Scissor #define DGL_SetScissor _api_GL.SetScissor #define DGL_SetScissor2 _api_GL.SetScissor2 #define DGL_MatrixMode _api_GL.MatrixMode diff --git a/doomsday/api/apis.h b/doomsday/api/apis.h index 8ccb55d0ce..d7481352b7 100644 --- a/doomsday/api/apis.h +++ b/doomsday/api/apis.h @@ -83,7 +83,8 @@ enum { DE_API_FONT_RENDER = DE_API_FONT_RENDER_v1, DE_API_GL_v1 = 800, // 1.10 - DE_API_GL = DE_API_GL_v1, + DE_API_GL_v2 = 801, // 1.13 + DE_API_GL = DE_API_GL_v2, DE_API_INFINE_v1 = 900, // 1.10 DE_API_INFINE = DE_API_INFINE_v1, diff --git a/doomsday/client/src/gl/dgl_common.cpp b/doomsday/client/src/gl/dgl_common.cpp index 6e0b2bb0fa..41b614ddc0 100644 --- a/doomsday/client/src/gl/dgl_common.cpp +++ b/doomsday/client/src/gl/dgl_common.cpp @@ -371,10 +371,10 @@ DENG_EXTERN_C void DGL_SetScissor(RectRaw const *rect) DENG_ASSERT_IN_MAIN_THREAD(); DENG_ASSERT_GL_CONTEXT_ACTIVE(); - //glScissor(rect->origin.x, FLIP(rect->origin.y + rect->size.height - 1), rect->size.width, rect->size.height); - - GLState::top().setScissor(Rectangleui(rect->origin.x, rect->origin.y, - rect->size.width, rect->size.height)).apply(); + GLState::top().setNormalizedScissor( + ClientWindow::main().game().normalizedRect( + Rectanglei(rect->origin.x, rect->origin.y, + rect->size.width, rect->size.height))).apply(); } #undef DGL_SetScissor2 @@ -388,25 +388,6 @@ DENG_EXTERN_C void DGL_SetScissor2(int x, int y, int width, int height) DGL_SetScissor(&rect); } -#undef DGL_Scissor -DENG_EXTERN_C void DGL_Scissor(RectRaw *rect) -{ - if(!rect) return; - - DENG_ASSERT_IN_MAIN_THREAD(); - DENG_ASSERT_GL_CONTEXT_ACTIVE(); - - GLint v[4]; - glGetIntegerv(GL_SCISSOR_BOX, (GLint*)v); - // Y is flipped. - v[1] = FLIP(v[1] + v[3] - 1); - - rect->origin.x = v[0]; - rect->origin.y = v[1]; - rect->size.width = v[2]; - rect->size.height = v[3]; -} - #undef DGL_GetIntegerv boolean DGL_GetIntegerv(int name, int *v) { @@ -421,7 +402,8 @@ boolean DGL_GetIntegerv(int name, int *v) break; case DGL_SCISSOR_TEST: - glGetIntegerv(GL_SCISSOR_TEST, (GLint*) v); + //glGetIntegerv(GL_SCISSOR_TEST, (GLint*) v); + *(GLint *) v = GLState::top().scissor(); break; case DGL_FOG: @@ -579,6 +561,21 @@ boolean DGL_SetFloat(int name, float value) return true; } +#undef DGL_PushState +void DGL_PushState(void) +{ + GLState::push(); +} + +#undef DGL_PopState +void DGL_PopState(void) +{ + GLState::pop(); + + // Make sure the restored state is immediately in effect. + GLState::top().apply(); +} + #undef DGL_Enable int DGL_Enable(int cap) { @@ -599,7 +596,7 @@ int DGL_Enable(int cap) break; case DGL_SCISSOR_TEST: - glEnable(GL_SCISSOR_TEST); + //glEnable(GL_SCISSOR_TEST); break; case DGL_LINE_SMOOTH: @@ -635,7 +632,8 @@ void DGL_Disable(int cap) break; case DGL_SCISSOR_TEST: - glDisable(GL_SCISSOR_TEST); + //glDisable(GL_SCISSOR_TEST); + GLState::top().clearScissor().apply(); break; case DGL_LINE_SMOOTH: @@ -927,6 +925,8 @@ DENG_DECLARE_API(GL) = { DE_API_GL }, DGL_Enable, DGL_Disable, + DGL_PushState, + DGL_PopState, DGL_GetIntegerv, DGL_GetInteger, DGL_SetInteger, @@ -934,7 +934,6 @@ DENG_DECLARE_API(GL) = DGL_GetFloat, DGL_SetFloat, DGL_Ortho, - DGL_Scissor, DGL_SetScissor, DGL_SetScissor2, DGL_MatrixMode, diff --git a/doomsday/client/src/gl/gl_draw.cpp b/doomsday/client/src/gl/gl_draw.cpp index 2f2b9287db..13505850e1 100644 --- a/doomsday/client/src/gl/gl_draw.cpp +++ b/doomsday/client/src/gl/gl_draw.cpp @@ -33,6 +33,8 @@ #include "gl/sys_opengl.h" #include "api_render.h" +#include + using namespace de; static bool drawFilter = false; @@ -367,9 +369,11 @@ DENG_EXTERN_C void GL_ConfigureBorderedProjection2(dgl_borderedprojectionstate_t bp->alignHorizontal = R_ChooseAlignModeAndScaleFactor(&bp->scaleFactor, bp->width, bp->height, bp->availWidth, bp->availHeight, bp->scaleMode); + /* bp->scissorState = 0; bp->scissorRegion.origin.x = bp->scissorRegion.origin.y = 0; bp->scissorRegion.size.width = bp->scissorRegion.size.height = 0; + */ } #undef GL_ConfigureBorderedProjection @@ -409,17 +413,20 @@ DENG_EXTERN_C void GL_BeginBorderedProjection(dgl_borderedprojectionstate_t* bp) glMatrixMode(GL_MODELVIEW); glPushMatrix(); + + GLState::push(); + if(bp->alignHorizontal) { // "Pillarbox": if(bp->flags & BPF_OVERDRAW_CLIP) { int w = .5f + (bp->availWidth - bp->width * bp->scaleFactor) / 2; - bp->scissorState = DGL_GetInteger(DGL_SCISSOR_TEST); - DGL_Scissor(&bp->scissorRegion); + //bp->scissorState = DGL_GetInteger(DGL_SCISSOR_TEST); + //DGL_Scissor(&bp->scissorRegion); DGL_SetScissor2(DENG_GAMEVIEW_X + w, DENG_GAMEVIEW_Y, bp->width * bp->scaleFactor, bp->availHeight); - DGL_Enable(DGL_SCISSOR_TEST); + //DGL_Enable(DGL_SCISSOR_TEST); } glTranslatef((float)bp->availWidth/2, 0, 0); @@ -433,11 +440,11 @@ DENG_EXTERN_C void GL_BeginBorderedProjection(dgl_borderedprojectionstate_t* bp) if(bp->flags & BPF_OVERDRAW_CLIP) { int h = .5f + (bp->availHeight - bp->height * bp->scaleFactor) / 2; - bp->scissorState = DGL_GetInteger(DGL_SCISSOR_TEST); - DGL_Scissor(&bp->scissorRegion); + //bp->scissorState = DGL_GetInteger(DGL_SCISSOR_TEST); + //DGL_Scissor(&bp->scissorRegion); DGL_SetScissor2(DENG_GAMEVIEW_X, DENG_GAMEVIEW_Y + h, bp->availWidth, bp->height * bp->scaleFactor); - DGL_Enable(DGL_SCISSOR_TEST); + //DGL_Enable(DGL_SCISSOR_TEST); } glTranslatef(0, (float)bp->availHeight/2, 0); @@ -463,14 +470,16 @@ DENG_EXTERN_C void GL_EndBorderedProjection(dgl_borderedprojectionstate_t* bp) DENG_ASSERT_IN_MAIN_THREAD(); DENG_ASSERT_GL_CONTEXT_ACTIVE(); + GLState::pop(); + glMatrixMode(GL_MODELVIEW); glPopMatrix(); if(bp->flags & BPF_OVERDRAW_CLIP) { - if(!bp->scissorState) - DGL_Disable(DGL_SCISSOR_TEST); - DGL_SetScissor(&bp->scissorRegion); + //if(!bp->scissorState) + // DGL_Disable(DGL_SCISSOR_TEST); + //DGL_SetScissor(&bp->scissorRegion); } if(bp->flags & BPF_OVERDRAW_MASK) diff --git a/doomsday/plugins/common/include/hu_automap.h b/doomsday/plugins/common/include/hu_automap.h index c58a075a44..2ccbe15b4f 100644 --- a/doomsday/plugins/common/include/hu_automap.h +++ b/doomsday/plugins/common/include/hu_automap.h @@ -64,8 +64,8 @@ typedef struct { typedef struct { automapcfg_t* mcfg; - int scissorState; - RectRaw scissorRegion; + //int scissorState; + //RectRaw scissorRegion; // DGL display lists: DGLuint lists[NUM_MAP_OBJECTLISTS]; // Each list contains one or more of given type of automap obj. diff --git a/doomsday/plugins/common/src/hu_automap.c b/doomsday/plugins/common/src/hu_automap.c index 71bfd640e1..581ca9d24e 100644 --- a/doomsday/plugins/common/src/hu_automap.c +++ b/doomsday/plugins/common/src/hu_automap.c @@ -1173,10 +1173,10 @@ static void setupGLStateForMap(uiwidget_t* obj) Rect_Raw(obj->geometry, &geometry); - // Check for scissor box (to clip the map lines and stuff). - // Store the old scissor state. - am->scissorState = DGL_GetInteger(DGL_SCISSOR_TEST); - DGL_Scissor(&am->scissorRegion); + // Store the old scissor state (to clip the map lines and stuff). + //am->scissorState = DGL_GetInteger(DGL_SCISSOR_TEST); + //DGL_Scissor(&am->scissorRegion); + DGL_PushState(); DGL_MatrixMode(DGL_MODELVIEW); DGL_PushMatrix(); @@ -1314,7 +1314,7 @@ static void setupGLStateForMap(uiwidget_t* obj) clipRegion.size.height -= 2 * border; DGL_SetScissor(&clipRegion); - DGL_Enable(DGL_SCISSOR_TEST); + //DGL_Enable(DGL_SCISSOR_TEST); } } @@ -1323,11 +1323,15 @@ static void setupGLStateForMap(uiwidget_t* obj) */ static void restoreGLStateFromMap(uiwidget_t* obj) { - guidata_automap_t* am = (guidata_automap_t*)obj->typedata; - // Restore the previous scissor state. - if(!am->scissorState) - DGL_Disable(DGL_SCISSOR_TEST); - DGL_SetScissor(&am->scissorRegion); + DENG_UNUSED(obj); + + //guidata_automap_t* am = (guidata_automap_t*)obj->typedata; + //if(!am->scissorState) + //DGL_Disable(DGL_SCISSOR_TEST); + //DGL_SetScissor(&am->scissorRegion); + + // Restore the previous GL state. + DGL_PopState(); } static void renderVertexes(uiwidget_t* obj)