/**************************************************************************** ** ** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** 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 https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #if !defined(QT_OPENGL_ES_2) && defined(QT_OPENGL_4_3) #define TEST_SHOULD_BE_PERFORMED 1 using namespace Qt3DRender; using namespace Qt3DRender::Render; using namespace Qt3DRender::Render::OpenGL; namespace { const QByteArray vertCode = QByteArrayLiteral( "#version 430 core\n" \ "layout(location = 1) in vec3 vertexPosition;\n" \ "layout(location = 2) in vec2 vertexTexCoord;\n" \ "out vec2 texCoord;\n" \ "void main()\n" \ "{\n" \ " texCoord = vertexTexCoord;\n" \ " gl_Position = vec4(vertexPosition, 1.0);\n" \ "}\n"); const QByteArray vertCodeUniformBuffer = QByteArrayLiteral( "#version 430 core\n" \ "layout(location = 1) in vec3 vertexPosition;\n" \ "layout(location = 2) in vec2 vertexTexCoord;\n" \ "layout(location = 3) in int vertexColorIndex;\n" \ "layout(location = 4) in double vertexTexCoordScale;\n" \ "out vec2 texCoord;\n" \ "flat out int colorIndex;\n" \ "void main()\n" \ "{\n" \ " texCoord = vec2(vertexTexCoordScale * vertexTexCoord);\n" \ " colorIndex = vertexColorIndex;\n" \ " gl_Position = vec4(vertexPosition, 1.0);\n" \ "}\n"); const QByteArray fragCodeFragOutputs = QByteArrayLiteral( "#version 430 core\n" \ "out vec4 color;\n" \ "out vec2 temp;\n" \ "void main()\n" \ "{\n" \ " color = vec4(1.0, 0.0, 0.0, 1.0);\n" \ " temp = vec2(1.0, 0.3);\n" \ "}\n"); const QByteArray fragCodeUniformsFloat = QByteArrayLiteral( "#version 430 core\n" \ "out vec4 color;\n" \ "layout(location = 1) uniform float multiplier;\n" \ "layout(location = 2) uniform vec2 multiplierVec2;\n" \ "layout(location = 3) uniform vec3 multiplierVec3;\n" \ "layout(location = 4) uniform vec4 multiplierVec4;\n" \ "void main()\n" \ "{\n" \ " vec4 randomMult = multiplierVec4 + vec4(multiplierVec3, 0.0) + vec4(multiplierVec2, 0.0, 0.0);\n" \ " color = vec4(1.0, 0.0, 0.0, 1.0) * randomMult * multiplier;\n" \ "}\n"); const QByteArray fragCodeUniformsInt = QByteArrayLiteral( "#version 430 core\n" \ "out ivec4 color;\n" \ "layout(location = 1) uniform int multiplier;\n" \ "layout(location = 2) uniform ivec2 multiplierVec2;\n" \ "layout(location = 3) uniform ivec3 multiplierVec3;\n" \ "layout(location = 4) uniform ivec4 multiplierVec4;\n" \ "void main()\n" \ "{\n" \ " ivec4 randomMult = multiplierVec4 + ivec4(multiplierVec3, 0) + ivec4(multiplierVec2, 0, 0);\n" \ " color = ivec4(1, 0, 0, 1) * randomMult * multiplier;\n" \ "}\n"); const QByteArray fragCodeUniformsUInt = QByteArrayLiteral( "#version 430 core\n" \ "out uvec4 color;\n" \ "layout(location = 1) uniform uint multiplier;\n" \ "layout(location = 2) uniform uvec2 multiplierVec2;\n" \ "layout(location = 3) uniform uvec3 multiplierVec3;\n" \ "layout(location = 4) uniform uvec4 multiplierVec4;\n" \ "void main()\n" \ "{\n" \ " uvec4 randomMult = multiplierVec4 + uvec4(multiplierVec3, 0) + uvec4(multiplierVec2, 0, 0);\n" \ " color = uvec4(1, 0, 0, 1) * randomMult * multiplier;\n" \ "}\n"); const QByteArray fragCodeUniformsFloatMatrices = QByteArrayLiteral( "#version 430 core\n" \ "out vec4 color;\n" \ "layout(location = 1) uniform mat2 m2;\n" \ "layout(location = 2) uniform mat2x3 m23;\n" \ "layout(location = 3) uniform mat3x2 m32;\n" \ "layout(location = 4) uniform mat2x4 m24;\n" \ "layout(location = 5) uniform mat4x2 m42;\n" \ "layout(location = 6) uniform mat3 m3;\n" \ "layout(location = 7) uniform mat3x4 m34;\n" \ "layout(location = 8) uniform mat4x3 m43;\n" \ "layout(location = 9) uniform mat4 m4;\n" \ "void main()\n" \ "{\n" \ " float lengthSum = m2[0][0] + m23[0][0] + m32[0][0] + m24[0][0] + m42[0][0] + m3[0][0] + m34[0][0] + m43[0][0] + m4[0][0];\n" \ " color = vec4(1, 0, 0, 1) * lengthSum;\n" \ "}\n"); const QByteArray fragCodeUniformBuffer = QByteArrayLiteral( "#version 430 core\n" \ "out vec4 color;\n" \ "in vec2 texCoord;\n" \ "flat in int colorIndex;\n" \ "layout(binding = 2, std140) uniform ColorArray\n" \ "{\n" \ " vec4 colors[256];\n" \ "};\n" \ "void main()\n" \ "{\n" \ " color = colors[colorIndex] + vec4(texCoord.s, texCoord.t, 0.0, 1.0);\n" \ "}\n"); const QByteArray fragCodeSamplers = QByteArrayLiteral( "#version 430 core\n" \ "in vec2 texCoord;\n" \ "out vec4 color;\n" \ "layout(location = 1) uniform sampler1D s1;\n" \ "layout(location = 2) uniform sampler2D s2;\n" \ "layout(location = 3) uniform sampler2DArray s2a;\n" \ "layout(location = 4) uniform sampler3D s3;\n" \ "layout(location = 5) uniform samplerCube scube;\n" \ "layout(location = 6) uniform sampler2DRect srect;\n" \ "void main()\n" \ "{\n" \ " color = vec4(1, 0, 0, 1) *" \ " texture(s1, texCoord.x) *" \ " texture(s2, texCoord) *" \ " texture(s2a, vec3(texCoord, 0.0)) *" \ " texture(s3, vec3(texCoord, 0.0)) *" \ " texture(scube, vec3(texCoord, 0)) *" \ " texture(srect, texCoord);\n" \ "}\n"); const QByteArray fragCodeImages = QByteArrayLiteral( "#version 430 core\n" \ "in vec2 texCoord;\n" \ "out vec4 color;\n" \ "layout(location = 1, rgba32f) readonly uniform image1D s1;\n" \ "layout(location = 2, rg16f) readonly uniform image2D s2;\n" \ "layout(location = 3, r16f) readonly uniform image2DArray s2a;\n" \ "layout(location = 4, rg8) readonly uniform image3D s3;\n" \ "layout(location = 5, rgba16_snorm) readonly uniform imageCube scube;\n" \ "layout(location = 6, rg16) readonly uniform image2DRect srect;\n" \ "void main()\n" \ "{\n" \ " ivec2 coords = ivec2(texCoord);\n"\ " color = vec4(1, 0, 0, 1) *" \ " imageLoad(s1, coords.x) *" \ " imageLoad(s2, coords) *" \ " imageLoad(s2a, ivec3(coords, 0)) *" \ " imageLoad(s3, ivec3(coords, 0)) *" \ " imageLoad(scube, ivec3(coords, 0)) *" \ " imageLoad(srect, coords);\n" \ "}\n"); const QByteArray computeShader = QByteArrayLiteral( "#version 430 core\n" \ "uniform float particleStep;\n" \ "uniform float finalCollisionFactor;\n" \ "layout (local_size_x = 1024) in;\n" \ "struct ParticleData\n" \ "{\n" \ " vec4 position;\n" \ " vec4 direction;\n" \ " vec4 color;\n" \ "};\n" \ "layout (std140, binding = 6) coherent buffer Particles\n" \ "{\n" \ " ParticleData particles[];\n" \ "} data;\n" \ "void main(void)\n" \ "{\n" \ " uint globalId = gl_GlobalInvocationID.x;\n" \ " ParticleData currentParticle = data.particles[globalId];\n" \ " currentParticle.position = currentParticle.position + currentParticle.direction * particleStep;\n" \ " vec4 acceleration = normalize(vec4(0.0) - currentParticle.position) * finalCollisionFactor;\n" \ " currentParticle.direction = currentParticle.direction + acceleration * particleStep;\n" \ " data.particles[globalId] = currentParticle;\n" \ "}"); } // anonymous class tst_GraphicsHelperGL4 : public QObject { Q_OBJECT private Q_SLOTS: void init() { m_window.reset(new QWindow); m_window->setSurfaceType(QWindow::OpenGLSurface); m_window->setGeometry(0, 0, 10, 10); QSurfaceFormat format; format.setVersion(4, 3); format.setProfile(QSurfaceFormat::CoreProfile); format.setDepthBufferSize(24); format.setSamples(4); format.setStencilBufferSize(8); m_window->setFormat(format); m_glContext.setFormat(format); m_window->create(); if (!m_glContext.create()) { qWarning() << "Failed to create OpenGL context"; return; } if (!m_glContext.makeCurrent(m_window.data())) { qWarning() << "Failed to make OpenGL context current"; return; } if ((m_func = m_glContext.versionFunctions()) != nullptr) { m_glHelper.initializeHelper(&m_glContext, m_func); m_initializationSuccessful = true; } } void cleanup() { m_glContext.doneCurrent(); } void alphaTest() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // Deprecated } void bindBufferBase() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLuint bufferId = 0; // WHEN m_func->glGenBuffers(1, &bufferId); // THEN QVERIFY(bufferId != 0); // WHEN m_func->glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferId); m_glHelper.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bufferId); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); GLint boundToPointBufferId = 0; m_func->glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, 2, &boundToPointBufferId); QVERIFY(boundToPointBufferId == GLint(bufferId)); // Restore to sane state m_func->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); m_func->glDeleteBuffers(1, &bufferId); } void bindFragDataLocation() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeFragOutputs); // WHEN QHash fragLocations; fragLocations.insert(QStringLiteral("temp"), 2); fragLocations.insert(QStringLiteral("color"), 1); m_glHelper.bindFragDataLocation(shaderProgram.programId(), fragLocations); // THEN QVERIFY(shaderProgram.link()); const GLint error = m_func->glGetError(); QVERIFY(error == 0); const GLint tempLocation = m_func->glGetFragDataLocation(shaderProgram.programId(), "temp"); const GLint colorLocation = m_func->glGetFragDataLocation(shaderProgram.programId(), "color"); QCOMPARE(tempLocation, 2); QCOMPARE(colorLocation, 1); } void bindFrameBufferAttachment() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); { // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); Attachment attachment; attachment.m_point = QRenderTargetOutput::Color2; // THEN QVERIFY(fboId != 0); // WHEN m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); QOpenGLTexture texture(QOpenGLTexture::Target2D); texture.setSize(512, 512); texture.setFormat(QOpenGLTexture::RGBA32F); texture.setMinificationFilter(QOpenGLTexture::Linear); texture.setMagnificationFilter(QOpenGLTexture::Linear); texture.setWrapMode(QOpenGLTexture::ClampToEdge); if (!texture.create()) qWarning() << "Texture creation failed"; texture.allocateStorage(); QVERIFY(texture.isStorageAllocated()); GLint error = m_func->glGetError(); QVERIFY(error == 0); m_glHelper.bindFrameBufferAttachment(&texture, attachment); // THEN GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); error = m_func->glGetError(); QVERIFY(error == 0); GLint textureAttachmentId = 0; m_func->glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 2, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &textureAttachmentId); QCOMPARE(GLuint(textureAttachmentId), texture.textureId()); // Restore state m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_func->glDeleteFramebuffers(1, &fboId); } { // GIVEN QOpenGLTexture texture(QOpenGLTexture::TargetCubeMap); texture.setSize(512, 512); texture.setFormat(QOpenGLTexture::RGBA32F); texture.setMinificationFilter(QOpenGLTexture::Linear); texture.setMagnificationFilter(QOpenGLTexture::Linear); texture.setWrapMode(QOpenGLTexture::ClampToEdge); if (!texture.create()) qWarning() << "Texture creation failed"; texture.allocateStorage(); QVERIFY(texture.isStorageAllocated()); GLint error = m_func->glGetError(); QVERIFY(error == 0); { // Check All Faces // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); // THEN QVERIFY(fboId != 0); // WHEN m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); Attachment attachment; attachment.m_point = QRenderTargetOutput::Color0; attachment.m_face = Qt3DRender::QAbstractTexture::AllFaces; m_glHelper.bindFrameBufferAttachment(&texture, attachment); // THEN GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); error = m_func->glGetError(); QVERIFY(error == 0); GLint textureIsLayered = 0; m_func->glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_LAYERED, &textureIsLayered); QCOMPARE(textureIsLayered, GL_TRUE); // Restore state m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_func->glDeleteFramebuffers(1, &fboId); } { // Check Specific Faces // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); // THEN QVERIFY(fboId != 0); // WHEN m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); Attachment attachment; attachment.m_point = QRenderTargetOutput::Color0; attachment.m_face = Qt3DRender::QAbstractTexture::CubeMapNegativeZ; m_glHelper.bindFrameBufferAttachment(&texture, attachment); // THEN GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); error = m_func->glGetError(); QVERIFY(error == 0); GLint textureFace = 0; m_func->glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &textureFace); QCOMPARE(textureFace, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); GLint textureIsLayered = 0; m_func->glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_LAYERED, &textureIsLayered); QCOMPARE(textureIsLayered, GL_FALSE); // Restore state m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_func->glDeleteFramebuffers(1, &fboId); } } } void bindFrameBufferObject() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); // THEN QVERIFY(fboId != 0); // WHEN m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); // THEN GLint error = m_func->glGetError(); QVERIFY(error == 0); GLint boundindFBOId = 0; m_func->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundindFBOId); QVERIFY(GLuint(boundindFBOId) == fboId); // WHEN m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBORead); // THEN error = m_func->glGetError(); QVERIFY(error == 0); boundindFBOId = 0; m_func->glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundindFBOId); QVERIFY(GLuint(boundindFBOId) == fboId); // WHEN m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBOReadAndDraw); // THEN error = m_func->glGetError(); QVERIFY(error == 0); boundindFBOId = 0; m_func->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundindFBOId); QVERIFY(GLuint(boundindFBOId) == fboId); // Cleanup m_func->glDeleteFramebuffers(1, &fboId); } void bindImageTexture() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLTexture texture(QOpenGLTexture::Target2D); texture.setSize(512, 512); texture.setFormat(QOpenGLTexture::RGBA8U); texture.setMinificationFilter(QOpenGLTexture::Linear); texture.setMagnificationFilter(QOpenGLTexture::Linear); texture.create(); texture.allocateStorage(); // THEN QVERIFY(texture.textureId() != 0 && texture.isCreated() && texture.isStorageAllocated()); // WHEN m_glHelper.bindImageTexture(0, texture.textureId(), 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI); // THEN GLint error = m_func->glGetError(); QVERIFY(error == 0); } void bindShaderStorageBlock() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Compute, computeShader); QVERIFY(shaderProgram.link()); // WHEN GLint index = m_func->glGetProgramResourceIndex(shaderProgram.programId(), GL_SHADER_STORAGE_BLOCK, "Particles"); // THEN GLint binding = -1; GLenum prop = GL_BUFFER_BINDING; m_func->glGetProgramResourceiv(shaderProgram.programId(), GL_SHADER_STORAGE_BLOCK, index, 1, &prop, 4, NULL, &binding); QCOMPARE(binding, 6); // WHEN m_glHelper.bindShaderStorageBlock(shaderProgram.programId(), index, 1); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); m_func->glGetProgramResourceiv(shaderProgram.programId(), GL_SHADER_STORAGE_BLOCK, index, 1, &prop, 4, NULL, &binding); QCOMPARE(binding, 1); } void bindUniformBlock() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer); QVERIFY(shaderProgram.link()); // WHEN GLint index = m_func->glGetUniformBlockIndex(shaderProgram.programId(), "ColorArray"); m_glHelper.bindUniformBlock(shaderProgram.programId(), index, 1); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); } void blendEquation() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLint equation = 0; m_func->glGetIntegerv(GL_BLEND_EQUATION_RGB, &equation); QCOMPARE(equation, GL_FUNC_ADD); // WHEN m_glHelper.blendEquation(GL_FUNC_REVERSE_SUBTRACT); // THEN m_func->glGetIntegerv(GL_BLEND_EQUATION_RGB, &equation); QCOMPARE(equation, GL_FUNC_REVERSE_SUBTRACT); } void blendFunci() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLint destinationRgb = 0; GLint destinationAlpha = 0; GLint sourceRgb = 0; GLint sourceAlpha = 0; m_func->glGetIntegeri_v(GL_BLEND_SRC_RGB, 4, &sourceRgb); m_func->glGetIntegeri_v(GL_BLEND_DST_RGB, 4, &destinationRgb); m_func->glGetIntegeri_v(GL_BLEND_SRC_ALPHA, 4, &sourceAlpha); m_func->glGetIntegeri_v(GL_BLEND_DST_ALPHA, 4, &destinationAlpha); // THEN QCOMPARE(destinationAlpha, GL_ZERO); QCOMPARE(destinationRgb, GL_ZERO); QCOMPARE(sourceRgb, GL_ONE); QCOMPARE(sourceAlpha, GL_ONE); // WHEN m_glHelper.blendFunci(4, GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA); m_func->glGetIntegeri_v(GL_BLEND_SRC_RGB, 4, &sourceRgb); m_func->glGetIntegeri_v(GL_BLEND_DST_RGB, 4, &destinationRgb); m_func->glGetIntegeri_v(GL_BLEND_SRC_ALPHA, 4, &sourceAlpha); m_func->glGetIntegeri_v(GL_BLEND_DST_ALPHA, 4, &destinationAlpha); // THEN QCOMPARE(destinationAlpha, GL_ONE_MINUS_SRC_ALPHA); QCOMPARE(destinationRgb, GL_ONE_MINUS_SRC_ALPHA); QCOMPARE(sourceRgb, GL_SRC_COLOR); QCOMPARE(sourceAlpha, GL_SRC_COLOR); // Reset default m_glHelper.blendFunci(4, GL_ONE, GL_ZERO); } void blendFuncSeparatei() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLint destinationRgb = 0; GLint destinationAlpha = 0; GLint sourceRgb = 0; GLint sourceAlpha = 0; m_func->glGetIntegeri_v(GL_BLEND_SRC_RGB, 2, &sourceRgb); m_func->glGetIntegeri_v(GL_BLEND_DST_RGB, 2, &destinationRgb); m_func->glGetIntegeri_v(GL_BLEND_SRC_ALPHA, 2, &sourceAlpha); m_func->glGetIntegeri_v(GL_BLEND_DST_ALPHA, 2, &destinationAlpha); // THEN QCOMPARE(destinationAlpha, GL_ZERO); QCOMPARE(destinationRgb, GL_ZERO); QCOMPARE(sourceRgb, GL_ONE); QCOMPARE(sourceAlpha, GL_ONE); // WHEN m_glHelper.blendFuncSeparatei(2, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); m_func->glGetIntegeri_v(GL_BLEND_SRC_RGB, 2, &sourceRgb); m_func->glGetIntegeri_v(GL_BLEND_DST_RGB, 2, &destinationRgb); m_func->glGetIntegeri_v(GL_BLEND_SRC_ALPHA, 2, &sourceAlpha); m_func->glGetIntegeri_v(GL_BLEND_DST_ALPHA, 2, &destinationAlpha); // THEN QCOMPARE(destinationAlpha, GL_ONE_MINUS_SRC_ALPHA); QCOMPARE(destinationRgb, GL_ONE_MINUS_SRC_COLOR); QCOMPARE(sourceRgb, GL_SRC_COLOR); QCOMPARE(sourceAlpha, GL_SRC_ALPHA); // Reset default m_glHelper.blendFunci(4, GL_ONE, GL_ZERO); } void boundFrameBufferObject() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); // WHEN m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); // THEN GLint boundBuffer = 0; m_func->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundBuffer); QCOMPARE(GLuint(boundBuffer), fboId); // THEN QCOMPARE(m_glHelper.boundFrameBufferObject(), fboId); // Reset state m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_func->glDeleteFramebuffers(1, &fboId); } void checkFrameBufferComplete() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); Attachment attachment; attachment.m_point = QRenderTargetOutput::Color1; m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); QOpenGLTexture texture(QOpenGLTexture::Target2D); texture.setSize(512, 512); texture.setFormat(QOpenGLTexture::RGBA8U); texture.setMinificationFilter(QOpenGLTexture::Linear); texture.setMagnificationFilter(QOpenGLTexture::Linear); texture.create(); texture.allocateStorage(); m_glHelper.bindFrameBufferAttachment(&texture, attachment); // THEN GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); QVERIFY(m_glHelper.checkFrameBufferComplete()); // Restore m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_func->glDeleteFramebuffers(1, &fboId); } void clearBufferf() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); // THEN QVERIFY(fboId != 0); // WHEN m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); // Create 4 attachments QOpenGLTexture *textures[4]; for (int i = 0; i < 4; ++i) { Attachment attachment; attachment.m_point = static_cast(i); QOpenGLTexture *texture = new QOpenGLTexture(QOpenGLTexture::Target2D); textures[i] = texture; texture->setSize(512, 512); texture->setFormat(QOpenGLTexture::RGBA32F); texture->setMinificationFilter(QOpenGLTexture::Linear); texture->setMagnificationFilter(QOpenGLTexture::Linear); texture->setWrapMode(QOpenGLTexture::ClampToEdge); if (!texture->create()) qWarning() << "Texture creation failed"; texture->allocateStorage(); QVERIFY(texture->isStorageAllocated()); GLint error = m_func->glGetError(); QVERIFY(error == 0); m_glHelper.bindFrameBufferAttachment(texture, attachment); } GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); // Set Draw buffers GLenum clearBufferEnum = GL_COLOR_ATTACHMENT3; m_func->glDrawBuffers(1, &clearBufferEnum); const GLint bufferIndex = 0; // index of the element in the draw buffers GLint error = m_func->glGetError(); QVERIFY(error == 0); // WHEN const QVector4D clearValue1 = QVector4D(0.5f, 0.2f, 0.4f, 0.8f); m_func->glClearBufferfv(GL_COLOR, bufferIndex, reinterpret_cast(&clearValue1)); error = m_func->glGetError(); QVERIFY(error == 0); // THEN QVector colors(512 * 512); textures[3]->bind(); m_func->glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, colors.data()); textures[3]->release(); for (const QVector4D c : colors) { QVERIFY(c == clearValue1); } // WHEN const QVector4D clearValue2 = QVector4D(0.4f, 0.5f, 0.4f, 1.0f); m_glHelper.clearBufferf(bufferIndex, clearValue2); // THEN textures[3]->bind(); m_func->glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, colors.data()); textures[3]->release(); for (const QVector4D c : colors) { QVERIFY(c == clearValue2); } // Restore m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_func->glDeleteFramebuffers(1, &fboId); for (int i = 0; i < 4; ++i) delete textures[i]; } void createFrameBufferObject() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // WHEN const GLuint fboId = m_glHelper.createFrameBufferObject(); // THEN QVERIFY(fboId != 0); // Restore m_func->glDeleteFramebuffers(1, &fboId); } void depthMask() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLboolean depthWritingEnabled = false; m_func->glGetBooleanv(GL_DEPTH_WRITEMASK, &depthWritingEnabled); // THEN QVERIFY(depthWritingEnabled); // WHEN m_glHelper.depthMask(GL_FALSE); // THEN m_func->glGetBooleanv(GL_DEPTH_WRITEMASK, &depthWritingEnabled); QVERIFY(!depthWritingEnabled); // WHEN m_glHelper.depthMask(GL_TRUE); // THEN m_func->glGetBooleanv(GL_DEPTH_WRITEMASK, &depthWritingEnabled); QVERIFY(depthWritingEnabled); } void depthTest() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glDisable(GL_DEPTH_TEST); m_func->glDepthFunc(GL_LESS); // WHEN m_glHelper.depthTest(GL_LEQUAL); // THEN QVERIFY(m_func->glIsEnabled(GL_DEPTH_TEST)); GLint depthMode = 0; m_func->glGetIntegerv(GL_DEPTH_FUNC, &depthMode); QCOMPARE(depthMode, GL_LEQUAL); // WHEN m_glHelper.depthTest(GL_LESS); QVERIFY(m_func->glIsEnabled(GL_DEPTH_TEST)); m_func->glGetIntegerv(GL_DEPTH_FUNC, &depthMode); QCOMPARE(depthMode, GL_LESS); } void disableClipPlane() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glEnable(GL_CLIP_DISTANCE0 + 5); // THEN QVERIFY(m_func->glIsEnabled(GL_CLIP_DISTANCE0 + 5)); // WHEN m_glHelper.disableClipPlane(5); // THEN QVERIFY(!m_func->glIsEnabled(GL_CLIP_DISTANCE0 + 5)); } void disablei() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glEnablei(GL_BLEND, 2); // THEN QVERIFY(m_func->glIsEnabledi(GL_BLEND, 2)); // WHEN m_glHelper.disablei(GL_BLEND, 2); // THEN QVERIFY(!m_func->glIsEnabledi(GL_BLEND, 2)); } void disablePrimitiveRestart() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glEnable(GL_PRIMITIVE_RESTART); // THEN QVERIFY(m_func->glIsEnabled(GL_PRIMITIVE_RESTART)); // WHEN m_glHelper.disablePrimitiveRestart(); // THEN QVERIFY(!m_func->glIsEnabled(GL_PRIMITIVE_RESTART)); } void drawBuffers() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); // THEN QVERIFY(fboId != 0); // WHEN m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); QOpenGLTexture *textures[4]; // Create 4 attachments for (int i = 0; i < 4; ++i) { Attachment attachment; attachment.m_point = static_cast(i); QOpenGLTexture *texture = new QOpenGLTexture(QOpenGLTexture::Target2D); textures[i] = texture; texture->setSize(512, 512); texture->setFormat(QOpenGLTexture::RGBA32F); texture->setMinificationFilter(QOpenGLTexture::Linear); texture->setMagnificationFilter(QOpenGLTexture::Linear); texture->setWrapMode(QOpenGLTexture::ClampToEdge); if (!texture->create()) qWarning() << "Texture creation failed"; texture->allocateStorage(); QVERIFY(texture->isStorageAllocated()); GLint error = m_func->glGetError(); QVERIFY(error == 0); m_glHelper.bindFrameBufferAttachment(texture, attachment); } // THEN GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); // WHEN GLenum bufferEnum = GL_COLOR_ATTACHMENT4; m_func->glDrawBuffers(1, &bufferEnum); // THEN GLint enumValue = -1; m_func->glGetIntegerv(GL_DRAW_BUFFER0, &enumValue); QCOMPARE(enumValue, GL_COLOR_ATTACHMENT4); // WHEN GLint newBufferEnum = 2; m_glHelper.drawBuffers(1, &newBufferEnum); // THEN m_func->glGetIntegerv(GL_DRAW_BUFFER0, &enumValue); QCOMPARE(enumValue, GL_COLOR_ATTACHMENT0 + newBufferEnum); // WHEN newBufferEnum = 0; m_glHelper.drawBuffers(1, &newBufferEnum); // THEN m_func->glGetIntegerv(GL_DRAW_BUFFER0, &enumValue); QCOMPARE(enumValue, GL_COLOR_ATTACHMENT0 + newBufferEnum); // Restore m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_func->glDeleteFramebuffers(1, &fboId); for (int i = 0; i < 4; ++i) delete textures[i]; } void enableClipPlane() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glDisable(GL_CLIP_DISTANCE0 + 4); // THEN QVERIFY(!m_func->glIsEnabled(GL_CLIP_DISTANCE0 + 4)); // WHEN m_glHelper.enableClipPlane(4); // THEN QVERIFY(m_func->glIsEnabled(GL_CLIP_DISTANCE0 + 4)); } void enablei() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glDisablei(GL_BLEND, 4); // THEN QVERIFY(!m_func->glIsEnabledi(GL_BLEND, 4)); // WHEN m_glHelper.enablei(GL_BLEND, 4); // THEN QVERIFY(m_func->glIsEnabledi(GL_BLEND, 4)); } void enablePrimitiveRestart() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glDisable(GL_PRIMITIVE_RESTART); // THEN QVERIFY(!m_func->glIsEnabled(GL_PRIMITIVE_RESTART)); // WHEN m_glHelper.enablePrimitiveRestart(883); // THEN QVERIFY(m_func->glIsEnabled(GL_PRIMITIVE_RESTART)); GLint restartIndex = 0; m_func->glGetIntegerv(GL_PRIMITIVE_RESTART_INDEX, &restartIndex); QCOMPARE(restartIndex, 883); // Restore m_func->glDisable(GL_PRIMITIVE_RESTART); } void enableVertexAttribute() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLVertexArrayObject vao; vao.create(); QOpenGLVertexArrayObject::Binder binder(&vao); QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer); QVERIFY(shaderProgram.link()); shaderProgram.bind(); // WHEN GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition"); GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord"); GLint colorIndexLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexColorIndex"); m_glHelper.enableVertexAttributeArray(positionLocation); m_glHelper.enableVertexAttributeArray(texCoordLocation); m_glHelper.enableVertexAttributeArray(colorIndexLocation); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); } void frontFace() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glFrontFace(GL_CW); // THEN GLint face = 0; m_func->glGetIntegerv(GL_FRONT_FACE, &face); QCOMPARE(face, GL_CW); // WHEN m_glHelper.frontFace(GL_CCW); // THEN m_func->glGetIntegerv(GL_FRONT_FACE, &face); QCOMPARE(face, GL_CCW); } void getRenderBufferDimensions() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLuint renderBufferId = 0; m_func->glGenRenderbuffers(1, &renderBufferId); QVERIFY(renderBufferId != 0); // WHEN m_func->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId); m_func->glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8, 512, 512); m_func->glBindRenderbuffer(GL_RENDERBUFFER, 0); const QSize dimensions = m_glHelper.getRenderBufferDimensions(renderBufferId); // THEN QCOMPARE(dimensions, QSize(512, 512)); // Restore m_func->glDeleteRenderbuffers(1, &renderBufferId); } void getTextureDimensions() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLTexture texture(QOpenGLTexture::Target2D); texture.setSize(512, 512); texture.setFormat(QOpenGLTexture::RGBA8U); texture.setMinificationFilter(QOpenGLTexture::Linear); texture.setMagnificationFilter(QOpenGLTexture::Linear); texture.create(); texture.allocateStorage(); // WHEN const QSize dimensions = m_glHelper.getTextureDimensions(texture.textureId(), GL_TEXTURE_2D); // THEN QCOMPARE(dimensions, QSize(512, 512)); } void pointSize() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glEnable(GL_PROGRAM_POINT_SIZE); // THEN QVERIFY(m_func->glIsEnabled(GL_PROGRAM_POINT_SIZE)); GLfloat size = 0; m_func->glGetFloatv(GL_POINT_SIZE, &size); QCOMPARE(size, 1.0f); // WHEN m_glHelper.pointSize(false, 0.5f); // THEN QVERIFY(!m_func->glIsEnabled(GL_PROGRAM_POINT_SIZE)); m_func->glGetFloatv(GL_POINT_SIZE, &size); QCOMPARE(size, 0.5f); } void maxClipPlaneCount() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLint maxCount = -1; m_func->glGetIntegerv(GL_MAX_CLIP_PLANES, &maxCount); // THEN QCOMPARE(maxCount, m_glHelper.maxClipPlaneCount()); } void programUniformBlock() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer); QVERIFY(shaderProgram.link()); // WHEN const QVector activeUniformBlocks = m_glHelper.programUniformBlocks(shaderProgram.programId()); // THEN QCOMPARE(activeUniformBlocks.size(), 1); const ShaderUniformBlock uniformBlock = activeUniformBlocks.first(); QCOMPARE(uniformBlock.m_activeUniformsCount, 1); QCOMPARE(uniformBlock.m_name, QStringLiteral("ColorArray")); QCOMPARE(uniformBlock.m_binding, 2); } void programAttributesAndLocations() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeSamplers); QVERIFY(shaderProgram.link()); // WHEN QVector activeAttributes = m_glHelper.programAttributesAndLocations(shaderProgram.programId()); // THEN QCOMPARE(activeAttributes.size(), 2); std::sort(activeAttributes.begin(), activeAttributes.end(), [] (const ShaderAttribute &a, const ShaderAttribute &b) { return a.m_location < b.m_location; }); const ShaderAttribute attribute1 = activeAttributes.at(0); QCOMPARE(attribute1.m_name, QStringLiteral("vertexPosition")); QCOMPARE(attribute1.m_size, 1); QCOMPARE(attribute1.m_location, 1); QCOMPARE(attribute1.m_type, GLenum(GL_FLOAT_VEC3)); const ShaderAttribute attribute2 = activeAttributes.at(1); QCOMPARE(attribute2.m_name, QStringLiteral("vertexTexCoord")); QCOMPARE(attribute2.m_size, 1); QCOMPARE(attribute2.m_location, 2); QCOMPARE(attribute2.m_type, GLenum(GL_FLOAT_VEC2)); } void programUniformsAndLocations() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloat); QVERIFY(shaderProgram.link()); // WHEN QVector activeUniforms = m_glHelper.programUniformsAndLocations(shaderProgram.programId()); // THEN QCOMPARE(activeUniforms.size(), 4); std::sort(activeUniforms.begin(), activeUniforms.end(), [] (const ShaderUniform &a, const ShaderUniform &b) { return a.m_location < b.m_location; }); const ShaderUniform uniform1 = activeUniforms.at(0); QCOMPARE(uniform1.m_location, 1); QCOMPARE(uniform1.m_offset, -1); QCOMPARE(uniform1.m_blockIndex, -1); QCOMPARE(uniform1.m_arrayStride, -1); QCOMPARE(uniform1.m_matrixStride, -1); QCOMPARE(uniform1.m_size, 1); QCOMPARE(uniform1.m_type, GLenum(GL_FLOAT)); QCOMPARE(uniform1.m_name, QStringLiteral("multiplier")); const ShaderUniform uniform2 = activeUniforms.at(1); QCOMPARE(uniform2.m_location, 2); QCOMPARE(uniform2.m_offset, -1); QCOMPARE(uniform2.m_blockIndex, -1); QCOMPARE(uniform2.m_arrayStride, -1); QCOMPARE(uniform2.m_matrixStride, -1); QCOMPARE(uniform2.m_size, 1); QCOMPARE(uniform2.m_type, GLenum(GL_FLOAT_VEC2)); QCOMPARE(uniform2.m_name, QStringLiteral("multiplierVec2")); const ShaderUniform uniform3 = activeUniforms.at(2); QCOMPARE(uniform3.m_location, 3); QCOMPARE(uniform3.m_offset, -1); QCOMPARE(uniform3.m_blockIndex, -1); QCOMPARE(uniform3.m_arrayStride, -1); QCOMPARE(uniform3.m_matrixStride, -1); QCOMPARE(uniform3.m_size, 1); QCOMPARE(uniform3.m_type, GLenum(GL_FLOAT_VEC3)); QCOMPARE(uniform3.m_name, QStringLiteral("multiplierVec3")); const ShaderUniform uniform4 = activeUniforms.at(3); QCOMPARE(uniform4.m_location, 4); QCOMPARE(uniform4.m_offset, -1); QCOMPARE(uniform4.m_blockIndex, -1); QCOMPARE(uniform4.m_arrayStride, -1); QCOMPARE(uniform4.m_matrixStride, -1); QCOMPARE(uniform4.m_size, 1); QCOMPARE(uniform4.m_type, GLenum(GL_FLOAT_VEC4)); QCOMPARE(uniform4.m_name, QStringLiteral("multiplierVec4")); } void programShaderStorageBlock() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Compute, computeShader); QVERIFY(shaderProgram.link()); // WHEN const QVector activeShaderStorageBlocks = m_glHelper.programShaderStorageBlocks(shaderProgram.programId()); // THEN QVERIFY(activeShaderStorageBlocks.size() == 1); ShaderStorageBlock block = activeShaderStorageBlocks.first(); QCOMPARE(block.m_name, QStringLiteral("Particles")); QCOMPARE(block.m_activeVariablesCount, 3); QCOMPARE(block.m_index, 0); QCOMPARE(block.m_binding, 6); QCOMPARE(block.m_size, (4 + 4 + 4) * 4); } void releaseFrameBufferObject() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLuint fboId; m_func->glGenFramebuffers(1, &fboId); // THEN QVERIFY(fboId != 0); // WHEN m_glHelper.releaseFrameBufferObject(fboId); // THEN QVERIFY(!m_func->glIsFramebuffer(fboId)); } void setMSAAEnabled() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glDisable(GL_MULTISAMPLE); // THEN QVERIFY(!m_func->glIsEnabled(GL_MULTISAMPLE)); // WHEN m_glHelper.setMSAAEnabled(true); // THEN QVERIFY(m_func->glIsEnabled(GL_MULTISAMPLE)); // WHEN m_glHelper.setMSAAEnabled(false); // THEN QVERIFY(!m_func->glIsEnabled(GL_MULTISAMPLE)); } void setAlphaCoverageEnabled() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); // THEN QVERIFY(!m_func->glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)); // WHEN m_glHelper.setAlphaCoverageEnabled(true); // THEN QVERIFY(m_func->glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)); // WHEN m_glHelper.setAlphaCoverageEnabled(false); // THEN QVERIFY(!m_func->glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)); } void setClipPlane() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // Deprecated in GL 4 } void setSeamlessCubemap() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); QVERIFY(!m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); // WHEN m_glHelper.setSeamlessCubemap(true); // THEN QVERIFY(m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); // WHEN m_glHelper.setSeamlessCubemap(false); // THEN QVERIFY(!m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); } void setVerticesPerPatch() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN m_func->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // THEN QVERIFY(!m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); // WHEN m_glHelper.setSeamlessCubemap(true); // THEN QVERIFY(m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); // WHEN m_glHelper.setSeamlessCubemap(false); // THEN QVERIFY(!m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); } void supportsFeature() { for (int i = 0; i <= GraphicsHelperInterface::Fences; ++i) QVERIFY(m_glHelper.supportsFeature(static_cast(i))); } #define ADD_UNIFORM_ENTRY(FragShader, Type, Location, ComponentSize, ExpectedRawSize) \ QTest::newRow(#FragShader"_"#Type) << FragShader << Type << Location << ComponentSize << ExpectedRawSize; void uniformsByteSize_data() { QTest::addColumn("fragShader"); QTest::addColumn("type"); QTest::addColumn("location"); QTest::addColumn("componentSize"); QTest::addColumn("expectedByteSize"); ADD_UNIFORM_ENTRY(fragCodeUniformsFloat, GL_FLOAT, 1, 1, 4); ADD_UNIFORM_ENTRY(fragCodeUniformsFloat, GL_FLOAT_VEC2, 2, 1, 4 * 2); ADD_UNIFORM_ENTRY(fragCodeUniformsFloat, GL_FLOAT_VEC3, 3, 1, 4 * 3); ADD_UNIFORM_ENTRY(fragCodeUniformsFloat, GL_FLOAT_VEC4, 4, 1, 4 * 4); ADD_UNIFORM_ENTRY(fragCodeUniformsInt, GL_INT, 1, 1, 4); ADD_UNIFORM_ENTRY(fragCodeUniformsInt, GL_INT_VEC2, 2, 1, 4 * 2); ADD_UNIFORM_ENTRY(fragCodeUniformsInt, GL_INT_VEC3, 3, 1, 4 * 3); ADD_UNIFORM_ENTRY(fragCodeUniformsInt, GL_INT_VEC4, 4, 1, 4 * 4); ADD_UNIFORM_ENTRY(fragCodeUniformsUInt, GL_UNSIGNED_INT, 1, 1, 4); ADD_UNIFORM_ENTRY(fragCodeUniformsUInt, GL_UNSIGNED_INT_VEC2, 2, 1, 4 * 2); ADD_UNIFORM_ENTRY(fragCodeUniformsUInt, GL_UNSIGNED_INT_VEC3, 3, 1, 4 * 3); ADD_UNIFORM_ENTRY(fragCodeUniformsUInt, GL_UNSIGNED_INT_VEC4, 4, 1, 4 * 4); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT2, 1, 1, 4 * 2 * 2); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT2x3, 2, 1, 4 * 2 * 3); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT3x2, 3, 1, 4 * 3 * 2); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT2x4, 4, 1, 4 * 2 * 4); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT4x2, 5, 1, 4 * 4 * 2); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT3, 6, 1, 4 * 3 * 3); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT3x4, 7, 1, 4 * 3 * 4); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT4x3, 8, 1, 4 * 4 * 3); ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT4, 9, 1, 4 * 4 * 4); ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_1D, 1, 1, 4); ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_2D, 2, 1, 4); ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_2D_ARRAY, 3, 1, 4); ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_3D, 4, 1, 4); ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_CUBE, 5, 1, 4); ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_2D_RECT, 6, 1, 4); ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_1D, 1, 1, 4); ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_2D, 2, 1, 4); ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_2D_ARRAY, 3, 1, 4); ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_3D, 4, 1, 4); ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_CUBE, 5, 1, 4); ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_2D_RECT, 6, 1, 4); } void uniformsByteSize() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QFETCH(QByteArray, fragShader); QFETCH(int, type); QFETCH(int, location); QFETCH(int, componentSize); QFETCH(int, expectedByteSize); QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShader); QVERIFY(shaderProgram.link()); // WHEN const QVector activeUniforms = m_glHelper.programUniformsAndLocations(shaderProgram.programId()); ShaderUniform matchingUniform; for (const ShaderUniform &u : activeUniforms) { if (u.m_location == location) { matchingUniform = u; break; } } // THEN QCOMPARE(matchingUniform.m_location, location); QCOMPARE(matchingUniform.m_type, GLuint(type)); QCOMPARE(matchingUniform.m_size, componentSize); // WHEN const int computedRawByteSize = m_glHelper.uniformByteSize(matchingUniform); // THEN QCOMPARE(expectedByteSize, computedRawByteSize); // Restore m_func->glUseProgram(0); } void useProgram() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeFragOutputs); // THEN QVERIFY(shaderProgram.link()); GLint currentProg = 0; m_func->glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProg); QVERIFY(currentProg == 0); // WHEN m_glHelper.useProgram(shaderProgram.programId()); // THEN m_func->glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProg); QCOMPARE(GLuint(currentProg), shaderProgram.programId()); // WHEN m_glHelper.useProgram(0); // THEN m_func->glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProg); QVERIFY(currentProg == 0); } void vertexAttribDivisor() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); } void vertexAttributePointer() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLVertexArrayObject vao; vao.create(); QOpenGLVertexArrayObject::Binder binder(&vao); QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer); QVERIFY(shaderProgram.link()); GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition"); GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord"); GLint colorIndexLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexColorIndex"); GLint texCoordScaleLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoordScale"); const int vertexCount = 99; QOpenGLBuffer positionBuffer(QOpenGLBuffer::VertexBuffer); positionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); positionBuffer.create(); positionBuffer.bind(); positionBuffer.allocate(vertexCount * sizeof(QVector3D)); QOpenGLBuffer texCoordBuffer(QOpenGLBuffer::VertexBuffer); texCoordBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); texCoordBuffer.create(); texCoordBuffer.allocate(vertexCount * sizeof(QVector2D)); QOpenGLBuffer colorIndexBuffer(QOpenGLBuffer::VertexBuffer); colorIndexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); colorIndexBuffer.create(); colorIndexBuffer.allocate(vertexCount * sizeof(int)); QOpenGLBuffer scaleBuffer(QOpenGLBuffer::VertexBuffer); scaleBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); scaleBuffer.create(); scaleBuffer.allocate(vertexCount * sizeof(double)); // WHEN shaderProgram.bind(); positionBuffer.bind(); m_glHelper.enableVertexAttributeArray(positionLocation); m_glHelper.vertexAttributePointer(GL_FLOAT_VEC3, positionLocation, 3, GL_FLOAT, GL_TRUE, 0, 0); texCoordBuffer.bind(); m_glHelper.enableVertexAttributeArray(texCoordLocation); m_glHelper.vertexAttributePointer(GL_FLOAT_VEC2, texCoordLocation, 2, GL_FLOAT, GL_TRUE, 0, 0); colorIndexBuffer.bind(); m_glHelper.enableVertexAttributeArray(colorIndexLocation); m_glHelper.vertexAttributePointer(GL_INT, colorIndexLocation, 1, GL_INT, GL_TRUE, 0, 0); scaleBuffer.bind(); m_glHelper.enableVertexAttributeArray(colorIndexLocation); m_glHelper.vertexAttributePointer(GL_DOUBLE, texCoordScaleLocation, 1, GL_DOUBLE, GL_TRUE, 0, 0); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); } void glUniform1fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloat); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat value = 883.0f; m_glHelper.glUniform1fv(1, 1, &value); // THEN GLfloat setValue = 0.0f; m_func->glGetUniformfv(shaderProgram.programId(), 1, &setValue); QCOMPARE(value, setValue); // Restore m_func->glUseProgram(0); } void glUniform2fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloat); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[2] = { 383.0f, 427.0f }; m_glHelper.glUniform2fv(2, 1, values); // THEN GLfloat setValues[2] = { 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 2, setValues); for (int i = 0; i < 2; ++i) QCOMPARE(setValues[i], values[i]); // Restore m_func->glUseProgram(0); } void glUniform3fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloat); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[3] = { 572.0f, 1340.0f, 1584.0f }; m_glHelper.glUniform3fv(3, 1, values); // THEN GLfloat setValues[3] = { 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 3, setValues); for (int i = 0; i < 3; ++i) QCOMPARE(setValues[i], values[i]); // Restore m_func->glUseProgram(0); } void glUniform4fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloat); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[4] = { 454.0f, 350.0f, 883.0f, 355.0f }; m_glHelper.glUniform4fv(4, 1, values); // THEN GLfloat setValues[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 4, setValues); for (int i = 0; i < 4; ++i) QCOMPARE(setValues[i], values[i]); // Restore m_func->glUseProgram(0); } void glUniform1iv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsInt); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLint value = 883; m_glHelper.glUniform1iv(1, 1, &value); // THEN GLint setValue = 0; m_func->glGetUniformiv(shaderProgram.programId(), 1, &setValue); QCOMPARE(value, setValue); // Restore m_func->glUseProgram(0); } void glUniform2iv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsInt); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLint values[2] = { 383, 427 }; m_glHelper.glUniform2iv(2, 1, values); // THEN GLint setValues[2] = { 0, 0 }; m_func->glGetUniformiv(shaderProgram.programId(), 2, setValues); for (int i = 0; i < 2; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniform3iv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsInt); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLint values[3] = { 572, 1340, 1584 }; m_glHelper.glUniform3iv(3, 1, values); // THEN GLint setValues[3] = { 0, 0, 0 }; m_func->glGetUniformiv(shaderProgram.programId(), 3, setValues); for (int i = 0; i < 3; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniform4iv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsInt); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLint values[4] = { 454, 350, 883, 355 }; m_glHelper.glUniform4iv(4, 1, values); // THEN GLint setValues[4] = { 0, 0, 0, 0 }; m_func->glGetUniformiv(shaderProgram.programId(), 4, setValues); for (int i = 0; i < 4; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniform1uiv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsUInt); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLuint value = 883U; m_glHelper.glUniform1uiv(1, 1, &value); // THEN GLuint setValue = 0U; m_func->glGetUniformuiv(shaderProgram.programId(), 1, &setValue); QCOMPARE(value, setValue); // Restore m_func->glUseProgram(0); } void glUniform2uiv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsUInt); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLuint values[2] = { 383U, 427U }; m_glHelper.glUniform2uiv(2, 1, values); // THEN GLuint setValues[2] = { 0U, 0U }; m_func->glGetUniformuiv(shaderProgram.programId(), 2, setValues); for (int i = 0; i < 2; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniform3uiv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsUInt); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLuint values[3] = { 572U, 1340U, 1584U }; m_glHelper.glUniform3uiv(3, 1, values); // THEN GLuint setValues[3] = { 0U, 0U, 0U }; m_func->glGetUniformuiv(shaderProgram.programId(), 3, setValues); for (int i = 0; i < 3; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniform4uiv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsUInt); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLuint values[4] = { 454U, 350U, 883U, 355U }; m_glHelper.glUniform4uiv(4, 1, values); // THEN GLuint setValues[4] = { 0U, 0U, 0U, 0U }; m_func->glGetUniformuiv(shaderProgram.programId(), 4, setValues); for (int i = 0; i < 4; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix2fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[4] = { 454.0f, 350.0f, 883.0f, 355.0f }; m_glHelper.glUniformMatrix2fv(1, 1, values); // THEN GLfloat setValues[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 1, setValues); for (int i = 0; i < 4; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix3fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[9] = { 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f, 1200.0f, 427.0f, 396.0f }; m_glHelper.glUniformMatrix3fv(6, 1, values); // THEN GLfloat setValues[9] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 6, setValues); for (int i = 0; i < 9; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix4fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[16] = { 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f, 1200.0f, 427.0f, 396.0f, 1603.0f, 55.0f, 5.7f, 383.0f, 6.2f, 5.3f, 327.0f }; m_glHelper.glUniformMatrix4fv(9, 1, values); // THEN GLfloat setValues[16] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 9, setValues); for (int i = 0; i < 16; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix2x3fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[6] = { 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; m_glHelper.glUniformMatrix2x3fv(2, 1, values); // THEN GLfloat setValues[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 2, setValues); for (int i = 0; i < 6; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix3x2fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[6] = { 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; m_glHelper.glUniformMatrix3x2fv(3, 1, values); // THEN GLfloat setValues[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 3, setValues); for (int i = 0; i < 6; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix2x4fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[8] = { 383.0f, 427.0f, 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; m_glHelper.glUniformMatrix2x4fv(4, 1, values); // THEN GLfloat setValues[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 4, setValues); for (int i = 0; i < 8; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix4x2fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[8] = { 383.0f, 427.0f, 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; m_glHelper.glUniformMatrix4x2fv(5, 1, values); // THEN GLfloat setValues[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 5, setValues); for (int i = 0; i < 8; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix3x4fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[12] = { 55.0f, 5.7f, 383.0f, 6.2f, 5.3f, 383.0f, 427.0f, 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f,}; m_glHelper.glUniformMatrix3x4fv(7, 1, values); // THEN GLfloat setValues[12] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 7, setValues); for (int i = 0; i < 12; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void glUniformMatrix4x3fv() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN QOpenGLShaderProgram shaderProgram; shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode); shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformsFloatMatrices); QVERIFY(shaderProgram.link()); // WHEN m_func->glUseProgram(shaderProgram.programId()); GLfloat values[12] = { 55.0f, 5.7f, 383.0f, 6.2f, 383.0f, 427.0f, 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; m_glHelper.glUniformMatrix4x3fv(8, 1, values); // THEN GLfloat setValues[12] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; m_func->glGetUniformfv(shaderProgram.programId(), 8, setValues); for (int i = 0; i < 12; ++i) QCOMPARE(values[i], setValues[i]); // Restore m_func->glUseProgram(0); } void blitFramebuffer() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); // GIVEN GLuint fbos[2]; GLuint fboTextures[2]; m_func->glGenFramebuffers(2, fbos); m_func->glGenTextures(2, fboTextures); m_func->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, fboTextures[0]); m_func->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 10, 10, true); m_func->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); m_func->glBindTexture(GL_TEXTURE_2D, fboTextures[1]); m_func->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); m_func->glBindTexture(GL_TEXTURE_2D, 0); m_func->glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); m_func->glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fboTextures[1], 0); GLenum status = m_func->glCheckFramebufferStatus(GL_FRAMEBUFFER); QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); m_func->glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); m_func->glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fboTextures[0], 0); status = m_func->glCheckFramebufferStatus(GL_FRAMEBUFFER); QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); m_func->glEnable(GL_MULTISAMPLE); m_func->glClearColor(0.2f, 0.2f, 0.2f, 0.2f); m_func->glClear(GL_COLOR_BUFFER_BIT); m_func->glDisable(GL_MULTISAMPLE); m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); // WHEN m_glHelper.blitFramebuffer(0,0,10,10,0,0,10,10, GL_COLOR_BUFFER_BIT, GL_NEAREST); m_func->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[1]); GLuint result[10*10]; m_func->glReadPixels(0,0,10,10,GL_RGBA, GL_UNSIGNED_BYTE, result); // THEN GLuint v = (0.2f) * 255; v = v | (v<<8) | (v<<16) | (v<<24); for (GLuint value : result) { QCOMPARE(value, v); } m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_func->glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); m_func->glDeleteFramebuffers(2, fbos); m_func->glDeleteTextures(2, fboTextures); } #define ADD_GL_TYPE_ENTRY(Type, Expected) \ QTest::newRow(#Type) << Type << Expected; void uniformTypeFromGLType_data() { QTest::addColumn("glType"); QTest::addColumn("expected"); ADD_GL_TYPE_ENTRY(GL_FLOAT, UniformType::Float); ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC2, UniformType::Vec2); ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC3, UniformType::Vec3); ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC3, UniformType::Vec3); ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC2, UniformType::Vec2); ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC3, UniformType::Vec3); ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC3, UniformType::Vec3); ADD_GL_TYPE_ENTRY(GL_INT, UniformType::Int); ADD_GL_TYPE_ENTRY(GL_INT_VEC2, UniformType::IVec2); ADD_GL_TYPE_ENTRY(GL_INT_VEC3, UniformType::IVec3); ADD_GL_TYPE_ENTRY(GL_INT_VEC4, UniformType::IVec4); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT, UniformType::UInt); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_VEC2, UniformType::UIVec2); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_VEC3, UniformType::UIVec3); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_VEC4, UniformType::UIVec4); ADD_GL_TYPE_ENTRY(GL_BOOL, UniformType::Bool); ADD_GL_TYPE_ENTRY(GL_BOOL_VEC2, UniformType::BVec2); ADD_GL_TYPE_ENTRY(GL_BOOL_VEC3, UniformType::BVec3); ADD_GL_TYPE_ENTRY(GL_BOOL_VEC4, UniformType::BVec4); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT2, UniformType::Mat2); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT3, UniformType::Mat3); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT4, UniformType::Mat4); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT2x3, UniformType::Mat2x3); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT2x4, UniformType::Mat2x4); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT3x2, UniformType::Mat3x2); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT4x2, UniformType::Mat4x2); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT4x3, UniformType::Mat4x3); ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT3x4, UniformType::Mat3x4); ADD_GL_TYPE_ENTRY(GL_SAMPLER_1D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_1D_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_1D_SHADOW, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_RECT, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_MULTISAMPLE, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_MULTISAMPLE_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_SHADOW, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_ARRAY_SHADOW, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_3D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_CUBE, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_CUBE_SHADOW, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_CUBE_MAP_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_SAMPLER_BUFFER, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_1D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_2D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_3D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_BUFFER, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_2D_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_2D_MULTISAMPLE, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_CUBE, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_CUBE_MAP_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_1D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_2D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_3D, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_BUFFER, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_CUBE, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, UniformType::Sampler); ADD_GL_TYPE_ENTRY(GL_IMAGE_1D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_2D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_3D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_2D_RECT, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_CUBE, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_BUFFER, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_1D_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_2D_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_CUBE_MAP_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_2D_MULTISAMPLE, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_IMAGE_2D_MULTISAMPLE_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_1D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_3D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D_RECT, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_CUBE, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_BUFFER, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_1D_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_CUBE_MAP_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D_MULTISAMPLE, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_1D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_3D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D_RECT, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_CUBE, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_BUFFER, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_1D_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY, UniformType::Image); } void uniformTypeFromGLType() { // GIVEN QFETCH(int, glType); QFETCH(UniformType, expected); // WHEN UniformType computed = m_glHelper.uniformTypeFromGLType(glType); // THEN QCOMPARE(computed, expected); } void drawBuffer() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); m_func->glGetError(); // WHEN m_glHelper.drawBuffer(GL_FRONT); const GLint error = m_func->glGetError(); QVERIFY(error == 0); // THEN GLint p; m_func->glGetIntegerv(GL_DRAW_BUFFER, &p); QCOMPARE(p, GL_FRONT); } void readBuffer() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); m_func->glGetError(); // WHEN m_glHelper.readBuffer(GL_FRONT); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); GLint p; m_func->glGetIntegerv(GL_READ_BUFFER, &p); QCOMPARE(p, GL_FRONT); } void fenceSync() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); m_func->glGetError(); // WHEN GLsync sync = reinterpret_cast(m_glHelper.fenceSync()); // THEN QVERIFY(sync != nullptr); QCOMPARE(m_func->glIsSync(sync), GL_TRUE); const GLint error = m_func->glGetError(); QVERIFY(error == 0); } void clientWaitSync() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); m_func->glGetError(); // WHEN QElapsedTimer t; t.start(); GLsync sync = reinterpret_cast(m_glHelper.fenceSync()); m_glHelper.clientWaitSync(sync, 1000000); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); qDebug() << t.nsecsElapsed(); } void waitSync() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); m_func->glGetError(); // WHEN GLsync sync = reinterpret_cast(m_glHelper.fenceSync()); m_func->glFlush(); m_glHelper.waitSync(sync); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); } void wasSyncSignaled() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); m_func->glGetError(); // WHEN GLsync sync = reinterpret_cast(m_glHelper.fenceSync()); m_func->glFlush(); m_glHelper.waitSync(sync); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); // Shouldn't loop forever while (!m_glHelper.wasSyncSignaled(sync)) ; } void deleteSync() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); m_func->glGetError(); // WHEN GLsync sync = reinterpret_cast(m_glHelper.fenceSync()); m_glHelper.clientWaitSync(sync, GLuint64(-1)); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); QVERIFY(m_glHelper.wasSyncSignaled(sync) == true); // WHEN m_glHelper.deleteSync(sync); // THEN QCOMPARE(m_func->glIsSync(sync), GL_FALSE); } void rasterMode() { if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 4.3 functions not supported"); m_func->glGetError(); m_glHelper.rasterMode(GL_FRONT_AND_BACK, GL_LINE); // THEN const GLint error = m_func->glGetError(); QVERIFY(error == 0); GLint p; m_func->glGetIntegerv(GL_POLYGON_MODE, &p); QCOMPARE(p, GL_LINE); } private: QScopedPointer m_window; QOpenGLContext m_glContext; GraphicsHelperGL4 m_glHelper; QOpenGLFunctions_4_3_Core *m_func = nullptr; bool m_initializationSuccessful = false; }; #endif int main(int argc, char *argv[]) { #ifdef TEST_SHOULD_BE_PERFORMED QGuiApplication app(argc, argv); app.setAttribute(Qt::AA_Use96Dpi, true); tst_GraphicsHelperGL4 tc; QTEST_SET_MAIN_SOURCE_PATH return QTest::qExec(&tc, argc, argv); #endif return 0; } #ifdef TEST_SHOULD_BE_PERFORMED #include "tst_graphicshelpergl4.moc" #endif