| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the Qt Data Visualization module of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 or (at your option) any later version | 
| 20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by | 
| 21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 | 
| 22 | ** included in the packaging of this file. Please review the following | 
| 23 | ** information to ensure the GNU General Public License requirements will | 
| 24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 25 | ** | 
| 26 | ** $QT_END_LICENSE$ | 
| 27 | ** | 
| 28 | ****************************************************************************/ | 
| 29 |  | 
| 30 | #include "glstatestore_p.h" | 
| 31 | #include <QDebug> | 
| 32 | #include <QColor> | 
| 33 | #include <QFile> | 
| 34 |  | 
| 35 | #ifdef VERBOSE_STATE_STORE | 
| 36 | static QFile *beforeFile = 0; | 
| 37 | static QFile *afterFile = 0; | 
| 38 | #endif | 
| 39 |  | 
| 40 | GLStateStore::GLStateStore(QOpenGLContext *context, QObject *parent) : | 
| 41 |     QObject(parent), | 
| 42 |     QOpenGLFunctions(context) | 
| 43 |   #ifdef VERBOSE_STATE_STORE | 
| 44 |   , m_map(EnumToStringMap::newInstance()) | 
| 45 |   #endif | 
| 46 | { | 
| 47 |     GLint maxVertexAttribs; | 
| 48 |     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, params: &maxVertexAttribs); | 
| 49 |  | 
| 50 | #ifdef VERBOSE_STATE_STORE | 
| 51 |     qDebug() << "GL_MAX_VERTEX_ATTRIBS: "  << maxVertexAttribs; | 
| 52 |     if (!beforeFile) { | 
| 53 |         beforeFile = new QFile(QStringLiteral("state_before.txt" )); | 
| 54 |         afterFile = new QFile(QStringLiteral("state_after.txt" )); | 
| 55 |         beforeFile->open(QIODevice::WriteOnly); | 
| 56 |         afterFile->open(QIODevice::WriteOnly); | 
| 57 |         QDebug beforeInit(beforeFile); | 
| 58 |         QDebug afterInit(afterFile); | 
| 59 |         beforeInit << "GL states before 'context switch'"  << endl; | 
| 60 |         afterInit << "GL states after 'context switch'"  << endl; | 
| 61 |     } | 
| 62 | #endif | 
| 63 |  | 
| 64 |     m_maxVertexAttribs = qMin(a: maxVertexAttribs, b: 2); // Datavis only uses 2 attribs max | 
| 65 |     m_vertexAttribArrayEnabledStates.reset(other: new GLint[maxVertexAttribs]); | 
| 66 |     m_vertexAttribArrayBoundBuffers.reset(other: new GLint[maxVertexAttribs]); | 
| 67 |     m_vertexAttribArraySizes.reset(other: new GLint[maxVertexAttribs]); | 
| 68 |     m_vertexAttribArrayTypes.reset(other: new GLint[maxVertexAttribs]); | 
| 69 |     m_vertexAttribArrayNormalized.reset(other: new GLint[maxVertexAttribs]); | 
| 70 |     m_vertexAttribArrayStrides.reset(other: new GLint[maxVertexAttribs]); | 
| 71 |     m_vertexAttribArrayOffsets.reset(other: new void *[maxVertexAttribs]); | 
| 72 |  | 
| 73 |     initGLDefaultState(); | 
| 74 | } | 
| 75 |  | 
| 76 | GLStateStore::~GLStateStore() | 
| 77 | { | 
| 78 | #ifdef VERBOSE_STATE_STORE | 
| 79 |     EnumToStringMap::deleteInstance(); | 
| 80 |     m_map = 0; | 
| 81 | #endif | 
| 82 | } | 
| 83 |  | 
| 84 | void GLStateStore::storeGLState() | 
| 85 | { | 
| 86 | #ifdef VERBOSE_STATE_STORE | 
| 87 |     printCurrentState(true); | 
| 88 | #endif | 
| 89 |  | 
| 90 | #if !defined(QT_OPENGL_ES_2) | 
| 91 |     glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, params: &m_drawFramebuffer); | 
| 92 |     glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, params: &m_readFramebuffer); | 
| 93 |     glGetIntegerv(GL_RENDERBUFFER_BINDING, params: &m_renderbuffer); | 
| 94 | #endif | 
| 95 |     glGetFloatv(GL_COLOR_CLEAR_VALUE, params: m_clearColor); | 
| 96 |     m_isBlendingEnabled = glIsEnabled(GL_BLEND); | 
| 97 |     m_isDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST); | 
| 98 |     glGetBooleanv(GL_DEPTH_WRITEMASK, params: &m_isDepthWriteEnabled); | 
| 99 |     glGetFloatv(GL_DEPTH_CLEAR_VALUE, params: &m_clearDepth); | 
| 100 |     glGetIntegerv(GL_DEPTH_FUNC, params: &m_depthFunc); | 
| 101 |     glGetBooleanv(GL_POLYGON_OFFSET_FILL, params: &m_polygonOffsetFillEnabled); | 
| 102 |     glGetFloatv(GL_POLYGON_OFFSET_FACTOR, params: &m_polygonOffsetFactor); | 
| 103 |     glGetFloatv(GL_POLYGON_OFFSET_UNITS, params: &m_polygonOffsetUnits); | 
| 104 |  | 
| 105 |     glGetIntegerv(GL_CURRENT_PROGRAM, params: &m_currentProgram); | 
| 106 |     glGetIntegerv(GL_ACTIVE_TEXTURE, params: &m_activeTexture); | 
| 107 |     glGetIntegerv(GL_TEXTURE_BINDING_2D, params: &m_texBinding2D); | 
| 108 |     glGetIntegerv(GL_FRONT_FACE, params: &m_frontFace); | 
| 109 |     m_isCullFaceEnabled = glIsEnabled(GL_CULL_FACE); | 
| 110 |     glGetIntegerv(GL_CULL_FACE_MODE, params: &m_cullFaceMode); | 
| 111 |     glGetIntegerv(GL_BLEND_EQUATION_RGB, params: &m_blendEquationRGB); | 
| 112 |     glGetIntegerv(GL_BLEND_EQUATION_ALPHA, params: &m_blendEquationAlpha); | 
| 113 |     glGetIntegerv(GL_BLEND_DST_ALPHA, params: &m_blendDestAlpha); | 
| 114 |     glGetIntegerv(GL_BLEND_DST_RGB, params: &m_blendDestRGB); | 
| 115 |     glGetIntegerv(GL_BLEND_SRC_ALPHA, params: &m_blendSrcAlpha); | 
| 116 |     glGetIntegerv(GL_BLEND_SRC_RGB, params: &m_blendSrcRGB); | 
| 117 |     glGetIntegerv(GL_SCISSOR_BOX, params: m_scissorBox); | 
| 118 |     m_isScissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); | 
| 119 |  | 
| 120 |     glGetIntegerv(GL_ARRAY_BUFFER_BINDING, params: &m_boundArrayBuffer); | 
| 121 |     glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, params: &m_boundElementArrayBuffer); | 
| 122 |  | 
| 123 |     for (int i = 0; i < m_maxVertexAttribs;i++) { | 
| 124 |         glGetVertexAttribiv(index: i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, | 
| 125 |                             params: &m_vertexAttribArrayEnabledStates[i]); | 
| 126 |         glGetVertexAttribiv(index: i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, | 
| 127 |                             params: &m_vertexAttribArrayBoundBuffers[i]); | 
| 128 |         glGetVertexAttribiv(index: i, GL_VERTEX_ATTRIB_ARRAY_SIZE, params: &m_vertexAttribArraySizes[i]); | 
| 129 |         glGetVertexAttribiv(index: i, GL_VERTEX_ATTRIB_ARRAY_TYPE, params: &m_vertexAttribArrayTypes[i]); | 
| 130 |         glGetVertexAttribiv(index: i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, | 
| 131 |                             params: &m_vertexAttribArrayNormalized[i]); | 
| 132 |         glGetVertexAttribiv(index: i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, params: &m_vertexAttribArrayStrides[i]); | 
| 133 |     } | 
| 134 | } | 
| 135 |  | 
| 136 | #ifdef VERBOSE_STATE_STORE | 
| 137 | void GLStateStore::printCurrentState(bool in) | 
| 138 | { | 
| 139 |     QFile *file; | 
| 140 |     if (in) | 
| 141 |         file = beforeFile; | 
| 142 |     else | 
| 143 |         file = afterFile; | 
| 144 |  | 
| 145 |     if (file->isOpen()) { | 
| 146 |         QDebug msg(file); | 
| 147 | #if !defined(QT_OPENGL_ES_2) | 
| 148 |         GLint drawFramebuffer; | 
| 149 |         GLint readFramebuffer; | 
| 150 |         GLint renderbuffer; | 
| 151 | #endif | 
| 152 |         GLfloat clearColor[4]; | 
| 153 |         GLfloat clearDepth; | 
| 154 |         GLboolean isBlendingEnabled = glIsEnabled(GL_BLEND); | 
| 155 |         GLboolean isDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST); | 
| 156 |         GLint depthFunc; | 
| 157 |         GLboolean isDepthWriteEnabled; | 
| 158 |         GLint currentProgram; | 
| 159 |         GLint *vertexAttribArrayEnabledStates = new GLint[m_maxVertexAttribs]; | 
| 160 |         GLint *vertexAttribArrayBoundBuffers = new GLint[m_maxVertexAttribs]; | 
| 161 |         GLint *vertexAttribArraySizes = new GLint[m_maxVertexAttribs]; | 
| 162 |         GLint *vertexAttribArrayTypes = new GLint[m_maxVertexAttribs]; | 
| 163 |         GLint *vertexAttribArrayNormalized = new GLint[m_maxVertexAttribs]; | 
| 164 |         GLint *vertexAttribArrayStrides = new GLint[m_maxVertexAttribs]; | 
| 165 |         GLint activeTexture; | 
| 166 |         GLint texBinding2D; | 
| 167 |         GLint arrayBufferBinding; | 
| 168 |         GLint frontFace; | 
| 169 |         GLboolean isCullFaceEnabled = glIsEnabled(GL_CULL_FACE); | 
| 170 |         GLint cullFaceMode; | 
| 171 |         GLint blendEquationRGB; | 
| 172 |         GLint blendEquationAlpha; | 
| 173 |  | 
| 174 |         GLint blendDestAlpha; | 
| 175 |         GLint blendDestRGB; | 
| 176 |         GLint blendSrcAlpha; | 
| 177 |         GLint blendSrcRGB; | 
| 178 |         GLint scissorBox[4]; | 
| 179 |         GLboolean isScissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); | 
| 180 |         GLint boundElementArrayBuffer; | 
| 181 |         GLboolean polygonOffsetFillEnabled; | 
| 182 |         GLfloat polygonOffsetFactor; | 
| 183 |         GLfloat polygonOffsetUnits; | 
| 184 |  | 
| 185 |         glGetBooleanv(GL_DEPTH_WRITEMASK, &isDepthWriteEnabled); | 
| 186 | #if !defined(QT_OPENGL_ES_2) | 
| 187 |         glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFramebuffer); | 
| 188 |         glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFramebuffer); | 
| 189 |         glGetIntegerv(GL_RENDERBUFFER_BINDING, &renderbuffer); | 
| 190 | #endif | 
| 191 |         glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor); | 
| 192 |         glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth); | 
| 193 |         glGetIntegerv(GL_DEPTH_FUNC, &depthFunc); | 
| 194 |         glGetBooleanv(GL_POLYGON_OFFSET_FILL, &polygonOffsetFillEnabled); | 
| 195 |         glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &polygonOffsetFactor); | 
| 196 |         glGetFloatv(GL_POLYGON_OFFSET_UNITS, &polygonOffsetUnits); | 
| 197 |  | 
| 198 |         glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); | 
| 199 |         glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); | 
| 200 |         glGetIntegerv(GL_TEXTURE_BINDING_2D, &texBinding2D ); | 
| 201 |         glGetIntegerv(GL_FRONT_FACE, &frontFace); | 
| 202 |         glGetIntegerv(GL_CULL_FACE_MODE, &cullFaceMode); | 
| 203 |         glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); | 
| 204 |         glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); | 
| 205 |         glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); | 
| 206 |         glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB); | 
| 207 |         glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); | 
| 208 |         glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB); | 
| 209 |         glGetIntegerv(GL_SCISSOR_BOX, scissorBox); | 
| 210 |         glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &boundElementArrayBuffer); | 
| 211 |         glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBufferBinding); | 
| 212 |  | 
| 213 |         for (int i = 0; i < m_maxVertexAttribs;i++) { | 
| 214 |             glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, | 
| 215 |                                 &vertexAttribArrayEnabledStates[i]); | 
| 216 |             glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, | 
| 217 |                                 &vertexAttribArrayBoundBuffers[i]); | 
| 218 |             glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertexAttribArraySizes[i]); | 
| 219 |             glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertexAttribArrayTypes[i]); | 
| 220 |             glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, | 
| 221 |                                 &vertexAttribArrayNormalized[i]); | 
| 222 |             glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertexAttribArrayStrides[i]); | 
| 223 |         } | 
| 224 |  | 
| 225 |         QColor color; | 
| 226 |         color.setRgbF(clearColor[0], clearColor[1], clearColor[2]); | 
| 227 |         color.setAlphaF(clearColor[3]); | 
| 228 |  | 
| 229 | #if !defined(QT_OPENGL_ES_2) | 
| 230 |         msg << "---"  << endl; | 
| 231 |         msg << "    GL_DRAW_FRAMEBUFFER_BINDING " << drawFramebuffer << endl; | 
| 232 |         msg << "    GL_READ_FRAMEBUFFER_BINDING " << readFramebuffer << endl; | 
| 233 |         msg << "    GL_RENDERBUFFER_BINDING "  << renderbuffer << endl; | 
| 234 | #endif | 
| 235 |         msg << "    GL_SCISSOR_TEST "  << bool(isScissorTestEnabled) << endl; | 
| 236 |         msg << "    GL_SCISSOR_BOX "  << m_scissorBox[0] << m_scissorBox[1] << m_scissorBox[2] | 
| 237 |             << m_scissorBox[3] << endl; | 
| 238 |         msg << "    GL_COLOR_CLEAR_VALUE " << color << endl; | 
| 239 |         msg << "    GL_DEPTH_CLEAR_VALUE " << clearDepth << endl; | 
| 240 |         msg << "    GL_BLEND " << bool(isBlendingEnabled) << endl; | 
| 241 |         msg << "    GL_BLEND_EQUATION_RGB"  << m_map->lookUp(blendEquationRGB) << endl; | 
| 242 |         msg << "    GL_BLEND_EQUATION_ALPHA"  << m_map->lookUp(blendEquationAlpha) << endl; | 
| 243 |         msg << "    GL_BLEND_DST_ALPHA"  << m_map->lookUp(blendDestAlpha) << endl; | 
| 244 |         msg << "    GL_BLEND_DST_RGB"  << m_map->lookUp(blendDestRGB) << endl; | 
| 245 |         msg << "    GL_BLEND_SRC_ALPHA"  << m_map->lookUp(blendSrcAlpha) << endl; | 
| 246 |         msg << "    GL_BLEND_SRC_RGB"  << m_map->lookUp(blendSrcRGB) << endl; | 
| 247 |         msg << "    GL_DEPTH_TEST " << bool(isDepthTestEnabled) << endl; | 
| 248 |         msg << "    GL_DEPTH_WRITEMASK " << bool(isDepthWriteEnabled) << endl; | 
| 249 |         msg << "    GL_POLYGON_OFFSET_FILL"  << bool(polygonOffsetFillEnabled) << endl; | 
| 250 |         msg << "    GL_POLYGON_OFFSET_FACTOR " << polygonOffsetFactor << endl; | 
| 251 |         msg << "    GL_POLYGON_OFFSET_UNITS " << polygonOffsetUnits << endl; | 
| 252 |         msg << "    GL_CULL_FACE " << bool(isCullFaceEnabled) << endl; | 
| 253 |         msg << "    GL_CULL_FACE_MODE " << m_map->lookUp(cullFaceMode) << endl; | 
| 254 |         msg << "    GL_DEPTH_FUNC " << m_map->lookUp(depthFunc) << endl; | 
| 255 |         msg << "    GL_FRONT_FACE " << m_map->lookUp(frontFace) << endl; | 
| 256 |         msg << "    GL_CURRENT_PROGRAM " << currentProgram << endl; | 
| 257 |         msg << "    GL_ACTIVE_TEXTURE " << QString("0x%1" ).arg(activeTexture, 0, 16) << endl; | 
| 258 |         msg << "    GL_TEXTURE_BINDING_2D " << texBinding2D << endl; | 
| 259 |         msg << "    GL_ELEMENT_ARRAY_BUFFER_BINDING " << boundElementArrayBuffer << endl; | 
| 260 |         msg << "    GL_ARRAY_BUFFER_BINDING " << arrayBufferBinding << endl; | 
| 261 |         for (int i = 0; i < m_maxVertexAttribs;i++) { | 
| 262 |             msg << "    GL_VERTEX_ATTRIB_ARRAY_ENABLED " << i << "       = "  | 
| 263 |                 <<  bool(vertexAttribArrayEnabledStates[i]) << endl; | 
| 264 |             msg << "    GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING" << i << " = "  | 
| 265 |                 <<  vertexAttribArrayBoundBuffers[i] << endl; | 
| 266 |             msg << "    GL_VERTEX_ATTRIB_ARRAY_SIZE" << i << " = "  | 
| 267 |                 <<  vertexAttribArraySizes[i] << endl; | 
| 268 |             msg << "    GL_VERTEX_ATTRIB_ARRAY_TYPE" << i << " = "  | 
| 269 |                 <<  vertexAttribArrayTypes[i] << endl; | 
| 270 |             msg << "    GL_VERTEX_ATTRIB_ARRAY_NORMALIZED" << i << " = "  | 
| 271 |                 <<  vertexAttribArrayNormalized[i] << endl; | 
| 272 |             msg << "    GL_VERTEX_ATTRIB_ARRAY_STRIDE" << i << " = "  | 
| 273 |                 <<  vertexAttribArrayStrides[i] << endl; | 
| 274 |         } | 
| 275 |     } | 
| 276 | } | 
| 277 | #endif | 
| 278 |  | 
| 279 | void GLStateStore::restoreGLState() | 
| 280 | { | 
| 281 | #if !defined(QT_OPENGL_ES_2) | 
| 282 |     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer: m_readFramebuffer); | 
| 283 |     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: m_drawFramebuffer); | 
| 284 |     glBindRenderbuffer(GL_RENDERBUFFER_BINDING, renderbuffer: m_renderbuffer); | 
| 285 | #endif | 
| 286 |  | 
| 287 |     if (m_isScissorTestEnabled) | 
| 288 |         glEnable(GL_SCISSOR_TEST); | 
| 289 |     else | 
| 290 |         glDisable(GL_SCISSOR_TEST); | 
| 291 |  | 
| 292 |     glScissor(x: m_scissorBox[0], y: m_scissorBox[1], width: m_scissorBox[2], height: m_scissorBox[3]); | 
| 293 |     glClearColor(red: m_clearColor[0], green: m_clearColor[1], blue: m_clearColor[2], alpha: m_clearColor[3]); | 
| 294 |     glClearDepthf(depth: m_clearDepth); | 
| 295 |     if (m_isBlendingEnabled) | 
| 296 |         glEnable(GL_BLEND); | 
| 297 |     else | 
| 298 |         glDisable(GL_BLEND); | 
| 299 |  | 
| 300 |     if (m_isDepthTestEnabled) | 
| 301 |         glEnable(GL_DEPTH_TEST); | 
| 302 |     else | 
| 303 |         glDisable(GL_DEPTH_TEST); | 
| 304 |  | 
| 305 |     if (m_isCullFaceEnabled) | 
| 306 |         glEnable(GL_CULL_FACE); | 
| 307 |     else | 
| 308 |         glDisable(GL_CULL_FACE); | 
| 309 |  | 
| 310 |     glCullFace(mode: m_cullFaceMode); | 
| 311 |  | 
| 312 |     glBlendEquationSeparate(modeRGB: m_blendEquationRGB, modeAlpha: m_blendEquationAlpha); | 
| 313 |     glBlendFuncSeparate(srcRGB: m_blendSrcRGB, dstRGB: m_blendDestRGB, srcAlpha: m_blendSrcAlpha, dstAlpha: m_blendDestAlpha); | 
| 314 |  | 
| 315 |     glDepthMask(flag: m_isDepthWriteEnabled); | 
| 316 |     glDepthFunc(func: m_depthFunc); | 
| 317 |     glFrontFace(mode: m_frontFace); | 
| 318 |  | 
| 319 |     if (m_polygonOffsetFillEnabled) | 
| 320 |         glEnable(GL_POLYGON_OFFSET_FILL); | 
| 321 |     else | 
| 322 |         glDisable(GL_POLYGON_OFFSET_FILL); | 
| 323 |  | 
| 324 |     glPolygonOffset(factor: m_polygonOffsetFactor, units: m_polygonOffsetUnits); | 
| 325 |  | 
| 326 |     glUseProgram(program: m_currentProgram); | 
| 327 |  | 
| 328 |     glActiveTexture(texture: m_activeTexture); | 
| 329 |     glBindTexture(GL_TEXTURE_2D, texture: m_texBinding2D); | 
| 330 |  | 
| 331 |     // Restore bound element array buffer and array buffers | 
| 332 |     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer: m_boundElementArrayBuffer); | 
| 333 |     for (int i = 0; i < m_maxVertexAttribs; i++) { | 
| 334 |         if (m_vertexAttribArrayEnabledStates[i]) | 
| 335 |             glEnableVertexAttribArray(index: i); | 
| 336 |         else | 
| 337 |             glDisableVertexAttribArray(index: i); | 
| 338 |  | 
| 339 |         glBindBuffer(GL_ARRAY_BUFFER, buffer: m_vertexAttribArrayBoundBuffers[i]); | 
| 340 |         glVertexAttribPointer(indx: i, size: m_vertexAttribArraySizes[i], | 
| 341 |                               type: m_vertexAttribArrayTypes[i], | 
| 342 |                               normalized: m_vertexAttribArrayNormalized[i], | 
| 343 |                               stride: m_vertexAttribArrayStrides[i], | 
| 344 |                               ptr: m_vertexAttribArrayOffsets[i]); | 
| 345 |     } | 
| 346 |  | 
| 347 |     glBindBuffer(GL_ARRAY_BUFFER, buffer: m_boundArrayBuffer); | 
| 348 |  | 
| 349 | #ifdef VERBOSE_STATE_STORE | 
| 350 |     printCurrentState(false); | 
| 351 | #endif | 
| 352 | } | 
| 353 |  | 
| 354 | void GLStateStore::initGLDefaultState() | 
| 355 | { | 
| 356 | #if !defined(QT_OPENGL_ES_2) | 
| 357 |     m_drawFramebuffer = 0; | 
| 358 |     m_readFramebuffer = 0; | 
| 359 |     m_renderbuffer = 0; | 
| 360 | #endif | 
| 361 |     m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 1.0f; | 
| 362 |     m_clearDepth = 1.0f; | 
| 363 |     m_isBlendingEnabled = GL_FALSE; | 
| 364 |     m_isDepthTestEnabled = GL_FALSE; | 
| 365 |     m_depthFunc = GL_LESS; | 
| 366 |     m_isDepthWriteEnabled = GL_TRUE; | 
| 367 |     m_currentProgram = 0; | 
| 368 |     m_texBinding2D = 0; | 
| 369 |     for (int i = 0; i < m_maxVertexAttribs;i++) { | 
| 370 |         m_vertexAttribArrayEnabledStates[i] = GL_FALSE; | 
| 371 |         m_vertexAttribArrayBoundBuffers[i] = 0; | 
| 372 |         m_vertexAttribArraySizes[i] = 4; | 
| 373 |         m_vertexAttribArrayTypes[i] = GL_FLOAT; | 
| 374 |         m_vertexAttribArrayNormalized[i] = GL_FALSE; | 
| 375 |         m_vertexAttribArrayStrides[i] = 0; | 
| 376 |         m_vertexAttribArrayOffsets[i] = 0; | 
| 377 |     } | 
| 378 |     m_activeTexture = GL_TEXTURE0; | 
| 379 |     m_frontFace = GL_CCW; | 
| 380 |     m_isCullFaceEnabled = false; | 
| 381 |     m_cullFaceMode = GL_BACK; | 
| 382 |     m_blendEquationRGB = GL_FUNC_ADD; | 
| 383 |     m_blendEquationAlpha = GL_FUNC_ADD; | 
| 384 |     m_scissorBox[0] = 0; | 
| 385 |     m_scissorBox[1] = 0; | 
| 386 |     m_scissorBox[2] = 0; | 
| 387 |     m_scissorBox[3] = 0; | 
| 388 |     m_isScissorTestEnabled = GL_FALSE; | 
| 389 |  | 
| 390 |     m_polygonOffsetFillEnabled = GL_FALSE; | 
| 391 |     m_polygonOffsetFactor = 0.0; | 
| 392 |     m_polygonOffsetUnits = 0.0; | 
| 393 | } | 
| 394 |  |