blob: f485fc57bc46045aa21e40b192ffe09371a150d2 [file] [log] [blame]
/****************************************************************************
**
** 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;
if (!enabled) {
showWarning = false;
qWarning() << "MSAA cannot be disabled 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