1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qquickopenglutils.h" |
5 | |
6 | #include <QOpenGLContext> |
7 | #include <QOpenGLFunctions> |
8 | #include <QOpenGLFramebufferObject> |
9 | #include <private/qopenglvertexarrayobject_p.h> |
10 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | /*! |
14 | \namespace QQuickOpenGLUtils |
15 | \inmodule QtQuick |
16 | \since 6.0 |
17 | |
18 | \brief The QQuickOpenGLUtils namespace contains utilities for Qt |
19 | Quick when used with an OpenGL backend. |
20 | */ |
21 | |
22 | /*! |
23 | Call this function to reset the current OpenGL context its default state. |
24 | |
25 | The scene graph uses the OpenGL context and will both rely on and |
26 | clobber its state. When mixing raw OpenGL commands with scene |
27 | graph rendering, this function provides a convenient way of |
28 | resetting the OpenGL context state back to its default values. |
29 | |
30 | This function does not touch state in the fixed-function pipeline. |
31 | |
32 | \warning This function will only reset the OpenGL context in |
33 | relation to what may be changed internally as part of the OpenGL |
34 | scene graph. It does not reset anything that has been changed |
35 | externally such as direct OpenGL calls done inside the application |
36 | code if those same calls are not used internally (for example, |
37 | various OpenGL 3.x or 4.x specific state). |
38 | |
39 | \since 6.0 |
40 | */ |
41 | void QQuickOpenGLUtils::resetOpenGLState() |
42 | { |
43 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); |
44 | if (!ctx) |
45 | return; |
46 | |
47 | QOpenGLFunctions *gl = ctx->functions(); |
48 | |
49 | gl->glBindBuffer(GL_ARRAY_BUFFER, buffer: 0); |
50 | gl->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer: 0); |
51 | |
52 | QOpenGLVertexArrayObjectHelper *vaoHelper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(context: ctx); |
53 | if (vaoHelper->isValid()) |
54 | vaoHelper->glBindVertexArray(array: 0); |
55 | |
56 | if (ctx->isOpenGLES() || (gl->openGLFeatures() & QOpenGLFunctions::FixedFunctionPipeline)) { |
57 | int maxAttribs; |
58 | gl->glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, params: &maxAttribs); |
59 | for (int i=0; i<maxAttribs; ++i) { |
60 | gl->glVertexAttribPointer(indx: i, size: 4, GL_FLOAT, GL_FALSE, stride: 0, ptr: nullptr); |
61 | gl->glDisableVertexAttribArray(index: i); |
62 | } |
63 | } |
64 | |
65 | gl->glActiveTexture(GL_TEXTURE0); |
66 | gl->glBindTexture(GL_TEXTURE_2D, texture: 0); |
67 | |
68 | gl->glDisable(GL_DEPTH_TEST); |
69 | gl->glDisable(GL_STENCIL_TEST); |
70 | gl->glDisable(GL_SCISSOR_TEST); |
71 | |
72 | gl->glColorMask(red: true, green: true, blue: true, alpha: true); |
73 | gl->glClearColor(red: 0, green: 0, blue: 0, alpha: 0); |
74 | |
75 | gl->glDepthMask(flag: true); |
76 | gl->glDepthFunc(GL_LESS); |
77 | gl->glClearDepthf(depth: 1); |
78 | |
79 | gl->glStencilMask(mask: 0xff); |
80 | gl->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); |
81 | gl->glStencilFunc(GL_ALWAYS, ref: 0, mask: 0xff); |
82 | |
83 | gl->glDisable(GL_BLEND); |
84 | gl->glBlendFunc(GL_ONE, GL_ZERO); |
85 | |
86 | gl->glUseProgram(program: 0); |
87 | |
88 | QOpenGLFramebufferObject::bindDefault(); |
89 | } |
90 | |
91 | QT_END_NAMESPACE |
92 | |