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