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); openGLContext()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 defaultFBO()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; supportsVAO()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> applyUniformHelper(const ShaderUniform &,const UniformValue &)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