Skip to content

Commit

Permalink
API|GL: Public GL API now uses GLState for scissor; added push/pop state
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
skyjake committed Oct 25, 2013
1 parent 8eb4904 commit 4f58276
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 58 deletions.
16 changes: 7 additions & 9 deletions doomsday/api/api_gl.h
Expand Up @@ -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)
Expand All @@ -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);
Expand All @@ -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.
*
Expand All @@ -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);
Expand Down Expand Up @@ -349,14 +346,15 @@ 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
#define DGL_GetFloatv _api_GL.GetFloatv
#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
Expand Down
3 changes: 2 additions & 1 deletion doomsday/api/apis.h
Expand Up @@ -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,
Expand Down
53 changes: 26 additions & 27 deletions doomsday/client/src/gl/dgl_common.cpp
Expand Up @@ -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
Expand All @@ -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)
{
Expand All @@ -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:
Expand Down Expand Up @@ -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)
{
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -927,14 +925,15 @@ DENG_DECLARE_API(GL) =
{ DE_API_GL },
DGL_Enable,
DGL_Disable,
DGL_PushState,
DGL_PopState,
DGL_GetIntegerv,
DGL_GetInteger,
DGL_SetInteger,
DGL_GetFloatv,
DGL_GetFloat,
DGL_SetFloat,
DGL_Ortho,
DGL_Scissor,
DGL_SetScissor,
DGL_SetScissor2,
DGL_MatrixMode,
Expand Down
27 changes: 18 additions & 9 deletions doomsday/client/src/gl/gl_draw.cpp
Expand Up @@ -33,6 +33,8 @@
#include "gl/sys_opengl.h"
#include "api_render.h"

#include <de/GLState>

using namespace de;

static bool drawFilter = false;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions doomsday/plugins/common/include/hu_automap.h
Expand Up @@ -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.
Expand Down
24 changes: 14 additions & 10 deletions doomsday/plugins/common/src/hu_automap.c
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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)
Expand Down

0 comments on commit 4f58276

Please sign in to comment.