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 GLenum *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 rasterMode(GLenum faceMode, GLenum rasterMode);
145
146 // Helper methods
147 static GLint elementType(GLint type);
148 static GLint tupleSizeFromType(GLint type);
149 static GLuint byteSizeFromType(GLint type);
150 static GLint glDataTypeFromAttributeDataType(Qt3DCore::QAttribute::VertexBaseType dataType);
151
152 bool supportsDrawBuffersBlend() const;
153 bool supportsVAO() const { return m_supportsVAO; }
154
155 void initialize();
156 void initializeHelpers(QSurface *surface);
157 GraphicsHelperInterface *resolveHighestOpenGLFunctions();
158
159 bool m_initialized;
160 bool m_supportsVAO;
161 GLint m_maxTextureUnits;
162 GLint m_maxImageUnits;
163 GLuint m_defaultFBO;
164 QOpenGLContext *m_gl;
165 GraphicsHelperInterface *m_glHelper;
166
167 QHash<QSurface *, GraphicsHelperInterface*> m_glHelpers;
168 GraphicsApiFilterData m_contextInfo;
169#ifdef QT_OPENGL_LIB
170 QScopedPointer<QOpenGLDebugLogger> m_debugLogger;
171#endif
172
173 friend class OpenGLVertexArrayObject;
174 OpenGLVertexArrayObject *m_currentVAO;
175
176 void applyUniform(const ShaderUniform &description, const UniformValue &v);
177
178 template<UniformType>
179 void applyUniformHelper(const ShaderUniform &, const UniformValue &) const
180 {
181 Q_ASSERT_X(false, Q_FUNC_INFO, "Uniform: Didn't provide specialized apply() implementation");
182 }
183};
184
185#define QT3D_UNIFORM_TYPE_PROTO(UniformTypeEnum, BaseType, Func) \
186template<> \
187void GraphicsContext::applyUniformHelper<UniformTypeEnum>(const ShaderUniform &description, const UniformValue &value) const;
188
189#define QT3D_UNIFORM_TYPE_IMPL(UniformTypeEnum, BaseType, Func) \
190 template<> \
191 void GraphicsContext::applyUniformHelper<UniformTypeEnum>(const ShaderUniform &description, const UniformValue &value) const \
192{ \
193 const int count = qMin(description.m_size, int(value.byteSize() / description.m_rawByteSize)); \
194 m_glHelper->Func(description.m_location, count, value.constData<BaseType>()); \
195}
196
197
198QT3D_UNIFORM_TYPE_PROTO(UniformType::Float, float, glUniform1fv)
199QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec2, float, glUniform2fv)
200QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec3, float, glUniform3fv)
201QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec4, float, glUniform4fv)
202
203// OpenGL expects int* as values for booleans
204QT3D_UNIFORM_TYPE_PROTO(UniformType::Bool, int, glUniform1iv)
205QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec2, int, glUniform2iv)
206QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec3, int, glUniform3iv)
207QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec4, int, glUniform4iv)
208
209QT3D_UNIFORM_TYPE_PROTO(UniformType::Int, int, glUniform1iv)
210QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec2, int, glUniform2iv)
211QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec3, int, glUniform3iv)
212QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec4, int, glUniform4iv)
213
214QT3D_UNIFORM_TYPE_PROTO(UniformType::UInt, uint, glUniform1uiv)
215QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec2, uint, glUniform2uiv)
216QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec3, uint, glUniform3uiv)
217QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec4, uint, glUniform4uiv)
218
219QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2, float, glUniformMatrix2fv)
220QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3, float, glUniformMatrix3fv)
221QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4, float, glUniformMatrix4fv)
222QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x3, float, glUniformMatrix2x3fv)
223QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x2, float, glUniformMatrix3x2fv)
224QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x4, float, glUniformMatrix2x4fv)
225QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x2, float, glUniformMatrix4x2fv)
226QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x4, float, glUniformMatrix3x4fv)
227QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x3, float, glUniformMatrix4x3fv)
228
229} // namespace OpenGL
230} // namespace Render
231} // namespace Qt3DRender
232
233QT_END_NAMESPACE
234
235#endif // QT3DRENDER_RENDER_OPENGL_GRAPHICSCONTEXT_H
236

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