#include "Rendering/RenderState.h" bool RenderState::Enable(GLenum cap) { if (glIsEnabled(cap)) { //LOG_WARNING("Trying to enable somthing that is already enabled."); return false; } m_ResetFunctions.push_back(std::bind(glDisable, cap)); glEnable(cap); return !GLERROR("Enable"); } bool RenderState::Disable(GLenum cap) { if (!glIsEnabled(cap)) { return false; } m_ResetFunctions.push_back(std::bind(glEnable, cap)); glDisable(cap); return !GLERROR("Disable"); } bool RenderState::CullFace(GLenum mode) { if (!glIsEnabled(GL_CULL_FACE)) { LOG_ERROR("Setting GL_CULL_FACE without enabling it."); return false; } GLint original; glGetIntegerv(GL_CULL_FACE_MODE, &original); m_ResetFunctions.push_back(std::bind(glCullFace, original)); glCullFace(mode); return !GLERROR("CullFace"); } bool RenderState::ClearColor(glm::vec4 color) { GLfloat original[4]; glGetFloatv(GL_COLOR_CLEAR_VALUE, &original[0]); m_ResetFunctions.push_back(std::bind(glClearColor, original[0], original[1], original[2], original[3])); glClearColor(color.r, color.g, color.b, color.a); return !GLERROR("ClearColor"); } bool RenderState::BindFramebuffer(GLint framebuffer) { GLint originalRead; glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &originalRead); GLint originalDraw; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &originalDraw); m_ResetFunctions.push_back([originalRead, originalDraw]() { glBindFramebuffer(GL_READ_FRAMEBUFFER, originalRead); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, originalDraw); }); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); return !GLERROR("BindBuffer"); } bool RenderState::BlendEquation(GLenum mode) { GLint originalRGB; glGetIntegerv(GL_BLEND_EQUATION_RGB, &originalRGB); GLint originalAlpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &originalAlpha); m_ResetFunctions.push_back(std::bind(glBlendEquationSeparate, originalRGB, originalAlpha)); glBlendEquation(mode); return !GLERROR("BlendEquation"); } bool RenderState::BlendFunc(GLenum sfactor, GLenum dfactor) { GLint originalSrcRGB; glGetIntegerv(GL_BLEND_SRC_RGB, &originalSrcRGB); GLint originalSrcAlpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &originalSrcAlpha); GLint originalDestRGB; glGetIntegerv(GL_BLEND_DST_RGB, &originalDestRGB); GLint originalDestAlpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &originalDestAlpha); m_ResetFunctions.push_back(std::bind(glBlendFuncSeparate, originalSrcRGB, originalSrcAlpha, originalDestRGB, originalDestAlpha)); glBlendFunc(sfactor, dfactor); return !GLERROR("BlendFunc"); } bool RenderState::StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) { GLint originalSFail; glGetIntegerv(GL_STENCIL_FAIL, &originalSFail); GLint originalDPFail; glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &originalDPFail); GLint originalDPPass; glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &originalDPPass); m_ResetFunctions.push_back(std::bind(glStencilOp, originalSFail, originalDPFail, originalDPPass)); glStencilOp(sfail, dpfail, dppass); return !GLERROR("StencilOp"); } bool RenderState::StencilFunc(GLenum func, GLint ref, GLuint mask) { GLint originalFunc; glGetIntegerv(GL_STENCIL_FUNC, &originalFunc); GLint originalRef; glGetIntegerv(GL_STENCIL_REF, &originalRef); GLint originalMask; glGetIntegerv(GL_STENCIL_VALUE_MASK, &originalMask); m_ResetFunctions.push_back(std::bind(glStencilFunc, originalFunc, originalRef, originalMask)); glStencilFunc(func, ref, mask); return !GLERROR("StencilFunc"); } bool RenderState::StencilMask(GLuint mask) { GLint originalMask; glGetIntegerv(GL_STENCIL_WRITEMASK, &originalMask); m_ResetFunctions.push_back(std::bind(glStencilMask, mask)); glStencilMask(mask); return !GLERROR("StencilMask"); } bool RenderState::DepthMask(GLboolean flag) { GLboolean original; glGetBooleanv(GL_DEPTH_WRITEMASK, &original); m_ResetFunctions.push_back(std::bind(glDepthMask, original)); glDepthMask(flag); return !GLERROR("DepthMask"); } bool RenderState::DepthFunc(GLenum func) { GLint original; glGetIntegerv(GL_DEPTH_FUNC, &original); m_ResetFunctions.push_back(std::bind(glDepthFunc, original)); glDepthFunc(func); return !GLERROR("DepthFunc"); } bool RenderState::AlphaFunc(GLenum func, GLclampf thresholder) { GLint originalFunc; glGetIntegerv(GL_ALPHA_TEST_FUNC, &originalFunc); GLint originalRef; glGetIntegerv(GL_ALPHA_TEST_REF, &originalRef); m_ResetFunctions.push_back(std::bind(glAlphaFunc, originalFunc, originalRef)); glAlphaFunc(func, thresholder); return !GLERROR("AlphaFunc"); } RenderState::~RenderState() { for (auto& f : boost::adaptors::reverse(m_ResetFunctions)) { f(); } }