1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). |
4 | ** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the Qt3D module of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:LGPL$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU Lesser General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
22 | ** packaging of this file. Please review the following information to |
23 | ** ensure the GNU Lesser General Public License version 3 requirements |
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
25 | ** |
26 | ** GNU General Public License Usage |
27 | ** Alternatively, this file may be used under the terms of the GNU |
28 | ** General Public License version 2.0 or (at your option) the GNU General |
29 | ** Public license version 3 or any later version approved by the KDE Free |
30 | ** Qt Foundation. The licenses are as published by the Free Software |
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
32 | ** included in the packaging of this file. Please review the following |
33 | ** information to ensure the GNU General Public License requirements will |
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
36 | ** |
37 | ** $QT_END_LICENSE$ |
38 | ** |
39 | ****************************************************************************/ |
40 | |
41 | #ifndef QT3DRENDER_RENDER_OPENGL_GRAPHICSCONTEXT_H |
42 | #define QT3DRENDER_RENDER_OPENGL_GRAPHICSCONTEXT_H |
43 | |
44 | // |
45 | // W A R N I N G |
46 | // ------------- |
47 | // |
48 | // This file is not part of the Qt API. It exists for the convenience |
49 | // of other Qt classes. This header file may change from version to |
50 | // version without notice, or even be removed. |
51 | // |
52 | // We mean it. |
53 | // |
54 | |
55 | #include <QOpenGLContext> |
56 | #include <QOpenGLFunctions> |
57 | #include <QOpenGLVertexArrayObject> |
58 | #include <QHash> |
59 | #include <QColor> |
60 | #include <QMatrix4x4> |
61 | #include <QBitArray> |
62 | #include <QImage> |
63 | #include <Qt3DRender/qclearbuffers.h> |
64 | #include <Qt3DRender/private/shader_p.h> |
65 | #include <Qt3DRender/qattribute.h> |
66 | #include <Qt3DRender/qmemorybarrier.h> |
67 | #include <Qt3DRender/private/handle_types_p.h> |
68 | #include <Qt3DRender/private/qgraphicsapifilter_p.h> |
69 | #include <Qt3DRender/private/uniform_p.h> |
70 | #include <Qt3DRender/private/qblitframebuffer_p.h> |
71 | #include <gl_handle_types_p.h> |
72 | #include <glbuffer_p.h> |
73 | #include <shaderparameterpack_p.h> |
74 | #include <graphicshelperinterface_p.h> |
75 | #include <qmath.h> |
76 | |
77 | QT_BEGIN_NAMESPACE |
78 | |
79 | class QOpenGLShaderProgram; |
80 | class QAbstractOpenGLFunctions; |
81 | class QOpenGLDebugLogger; |
82 | |
83 | namespace Qt3DRender { |
84 | |
85 | namespace Render { |
86 | |
87 | class RenderTarget; |
88 | class AttachmentPack; |
89 | class ShaderManager; |
90 | |
91 | namespace OpenGL { |
92 | |
93 | class GraphicsHelperInterface; |
94 | class GLShader; |
95 | class GLShaderManager; |
96 | |
97 | typedef QPair<QString, int> NamedUniformLocation; |
98 | |
99 | class Q_AUTOTEST_EXPORT GraphicsContext |
100 | { |
101 | public: |
102 | GraphicsContext(); |
103 | ~GraphicsContext(); |
104 | |
105 | void setOpenGLContext(QOpenGLContext* ctx); |
106 | QOpenGLContext *openGLContext() { return m_gl; } |
107 | bool makeCurrent(QSurface *surface); |
108 | void doneCurrent(); |
109 | bool hasValidGLHelper() const; |
110 | bool isInitialized() const; |
111 | |
112 | // Shaders |
113 | struct ShaderCreationInfo |
114 | { |
115 | bool linkSucceeded = false; |
116 | QString logs; |
117 | }; |
118 | |
119 | ShaderCreationInfo createShaderProgram(GLShader *shaderNode); |
120 | void introspectShaderInterface(GLShader *shader); |
121 | void loadShader(Shader* shader, ShaderManager *shaderManager, GLShaderManager *glShaderManager); |
122 | |
123 | GLuint defaultFBO() const { return m_defaultFBO; } |
124 | |
125 | const GraphicsApiFilterData *contextInfo() const; |
126 | |
127 | // Wrapper methods |
128 | void clearBackBuffer(QClearBuffers::BufferTypeFlags buffers); |
129 | void alphaTest(GLenum mode1, GLenum mode2); |
130 | void bindFramebuffer(GLuint fbo, GraphicsHelperInterface::FBOBindMode mode); |
131 | void bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer); |
132 | void bindFragOutputs(GLuint shader, const QHash<QString, int> &outputs); |
133 | void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format); |
134 | void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding); |
135 | void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding); |
136 | void blendEquation(GLenum mode); |
137 | void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor); |
138 | void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha); |
139 | GLuint boundFrameBufferObject(); |
140 | void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer); |
141 | void clearBufferf(GLint drawbuffer, const QVector4D &values); |
142 | void clearColor(const QColor &color); |
143 | void clearDepthValue(float depth); |
144 | void clearStencilValue(int stencil); |
145 | void depthRange(GLdouble nearValue, GLdouble farValue); |
146 | void depthMask(GLenum mode); |
147 | void depthTest(GLenum mode); |
148 | void disableClipPlane(int clipPlane); |
149 | void disablei(GLenum cap, GLuint index); |
150 | void disablePrimitiveRestart(); |
151 | void dispatchCompute(int x, int y, int z); |
152 | char * mapBuffer(GLenum target, GLsizeiptr size); |
153 | GLboolean unmapBuffer(GLenum target); |
154 | void drawArrays(GLenum primitiveType, GLint first, GLsizei count); |
155 | void drawArraysIndirect(GLenum mode,void *indirect); |
156 | void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances); |
157 | void drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseinstance); |
158 | void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void * indices, GLint baseVertex); |
159 | void drawElementsIndirect(GLenum mode, GLenum type, void *indirect); |
160 | void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void * indices, GLsizei instances, GLint baseVertex, GLint baseInstance); |
161 | void enableClipPlane(int clipPlane); |
162 | void enablei(GLenum cap, GLuint index); |
163 | void enablePrimitiveRestart(int restartIndex); |
164 | void frontFace(GLenum mode); |
165 | GLint maxClipPlaneCount(); |
166 | GLint maxTextureUnitsCount() const; |
167 | GLint maxImageUnitsCount() const; |
168 | void pointSize(bool programmable, GLfloat value); |
169 | void readBuffer(GLenum mode); |
170 | void drawBuffer(GLenum mode); |
171 | void drawBuffers(GLsizei n, const int *bufs); |
172 | void setMSAAEnabled(bool enabled); |
173 | void setAlphaCoverageEnabled(bool enabled); |
174 | void setClipPlane(int clipPlane, const QVector3D &normal, float distance); |
175 | void setSeamlessCubemap(bool enable); |
176 | void setVerticesPerPatch(GLint verticesPerPatch); |
177 | void memoryBarrier(QMemoryBarrier::Operations barriers); |
178 | void activateDrawBuffers(const AttachmentPack &attachments); |
179 | void rasterMode(GLenum faceMode, GLenum rasterMode); |
180 | |
181 | // Helper methods |
182 | static GLint elementType(GLint type); |
183 | static GLint tupleSizeFromType(GLint type); |
184 | static GLuint byteSizeFromType(GLint type); |
185 | static GLint glDataTypeFromAttributeDataType(QAttribute::VertexBaseType dataType); |
186 | |
187 | bool supportsDrawBuffersBlend() const; |
188 | bool supportsVAO() const { return m_supportsVAO; } |
189 | |
190 | void initialize(); |
191 | void initializeHelpers(QSurface *surface); |
192 | GraphicsHelperInterface *resolveHighestOpenGLFunctions(); |
193 | |
194 | bool m_initialized; |
195 | bool m_supportsVAO; |
196 | GLint m_maxTextureUnits; |
197 | GLint m_maxImageUnits; |
198 | GLuint m_defaultFBO; |
199 | QOpenGLContext *m_gl; |
200 | GraphicsHelperInterface *m_glHelper; |
201 | |
202 | QHash<QSurface *, GraphicsHelperInterface*> m_glHelpers; |
203 | GraphicsApiFilterData m_contextInfo; |
204 | QScopedPointer<QOpenGLDebugLogger> m_debugLogger; |
205 | |
206 | friend class OpenGLVertexArrayObject; |
207 | OpenGLVertexArrayObject *m_currentVAO; |
208 | |
209 | void applyUniform(const ShaderUniform &description, const UniformValue &v); |
210 | |
211 | template<UniformType> |
212 | void applyUniformHelper(const ShaderUniform &, const UniformValue &) const |
213 | { |
214 | Q_ASSERT_X(false, Q_FUNC_INFO, "Uniform: Didn't provide specialized apply() implementation" ); |
215 | } |
216 | }; |
217 | |
218 | #define QT3D_UNIFORM_TYPE_PROTO(UniformTypeEnum, BaseType, Func) \ |
219 | template<> \ |
220 | void GraphicsContext::applyUniformHelper<UniformTypeEnum>(const ShaderUniform &description, const UniformValue &value) const; |
221 | |
222 | #define QT3D_UNIFORM_TYPE_IMPL(UniformTypeEnum, BaseType, Func) \ |
223 | template<> \ |
224 | void GraphicsContext::applyUniformHelper<UniformTypeEnum>(const ShaderUniform &description, const UniformValue &value) const \ |
225 | { \ |
226 | const int count = qMin(description.m_size, int(value.byteSize() / description.m_rawByteSize)); \ |
227 | m_glHelper->Func(description.m_location, count, value.constData<BaseType>()); \ |
228 | } |
229 | |
230 | |
231 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Float, float, glUniform1fv) |
232 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec2, float, glUniform2fv) |
233 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec3, float, glUniform3fv) |
234 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec4, float, glUniform4fv) |
235 | |
236 | // OpenGL expects int* as values for booleans |
237 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Bool, int, glUniform1iv) |
238 | QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec2, int, glUniform2iv) |
239 | QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec3, int, glUniform3iv) |
240 | QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec4, int, glUniform4iv) |
241 | |
242 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Int, int, glUniform1iv) |
243 | QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec2, int, glUniform2iv) |
244 | QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec3, int, glUniform3iv) |
245 | QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec4, int, glUniform4iv) |
246 | |
247 | QT3D_UNIFORM_TYPE_PROTO(UniformType::UInt, uint, glUniform1uiv) |
248 | QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec2, uint, glUniform2uiv) |
249 | QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec3, uint, glUniform3uiv) |
250 | QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec4, uint, glUniform4uiv) |
251 | |
252 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2, float, glUniformMatrix2fv) |
253 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3, float, glUniformMatrix3fv) |
254 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4, float, glUniformMatrix4fv) |
255 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x3, float, glUniformMatrix2x3fv) |
256 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x2, float, glUniformMatrix3x2fv) |
257 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x4, float, glUniformMatrix2x4fv) |
258 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x2, float, glUniformMatrix4x2fv) |
259 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x4, float, glUniformMatrix3x4fv) |
260 | QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x3, float, glUniformMatrix4x3fv) |
261 | |
262 | } // namespace OpenGL |
263 | } // namespace Render |
264 | } // namespace Qt3DRender |
265 | |
266 | QT_END_NAMESPACE |
267 | |
268 | #endif // QT3DRENDER_RENDER_OPENGL_GRAPHICSCONTEXT_H |
269 | |