Skip to content

Commit

Permalink
libgui|GLState: Scissor
Browse files Browse the repository at this point in the history
The scissor test can now be controlled via GLState.
  • Loading branch information
skyjake committed May 22, 2013
1 parent 3a86a50 commit 7007f9c
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 5 deletions.
7 changes: 6 additions & 1 deletion doomsday/libdeng2/include/de/rectangle.h
Expand Up @@ -58,7 +58,7 @@ class Rectangle
}
static RectangleType fromQRect(QRect const &qr) {
return RectangleType(qr.left(), qr.top(), qr.width(), qr.height());
}
}

SizeType width() const { return abs(bottomRight.x - topLeft.x); }
SizeType height() const { return abs(bottomRight.y - topLeft.y); }
Expand All @@ -85,6 +85,11 @@ class Rectangle
RectangleType adjusted(CornerVectorType const &tl, CornerVectorType const &br) const {
return RectangleType(topLeft + tl, bottomRight + br);
}
Rectangle<Vector2ui, Vector2ui> toRectangleui() const {
Vector2ui tl(duint(de::max(0, topLeft.x)), duint(de::max(0, topLeft.y)));
Vector2ui br(duint(de::max(0, bottomRight.x)), duint(de::max(0, bottomRight.y)));
return Rectangle<Vector2ui, Vector2ui>(tl, br);
}
bool contains(Corner const &point) const {
return point >= topLeft && point <= bottomRight;
}
Expand Down
5 changes: 5 additions & 0 deletions doomsday/libgui/include/de/gui/glstate.h
Expand Up @@ -109,6 +109,9 @@ class LIBGUI_PUBLIC GLState
GLState &setTarget(GLTarget &target);
GLState &setDefaultTarget();
GLState &setViewport(Rectangleui const &viewportRect);
GLState &setScissor(Rectanglei const &scissorRect);
GLState &setScissor(Rectangleui const &scissorRect);
GLState &clearScissor();

gl::Cull cull() const;
bool depthTest() const;
Expand All @@ -121,6 +124,8 @@ class LIBGUI_PUBLIC GLState
gl::BlendOp blendOp() const;
GLTarget &target() const;
Rectangleui viewport() const;
bool scissor() const;
Rectangleui scissorRect() const;

/**
* Updates the OpenGL state to match this GLState. Until this is called no
Expand Down
87 changes: 83 additions & 4 deletions doomsday/libgui/src/glstate.cpp
Expand Up @@ -38,6 +38,11 @@ namespace internal
BlendFuncSrc,
BlendFuncDest,
BlendOp,
Scissor,
ScissorX,
ScissorY,
ScissorWidth,
ScissorHeight,
ViewportX,
ViewportY,
ViewportWidth,
Expand Down Expand Up @@ -78,10 +83,15 @@ DENG2_PIMPL(GLState)
{ BlendFuncSrc, 4 },
{ BlendFuncDest, 4 },
{ BlendOp, 2 },
{ ViewportX, 12 }, // 4096 max
{ ViewportY, 12 }, // 4096 max
{ ViewportWidth, 12 }, // 4096 max
{ ViewportHeight, 12 } // 4096 max
{ Scissor, 1 },
{ ScissorX, 12 }, // 12 bits == 4096 max
{ ScissorY, 12 },
{ ScissorWidth, 12 },
{ ScissorHeight, 12 },
{ ViewportX, 12 },
{ ViewportY, 12 },
{ ViewportWidth, 12 },
{ ViewportHeight, 12 }
};
props.addElements(propSpecs, MAX_PROPERTIES);
}
Expand Down Expand Up @@ -192,6 +202,28 @@ DENG2_PIMPL(GLState)
}
break;

case Scissor:
case ScissorX:
case ScissorY:
case ScissorWidth:
case ScissorHeight:
{
if(self.scissor())
{
glEnable(GL_SCISSOR_TEST);

Rectangleui scr = self.scissorRect();
glScissor(scr.left(), self.target().size().y - scr.bottom(),
scr.width(), scr.height());
//glScissor(scr.left(), scr.top(), scr.width(), scr.height());
}
else
{
glDisable(GL_SCISSOR_TEST);
}
break;
}

case ViewportX:
case ViewportY:
case ViewportWidth:
Expand All @@ -215,6 +247,15 @@ DENG2_PIMPL(GLState)
changed.remove(BlendFuncDest);
}

if(changed.contains(ScissorX) || changed.contains(ScissorY) ||
changed.contains(ScissorWidth) || changed.contains(ScissorHeight))
{
changed.insert(ScissorX);
changed.remove(ScissorY);
changed.remove(ScissorWidth);
changed.remove(ScissorHeight);
}

if(changed.contains(ViewportX) || changed.contains(ViewportY) ||
changed.contains(ViewportWidth) || changed.contains(ViewportHeight))
{
Expand Down Expand Up @@ -313,6 +354,31 @@ GLState &GLState::setViewport(Rectangleui const &viewportRect)
return *this;
}

GLState &GLState::setScissor(Rectanglei const &scissorRect)
{
return setScissor(scissorRect.toRectangleui());
}

GLState &GLState::setScissor(Rectangleui const &scissorRect)
{
d->props.set(Scissor, true);
d->props.set(ScissorX, scissorRect.left());
d->props.set(ScissorY, scissorRect.top());
d->props.set(ScissorWidth, scissorRect.width());
d->props.set(ScissorHeight, scissorRect.height());
return *this;
}

GLState &GLState::clearScissor()
{
d->props.set(Scissor, false);
d->props.set(ScissorX, 0u);
d->props.set(ScissorY, 0u);
d->props.set(ScissorWidth, 0u);
d->props.set(ScissorHeight, 0u);
return *this;
}

gl::Cull GLState::cull() const
{
return d->props.valueAs<gl::Cull>(CullMode);
Expand Down Expand Up @@ -375,6 +441,19 @@ Rectangleui GLState::viewport() const
d->props[ViewportHeight]);
}

bool GLState::scissor() const
{
return d->props.asBool(Scissor);
}

Rectangleui GLState::scissorRect() const
{
return Rectangleui(d->props[ScissorX],
d->props[ScissorY],
d->props[ScissorWidth],
d->props[ScissorHeight]);
}

void GLState::apply() const
{
// Update the render target.
Expand Down

0 comments on commit 7007f9c

Please sign in to comment.