diff options
Diffstat (limited to 'src/plugins/renderers/opengl/graphicshelpers/graphicshelperes2.cpp')
-rw-r--r-- | src/plugins/renderers/opengl/graphicshelpers/graphicshelperes2.cpp | 1037 |
1 files changed, 1037 insertions, 0 deletions
diff --git a/src/plugins/renderers/opengl/graphicshelpers/graphicshelperes2.cpp b/src/plugins/renderers/opengl/graphicshelpers/graphicshelperes2.cpp new file mode 100644 index 000000000..3ae9ed932 --- /dev/null +++ b/src/plugins/renderers/opengl/graphicshelpers/graphicshelperes2.cpp @@ -0,0 +1,1037 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "graphicshelperes2_p.h" +#include <private/attachmentpack_p.h> +#include <qgraphicsutils_p.h> +#include <renderbuffer_p.h> +#include <logging_p.h> +#include <QtGui/private/qopenglextensions_p.h> + + +QT_BEGIN_NAMESPACE + +// ES 3.0+ +#ifndef GL_SAMPLER_3D +#define GL_SAMPLER_3D 0x8B5F +#endif +#ifndef GL_SAMPLER_2D_SHADOW +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#endif +#ifndef GL_SAMPLER_CUBE_SHADOW +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#endif +#ifndef GL_SAMPLER_2D_ARRAY +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#endif +#ifndef GL_SAMPLER_2D_ARRAY_SHADOW +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#endif + +namespace Qt3DRender { +namespace Render { +namespace OpenGL { + +GraphicsHelperES2::GraphicsHelperES2() + : m_funcs(0) + , m_supportFramebufferBlit(false) +{ +} + +GraphicsHelperES2::~GraphicsHelperES2() +{ +} + +void GraphicsHelperES2::initializeHelper(QOpenGLContext *context, + QAbstractOpenGLFunctions *) +{ + Q_ASSERT(context); + m_funcs = context->functions(); + Q_ASSERT(m_funcs); + m_ext.reset(new QOpenGLExtensions(context)); + if (m_ext->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)) + m_supportFramebufferBlit = true; +} + +void GraphicsHelperES2::drawElementsInstancedBaseVertexBaseInstance(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"; + + if (baseVertex != 0) + qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 2"; + + for (GLint i = 0; i < instances; i++) + drawElements(primitiveType, + primitiveCount, + indexType, + indices); +} + +void GraphicsHelperES2::drawArraysInstanced(GLenum primitiveType, + GLint first, + GLsizei count, + GLsizei instances) +{ + for (GLint i = 0; i < instances; i++) + drawArrays(primitiveType, + first, + count); +} + +void GraphicsHelperES2::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) +{ + if (baseInstance != 0) + qWarning() << "glDrawArraysInstancedBaseInstance is not supported with OpenGL ES 2"; + for (GLint i = 0; i < instances; i++) + drawArrays(primitiveType, + first, + count); +} + +void GraphicsHelperES2::drawElements(GLenum primitiveType, + GLsizei primitiveCount, + GLint indexType, + void *indices, + GLint baseVertex) +{ + if (baseVertex != 0) + qWarning() << "glDrawElementsBaseVertex is not supported with OpenGL ES 2"; + QOpenGLExtensions *xfuncs = static_cast<QOpenGLExtensions *>(m_funcs); + if (indexType == GL_UNSIGNED_INT && !xfuncs->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint)) { + static bool warnShown = false; + if (!warnShown) { + warnShown = true; + qWarning("GL_UNSIGNED_INT index type not supported on this system, skipping draw call."); + } + return; + } + m_funcs->glDrawElements(primitiveType, + primitiveCount, + indexType, + indices); +} + +void GraphicsHelperES2::drawArrays(GLenum primitiveType, + GLint first, + GLsizei count) +{ + m_funcs->glDrawArrays(primitiveType, + first, + count); +} + +void GraphicsHelperES2::drawElementsIndirect(GLenum, GLenum, void *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "Indirect Drawing is not supported with OpenGL ES 2"; +} + +void GraphicsHelperES2::drawArraysIndirect(GLenum , void *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "Indirect Drawing is not supported with OpenGL ES 2"; +} + +void GraphicsHelperES2::setVerticesPerPatch(GLint verticesPerPatch) +{ + Q_UNUSED(verticesPerPatch); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "Tessellation not supported with OpenGL ES 2"; +} + +void GraphicsHelperES2::useProgram(GLuint programId) +{ + m_funcs->glUseProgram(programId); +} + +QVector<ShaderUniform> GraphicsHelperES2::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); + // Work around for uniform array names that aren't returned with [0] by some drivers + if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]"))) + uniform.m_name.append(QLatin1String("[0]")); + uniform.m_rawByteSize = uniformByteSize(uniform); + uniforms.append(uniform); + } + return uniforms; +} + +QVector<ShaderAttribute> GraphicsHelperES2::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> GraphicsHelperES2::programUniformBlocks(GLuint programId) +{ + Q_UNUSED(programId); + QVector<ShaderUniformBlock> blocks; + static bool showWarning = true; + if (!showWarning) + return blocks; + showWarning = false; + qWarning() << "UBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; + return blocks; +} + +QVector<ShaderStorageBlock> GraphicsHelperES2::programShaderStorageBlocks(GLuint programId) +{ + Q_UNUSED(programId); + QVector<ShaderStorageBlock> blocks; + static bool showWarning = true; + if (!showWarning) + return blocks; + showWarning = false; + qWarning() << "SSBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.1)"; + return blocks; +} + +void GraphicsHelperES2::vertexAttribDivisor(GLuint index, GLuint divisor) +{ + Q_UNUSED(index); + Q_UNUSED(divisor); +} + +void GraphicsHelperES2::vertexAttributePointer(GLenum shaderDataType, + GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const GLvoid *pointer) +{ + switch (shaderDataType) { + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: + m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer); + break; + + default: + qCWarning(Rendering) << "vertexAttribPointer: Unhandled type"; + Q_UNREACHABLE(); + } +} + +void GraphicsHelperES2::readBuffer(GLenum mode) +{ + Q_UNUSED(mode) + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glReadBuffer not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; +} + +void GraphicsHelperES2::drawBuffer(GLenum mode) +{ + Q_UNUSED(mode); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glDrawBuffer is not supported with OpenGL ES 2"; +} + +void *GraphicsHelperES2::fenceSync() +{ + qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; + return nullptr; +} + +void GraphicsHelperES2::clientWaitSync(void *, GLuint64 ) +{ + qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; +} + +void GraphicsHelperES2::waitSync(void *) +{ + qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; +} + +bool GraphicsHelperES2::wasSyncSignaled(void *) +{ + qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; + return false; +} + +void GraphicsHelperES2::deleteSync(void *) +{ + qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; +} + +void GraphicsHelperES2::rasterMode(GLenum faceMode, GLenum rasterMode) +{ + Q_UNUSED(faceMode); + Q_UNUSED(rasterMode); + qWarning() << "glPolyonMode is not supported with OpenGL ES"; +} + +void GraphicsHelperES2::blendEquation(GLenum mode) +{ + m_funcs->glBlendEquation(mode); +} + +void GraphicsHelperES2::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) +{ + Q_UNUSED(buf); + Q_UNUSED(sfactor); + Q_UNUSED(dfactor); + + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glBlendFunci() not supported by OpenGL ES 2.0"; +} + +void GraphicsHelperES2::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) +{ + Q_UNUSED(buf); + Q_UNUSED(sRGB); + Q_UNUSED(dRGB); + Q_UNUSED(sAlpha); + Q_UNUSED(dAlpha); + + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glBlendFuncSeparatei() not supported by OpenGL ES 2.0"; +} + +void GraphicsHelperES2::alphaTest(GLenum, GLenum) +{ + qCWarning(Rendering) << Q_FUNC_INFO << "AlphaTest not available with OpenGL ES 2.0"; +} + +void GraphicsHelperES2::depthTest(GLenum mode) +{ + m_funcs->glEnable(GL_DEPTH_TEST); + m_funcs->glDepthFunc(mode); +} + +void GraphicsHelperES2::depthMask(GLenum mode) +{ + m_funcs->glDepthMask(mode); +} + +void GraphicsHelperES2::depthRange(GLdouble nearValue, GLdouble farValue) +{ + m_funcs->glDepthRangef(static_cast<float>(nearValue), static_cast<float>(farValue)); +} + +void GraphicsHelperES2::frontFace(GLenum mode) +{ + m_funcs->glFrontFace(mode); +} + +void GraphicsHelperES2::setMSAAEnabled(bool enabled) +{ + Q_UNUSED(enabled); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "MSAA not available with OpenGL ES 2.0"; +} + +void GraphicsHelperES2::setAlphaCoverageEnabled(bool enabled) +{ + enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) + : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); +} + +GLuint GraphicsHelperES2::createFrameBufferObject() +{ + GLuint id; + m_funcs->glGenFramebuffers(1, &id); + return id; +} + +void GraphicsHelperES2::releaseFrameBufferObject(GLuint frameBufferId) +{ + m_funcs->glDeleteFramebuffers(1, &frameBufferId); +} + +void GraphicsHelperES2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) +{ + Q_UNUSED(mode) + // For ES2 the spec states for target: The symbolic constant must be GL_FRAMEBUFFER + // so mode is ignored and is always set to GL_FRAMEBUFFER + m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); +} + +void GraphicsHelperES2::bindImageTexture(GLuint imageUnit, GLuint texture, + GLint mipLevel, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + Q_UNUSED(imageUnit) + Q_UNUSED(texture) + Q_UNUSED(mipLevel) + Q_UNUSED(layered) + Q_UNUSED(layer) + Q_UNUSED(access) + Q_UNUSED(format) + qWarning() << "Shader Images are not supported by ES 2.0 (since ES 3.1)"; + +} + +GLuint GraphicsHelperES2::boundFrameBufferObject() +{ + GLint id = 0; + m_funcs->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &id); + return id; +} + +bool GraphicsHelperES2::checkFrameBufferComplete() +{ + return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); +} + +bool GraphicsHelperES2::frameBufferNeedsRenderBuffer(const Attachment &attachment) +{ + // Use a renderbuffer for depth or stencil attachments since this is + // problematic before GLES 3.2. Keep using textures for everything else. + // For ES2 individual Depth and Stencil buffers need to be an option because + // DepthStencil is an extension. + return attachment.m_point == QRenderTargetOutput::DepthStencil || + attachment.m_point == QRenderTargetOutput::Depth || + attachment.m_point == QRenderTargetOutput::Stencil; +} + +void GraphicsHelperES2::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) +{ + GLenum attr = GL_COLOR_ATTACHMENT0; + + if (attachment.m_point == QRenderTargetOutput::Color0) + attr = GL_COLOR_ATTACHMENT0; + else if (attachment.m_point == QRenderTargetOutput::Depth) + attr = GL_DEPTH_ATTACHMENT; + else if (attachment.m_point == QRenderTargetOutput::Stencil) + attr = GL_STENCIL_ATTACHMENT; + else + qCritical() << "Unsupported FBO attachment OpenGL ES 2.0"; + + const QOpenGLTexture::Target target = texture->target(); + + if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face == QAbstractTexture::AllFaces) { + qWarning() << "OpenGL ES 2.0 doesn't handle attaching all the faces of a cube map texture at once to an FBO"; + return; + } + + texture->bind(); + if (target == QOpenGLTexture::Target2D) + m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel); + else if (target == QOpenGLTexture::TargetCubeMap) + m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel); + else + qCritical() << "Unsupported Texture FBO attachment format"; + texture->release(); +} + +void GraphicsHelperES2::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) +{ + if (attachment.m_point != QRenderTargetOutput::DepthStencil && + attachment.m_point != QRenderTargetOutput::Depth && + attachment.m_point != QRenderTargetOutput::Stencil) { + qCritical() << "Renderbuffers only supported for combined depth-stencil, depth, or stencil, but got attachment point" + << attachment.m_point; + return; + } + + renderBuffer->bind(); + if (attachment.m_point == QRenderTargetOutput::DepthStencil || + attachment.m_point == QRenderTargetOutput::Depth) + m_funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer->renderBufferId()); + if (attachment.m_point == QRenderTargetOutput::DepthStencil || + attachment.m_point == QRenderTargetOutput::Stencil) + m_funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer->renderBufferId()); + renderBuffer->release(); +} + +bool GraphicsHelperES2::supportsFeature(GraphicsHelperInterface::Feature feature) const +{ + switch (feature) { + case RenderBufferDimensionRetrieval: + return true; + case BlitFramebuffer: + return m_supportFramebufferBlit; + default: + return false; + } +} + +void GraphicsHelperES2::drawBuffers(GLsizei, const int *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "drawBuffers is not supported by ES 2.0"; +} + +void GraphicsHelperES2::bindFragDataLocation(GLuint , const QHash<QString, int> &) +{ + qCritical() << "bindFragDataLocation is not supported by ES 2.0"; +} + +void GraphicsHelperES2::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +{ + Q_UNUSED(programId); + Q_UNUSED(uniformBlockIndex); + Q_UNUSED(uniformBlockBinding); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)"; +} + +void GraphicsHelperES2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) +{ + Q_UNUSED(programId); + Q_UNUSED(shaderStorageBlockIndex); + Q_UNUSED(shaderStorageBlockBinding); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "SSBO are not supported by ES 2.0 (since ES 3.1)"; +} + +void GraphicsHelperES2::bindBufferBase(GLenum target, GLuint index, GLuint buffer) +{ + Q_UNUSED(target); + Q_UNUSED(index); + Q_UNUSED(buffer); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "bindBufferBase is not supported by ES 2.0 (since ES 3.0)"; +} + +void GraphicsHelperES2::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) +{ + Q_UNUSED(v); + Q_UNUSED(description); + Q_UNUSED(buffer); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)"; +} + +uint GraphicsHelperES2::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: + rawByteSize = 8; + break; + + case GL_FLOAT_VEC3: + case GL_INT_VEC3: + rawByteSize = 12; + break; + + case GL_FLOAT_VEC4: + case GL_INT_VEC4: + rawByteSize = 16; + break; + + case GL_FLOAT_MAT2: + rawByteSize = matrixStride ? 2 * matrixStride : 16; + break; + + case GL_FLOAT_MAT3: + rawByteSize = matrixStride ? 3 * matrixStride : 36; + break; + + case GL_FLOAT_MAT4: + rawByteSize = matrixStride ? 4 * matrixStride : 64; + 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_SAMPLER_2D: + case GL_SAMPLER_CUBE: + rawByteSize = 4; + break; + } + + return arrayStride ? rawByteSize * arrayStride : rawByteSize; +} + +void GraphicsHelperES2::enableClipPlane(int) +{ +} + +void GraphicsHelperES2::disableClipPlane(int) +{ +} + +void GraphicsHelperES2::setClipPlane(int, const QVector3D &, float) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "Clip planes not supported by OpenGL ES 2.0"; +} + +GLint GraphicsHelperES2::maxClipPlaneCount() +{ + return 0; +} + +void GraphicsHelperES2::memoryBarrier(QMemoryBarrier::Operations barriers) +{ + Q_UNUSED(barriers); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "memory barrier is not supported by OpenGL ES 2.0 (since 4.3)"; +} + +void GraphicsHelperES2::enablePrimitiveRestart(int) +{ +} + +void GraphicsHelperES2::enableVertexAttributeArray(int location) +{ + m_funcs->glEnableVertexAttribArray(location); +} + +void GraphicsHelperES2::disablePrimitiveRestart() +{ +} + +void GraphicsHelperES2::clearBufferf(GLint drawbuffer, const QVector4D &values) +{ + Q_UNUSED(drawbuffer); + Q_UNUSED(values); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glClearBuffer*() not supported by OpenGL ES 2.0"; +} + +void GraphicsHelperES2::pointSize(bool programmable, GLfloat value) +{ + // If this is not a reset to default values, print a warning + if (programmable || !qFuzzyCompare(value, 1.0f)) { + static bool warned = false; + if (!warned) { + qWarning() << "glPointSize() and GL_PROGRAM_POINT_SIZE are not supported by ES 2.0"; + warned = true; + } + } +} + +void GraphicsHelperES2::enablei(GLenum cap, GLuint index) +{ + Q_UNUSED(cap); + Q_UNUSED(index); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glEnablei() not supported by OpenGL ES 2.0"; +} + +void GraphicsHelperES2::disablei(GLenum cap, GLuint index) +{ + Q_UNUSED(cap); + Q_UNUSED(index); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glDisablei() not supported by OpenGL ES 2.0"; +} + +void GraphicsHelperES2::setSeamlessCubemap(bool enable) +{ + Q_UNUSED(enable); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "GL_TEXTURE_CUBE_MAP_SEAMLESS not supported by OpenGL ES 2.0"; +} + +QSize GraphicsHelperES2::getRenderBufferDimensions(GLuint renderBufferId) +{ + GLint width = 0; + GLint height = 0; + + m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId); + m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); + m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); + m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0); + + return QSize(width, height); +} + +QSize GraphicsHelperES2::getTextureDimensions(GLuint textureId, GLenum target, uint level) +{ + Q_UNUSED(textureId); + Q_UNUSED(target); + Q_UNUSED(level); + qCritical() << "getTextureDimensions is not supported by ES 2.0"; + return QSize(0, 0); +} + +void GraphicsHelperES2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) +{ + Q_UNUSED(wx); + Q_UNUSED(wy); + Q_UNUSED(wz); + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "Compute Shaders are not supported by ES 2.0 (since ES 3.1)"; +} + +char *GraphicsHelperES2::mapBuffer(GLenum target, GLsizeiptr size) +{ + Q_UNUSED(target); + Q_UNUSED(size); + static bool showWarning = true; + if (!showWarning) + return nullptr; + showWarning = false; + qWarning() << "Map buffer is not a core requirement for ES 2.0"; + return nullptr; +} + +GLboolean GraphicsHelperES2::unmapBuffer(GLenum target) +{ + Q_UNUSED(target); + static bool showWarning = true; + if (!showWarning) + return false; + showWarning = false; + qWarning() << "unMap buffer is not a core requirement for ES 2.0"; + return false; +} + +void GraphicsHelperES2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform1fv(location, count, values); +} + +void GraphicsHelperES2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform2fv(location, count, values); +} + +void GraphicsHelperES2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform3fv(location, count, values); +} + +void GraphicsHelperES2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform4fv(location, count, values); +} + +void GraphicsHelperES2::glUniform1iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform1iv(location, count, values); +} + +void GraphicsHelperES2::glUniform2iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform2iv(location, count, values); +} + +void GraphicsHelperES2::glUniform3iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform3iv(location, count, values); +} + +void GraphicsHelperES2::glUniform4iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform4iv(location, count, values); +} + +void GraphicsHelperES2::glUniform1uiv(GLint , GLsizei , const GLuint *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniform1uiv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniform2uiv(GLint , GLsizei , const GLuint *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniform2uiv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniform3uiv(GLint , GLsizei , const GLuint *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniform3uiv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniform4uiv(GLint , GLsizei , const GLuint *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniform4uiv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2fv(location, count, false, values); +} + +void GraphicsHelperES2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3fv(location, count, false, values); +} + +void GraphicsHelperES2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4fv(location, count, false, values); +} + +void GraphicsHelperES2::glUniformMatrix2x3fv(GLint , GLsizei , const GLfloat *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniformMatrix2x3fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix3x2fv(GLint , GLsizei , const GLfloat *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniformMatrix3x2fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix2x4fv(GLint , GLsizei , const GLfloat *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniformMatrix2x4fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix4x2fv(GLint , GLsizei , const GLfloat *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniformMatrix4x2fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix3x4fv(GLint , GLsizei , const GLfloat *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniformMatrix3x4fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix4x3fv(GLint , GLsizei , const GLfloat *) +{ + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "glUniformMatrix4x3fv not supported by ES 2"; +} + +UniformType GraphicsHelperES2::uniformTypeFromGLType(GLenum type) +{ + switch (type) { + case GL_FLOAT: + return UniformType::Float; + case GL_FLOAT_VEC2: + return UniformType::Vec2; + case GL_FLOAT_VEC3: + return UniformType::Vec3; + case GL_FLOAT_VEC4: + return UniformType::Vec4; + case GL_FLOAT_MAT2: + return UniformType::Mat2; + case GL_FLOAT_MAT3: + return UniformType::Mat3; + case GL_FLOAT_MAT4: + return UniformType::Mat4; + case GL_INT: + return UniformType::Int; + case GL_INT_VEC2: + return UniformType::IVec2; + case GL_INT_VEC3: + return UniformType::IVec3; + case GL_INT_VEC4: + return UniformType::IVec4; + case GL_BOOL: + return UniformType::Bool; + case GL_BOOL_VEC2: + return UniformType::BVec2; + case GL_BOOL_VEC3: + return UniformType::BVec3; + case GL_BOOL_VEC4: + return UniformType::BVec4; + + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + return UniformType::Sampler; + default: + Q_UNREACHABLE(); + return UniformType::Float; + } +} + +void GraphicsHelperES2::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +{ + if (!m_supportFramebufferBlit) { + static bool showWarning = true; + if (!showWarning) + return; + showWarning = false; + qWarning() << "Framebuffer blits are not supported by ES 2.0 (since ES 3.1)"; + } else + m_ext->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +} // namespace OpenGL +} // namespace Render +} // namespace Qt3DRender + +QT_END_NAMESPACE |