summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire350@gmail.com>2015-08-10 15:50:30 +0200
committerSean Harmer <sean.harmer@kdab.com>2015-08-11 17:29:34 +0000
commite49cec310cd4d24949e3bb8cbc39d5b161893e39 (patch)
treeb6d463be12323bb7a240e00ab68c76dc06078ceb
parent86efa9fe761915d738ba231a5d94c74af3660500 (diff)
QGraphicsHelperGL4: dedicated helper for OpenGL 4.3+
Will allow the introduction of indirect draw calls Change-Id: Ia830c0f6638382a4884097dd96de61e0fbb4c015 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/backend/qgraphicscontext.cpp7
-rw-r--r--src/render/backend/qgraphicshelpergl4.cpp871
-rw-r--r--src/render/backend/qgraphicshelpergl4_p.h106
-rw-r--r--src/render/backend/render-backend.pri2
4 files changed, 985 insertions, 1 deletions
diff --git a/src/render/backend/qgraphicscontext.cpp b/src/render/backend/qgraphicscontext.cpp
index 24c627786..797f31041 100644
--- a/src/render/backend/qgraphicscontext.cpp
+++ b/src/render/backend/qgraphicscontext.cpp
@@ -57,8 +57,10 @@
#if !defined(QT_OPENGL_ES_2)
#include <QOpenGLFunctions_2_0>
#include <QOpenGLFunctions_3_2_Core>
+#include <QOpenGLFunctions_4_3_Core>
#include <Qt3DRenderer/private/qgraphicshelpergl2_p.h>
#include <Qt3DRenderer/private/qgraphicshelpergl3_p.h>
+#include <Qt3DRenderer/private/qgraphicshelpergl4_p.h>
#endif
#include <Qt3DRenderer/private/qgraphicshelperes2_p.h>
@@ -519,7 +521,10 @@ void QGraphicsContext::resolveHighestOpenGLFunctions()
#ifndef QT_OPENGL_ES_2
else {
QAbstractOpenGLFunctions *glFunctions = Q_NULLPTR;
- if ((glFunctions = m_gl->versionFunctions<QOpenGLFunctions_3_2_Core>()) != Q_NULLPTR) {
+ if ((glFunctions = m_gl->versionFunctions<QOpenGLFunctions_4_3_Core>()) != Q_NULLPTR) {
+ qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 4.3";
+ m_glHelper = new QGraphicsHelperGL4();
+ } else if ((glFunctions = m_gl->versionFunctions<QOpenGLFunctions_3_2_Core>()) != Q_NULLPTR) {
qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 3.2";
m_glHelper = new QGraphicsHelperGL3();
}
diff --git a/src/render/backend/qgraphicshelpergl4.cpp b/src/render/backend/qgraphicshelpergl4.cpp
new file mode 100644
index 000000000..103ea15bf
--- /dev/null
+++ b/src/render/backend/qgraphicshelpergl4.cpp
@@ -0,0 +1,871 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgraphicshelpergl4_p.h"
+
+#ifndef QT_OPENGL_ES_2
+#include <QOpenGLFunctions_4_3_Core>
+#include <QtOpenGLExtensions/qopenglextensions.h>
+#include <Qt3DRenderer/private/renderlogging_p.h>
+#include <private/attachmentpack_p.h>
+#include <private/qgraphicsutils_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3D {
+namespace Render {
+
+QGraphicsHelperGL4::QGraphicsHelperGL4()
+ : m_funcs(Q_NULLPTR)
+{
+}
+
+void QGraphicsHelperGL4::initializeHelper(QOpenGLContext *context,
+ QAbstractOpenGLFunctions *functions)
+{
+ Q_UNUSED(context);
+ m_funcs = static_cast<QOpenGLFunctions_4_3_Core*>(functions);
+ const bool ok = m_funcs->initializeOpenGLFunctions();
+ Q_ASSERT(ok);
+ Q_UNUSED(ok);
+}
+
+void QGraphicsHelperGL4::drawElementsInstanced(GLenum primitiveType,
+ GLsizei primitiveCount,
+ GLint indexType,
+ void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLint baseInstance)
+{
+ if (baseInstance != 0)
+ qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2";
+
+ // glDrawElements OpenGL 3.1 or greater
+ m_funcs->glDrawElementsInstancedBaseVertex(primitiveType,
+ primitiveCount,
+ indexType,
+ indices,
+ instances,
+ baseVertex);
+}
+
+void QGraphicsHelperGL4::drawArraysInstanced(GLenum primitiveType,
+ GLint first,
+ GLsizei count,
+ GLsizei instances)
+{
+ // glDrawArraysInstanced OpenGL 3.1 or greater
+ m_funcs->glDrawArraysInstanced(primitiveType,
+ first,
+ count,
+ instances);
+}
+
+void QGraphicsHelperGL4::drawElements(GLenum primitiveType,
+ GLsizei primitiveCount,
+ GLint indexType,
+ void *indices,
+ GLint baseVertex)
+{
+ m_funcs->glDrawElementsBaseVertex(primitiveType,
+ primitiveCount,
+ indexType,
+ indices,
+ baseVertex);
+}
+
+void QGraphicsHelperGL4::drawArrays(GLenum primitiveType,
+ GLint first,
+ GLsizei count)
+{
+ m_funcs->glDrawArrays(primitiveType,
+ first,
+ count);
+}
+
+void QGraphicsHelperGL4::setVerticesPerPatch(GLint verticesPerPatch)
+{
+ m_funcs->glPatchParameteri(GL_PATCH_VERTICES, verticesPerPatch);
+}
+
+void QGraphicsHelperGL4::useProgram(GLuint programId)
+{
+ m_funcs->glUseProgram(programId);
+}
+
+QVector<ShaderUniform> QGraphicsHelperGL4::programUniformsAndLocations(GLuint programId)
+{
+ QVector<ShaderUniform> uniforms;
+
+ GLint nbrActiveUniforms = 0;
+ m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms);
+ uniforms.reserve(nbrActiveUniforms);
+ char uniformName[256];
+ for (GLint i = 0; i < nbrActiveUniforms; i++) {
+ ShaderUniform uniform;
+ GLsizei uniformNameLength = 0;
+ // Size is 1 for scalar and more for struct or arrays
+ // Type is the GL Type
+ m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength,
+ &uniform.m_size, &uniform.m_type, uniformName);
+ uniformName[sizeof(uniformName) - 1] = '\0';
+ uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName);
+ uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength);
+ m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &uniform.m_blockIndex);
+ m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_OFFSET, &uniform.m_offset);
+ m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, &uniform.m_arrayStride);
+ m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, &uniform.m_matrixStride);
+ uniform.m_rawByteSize = uniformByteSize(uniform);
+ uniforms.append(uniform);
+ qCDebug(Render::Rendering) << uniform.m_name << "size" << uniform.m_size
+ << " offset" << uniform.m_offset
+ << " rawSize" << uniform.m_rawByteSize;
+ }
+
+ return uniforms;
+}
+
+QVector<ShaderAttribute> QGraphicsHelperGL4::programAttributesAndLocations(GLuint programId)
+{
+ QVector<ShaderAttribute> attributes;
+ GLint nbrActiveAttributes = 0;
+ m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes);
+ attributes.reserve(nbrActiveAttributes);
+ char attributeName[256];
+ for (GLint i = 0; i < nbrActiveAttributes; i++) {
+ ShaderAttribute attribute;
+ GLsizei attributeNameLength = 0;
+ // Size is 1 for scalar and more for struct or arrays
+ // Type is the GL Type
+ m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength,
+ &attribute.m_size, &attribute.m_type, attributeName);
+ attributeName[sizeof(attributeName) - 1] = '\0';
+ attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName);
+ attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength);
+ attributes.append(attribute);
+ }
+ return attributes;
+}
+
+QVector<ShaderUniformBlock> QGraphicsHelperGL4::programUniformBlocks(GLuint programId)
+{
+ QVector<ShaderUniformBlock> blocks;
+ GLint nbrActiveUniformsBlocks = 0;
+ m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORM_BLOCKS, &nbrActiveUniformsBlocks);
+ blocks.reserve(nbrActiveUniformsBlocks);
+ for (GLint i = 0; i < nbrActiveUniformsBlocks; i++) {
+ QByteArray uniformBlockName(256, '\0');
+ ShaderUniformBlock uniformBlock;
+ m_funcs->glGetActiveUniformBlockName(programId, i, 256, NULL, uniformBlockName.data());
+ uniformBlock.m_name = QString::fromUtf8(uniformBlockName);
+ uniformBlock.m_index = i;
+ m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformBlock.m_activeUniformsCount);
+ m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_BINDING, &uniformBlock.m_binding);
+ m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlock.m_size);
+ blocks.append(uniformBlock);
+ }
+ return blocks;
+}
+
+void QGraphicsHelperGL4::vertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ Q_UNUSED(index);
+ Q_UNUSED(divisor);
+}
+
+void QGraphicsHelperGL4::blendEquation(GLenum mode)
+{
+ m_funcs->glBlendEquation(mode);
+}
+
+void QGraphicsHelperGL4::alphaTest(GLenum, GLenum)
+{
+ qCWarning(Render::Rendering) << "AlphaTest not available with OpenGL 3.2 core";
+}
+
+void QGraphicsHelperGL4::depthTest(GLenum mode)
+{
+ m_funcs->glEnable(GL_DEPTH_TEST);
+ m_funcs->glDepthFunc(mode);
+}
+
+void QGraphicsHelperGL4::depthMask(GLenum mode)
+{
+ m_funcs->glDepthMask(mode);
+}
+
+void QGraphicsHelperGL4::cullFace(GLenum mode)
+{
+ m_funcs->glEnable(GL_CULL_FACE);
+ m_funcs->glCullFace(mode);
+}
+
+void QGraphicsHelperGL4::frontFace(GLenum mode)
+{
+ m_funcs->glFrontFace(mode);
+
+}
+
+void QGraphicsHelperGL4::enableAlphaCoverage()
+{
+ m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
+}
+
+void QGraphicsHelperGL4::disableAlphaCoverage()
+{
+ m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
+}
+
+GLuint QGraphicsHelperGL4::createFrameBufferObject()
+{
+ GLuint id;
+ m_funcs->glGenFramebuffers(1, &id);
+ return id;
+}
+
+void QGraphicsHelperGL4::releaseFrameBufferObject(GLuint frameBufferId)
+{
+ m_funcs->glDeleteFramebuffers(1, &frameBufferId);
+}
+
+void QGraphicsHelperGL4::bindFrameBufferObject(GLuint frameBufferId)
+{
+ m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+}
+
+GLuint QGraphicsHelperGL4::boundFrameBufferObject()
+{
+ GLint id = 0;
+ m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &id);
+ return id;
+}
+
+bool QGraphicsHelperGL4::checkFrameBufferComplete()
+{
+ return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+}
+
+void QGraphicsHelperGL4::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment)
+{
+ GLenum attr = GL_DEPTH_STENCIL_ATTACHMENT;
+
+ if (attachment.m_type <= QRenderAttachment::ColorAttachment15)
+ attr = GL_COLOR_ATTACHMENT0 + attachment.m_type;
+ else if (attachment.m_type == QRenderAttachment::DepthAttachment)
+ attr = GL_DEPTH_ATTACHMENT;
+ else if (attachment.m_type == QRenderAttachment::StencilAttachment)
+ attr = GL_STENCIL_ATTACHMENT;
+
+ texture->bind();
+ QOpenGLTexture::Target target = texture->target();
+ if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray ||
+ target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D)
+ m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
+ else if (target == QOpenGLTexture::TargetCubeMapArray)
+ m_funcs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
+ else if (target == QOpenGLTexture::TargetCubeMap)
+ m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
+ else
+ m_funcs->glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel);
+ texture->release();
+}
+
+bool QGraphicsHelperGL4::supportsFeature(QGraphicsHelperInterface::Feature feature) const
+{
+ switch (feature) {
+ case MRT:
+ case Tessellation:
+ case UniformBufferObject:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void QGraphicsHelperGL4::drawBuffers(GLsizei n, const int *bufs)
+{
+ // Use QVarLengthArray here
+ QVarLengthArray<GLenum, 16> drawBufs(n);
+
+ for (int i = 0; i < n; i++)
+ drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i];
+ m_funcs->glDrawBuffers(n, drawBufs.constData());
+}
+
+void QGraphicsHelperGL4::bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs)
+{
+ Q_FOREACH (const QString &name, outputs.keys())
+ m_funcs->glBindFragDataLocation(shader, outputs.value(name), name.toStdString().c_str());
+}
+
+void QGraphicsHelperGL4::bindUniform(const QVariant &v, const ShaderUniform &description)
+{
+ switch (description.m_type) {
+
+ case GL_FLOAT:
+ m_funcs->glUniform1fv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1));
+ break;
+
+ case GL_FLOAT_VEC2:
+ m_funcs->glUniform2fv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2));
+ break;
+
+ case GL_FLOAT_VEC3:
+ m_funcs->glUniform3fv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3));
+ break;
+
+ case GL_FLOAT_VEC4:
+ m_funcs->glUniform4fv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4));
+ break;
+
+ case GL_FLOAT_MAT2:
+ m_funcs->glUniformMatrix2fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4));
+ break;
+
+ case GL_FLOAT_MAT2x3:
+ m_funcs->glUniformMatrix2x3fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6));
+ break;
+
+ case GL_FLOAT_MAT2x4:
+ m_funcs->glUniformMatrix2x4fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8));
+ break;
+
+ case GL_FLOAT_MAT3:
+ m_funcs->glUniformMatrix3fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9));
+ break;
+
+ case GL_FLOAT_MAT3x2:
+ m_funcs->glUniformMatrix3x2fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6));
+ break;
+
+ case GL_FLOAT_MAT3x4:
+ m_funcs->glUniformMatrix3x4fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12));
+ break;
+
+ case GL_FLOAT_MAT4:
+ m_funcs->glUniformMatrix4fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16));
+ break;
+
+ case GL_FLOAT_MAT4x2:
+ m_funcs->glUniformMatrix4x2fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8));
+ break;
+
+ case GL_FLOAT_MAT4x3:
+ m_funcs->glUniformMatrix4x3fv(description.m_location, description.m_size, GL_FALSE,
+ QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12));
+ break;
+
+ case GL_INT:
+ m_funcs->glUniform1iv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1));
+ break;
+
+ case GL_INT_VEC2:
+ m_funcs->glUniform2iv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2));
+ break;
+
+ case GL_INT_VEC3:
+ m_funcs->glUniform3iv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3));
+ break;
+
+ case GL_INT_VEC4:
+ m_funcs->glUniform4iv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4));
+ break;
+
+ case GL_UNSIGNED_INT:
+ m_funcs->glUniform1uiv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1));
+ break;
+
+ case GL_UNSIGNED_INT_VEC2:
+ m_funcs->glUniform2uiv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2));
+ break;
+
+ case GL_UNSIGNED_INT_VEC3:
+ m_funcs->glUniform3uiv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3));
+ break;
+
+ case GL_UNSIGNED_INT_VEC4:
+ m_funcs->glUniform4uiv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4));
+ break;
+
+ case GL_BOOL:
+ m_funcs->glUniform1iv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1));
+ break;
+
+ case GL_BOOL_VEC2:
+ m_funcs->glUniform2iv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2));
+ break;
+
+ case GL_BOOL_VEC3:
+ m_funcs->glUniform3iv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3));
+ break;
+
+ case GL_BOOL_VEC4:
+ m_funcs->glUniform4iv(description.m_location, description.m_size,
+ QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4));
+ break;
+
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_RECT:
+ case GL_INT_SAMPLER_1D:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D_RECT:
+ case GL_UNSIGNED_INT_SAMPLER_1D:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
+ case GL_SAMPLER_1D_SHADOW:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_1D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_1D_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_1D_ARRAY_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_2D_RECT_SHADOW:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: {
+ Q_ASSERT(description.m_size == 1);
+ m_funcs->glUniform1i(description.m_location, v.toInt());
+ break;
+ }
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name;
+ break;
+ }
+}
+
+void QGraphicsHelperGL4::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+ m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding);
+}
+
+void QGraphicsHelperGL4::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+ m_funcs->glBindBufferBase(target, index, buffer);
+}
+
+void QGraphicsHelperGL4::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer)
+{
+ char *bufferData = buffer.data();
+
+ switch (description.m_type) {
+
+ case GL_FLOAT: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
+ break;
+ }
+
+ case GL_FLOAT_VEC2: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
+ break;
+ }
+
+ case GL_FLOAT_VEC3: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
+ break;
+ }
+
+ case GL_FLOAT_VEC4: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
+ break;
+ }
+
+ case GL_FLOAT_MAT2: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 2);
+ break;
+ }
+
+ case GL_FLOAT_MAT2x3: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 3);
+ break;
+ }
+
+ case GL_FLOAT_MAT2x4: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 4);
+ break;
+ }
+
+ case GL_FLOAT_MAT3: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 3);
+ break;
+ }
+
+ case GL_FLOAT_MAT3x2: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 2);
+ break;
+ }
+
+ case GL_FLOAT_MAT3x4: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 4);
+ break;
+ }
+
+ case GL_FLOAT_MAT4: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 4);
+ break;
+ }
+
+ case GL_FLOAT_MAT4x2: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 2);
+ break;
+ }
+
+ case GL_FLOAT_MAT4x3: {
+ const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12);
+ QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 3);
+ break;
+ }
+
+ case GL_INT: {
+ const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
+ break;
+ }
+
+ case GL_INT_VEC2: {
+ const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
+ break;
+ }
+
+ case GL_INT_VEC3: {
+ const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
+ break;
+ }
+
+ case GL_INT_VEC4: {
+ const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
+ break;
+ }
+
+ case GL_UNSIGNED_INT: {
+ const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
+ break;
+ }
+
+ case GL_UNSIGNED_INT_VEC2: {
+ const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
+ break;
+ }
+
+ case GL_UNSIGNED_INT_VEC3: {
+ const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
+ break;
+ }
+
+ case GL_UNSIGNED_INT_VEC4: {
+ const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
+ break;
+ }
+
+ case GL_BOOL: {
+ const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 1);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
+ break;
+ }
+
+ case GL_BOOL_VEC2: {
+ const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 2);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
+ break;
+ }
+
+ case GL_BOOL_VEC3: {
+ const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 3);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
+ break;
+ }
+
+ case GL_BOOL_VEC4: {
+ const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 4);
+ QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
+ break;
+ }
+
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_RECT:
+ case GL_INT_SAMPLER_1D:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D_RECT:
+ case GL_UNSIGNED_INT_SAMPLER_1D:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
+ case GL_SAMPLER_1D_SHADOW:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_1D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_1D_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_1D_ARRAY_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_2D_RECT_SHADOW:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: {
+ Q_ASSERT(description.m_size == 1);
+ int value = v.toInt();
+ QGraphicsUtils::fillDataArray<GLint>(bufferData, &value, description, 1);
+ break;
+ }
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name;
+ break;
+ }
+}
+
+uint QGraphicsHelperGL4::uniformByteSize(const ShaderUniform &description)
+{
+ uint rawByteSize = 0;
+ int arrayStride = qMax(description.m_arrayStride, 0);
+ int matrixStride = qMax(description.m_matrixStride, 0);
+
+ switch (description.m_type) {
+
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ rawByteSize = 8;
+ break;
+
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ rawByteSize = 12;
+ break;
+
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ rawByteSize = 16;
+ break;
+
+ case GL_FLOAT_MAT2:
+ rawByteSize = matrixStride ? 2 * matrixStride : 16;
+ break;
+
+ case GL_FLOAT_MAT2x4:
+ rawByteSize = matrixStride ? 2 * matrixStride : 32;
+ break;
+
+ case GL_FLOAT_MAT4x2:
+ rawByteSize = matrixStride ? 4 * matrixStride : 32;
+ break;
+
+ case GL_FLOAT_MAT3:
+ rawByteSize = matrixStride ? 3 * matrixStride : 36;
+ break;
+
+ case GL_FLOAT_MAT2x3:
+ rawByteSize = matrixStride ? 2 * matrixStride : 24;
+ break;
+
+ case GL_FLOAT_MAT3x2:
+ rawByteSize = matrixStride ? 3 * matrixStride : 24;
+ break;
+
+ case GL_FLOAT_MAT4:
+ rawByteSize = matrixStride ? 4 * matrixStride : 64;
+ break;
+
+ case GL_FLOAT_MAT4x3:
+ rawByteSize = matrixStride ? 4 * matrixStride : 48;
+ break;
+
+ case GL_FLOAT_MAT3x4:
+ rawByteSize = matrixStride ? 3 * matrixStride : 48;
+ break;
+
+ case GL_BOOL:
+ rawByteSize = 1;
+ break;
+
+ case GL_BOOL_VEC2:
+ rawByteSize = 2;
+ break;
+
+ case GL_BOOL_VEC3:
+ rawByteSize = 3;
+ break;
+
+ case GL_BOOL_VEC4:
+ rawByteSize = 4;
+ break;
+
+ case GL_INT:
+ case GL_FLOAT:
+ case GL_UNSIGNED_INT:
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_RECT:
+ case GL_INT_SAMPLER_1D:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D_RECT:
+ case GL_UNSIGNED_INT_SAMPLER_1D:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
+ case GL_SAMPLER_1D_SHADOW:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_1D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_1D_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_1D_ARRAY_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_2D_RECT_SHADOW:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ rawByteSize = 4;
+ break;
+ }
+
+ return arrayStride ? rawByteSize * arrayStride : rawByteSize;
+}
+
+void QGraphicsHelperGL4::enableClipPlane(int clipPlane)
+{
+ m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane);
+}
+
+void QGraphicsHelperGL4::disableClipPlane(int clipPlane)
+{
+ m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane);
+}
+
+GLint QGraphicsHelperGL4::maxClipPlaneCount()
+{
+ GLint max = 0;
+ m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max);
+ return max;
+}
+
+} // Render
+} // Qt3D
+
+QT_END_NAMESPACE
+
+#endif // !QT_OPENGL_ES_2
diff --git a/src/render/backend/qgraphicshelpergl4_p.h b/src/render/backend/qgraphicshelpergl4_p.h
new file mode 100644
index 000000000..0c2f82f3c
--- /dev/null
+++ b/src/render/backend/qgraphicshelpergl4_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_QGRAPHICSHELPERGL4_H
+#define QT3D_RENDER_QGRAPHICSHELPERGL4_H
+
+#include <Qt3DRenderer/private/qgraphicshelperinterface_p.h>
+#include <QtCore/qscopedpointer.h>
+
+#ifndef QT_OPENGL_ES_2
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLFunctions_4_3_Core;
+
+namespace Qt3D {
+namespace Render {
+
+class QGraphicsHelperGL4 : public QGraphicsHelperInterface
+{
+public:
+ QGraphicsHelperGL4();
+
+ // QGraphicHelperInterface interface
+ void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE;
+ void drawElementsInstanced(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) Q_DECL_OVERRIDE;
+ void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) Q_DECL_OVERRIDE;
+ void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLint baseVertex = 0) Q_DECL_OVERRIDE;
+ void drawArrays(GLenum primitiveType, GLint first, GLsizei count) Q_DECL_OVERRIDE;
+ void setVerticesPerPatch(GLint verticesPerPatch) Q_DECL_OVERRIDE;
+ void useProgram(GLuint programId) Q_DECL_OVERRIDE;
+ QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE;
+ QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE;
+ QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE;
+ void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE;
+ void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
+ void alphaTest(GLenum mode1, GLenum mode2) Q_DECL_OVERRIDE;
+ void depthTest(GLenum mode) Q_DECL_OVERRIDE;
+ void depthMask(GLenum mode) Q_DECL_OVERRIDE;
+ void cullFace(GLenum mode) Q_DECL_OVERRIDE;
+ void frontFace(GLenum mode) Q_DECL_OVERRIDE;
+ void enableAlphaCoverage() Q_DECL_OVERRIDE;
+ void disableAlphaCoverage() Q_DECL_OVERRIDE;
+ GLuint createFrameBufferObject() Q_DECL_OVERRIDE;
+ void releaseFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ GLuint boundFrameBufferObject() Q_DECL_OVERRIDE;
+ bool checkFrameBufferComplete() Q_DECL_OVERRIDE;
+ void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
+ bool supportsFeature(Feature feature) const Q_DECL_OVERRIDE;
+ void drawBuffers(GLsizei n, const int *bufs) Q_DECL_OVERRIDE;
+ void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) Q_DECL_OVERRIDE;
+ void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE;
+ void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
+ void bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer) Q_DECL_OVERRIDE;
+ void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) Q_DECL_OVERRIDE;
+ uint uniformByteSize(const ShaderUniform &description) Q_DECL_OVERRIDE;
+ void enableClipPlane(int clipPlane) Q_DECL_OVERRIDE;
+ void disableClipPlane(int clipPlane) Q_DECL_OVERRIDE;
+ GLint maxClipPlaneCount() Q_DECL_OVERRIDE;
+
+private:
+ QOpenGLFunctions_4_3_Core *m_funcs;
+};
+
+} // Render
+} // Qt3D
+
+QT_END_NAMESPACE
+
+#endif // !QT_OPENGL_ES_2
+
+#endif // QT3D_RENDER_QGRAPHICSHELPERGL4_H
diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri
index 0f57db809..316e33e27 100644
--- a/src/render/backend/render-backend.pri
+++ b/src/render/backend/render-backend.pri
@@ -19,6 +19,7 @@ HEADERS += \
$$PWD/states/blendstate_p.h \
$$PWD/genericstate_p.h \
$$PWD/qgraphicshelperinterface_p.h \
+ $$PWD/qgraphicshelpergl4_p.h \
$$PWD/qgraphicshelpergl3_p.h \
$$PWD/qgraphicshelperes2_p.h \
$$PWD/qgraphicshelpergl2_p.h \
@@ -72,6 +73,7 @@ SOURCES += \
$$PWD/quniformvalue.cpp \
$$PWD/rendertexture.cpp \
$$PWD/states/blendstate.cpp \
+ $$PWD/qgraphicshelpergl4.cpp \
$$PWD/qgraphicshelpergl3.cpp \
$$PWD/qgraphicshelperes2.cpp \
$$PWD/qgraphicshelpergl2.cpp \