221 lines
5.8 KiB
C++
221 lines
5.8 KiB
C++
/* This file is part of the Pangolin Project.
|
|
* http://github.com/stevenlovegrove/Pangolin
|
|
*
|
|
* Copyright (c) 2013 Vincent Mamo, Steven Lovegrove
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* files (the "Software"), to deal in the Software without
|
|
* restriction, including without limitation the rights to use,
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following
|
|
* conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <pangolin/gl/glinclude.h>
|
|
#include <stack>
|
|
|
|
namespace pangolin
|
|
{
|
|
|
|
class GlState {
|
|
|
|
class CapabilityState {
|
|
public:
|
|
|
|
CapabilityState(GLenum cap, GLboolean enable)
|
|
: m_cap(cap), m_enable(enable)
|
|
{
|
|
|
|
}
|
|
|
|
void Apply() {
|
|
if(m_enable) {
|
|
::glEnable(m_cap);
|
|
}else{
|
|
::glDisable(m_cap);
|
|
}
|
|
}
|
|
|
|
void UnApply() {
|
|
if(m_enable) {
|
|
::glDisable(m_cap);
|
|
}else{
|
|
::glEnable(m_cap);
|
|
}
|
|
}
|
|
|
|
protected:
|
|
GLenum m_cap;
|
|
GLboolean m_enable;
|
|
};
|
|
|
|
public:
|
|
GlState()
|
|
: m_DepthMaskCalled(false),
|
|
m_ShadeModelCalled(false),
|
|
m_CullFaceCalled(false),
|
|
m_PointSizeCalled(false),
|
|
m_LineWidthCalled(false),
|
|
m_ColorMaskCalled(false),
|
|
m_ViewportCalled(false)
|
|
{
|
|
}
|
|
|
|
~GlState() {
|
|
// Restore original state
|
|
while (!m_history.empty()) {
|
|
m_history.top().UnApply();
|
|
m_history.pop();
|
|
}
|
|
|
|
if (m_DepthMaskCalled) {
|
|
::glDepthMask(m_OriginalDepthMask);
|
|
}
|
|
|
|
if (m_ShadeModelCalled) {
|
|
::glShadeModel(m_OriginalShadeModel);
|
|
}
|
|
|
|
if (m_CullFaceCalled) {
|
|
::glCullFace(m_OriginalCullFace);
|
|
}
|
|
|
|
if(m_PointSizeCalled) {
|
|
::glPointSize(m_OriginalPointSize);
|
|
}
|
|
|
|
if(m_LineWidthCalled) {
|
|
::glLineWidth(m_OriginalLineWidth);
|
|
}
|
|
|
|
if (m_ColorMaskCalled) {
|
|
::glColorMask(m_OriginalColorMask[0], m_OriginalColorMask[1], m_OriginalColorMask[2], m_OriginalColorMask[3]);
|
|
}
|
|
|
|
if (m_ViewportCalled) {
|
|
::glViewport(m_OriginalViewport[0], m_OriginalViewport[1], m_OriginalViewport[2], m_OriginalViewport[3]);
|
|
}
|
|
}
|
|
|
|
static inline GLboolean IsEnabled(GLenum cap)
|
|
{
|
|
GLboolean curVal;
|
|
glGetBooleanv(cap, &curVal);
|
|
return curVal;
|
|
}
|
|
|
|
inline void glEnable(GLenum cap)
|
|
{
|
|
if(!IsEnabled(cap)) {
|
|
m_history.push(CapabilityState(cap,true));
|
|
::glEnable(cap);
|
|
}
|
|
}
|
|
|
|
inline void glDisable(GLenum cap)
|
|
{
|
|
if(IsEnabled(cap)) {
|
|
m_history.push(CapabilityState(cap,false));
|
|
::glDisable(cap);
|
|
}
|
|
}
|
|
|
|
bool m_DepthMaskCalled;
|
|
GLboolean m_OriginalDepthMask;
|
|
inline void glDepthMask(GLboolean flag)
|
|
{
|
|
if(!m_DepthMaskCalled) {
|
|
m_DepthMaskCalled = true;
|
|
glGetBooleanv(GL_DEPTH_WRITEMASK, &m_OriginalDepthMask);
|
|
}
|
|
::glDepthMask(flag);
|
|
}
|
|
|
|
bool m_ShadeModelCalled;
|
|
GLint m_OriginalShadeModel;
|
|
inline void glShadeModel(GLint mode)
|
|
{
|
|
if(!m_ShadeModelCalled) {
|
|
m_ShadeModelCalled = true;
|
|
glGetIntegerv(GL_SHADE_MODEL, &m_OriginalShadeModel);
|
|
}
|
|
::glShadeModel(mode);
|
|
}
|
|
|
|
bool m_CullFaceCalled;
|
|
GLint m_OriginalCullFace;
|
|
void glCullFace(GLenum mode)
|
|
{
|
|
if(!m_ShadeModelCalled) {
|
|
m_ShadeModelCalled = true;
|
|
glGetIntegerv(GL_CULL_FACE_MODE, &m_OriginalCullFace);
|
|
}
|
|
::glCullFace(mode);
|
|
}
|
|
|
|
bool m_PointSizeCalled;
|
|
GLfloat m_OriginalPointSize;
|
|
void glPointSize(GLfloat size)
|
|
{
|
|
if(!m_PointSizeCalled) {
|
|
m_PointSizeCalled = true;
|
|
glGetFloatv(GL_POINT_SIZE, &m_OriginalPointSize);
|
|
}
|
|
::glPointSize(size);
|
|
}
|
|
|
|
bool m_LineWidthCalled;
|
|
GLfloat m_OriginalLineWidth;
|
|
void glLineWidth(GLfloat width)
|
|
{
|
|
if(!m_LineWidthCalled) {
|
|
m_LineWidthCalled = true;
|
|
glGetFloatv(GL_LINE_WIDTH, &m_OriginalLineWidth);
|
|
}
|
|
::glLineWidth(width);
|
|
|
|
}
|
|
|
|
bool m_ColorMaskCalled;
|
|
GLboolean m_OriginalColorMask[4];
|
|
inline void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
|
|
{
|
|
if(!m_ColorMaskCalled) {
|
|
m_ColorMaskCalled = true;
|
|
glGetBooleanv(GL_COLOR_WRITEMASK, m_OriginalColorMask);
|
|
}
|
|
::glColorMask(red, green, blue, alpha);
|
|
}
|
|
|
|
bool m_ViewportCalled;
|
|
GLint m_OriginalViewport[4];
|
|
inline void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
|
{
|
|
if(!m_ViewportCalled) {
|
|
m_ViewportCalled = true;
|
|
glGetIntegerv(GL_VIEWPORT, m_OriginalViewport);
|
|
}
|
|
::glViewport(x, y, width, height);
|
|
}
|
|
|
|
std::stack<CapabilityState> m_history;
|
|
};
|
|
|
|
}
|