1 /** @file glstate.h GL state. 2 * 3 * GL state management is abstracted inside this class to retain plausible 4 * independence from OpenGL as the underlying rendering API. Also, Direct3D 5 * uses object-based state management. 6 * 7 * @authors Copyright (c) 2013-2017 Jaakko Keränen <jaakko.keranen@iki.fi> 8 * 9 * @par License 10 * LGPL: http://www.gnu.org/licenses/lgpl.html 11 * 12 * <small>This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU Lesser General Public License as published by 14 * the Free Software Foundation; either version 3 of the License, or (at your 15 * option) any later version. This program is distributed in the hope that it 16 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 17 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 18 * General Public License for more details. You should have received a copy of 19 * the GNU Lesser General Public License along with this program; if not, see: 20 * http://www.gnu.org/licenses</small> 21 */ 22 23 #ifndef LIBGUI_GLSTATE_H 24 #define LIBGUI_GLSTATE_H 25 26 #include <de/libcore.h> 27 #include <de/Rectangle> 28 #include <utility> 29 30 #include "../GLInfo" 31 32 namespace de { 33 34 class GLFramebuffer; 35 36 namespace gl /// OpenGL constants, flags, and other definitions. 37 { 38 enum ColorMaskFlag { 39 WriteNone = 0, 40 WriteRed = 0x1, 41 WriteGreen = 0x2, 42 WriteBlue = 0x4, 43 WriteAlpha = 0x8, 44 WriteAll = WriteRed | WriteGreen | WriteBlue | WriteAlpha 45 }; 46 Q_DECLARE_FLAGS(ColorMask, ColorMaskFlag) 47 Q_DECLARE_OPERATORS_FOR_FLAGS(ColorMask) 48 49 enum Comparison { 50 Never, 51 Always, 52 Equal, 53 NotEqual, 54 Less, 55 Greater, 56 LessOrEqual, 57 GreaterOrEqual 58 }; 59 enum Blend { 60 Zero, 61 One, 62 SrcColor, 63 OneMinusSrcColor, 64 SrcAlpha, 65 OneMinusSrcAlpha, 66 DestColor, 67 OneMinusDestColor, 68 DestAlpha, 69 OneMinusDestAlpha 70 }; 71 typedef std::pair<Blend, Blend> BlendFunc; 72 enum BlendOp { 73 Add, 74 Subtract, 75 ReverseSubtract 76 }; 77 enum Cull { 78 None, 79 Front, 80 Back 81 }; 82 } // namespace gl 83 84 /** 85 * GL state. 86 * 87 * All manipulation of OpenGL state must occur through this class. If OpenGL 88 * state is changed manually, it will result in GLState not knowing about it, 89 * potentially leading to the incorrect state being in effect later on. 90 * 91 * GLState instances can either be created on demand with GLState::push(), or 92 * one can keep a GLState instance around for repeating use. The stack exists 93 * to aid structured drawing: it is not required to use the stack for all 94 * drawing. GLState::apply() can be called for any GLState instance to use it 95 * as the current GL state. 96 * 97 * @note The default viewport is (0,0)→(0,0). The viewport has to be set 98 * when the desired size is known (for instance when a Canvas is resized). 99 * 100 * @ingroup gl 101 */ 102 class LIBGUI_PUBLIC GLState 103 { 104 public: 105 /** 106 * Constructs a GL state with the default values for all properties. 107 */ 108 GLState(); 109 110 GLState(GLState const &other); 111 GLState &operator=(GLState const &other); 112 bool operator==(const GLState &); 113 114 GLState &setCull(gl::Cull mode); 115 GLState &setDepthTest(bool enable); 116 GLState &setDepthFunc(gl::Comparison func); 117 GLState &setDepthWrite(bool enable); 118 GLState &setAlphaTest(bool enable); 119 GLState &setAlphaLimit(float greaterThanValue); 120 GLState &setBlend(bool enable); 121 GLState &setBlendFunc(gl::Blend src, gl::Blend dest); 122 GLState &setBlendFunc(gl::BlendFunc func); 123 GLState &setBlendOp(gl::BlendOp op); 124 GLState &setColorMask(gl::ColorMask mask); 125 GLState &setTarget(GLFramebuffer &target); 126 GLState &setDefaultTarget(); 127 GLState &setViewport(Rectanglei const &viewportRect); 128 GLState &setViewport(Rectangleui const &viewportRect); 129 130 /** 131 * Sets a viewport using coordinates that have been normalized within the 132 * current render target. This is useful for operations that should be 133 * independent of target size. 134 * 135 * @param normViewportRect Normalized viewport rectangle. 136 */ 137 GLState &setNormalizedViewport(Rectanglef const &normViewportRect); 138 139 GLState &setScissor(Rectanglei const &scissorRect); 140 GLState &setScissor(Rectangleui const &scissorRect); 141 142 /** 143 * Sets a scissor using coordinates that have been normalized within the 144 * current viewport. 145 * 146 * @param normScissorRect Normalized scissor rectangle. 147 */ 148 GLState &setNormalizedScissor(Rectanglef const &normScissorRect); 149 150 GLState &clearScissor(); 151 152 gl::Cull cull() const; 153 bool depthTest() const; 154 gl::Comparison depthFunc() const; 155 bool depthWrite() const; 156 bool alphaTest() const; 157 float alphaLimit() const; 158 bool blend() const; 159 gl::Blend srcBlendFunc() const; 160 gl::Blend destBlendFunc() const; 161 gl::BlendFunc blendFunc() const; 162 gl::BlendOp blendOp() const; 163 gl::ColorMask colorMask() const; 164 GLFramebuffer &target() const; 165 Rectangleui viewport() const; 166 Rectanglef normalizedViewport() const; 167 bool scissor() const; 168 Rectangleui scissorRect() const; 169 170 /** 171 * Updates the OpenGL state to match this GLState. Until this is called no 172 * changes occur in the OpenGL state. Calling this more than once is 173 * allowed; the subsequent calls do nothing. 174 * 175 * @todo Remove excess calls to apply() once all direct GL1 state 176 * manipulation has been removed. 177 */ 178 void apply() const; 179 180 public: 181 /** 182 * Tells GLState to consider the native OpenGL state undefined, meaning 183 * that when the next GLState is applied, all properties need to be set 184 * rather than just the changed ones. 185 * 186 * @todo Remove this once all direct OpenGL state changes have been 187 * removed. 188 */ 189 static void considerNativeStateUndefined(); 190 191 /** 192 * Returns the current (i.e., topmost) state on the GL state stack. 193 */ 194 static GLState ¤t(); 195 196 /** 197 * Pushes a copy of the current state onto the current thread's GL state 198 * stack. 199 * 200 * @return Reference to the new state. 201 */ 202 static GLState &push(); 203 204 /** 205 * Pops the topmost state off the current thread's stack. Returns a reference 206 * to the state that has now become the new current state. 207 */ 208 static GLState &pop(); 209 210 /** 211 * Pushes a state onto the current thread's GL state stack. 212 * 213 * @param state State to push. Ownership taken. 214 */ 215 static void push(GLState *state); 216 217 /** 218 * Removes the topmost state off of the current thread's stack. 219 * 220 * @return State instance. Ownership given to caller. 221 */ 222 static GLState *take(); 223 224 static dsize stackDepth(); 225 226 private: 227 DENG2_PRIVATE(d) 228 }; 229 230 } // namespace de 231 232 #endif // LIBGUI_GLSTATE_H 233