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
41QT_BEGIN_NAMESPACE
42
43class QOpenGLShaderProgram;
44class QAbstractOpenGLFunctions;
45#ifdef QT_OPENGL_LIB
46class QOpenGLDebugLogger;
47#endif
48
49namespace Qt3DRender {
50
51namespace Render {
52
53class RenderTarget;
54class AttachmentPack;
55class ShaderManager;
56
57namespace OpenGL {
58
59class GraphicsHelperInterface;
60class GLShader;
61class GLShaderManager;
62
63typedef QPair<QString, int> NamedUniformLocation;
64
65class Q_AUTOTEST_EXPORT GraphicsContext
66{
67public:
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) \
187template<> \
188void 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
199QT3D_UNIFORM_TYPE_PROTO(UniformType::Float, float, glUniform1fv)
200QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec2, float, glUniform2fv)
201QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec3, float, glUniform3fv)
202QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec4, float, glUniform4fv)
203
204// OpenGL expects int* as values for booleans
205QT3D_UNIFORM_TYPE_PROTO(UniformType::Bool, int, glUniform1iv)
206QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec2, int, glUniform2iv)
207QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec3, int, glUniform3iv)
208QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec4, int, glUniform4iv)
209
210QT3D_UNIFORM_TYPE_PROTO(UniformType::Int, int, glUniform1iv)
211QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec2, int, glUniform2iv)
212QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec3, int, glUniform3iv)
213QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec4, int, glUniform4iv)
214
215QT3D_UNIFORM_TYPE_PROTO(UniformType::UInt, uint, glUniform1uiv)
216QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec2, uint, glUniform2uiv)
217QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec3, uint, glUniform3uiv)
218QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec4, uint, glUniform4uiv)
219
220QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2, float, glUniformMatrix2fv)
221QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3, float, glUniformMatrix3fv)
222QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4, float, glUniformMatrix4fv)
223QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x3, float, glUniformMatrix2x3fv)
224QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x2, float, glUniformMatrix3x2fv)
225QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x4, float, glUniformMatrix2x4fv)
226QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x2, float, glUniformMatrix4x2fv)
227QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x4, float, glUniformMatrix3x4fv)
228QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x3, float, glUniformMatrix4x3fv)
229
230} // namespace OpenGL
231} // namespace Render
232} // namespace Qt3DRender
233
234QT_END_NAMESPACE
235
236#endif // QT3DRENDER_RENDER_OPENGL_GRAPHICSCONTEXT_H
237

source code of qt3d/src/plugins/renderers/opengl/graphicshelpers/graphicscontext_p.h