context3d.cpp 215.22 KiB
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCanvas3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
** $QT_END_LICENSE$
****************************************************************************/
#include "canvasglstatedump_p.h"
#include "activeinfo3d_p.h"
#include "canvas3d_p.h"
#include "context3d_p.h"
#include "texture3d_p.h"
#include "shader3d_p.h"
#include "program3d_p.h"
#include "buffer3d_p.h"
#include "framebuffer3d_p.h"
#include "renderbuffer3d_p.h"
#include "uniformlocation_p.h"
#include "teximage3d_p.h"
#include "arrayutils_p.h"
#include "shaderprecisionformat_p.h"
#include "enumtostringmap_p.h"
#include "canvas3dcommon_p.h"
#include <QtGui/QOpenGLShader>
#include <QtQml/private/qv4typedarray_p.h>
#include <QtQml/private/qv4arraybuffer_p.h>
#include <QtQml/private/qjsvalue_p.h>
#include <QtCore/private/qbytedata_p.h>
QT_BEGIN_NAMESPACE
QT_CANVAS3D_BEGIN_NAMESPACE
/*!
 * \qmltype Context3D
 * \since QtCanvas3D 1.0
 * \ingroup qtcanvas3d-qml-types
 * \brief Provides the 3D rendering API and context.
 * An uncreatable QML type that provides a WebGL-like API that can be used to draw 3D graphics to
 * the Canvas3D element. You can get it by calling \l{Canvas3D::getContext}{Canvas3D.getContext}
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
* method. * * \sa Canvas3D */ CanvasContext::CanvasContext(QOpenGLContext *context, QSurface *surface, QQmlEngine *engine, int width, int height, bool isES2, QObject *parent) : CanvasAbstractObject(parent), QOpenGLFunctions(context), m_engine(engine), m_v4engine(QQmlEnginePrivate::getV4Engine(engine)), m_unpackFlipYEnabled(false), m_unpackPremultiplyAlphaEnabled(false), m_glViewportRect(0, 0, width, height), m_devicePixelRatio(1.0), m_currentProgram(0), m_currentArrayBuffer(0), m_currentElementArrayBuffer(0), m_currentTexture2D(0), m_context(context), m_surface(surface), m_error(NO_ERROR), m_currentFramebuffer(0), m_map(EnumToStringMap::newInstance()), m_canvas(0), m_maxVertexAttribs(0), m_isOpenGLES2(isES2), m_stateDumpExt(0), m_standardDerivatives(0) { m_extensions = m_context->extensions(); int value = 0; glGetIntegerv(MAX_VERTEX_ATTRIBS, &value); m_maxVertexAttribs = uint(value); #ifndef QT_NO_DEBUG const GLubyte *version = glGetString(GL_VERSION); qCDebug(canvas3dinfo).nospace() << "Context3D::" << __FUNCTION__ << "OpenGL version:" << (const char *)version; version = glGetString(GL_SHADING_LANGUAGE_VERSION); qCDebug(canvas3dinfo).nospace() << "Context3D::" << __FUNCTION__ << "GLSL version:" << (const char *)version; qCDebug(canvas3dinfo).nospace() << "Context3D::" << __FUNCTION__ << "EXTENSIONS: " << m_extensions; #endif } /*! * \internal */ CanvasContext::~CanvasContext() { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__; EnumToStringMap::deleteInstance(); } /*! * \internal */ void CanvasContext::setCanvas(Canvas *canvas) { if (m_canvas != canvas) { if (m_canvas) { disconnect(m_canvas, &QQuickItem::widthChanged, this, 0); disconnect(m_canvas, &QQuickItem::heightChanged, this, 0); }
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
m_canvas = canvas; emit canvasChanged(canvas); connect(m_canvas, &QQuickItem::widthChanged, this, &CanvasContext::drawingBufferWidthChanged); connect(m_canvas, &QQuickItem::heightChanged, this, &CanvasContext::drawingBufferHeightChanged); } } /*! * \qmlproperty Canvas3D Context3D::canvas * Holds the read only reference to the Canvas3D for this Context3D. */ Canvas *CanvasContext::canvas() { return m_canvas; } /*! * \qmlproperty int Context3D::drawingBufferWidth * Holds the current read-only logical pixel width of the drawing buffer. To get width in physical pixels * you need to multiply this with the \c devicePixelRatio. */ uint CanvasContext::drawingBufferWidth() { uint width = 0; if (m_canvas) width = m_canvas->width(); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(): " << width; return width; } /*! * \qmlproperty int Context3D::drawingBufferHeight * Holds the current read-only logical pixel height of the drawing buffer. To get height in physical pixels * you need to multiply this with the \c devicePixelRatio. */ uint CanvasContext::drawingBufferHeight() { uint height = 0; if (m_canvas) height = m_canvas->height(); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(): " << height; return height; } /*! * \internal */ QString CanvasContext::glEnumToString(glEnums value) const { return m_map->lookUp(value); } /*! * \internal */ void CanvasContext::logAllGLErrors(const QString &funcName) { if (!((QLoggingCategory &) canvas3dglerrors()).isDebugEnabled()) return; GLenum err; while ((err = glGetError()) != GL_NO_ERROR) {
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
qCWarning(canvas3dglerrors).nospace() << "Context3D::" << funcName << ": OpenGL ERROR: " << glEnumToString(CanvasContext::glEnums(err)); } } /*! * \internal */ void CanvasContext::setContextAttributes(const CanvasContextAttributes &attribs) { m_contextAttributes.setFrom(attribs); } /*! * \internal */ float CanvasContext::devicePixelRatio() { return m_devicePixelRatio; } /*! * \internal */ void CanvasContext::setDevicePixelRatio(float ratio) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(" << ratio << ")"; m_devicePixelRatio = ratio; } /*! * \internal */ QRect CanvasContext::glViewportRect() const { return m_glViewportRect; } /*! * \internal */ GLuint CanvasContext::currentFramebuffer() { if (!m_currentFramebuffer) return 0; return m_currentFramebuffer->id(); } /*! * \qmlmethod ShaderPrecisionFormat Context3D::getShaderPrecisionFormat(glEnums shadertype, glEnums precisiontype) * Return a new ShaderPrecisionFormat describing the range and precision for the specified shader * numeric format. * \a shadertype Type of the shader, either \c Context3D.FRAGMENT_SHADER or * \c{Context3D.VERTEX_SHADER}. * \a precisiontype Can be \c{Context3D.LOW_FLOAT}, \c{Context3D.MEDIUM_FLOAT}, * \c{Context3D.HIGH_FLOAT}, \c{Context3D.LOW_INT}, \c{Context3D.MEDIUM_INT} or * \c{Context3D.HIGH_INT}. * * \sa ShaderPrecisionFormat */ /*! * \internal */ QJSValue CanvasContext::getShaderPrecisionFormat(glEnums shadertype, glEnums precisiontype) { QString str = QString(__FUNCTION__); str += QStringLiteral("(shaderType:")
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
+ glEnumToString(shadertype) + QStringLiteral(", precisionType:") + glEnumToString(precisiontype) + QStringLiteral(")"); qCDebug(canvas3drendering).nospace() << "Context3D::" << str; GLint range[2]; range[0] = 1; range[1] = 1; GLint precision = 1; glGetShaderPrecisionFormat((GLenum)(shadertype), (GLenum)(precisiontype), range, &precision); logAllGLErrors(str); CanvasShaderPrecisionFormat *format = new CanvasShaderPrecisionFormat(); format->setPrecision(int(precision)); format->setRangeMin(int(range[0])); format->setRangeMax(int(range[1])); return m_engine->newQObject(format); } /*! * \qmlmethod bool Context3D::isContextLost() * Always returns false. */ /*! * \internal */ bool CanvasContext::isContextLost() { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(): false"; return false; } /*! * \qmlmethod ContextAttributes Context3D::getContextAttributes() * Returns a copy of the actual context parameters that are used in the current context. */ /*! * \internal */ QJSValue CanvasContext::getContextAttributes() { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "()"; CanvasContextAttributes *attributes = new CanvasContextAttributes(); attributes->setAlpha(m_contextAttributes.alpha()); attributes->setDepth(m_contextAttributes.depth()); attributes->setStencil(m_contextAttributes.stencil()); attributes->setAntialias(m_contextAttributes.antialias()); attributes->setPremultipliedAlpha(m_contextAttributes.premultipliedAlpha()); attributes->setPreserveDrawingBuffer(m_contextAttributes.preserveDrawingBuffer()); attributes->setPreferLowPowerToHighPerformance( m_contextAttributes.preferLowPowerToHighPerformance()); attributes->setFailIfMajorPerformanceCaveat( m_contextAttributes.failIfMajorPerformanceCaveat()); return m_engine->newQObject(attributes); } /*! * \qmlmethod void Context3D::flush() * Indicates to graphics driver that previously sent commands must complete within finite time. */ /*! * \internal */ void CanvasContext::flush()
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
{ qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "()"; glFlush(); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::finish() * Forces all previous 3D rendering commands to complete. */ /*! * \internal */ void CanvasContext::finish() { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "()"; glFinish(); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod Texture3D Context3D::createTexture() * Create a Texture3D object and initialize a name for it as by calling \c{glGenTextures()}. */ /*! * \internal */ QJSValue CanvasContext::createTexture() { CanvasTexture *texture = new CanvasTexture(this); QJSValue value = m_engine->newQObject(texture); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "():" << value.toString(); logAllGLErrors(__FUNCTION__); return value; } /*! * \qmlmethod void Context3D::deleteTexture(Texture3D texture3D) * Deletes the given texture as if by calling \c{glDeleteTextures()}. * Calling this method repeatedly on the same object has no side effects. * \a texture3D is the Texture3D to be deleted. */ /*! * \internal */ void CanvasContext::deleteTexture(QJSValue texture3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(texture:" << texture3D.toString() << ")"; CanvasTexture *texture = getAsTexture3D(texture3D); if (!texture) { texture->del(); logAllGLErrors(__FUNCTION__); } else { m_error = INVALID_VALUE; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID texture handle:" << texture3D.toString(); } } /*! * \qmlmethod void Context3D::scissor(int x, int y, int width, int height) * Defines a rectangle that constrains the drawing. * \a x is theleft edge of the rectangle. * \a y is the bottom edge of the rectangle. * \a width is the width of the rectangle.
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
* \a height is the height of the rectangle. */ /*! * \internal */ void CanvasContext::scissor(int x, int y, int width, int height) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(x:" << x << ", y:" << y << ", width:" << width << ", height:" << height << ")"; glScissor(x, y, width, height); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::activeTexture(glEnums texture) * Sets the given texture unit as active. Number of texture units is implementation dependent, * but must be at least 8. Initially \c Context3D.TEXTURE0 is active. * \a texture must be one of \c Context3D.TEXTUREi values where \c i ranges from \c 0 to * \c{(Context3D.MAX_COMBINED_TEXTURE_IMAGE_UNITS-1)}. */ /*! * \internal */ void CanvasContext::activeTexture(glEnums texture) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(texture:" << glEnumToString(texture) << ")"; glActiveTexture(GLenum(texture)); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::bindTexture(glEnums target, Texture3D texture3D) * Bind a Texture3D to a texturing target. * \a target is the target of the active texture unit to which the Texture3D will be bound. * Must be either \c{Context3D.TEXTURE_2D} or \c{Context3D.TEXTURE_CUBE_MAP}. * \a texture3D is the Texture3D to be bound. */ /*! * \internal */ void CanvasContext::bindTexture(glEnums target, QJSValue texture3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", texture:" << texture3D.toString() << ")"; CanvasTexture *texture = getAsTexture3D(texture3D); if (target == TEXTURE_2D) m_currentTexture2D = texture; else if (target == TEXTURE_CUBE_MAP) m_currentTextureCubeMap = texture; if (texture) { if (!texture->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": Trying to bind deleted texture object"; return; } if (target == TEXTURE_2D) m_currentTexture2D->bind(target); else if (target == TEXTURE_CUBE_MAP)
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
m_currentTextureCubeMap->bind(target); } else { glBindTexture(GLenum(target), 0); } logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::generateMipmap(glEnums target) * Generates a complete set of mipmaps for a texture object of the currently active texture unit. * \a target defines the texture target to which the texture object is bound whose mipmaps will be * generated. Must be either \c{Context3D.TEXTURE_2D} or \c{Context3D.TEXTURE_CUBE_MAP}. */ /*! * \internal */ void CanvasContext::generateMipmap(glEnums target) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ")"; if (target == TEXTURE_2D) { if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current TEXTURE_2D bound"; m_error = INVALID_OPERATION; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION " << "Currently bound TEXTURE_2D is deleted"; m_error = INVALID_OPERATION; } else { glGenerateMipmap(target); logAllGLErrors(__FUNCTION__); } } else if (target == TEXTURE_CUBE_MAP) { if (!m_currentTextureCubeMap) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION " << "No current TEXTURE_CUBE_MAP bound"; m_error = INVALID_OPERATION; } else if (!m_currentTextureCubeMap->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION " << "Currently bound TEXTURE_CUBE_MAP is deleted"; m_error = INVALID_OPERATION; } else { glGenerateMipmap(target); logAllGLErrors(__FUNCTION__); } } } /*! * \qmlmethod bool Context3D::isTexture(Object anyObject) * Returns true if the given object is a valid Texture3D object. * \a anyObject is the object that is to be verified as a valid texture. */ /*! * \internal */ bool CanvasContext::isTexture(QJSValue anyObject) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(anyObject:" << anyObject.toString() << ")"; CanvasTexture *texture = getAsTexture3D(anyObject);
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
if (!texture) return false; return glIsTexture(texture->textureId()); } /*! * \internal */ CanvasTexture *CanvasContext::getAsTexture3D(QJSValue anyObject) { if (!anyObject.isQObject()) return 0; if (!isOfType(anyObject, "QtCanvas3D::CanvasTexture")) return 0; CanvasTexture *texture = static_cast<CanvasTexture *>(anyObject.toQObject()); if (!texture->isAlive()) return 0; return texture; } /*! * \qmlmethod void Context3D::compressedTexImage2D(glEnums target, int level, glEnums internalformat, int width, int height, int border, TypedArray pixels) * Not supported, \c{Context3D.INVALID_OPERATION} is generated when called. * \a target, \a level, \a internalformat, \a width, \a height, \a border and \a pixels are ignored. */ /*! * \internal */ void CanvasContext::compressedTexImage2D(glEnums target, int level, glEnums internalformat, int width, int height, int border, QJSValue pixels) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", level:" << level << ", internalformat:" << glEnumToString(internalformat) << ", width:" << width << ", height:" << height << ", border:" << border << ", pixels:" << pixels.toString() << ")"; if (target == TEXTURE_2D) { if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION " << "No current TEXTURE_2D bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION " << "Currently bound TEXTURE_2D is deleted"; m_error = INVALID_OPERATION; return; } } else if (target == TEXTURE_CUBE_MAP) { if (!m_currentTextureCubeMap) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION " << "No current TEXTURE_CUBE_MAP bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTextureCubeMap->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
<< ":INVALID_OPERATION " << "Currently bound TEXTURE_CUBE_MAP is deleted"; m_error = INVALID_OPERATION; return; } } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, pixels)); if (typedArray) { glCompressedTexImage2D(target, level, internalformat, width, height, border, typedArray->byteLength(), (GLvoid *) typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } else { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE pixels must be TypedArray"; m_error = INVALID_VALUE; return; } } /*! * \qmlmethod void Context3D::compressedTexSubImage2D(glEnums target, int level, int xoffset, int yoffset, int width, int height, glEnums format, TypedArray pixels) * Not supported, \c{Context3D.INVALID_OPERATION} is generated when called. * \a target, \a level, \a xoffset, \a yoffset, \a width, \a height, \a format and \a pixels are * ignored. */ /*! * \internal */ void CanvasContext::compressedTexSubImage2D(glEnums target, int level, int xoffset, int yoffset, int width, int height, glEnums format, QJSValue pixels) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", level:" << level << ", xoffset:" << xoffset << ", yoffset:" << yoffset << ", width:" << width << ", height:" << height << ", format:" << glEnumToString(format) << ", pixels:" << pixels.toString() << ")"; if (target == TEXTURE_2D) { if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current TEXTURE_2D bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION " << "Currently bound TEXTURE_2D is deleted"; m_error = INVALID_OPERATION; return; } } else if (target == TEXTURE_CUBE_MAP) { if (!m_currentTextureCubeMap) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION "
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
<< "No current TEXTURE_CUBE_MAP bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTextureCubeMap->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION " << "Currently bound TEXTURE_CUBE_MAP is deleted"; m_error = INVALID_OPERATION; return; } } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, pixels)); if (typedArray) { glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, typedArray->byteLength(), (GLvoid *) typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } else { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE pixels must be TypedArray"; m_error = INVALID_VALUE; return; } } /*! * \qmlmethod void Context3D::copyTexImage2D(glEnums target, int level, glEnums internalformat, int x, int y, int width, int height, int border) * Copies pixels into currently bound 2D texture. * \a target specifies the target texture of the active texture unit. Must be \c{Context3D.TEXTURE_2D}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_X}, \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_X}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Y}, \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_Y}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Z}, or \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_Z}. * \a level specifies the level of detail number. Level \c 0 is the base image level. Level \c n is * the \c{n}th mipmap reduction image. * \a internalformat specifies the internal format of the texture. Must be \c{Context3D.ALPHA}, * \c{Context3D.LUMINANCE}, \c{Context3D.LUMINANCE_ALPHA}, \c{Context3D.RGB} or \c{Context3D.RGBA}. * \a x specifies the window coordinate of the left edge of the rectangular region of pixels to be * copied. * \a y specifies the window coordinate of the lower edge of the rectangular region of pixels to be * copied. * \a width specifies the width of the texture image. All implementations will support 2D texture * images that are at least 64 texels wide and cube-mapped texture images that are at least 16 * texels wide. * \a height specifies the height of the texture image. All implementations will support 2D texture * images that are at least 64 texels high and cube-mapped texture images that are at least 16 * texels high. * \a border must be \c{0}. */ /*! * \internal */ void CanvasContext::copyTexImage2D(glEnums target, int level, glEnums internalformat, int x, int y, int width, int height, int border) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", level:" << level << ", internalformat:" << glEnumToString(internalformat) << ", x:" << x << ", y:" << y << ", width:" << width
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
<< ", height:" << height << ", border:" << border << ")"; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; } else { glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); logAllGLErrors(__FUNCTION__); } } /*! * \qmlmethod void Context3D::copyTexSubImage2D(glEnums target, int level, int xoffset, int yoffset, int x, int y, int width, int height) * Copies to into a currently bound 2D texture subimage. * \a target specifies the target texture of the active texture unit. Must be * \c{Context3D.TEXTURE_2D}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_X}, \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_X}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Y}, \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_Y}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Z}, or \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_Z}. * \a level specifies the level of detail number. Level \c 0 is the base image level. Level \c n is * the \c{n}th mipmap reduction image. * \a xoffset specifies the texel offset in the x direction within the texture array. * \a yoffset specifies the texel offset in the y direction within the texture array. * \a x specifies the window coordinate of the left edge of the rectangular region of pixels to be * copied. * \a y specifies the window coordinate of the lower edge of the rectangular region of pixels to be * copied. * \a width specifies the width of the texture subimage. * \a height specifies the height of the texture subimage. */ /*! * \internal */ void CanvasContext::copyTexSubImage2D(glEnums target, int level, int xoffset, int yoffset, int x, int y, int width, int height) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", level:" << level << ", xoffset:" << xoffset << ", yoffset:" << yoffset << ", x:" << x << ", y:" << y << ", width:" << width << ", height:" << height << ")"; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; } else { copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); logAllGLErrors(__FUNCTION__); } }
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
/*! * \qmlmethod void Context3D::texImage2D(glEnums target, int level, glEnums internalformat, int width, int height, int border, glEnums format, glEnums type, TypedArray pixels) * Specify a 2D texture image. * \a target specifies the target texture of the active texture unit. Must be one of: * \c{Context3D.TEXTURE_2D}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_X}, \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_X}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Y}, \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_Y}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Z}, or \c{Context3D.TEXTURE_CUBE_MAP_NEGATIVE_Z}. * \a level specifies the level of detail number. Level \c 0 is the base image level. Level \c n is * the \c{n}th mipmap reduction image. * \a internalformat specifies the internal format of the texture. Must be \c{Context3D.ALPHA}, * \c{Context3D.LUMINANCE}, \c{Context3D.LUMINANCE_ALPHA}, \c{Context3D.RGB} or \c{Context3D.RGBA}. * \a width specifies the width of the texture image. All implementations will support 2D texture * images that are at least 64 texels wide and cube-mapped texture images that are at least 16 * texels wide. * \a height specifies the height of the texture image. All implementations will support 2D texture * images that are at least 64 texels high and cube-mapped texture images that are at least 16 * texels high. * \a border must be \c{0}. * \a format specifies the format of the texel data given in \a pixels, must match the value * of \a internalFormat. * \a type specifies the data type of the data given in \a pixels, must match the TypedArray type * of \a pixels. Must be \c{Context3D.UNSIGNED_BYTE}, \c{Context3D.UNSIGNED_SHORT_5_6_5}, * \c{Context3D.UNSIGNED_SHORT_4_4_4_4} or \c{Context3D.UNSIGNED_SHORT_5_5_5_1}. * \a pixels specifies the TypedArray containing the image data. If pixels is \c{null}, a buffer * of sufficient size initialized to 0 is passed. */ /*! * \internal */ void CanvasContext::texImage2D(glEnums target, int level, glEnums internalformat, int width, int height, int border, glEnums format, glEnums type, QJSValue pixels) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", level:" << level << ", internalformat:" << glEnumToString(internalformat) << ", width:" << width << ", height:" << height << ", border:" << border << ", format:" << glEnumToString(format) << ", type:" << glEnumToString(type) << ", pixels:" << pixels.toString() << ")"; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; return; } int bytesPerPixel = 0; uchar *srcData = 0; uchar *unpackedData = 0; bool deleteTempPixels = false; if (pixels.isNull()) { deleteTempPixels = true; int size = getSufficientSize(type, width, height); srcData = new uchar[size]; memset(srcData, 0, size); }
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
switch (type) { case UNSIGNED_BYTE: { switch (format) { case ALPHA: bytesPerPixel = 1; break; case RGB: bytesPerPixel = 3; break; case RGBA: bytesPerPixel = 4; break; case LUMINANCE: bytesPerPixel = 1; break; case LUMINANCE_ALPHA: bytesPerPixel = 2; break; default: break; } if (bytesPerPixel == 0) { m_error = INVALID_ENUM; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM Invalid format supplied " << glEnumToString(format); return; } if (!srcData) srcData = getAsUint8ArrayRawPtr(pixels); if (!srcData) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Expected Uint8Array, received " << pixels.toString(); m_error = INVALID_OPERATION; return; } unpackedData = unpackPixels(srcData, false, bytesPerPixel, width, height); glTexImage2D(target, level, internalformat, width, height, border, format, type, unpackedData); logAllGLErrors(__FUNCTION__); } break; case UNSIGNED_SHORT_4_4_4_4: case UNSIGNED_SHORT_5_6_5: case UNSIGNED_SHORT_5_5_5_1: { if (!srcData) srcData = getAsUint16ArrayRawPtr(pixels); if (!srcData) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Expected Uint16Array, received " << pixels.toString(); m_error = INVALID_OPERATION; return; } unpackedData = unpackPixels(srcData, false, 2, width, height); glTexImage2D(target, level, internalformat, width, height, border, format, type, unpackedData); logAllGLErrors(__FUNCTION__); } break; default:
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM Invalid type enum"; m_error = INVALID_ENUM; break; } // Delete temp data if (unpackedData != srcData) delete unpackedData; if (deleteTempPixels) delete[] srcData; } /*! * \internal */ uchar *CanvasContext::getAsUint8ArrayRawPtr(QJSValue jsValue) { QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, jsValue)); if (!typedArray) return 0; if (typedArray->arrayType() != QV4::Heap::TypedArray::UInt8Array) return 0; return reinterpret_cast<unsigned char *>(typedArray->arrayData()->data()); } /*! * \internal */ uchar *CanvasContext::getAsUint16ArrayRawPtr(QJSValue jsValue) { QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, jsValue)); if (!typedArray) return 0; if (typedArray->arrayType() != QV4::Heap::TypedArray::UInt16Array) return 0; return reinterpret_cast<unsigned char *>(typedArray->arrayData()->data()); } /*! * \qmlmethod void Context3D::texSubImage2D(glEnums target, int level, int xoffset, int yoffset, int width, int height, glEnums format, glEnums type, TypedArray pixels) * Specify a 2D texture subimage. * \a target Target texture of the active texture unit. Must be \c{Context3D.TEXTURE_2D}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_X}, \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_X}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Y}, \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_Y}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Z}, or \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_Z}. * \a level Level of detail number. Level \c 0 is the base image level. Level \c n is the \c{n}th * mipmap reduction image. * \a xoffset Specifies a texel offset in the x direction within the texture array. * \a yoffset Specifies a texel offset in the y direction within the texture array. * \a width Width of the texture subimage. * \a height Height of the texture subimage. * \a format Format of the texel data given in \a pixels, must match the value * of \a internalFormat. * \a type Data type of the data given in \a pixels, must match the TypedArray type * of \a pixels. Must be \c{Context3D.UNSIGNED_BYTE}, \c{Context3D.UNSIGNED_SHORT_5_6_5}, * \c{Context3D.UNSIGNED_SHORT_4_4_4_4} or \c{Context3D.UNSIGNED_SHORT_5_5_5_1}. * \a pixels TypedArray containing the image data. If pixels is \c null, a buffer of
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
* sufficient size initialized to 0 is passed. */ /*! * \internal */ void CanvasContext::texSubImage2D(glEnums target, int level, int xoffset, int yoffset, int width, int height, glEnums format, glEnums type, QJSValue pixels) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", level:" << level << ", xoffset:" << xoffset << ", yoffset:" << yoffset << ", width:" << width << ", height:" << height << ", format:" << glEnumToString(format) << ", type:" << glEnumToString(type) << ", pixels:" << pixels.toString() << ")"; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; return; } if (pixels.isNull()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE pixels was null"; m_error = INVALID_VALUE; return; } int bytesPerPixel = 0; uchar *srcData = 0; uchar *unpackedData = 0; switch (type) { case UNSIGNED_BYTE: { switch (format) { case ALPHA: bytesPerPixel = 1; break; case RGB: bytesPerPixel = 3; break; case RGBA: bytesPerPixel = 4; break; case LUMINANCE: bytesPerPixel = 1; break; case LUMINANCE_ALPHA: bytesPerPixel = 2; break; default: break; } if (bytesPerPixel == 0) { m_error = INVALID_ENUM; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
<< ":INVALID_ENUM Invalid format supplied " << glEnumToString(format); return; } srcData = getAsUint8ArrayRawPtr(pixels); if (!srcData) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Expected Uint8Array, received " << pixels.toString(); m_error = INVALID_OPERATION; return; } unpackedData = unpackPixels(srcData, false, bytesPerPixel, width, height); glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, unpackedData); logAllGLErrors(__FUNCTION__); } break; case UNSIGNED_SHORT_4_4_4_4: case UNSIGNED_SHORT_5_6_5: case UNSIGNED_SHORT_5_5_5_1: { srcData = getAsUint16ArrayRawPtr(pixels); if (!srcData) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Expected Uint16Array, received " << pixels.toString(); m_error = INVALID_OPERATION; return; } unpackedData = unpackPixels(srcData, false, 2, width, height); glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, unpackedData); logAllGLErrors(__FUNCTION__); } break; default: qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM Invalid type enum"; m_error = INVALID_ENUM; break; } // Delete temp data if (unpackedData != srcData) delete unpackedData; } /*! * \internal */ uchar* CanvasContext::unpackPixels(uchar *srcData, bool useSrcDataAsDst, int bytesPerPixel, int width, int height) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(srcData:" << srcData << ", useSrcDataAsDst:" << useSrcDataAsDst << ", bytesPerPixel:" << bytesPerPixel << ", width:" << width << ", height:" << height << ")"; // Check if no processing is needed if (!m_unpackFlipYEnabled || srcData == 0 || width == 0 || height == 0 || bytesPerPixel == 0) return srcData; uchar *unpackedData = srcData; int bytesPerRow = width * bytesPerPixel; if (m_unpackFlipYEnabled) {
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
if (useSrcDataAsDst) { uchar *row = new uchar[width*bytesPerPixel]; for (int y = 0; y < height; y++) { memcpy(row, srcData + y * bytesPerRow, bytesPerRow); memcpy(srcData + y * bytesPerRow, srcData + (height - y - 1) * bytesPerRow, bytesPerRow); memcpy(srcData + (height - y - 1) * bytesPerRow, row, bytesPerRow); } } else { unpackedData = new uchar[height * bytesPerRow]; for (int y = 0; y < height; y++) { memcpy(unpackedData + (height - y - 1) * bytesPerRow, srcData + y * bytesPerRow, bytesPerRow); } } } return unpackedData; } /*! * \qmlmethod void Context3D::texImage2D(glEnums target, int level, glEnums internalformat, glEnums format, glEnums type, TextureImage texImage) * Uploads the given TextureImage element to the currently bound Texture3D. * \a target Target texture of the active texture unit. Must be \c{Context3D.TEXTURE_2D}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_X}, \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_X}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Y}, \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_Y}, * \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Z}, or \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_Z}. * \a level Level of detail number. Level \c 0 is the base image level. Level \c n is the \c{n}th * mipmap reduction image. * \a internalformat Internal format of the texture, conceptually the given image is first * converted to this format, then uploaded. Must be \c{Context3D.ALPHA}, \c{Context3D.LUMINANCE}, * \c{Context3D.LUMINANCE_ALPHA}, \c{Context3D.RGB} or \c{Context3D.RGBA}. * \a format Format of the texture, must match the value of \a internalFormat. * \a type Type of the data, conceptually the given image is first converted to this type, then * uploaded. Must be \c{Context3D.UNSIGNED_BYTE}, \c{Context3D.UNSIGNED_SHORT_5_6_5}, * \c{Context3D.UNSIGNED_SHORT_4_4_4_4} or \c{Context3D.UNSIGNED_SHORT_5_5_5_1}. * \a texImage A complete \c{TextureImage} loaded using the \c{TextureImageLoader}. */ /*! * \internal */ void CanvasContext::texImage2D(glEnums target, int level, glEnums internalformat, glEnums format, glEnums type, QJSValue texImage) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", level:" << level << ", internalformat:" << glEnumToString(internalformat) << ", format:" << glEnumToString(format) << ", type:" << glEnumToString(type) << ", texImage:" << texImage.toString() << ")"; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; return; }
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
CanvasTextureImage *image = getAsTextureImage(texImage); if (!image) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE invalid texImage " << texImage.toString(); m_error = INVALID_VALUE; return; } uchar *pixels = 0; switch (type) { case UNSIGNED_BYTE: pixels = image->convertToFormat(type, m_unpackFlipYEnabled, m_unpackPremultiplyAlphaEnabled); break; case UNSIGNED_SHORT_5_6_5: case UNSIGNED_SHORT_4_4_4_4: case UNSIGNED_SHORT_5_5_5_1: pixels = image->convertToFormat(type, m_unpackFlipYEnabled, m_unpackPremultiplyAlphaEnabled); break; default: qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM Invalid type enum"; m_error = INVALID_ENUM; return; } if (pixels == 0) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":Conversion of pixels to format failed."; return; } if (!m_currentTexture2D->hasSpecificName()) { m_currentTexture2D->setName("ImageTexture_"+image->name()); } glTexImage2D(target, level, internalformat, image->width(), image->height(), 0, format, type, pixels); logAllGLErrors(__FUNCTION__); } /*! * \internal */ CanvasTextureImage* CanvasContext::getAsTextureImage(QJSValue anyObject) { if (!anyObject.isQObject()) return 0; if (!isOfType(anyObject, "QtCanvas3D::CanvasTextureImage")) return 0; CanvasTextureImage *texImage = static_cast<CanvasTextureImage *>(anyObject.toQObject()); return texImage; } /*! * \qmlmethod void Context3D::texSubImage2D(glEnums target, int level, int xoffset, int yoffset, glEnums format, glEnums type, TextureImage texImage) * Uploads the given TextureImage element to the currently bound Texture3D. * \a target specifies the target texture of the active texture unit. Must be * \c{Context3D.TEXTURE_2D}, \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_X}, * \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_X}, \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Y}, * \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_Y}, \c{Context3D.TEXTURE_CUBE_MAP_POSITIVE_Z}, or * \c{Context3D.TEXTURE_CUBE_MAP__NEGATIVE_Z}. * \a level Level of detail number. Level \c 0 is the base image level. Level \c n is the \c{n}th * mipmap reduction image. * \a internalformat Internal format of the texture, conceptually the given image is first * converted to this format, then uploaded. Must be \c{Context3D.ALPHA}, \c{Context3D.LUMINANCE},
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
* \c{Context3D.LUMINANCE_ALPHA}, \c{Context3D.RGB} or \c{Context3D.RGBA}. * \a format Format of the texture, must match the value of \a internalFormat. * \a type Type of the data, conceptually the given image is first converted to this type, then * uploaded. Must be \c{Context3D.UNSIGNED_BYTE}, \c{Context3D.UNSIGNED_SHORT_5_6_5}, * \c{Context3D.UNSIGNED_SHORT_4_4_4_4} or \c{Context3D.UNSIGNED_SHORT_5_5_5_1}. * \a texImage A complete \c{TextureImage} loaded using the \c{TextureImageLoader}. */ /*! * \internal */ void CanvasContext::texSubImage2D(glEnums target, int level, int xoffset, int yoffset, glEnums format, glEnums type, QJSValue texImage) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "( target:" << glEnumToString(target) << ", level:" << level << ", xoffset:" << xoffset << ", yoffset:" << yoffset << ", format:" << glEnumToString(format) << ", type:" << glEnumToString(type) << ", texImage:" << texImage.toString() << ")"; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; return; } CanvasTextureImage *image = getAsTextureImage(texImage); if (!image) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE invalid texImage " << texImage.toString(); m_error = INVALID_VALUE; return; } uchar *pixels = 0; switch (type) { case UNSIGNED_BYTE: pixels = image->convertToFormat(type, m_unpackFlipYEnabled, m_unpackPremultiplyAlphaEnabled); break; case UNSIGNED_SHORT_5_6_5: case UNSIGNED_SHORT_4_4_4_4: case UNSIGNED_SHORT_5_5_5_1: pixels = image->convertToFormat(type, m_unpackFlipYEnabled, m_unpackPremultiplyAlphaEnabled); break; default: qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM Invalid type enum"; m_error = INVALID_ENUM; return; } if (pixels == 0) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":Conversion of pixels to format failed."; return;
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
} glTexSubImage2D(target, level, xoffset, yoffset, image->width(), image->height(), format, type, pixels); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::texParameterf(glEnums target, glEnums pname, float param) * Sets texture parameters. * \a target specifies the target texture of the active texture unit. Must be * \c{Context3D.TEXTURE_2D} or \c{Context3D.TEXTURE_CUBE_MAP}. * \a pname specifies the symbolic name of a texture parameter. pname can be * \c{Context3D.TEXTURE_MIN_FILTER}, \c{Context3D.TEXTURE_MAG_FILTER}, \c{Context3D.TEXTURE_WRAP_S} or * \c{Context3D.TEXTURE_WRAP_T}. * \a param specifies the new float value to be set to \a pname */ /*! * \internal */ void CanvasContext::texParameterf(glEnums target, glEnums pname, float param) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "( target:" << glEnumToString(target) << ", pname:" << glEnumToString(pname) << ", param:" << param << ")"; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; return; } glTexParameterf(GLenum(target), GLenum(pname), GLfloat(param)); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::texParameteri(glEnums target, glEnums pname, float param) * Sets texture parameters. * \a target specifies the target texture of the active texture unit. Must be * \c{Context3D.TEXTURE_2D} or \c{Context3D.TEXTURE_CUBE_MAP}. * \a pname specifies the symbolic name of a texture parameter. pname can be * \c{Context3D.TEXTURE_MIN_FILTER}, \c{Context3D.TEXTURE_MAG_FILTER}, \c{Context3D.TEXTURE_WRAP_S} or * \c{Context3D.TEXTURE_WRAP_T}. * \a param specifies the new int value to be set to \a pname */ /*! * \internal */ void CanvasContext::texParameteri(glEnums target, glEnums pname, int param) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", pname:" << glEnumToString(pname) << ", param:" << glEnumToString(glEnums(param)) << ")"; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; return; } else if (!m_currentTexture2D->isAlive()) {
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; return; } glTexParameteri(GLenum(target), GLenum(pname), GLint(param)); logAllGLErrors(__FUNCTION__); } /*! * \internal */ int CanvasContext::getSufficientSize(glEnums internalFormat, int width, int height) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "( internalFormat:" << glEnumToString(internalFormat) << " , width:" << width << ", height:" << height << ")"; int bytesPerPixel = 0; switch (internalFormat) { case UNSIGNED_BYTE: bytesPerPixel = 4; break; case UNSIGNED_SHORT_5_6_5: case UNSIGNED_SHORT_4_4_4_4: case UNSIGNED_SHORT_5_5_5_1: bytesPerPixel = 2; break; default: break; } return width * height * bytesPerPixel; } /*! * \qmlmethod FrameBuffer3D Context3D::createFramebuffer() * Returns a created FrameBuffer3D object that is initialized with a framebuffer object name as * if by calling \c{glGenFramebuffers()}. */ /*! * \internal */ QJSValue CanvasContext::createFramebuffer() { CanvasFrameBuffer *framebuffer = new CanvasFrameBuffer(this); QJSValue value = m_engine->newQObject(framebuffer); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << ":" << value.toString(); logAllGLErrors(__FUNCTION__); return value; } /*! * \qmlmethod void Context3D::bindFramebuffer(glEnums target, FrameBuffer3D buffer) * Binds the given \a buffer object to the given \a target. * \a target must be \c{Context3D.FRAMEBUFFER}. */ /*! * \internal */ void CanvasContext::bindFramebuffer(glEnums target, QJSValue buffer) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", framebuffer:" << buffer.toString() << ")";
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
if (target != FRAMEBUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_ENUM bind target, must be FRAMEBUFFER"; m_error = INVALID_ENUM; return; } CanvasFrameBuffer *framebuffer = getAsFramebuffer(buffer); if (framebuffer) m_currentFramebuffer = framebuffer; else m_currentFramebuffer = 0; // Let canvas component figure out the exact frame buffer id to use m_canvas->bindCurrentRenderTarget(); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod Context3D::glEnums Context3D::checkFramebufferStatus(glEnums target) * Returns the completeness status of the framebuffer object. * \a target must be \c{Context3D.FRAMEBUFFER}. * */ /*! * \internal */ CanvasContext::glEnums CanvasContext::checkFramebufferStatus(glEnums target) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ")"; if (target != FRAMEBUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_ENUM bind target, must be FRAMEBUFFER"; m_error = INVALID_ENUM; return FRAMEBUFFER_UNSUPPORTED; } if (m_currentFramebuffer) { return glEnums(glCheckFramebufferStatus(GL_FRAMEBUFFER)); } else { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_OPERATION no current framebuffer bound"; m_error = INVALID_OPERATION; return FRAMEBUFFER_UNSUPPORTED; } } /*! * \qmlmethod void Context3D::framebufferRenderbuffer(glEnums target, glEnums attachment, glEnums renderbuffertarget, RenderBuffer3D renderbuffer3D) * Attaches the given \a renderbuffer3D object to the \a attachment point of the current framebuffer * object. * \a target must be \c{Context3D.FRAMEBUFFER}. \a renderbuffertarget must * be \c{Context3D.RENDERBUFFER}. */ /*! * \internal */ void CanvasContext::framebufferRenderbuffer(glEnums target, glEnums attachment, glEnums renderbuffertarget, QJSValue renderbuffer3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << "attachment:" << glEnumToString(attachment) << "renderbuffertarget:" << glEnumToString(renderbuffertarget) << ", renderbuffer3D:" << renderbuffer3D.toString() << ")";
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
if (target != FRAMEBUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_ENUM bind target, must be FRAMEBUFFER"; m_error = INVALID_ENUM; return; } if (!m_currentFramebuffer) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_OPERATION no framebuffer bound"; m_error = INVALID_OPERATION; return; } if (attachment != COLOR_ATTACHMENT0 && attachment != DEPTH_ATTACHMENT && attachment != STENCIL_ATTACHMENT && attachment != DEPTH_STENCIL_ATTACHMENT) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_OPERATION attachment must be one of " << "COLOR_ATTACHMENT0, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT " << "or DEPTH_STENCIL_ATTACHMENT"; m_error = INVALID_OPERATION; return; } CanvasRenderBuffer *renderbuffer = getAsRenderbuffer3D(renderbuffer3D); if (renderbuffer && renderbuffertarget != RENDERBUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_OPERATION renderbuffertarget must be " << "RENDERBUFFER for non null renderbuffers"; m_error = INVALID_OPERATION; return; } GLuint renderbufferId = renderbuffer ? renderbuffer->id() : 0; glFramebufferRenderbuffer(GLenum(target), GLenum(attachment), GLenum(renderbuffertarget), renderbufferId); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::framebufferTexture2D(glEnums target, glEnums attachment, glEnums textarget, Texture3D texture3D, int level) * Attaches the given \a renderbuffer object to the \a attachment point of the current framebuffer * object. * \a target must be \c{Context3D.FRAMEBUFFER}. \a renderbuffertarget must * be \c{Context3D.RENDERBUFFER}. */ /*! * \internal */ void CanvasContext::framebufferTexture2D(glEnums target, glEnums attachment, glEnums textarget, QJSValue texture3D, int level) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", attachment:" << glEnumToString(attachment) << ", textarget:" << glEnumToString(textarget) << ", texture:" << texture3D.toString() << ", level:" << level << ")"; if (target != FRAMEBUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_ENUM bind target, must be FRAMEBUFFER"; m_error = INVALID_ENUM; return;
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
} if (!m_currentFramebuffer) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_OPERATION no current framebuffer bound"; m_error = INVALID_OPERATION; return; } if (attachment != COLOR_ATTACHMENT0 && attachment != DEPTH_ATTACHMENT && attachment != STENCIL_ATTACHMENT) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_OPERATION attachment must be one of " << "COLOR_ATTACHMENT0, DEPTH_ATTACHMENT or STENCIL_ATTACHMENT"; m_error = INVALID_OPERATION; return; } CanvasTexture *texture = getAsTexture3D(texture3D); if (texture) { if (textarget != TEXTURE_2D && textarget != TEXTURE_CUBE_MAP_POSITIVE_X && textarget != TEXTURE_CUBE_MAP_POSITIVE_Y && textarget != TEXTURE_CUBE_MAP_POSITIVE_Z && textarget != TEXTURE_CUBE_MAP_NEGATIVE_X && textarget != TEXTURE_CUBE_MAP_NEGATIVE_Y && textarget != TEXTURE_CUBE_MAP_NEGATIVE_Z) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): textarget must be one of TEXTURE_2D, " << "TEXTURE_CUBE_MAP_POSITIVE_X, " << "TEXTURE_CUBE_MAP_POSITIVE_Y, " << "TEXTURE_CUBE_MAP_POSITIVE_Z, " << "TEXTURE_CUBE_MAP_NEGATIVE_X, " << "TEXTURE_CUBE_MAP_NEGATIVE_Y or " << "TEXTURE_CUBE_MAP_NEGATIVE_Z"; m_error = INVALID_OPERATION; return; } if (level != 0) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_VALUE level must be 0"; m_error = INVALID_VALUE; return; } } GLuint textureId = texture ? texture->textureId() : 0; glFramebufferTexture2D(GLenum(target), GLenum(attachment), GLenum(textarget), textureId, level); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::isFramebuffer(Object anyObject) * Returns true if the given object is a valid FrameBuffer3D object. * \a anyObject is the object that is to be verified as a valid framebuffer. */ /*! * \internal */ bool CanvasContext::isFramebuffer(QJSValue anyObject) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "( anyObject:" << anyObject.toString() << ")"; CanvasFrameBuffer *fbo = getAsFramebuffer(anyObject); if (fbo) return glIsFramebuffer(fbo->id());
1751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
else return false; } /*! * \internal */ CanvasFrameBuffer *CanvasContext::getAsFramebuffer(QJSValue anyObject) { if (!anyObject.isQObject()) return 0; if (!isOfType(anyObject, "QtCanvas3D::CanvasFrameBuffer")) return 0; CanvasFrameBuffer *fbo = static_cast<CanvasFrameBuffer *>(anyObject.toQObject()); if (!fbo->isAlive()) return 0; return fbo; } /*! * \qmlmethod void Context3D::deleteFramebuffer(FrameBuffer3D buffer) * Deletes the given framebuffer as if by calling \c{glDeleteFramebuffers()}. * Calling this method repeatedly on the same object has no side effects. * \a buffer is the FrameBuffer3D to be deleted. */ /*! * \internal */ void CanvasContext::deleteFramebuffer(QJSValue buffer) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "( buffer:" << buffer.toString() << ")"; CanvasFrameBuffer *fbo = getAsFramebuffer(buffer); if (fbo) { fbo->del(); logAllGLErrors(__FUNCTION__); } else { m_error = INVALID_VALUE; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_VALUE buffer handle"; } } /*! * \qmlmethod RenderBuffer3D Context3D::createRenderbuffer() * Returns a created RenderBuffer3D object that is initialized with a renderbuffer object name * as if by calling \c{glGenRenderbuffers()}. */ /*! * \internal */ QJSValue CanvasContext::createRenderbuffer() { CanvasRenderBuffer *renderbuffer = new CanvasRenderBuffer(this); QJSValue value = m_engine->newQObject(renderbuffer); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "():" << value.toString(); logAllGLErrors(__FUNCTION__); return value; } /*! * \qmlmethod void Context3D::bindRenderbuffer(glEnums target, RenderBuffer3D renderbuffer) * Binds the given \a renderbuffer3D object to the given \a target.
1821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890
* \a target must be \c{Context3D.RENDERBUFFER}. */ /*! * \internal */ void CanvasContext::bindRenderbuffer(glEnums target, QJSValue renderbuffer3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", renderbuffer3D:" << renderbuffer3D.toString() << ")"; if (target != RENDERBUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_ENUM target must be RENDERBUFFER"; m_error = INVALID_ENUM; return; } CanvasRenderBuffer *renderbuffer = getAsRenderbuffer3D(renderbuffer3D); if (renderbuffer) { m_currentRenderbuffer = renderbuffer; glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer->id()); } else { m_currentRenderbuffer = 0; glBindRenderbuffer(GL_RENDERBUFFER, 0); } logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::renderbufferStorage(glEnums target, glEnums internalformat, int width, int height) * Create and initialize a data store for the \c renderbuffer object. * \a target must be \c Context3D.RENDERBUFFER. * \a internalformat specifies the color-renderable, depth-renderable or stencil-renderable format * of the renderbuffer. Must be one of \c{Context3D.RGBA4}, \c{Context3D.RGB565}, \c{Context3D.RGB5_A1}, * \c{Context3D.DEPTH_COMPONENT16} or \c{Context3D.STENCIL_INDEX8}. * \a width specifies the renderbuffer width in pixels. * \a height specifies the renderbuffer height in pixels. */ /*! * \internal */ void CanvasContext::renderbufferStorage(glEnums target, glEnums internalformat, int width, int height) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", internalformat:" << glEnumToString(internalformat) << ", width:" << width << ", height:" << height << ")"; if (target != RENDERBUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_ENUM target must be RENDERBUFFER"; m_error = INVALID_ENUM; return; } glRenderbufferStorage(GLenum(target), GLenum(internalformat), width, height); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod bool Context3D::isRenderbuffer(Object anyObject) * Returns true if the given object is a valid RenderBuffer3D object. * \a anyObject is the object that is to be verified as a valid renderbuffer. */ /*!
1891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960
* \internal */ bool CanvasContext::isRenderbuffer(QJSValue anyObject) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(anyObject:" << anyObject.toString() << ")"; CanvasRenderBuffer *rbo = getAsRenderbuffer3D(anyObject); if (!rbo) return false; return glIsRenderbuffer(rbo->id()); } /*! * \internal */ CanvasRenderBuffer *CanvasContext::getAsRenderbuffer3D(QJSValue anyObject) const { if (!anyObject.isQObject()) return 0; if (!isOfType(anyObject, "QtCanvas3D::CanvasRenderBuffer")) return 0; CanvasRenderBuffer *rbo = static_cast<CanvasRenderBuffer *>(anyObject.toQObject()); if (!rbo->isAlive()) return 0; return rbo; } /*! * \qmlmethod void Context3D::deleteRenderbuffer(RenderBuffer3D renderbuffer3D) * Deletes the given renderbuffer as if by calling \c{glDeleteRenderbuffers()}. * Calling this method repeatedly on the same object has no side effects. * \a renderbuffer3D is the RenderBuffer3D to be deleted. */ /*! * \internal */ void CanvasContext::deleteRenderbuffer(QJSValue renderbuffer3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(renderbuffer3D:" << renderbuffer3D.toString() << ")"; CanvasRenderBuffer *renderbuffer = getAsRenderbuffer3D(renderbuffer3D); if (renderbuffer) { renderbuffer->del(); logAllGLErrors(__FUNCTION__); } else { m_error = INVALID_VALUE; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): INVALID_VALUE renderbuffer handle"; } } /*! * \qmlmethod void Context3D::sampleCoverage(float value, bool invert) * Sets the multisample coverage parameters. * \a value specifies the floating-point sample coverage value. The value is clamped to the range * \c{[0, 1]} with initial value of \c{1.0}. * \a invert specifies if coverage masks should be inverted. */ /*! * \internal */ void CanvasContext::sampleCoverage(float value, bool invert)
1961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
{ qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(value:" << value << ", invert:" << invert << ")"; glSampleCoverage(value, invert); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod Program3D Context3D::createProgram() * Returns a created Program3D object that is initialized with a program object name as if by * calling \c{glCreateProgram()}. */ /*! * \internal */ QJSValue CanvasContext::createProgram() { CanvasProgram *program = new CanvasProgram(this); QJSValue value = m_engine->newQObject(program); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "():" << value.toString(); logAllGLErrors(__FUNCTION__); return value; } /*! * \qmlmethod bool Context3D::isProgram(Object anyObject) * Returns true if the given object is a valid Program3D object. * \a anyObject is the object that is to be verified as a valid program. */ /*! * \internal */ bool CanvasContext::isProgram(QJSValue anyObject) const { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(anyObject:" << anyObject.toString() << ")"; return (getAsProgram3D(anyObject) != Q_NULLPTR); } /*! * \internal */ CanvasProgram *CanvasContext::getAsProgram3D(QJSValue anyObject) const { if (!anyObject.isQObject()) return 0; if (!isOfType(anyObject, "QtCanvas3D::CanvasProgram")) return 0; CanvasProgram *program = static_cast<CanvasProgram *>(anyObject.toQObject()); if (!program->isAlive()) return 0; return program; } /*! * \qmlmethod void Context3D::deleteProgram(Program3D program3D) * Deletes the given program as if by calling \c{glDeleteProgram()}. * Calling this method repeatedly on the same object has no side effects. * \a program3D is the Program3D to be deleted. */ /*!
2031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100
* \internal */ void CanvasContext::deleteProgram(QJSValue program3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ")"; CanvasProgram *program = getAsProgram3D(program3D); if (program) { program->del(); logAllGLErrors(__FUNCTION__); } else { m_error = INVALID_VALUE; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_VALUE program handle:" << program3D.toString(); } } /*! * \qmlmethod void Context3D::attachShader(Program3D program3D, Shader3D shader3D) * Attaches the given \a shader3D object to the given \a program3D object. * Calling this method repeatedly on the same object has no side effects. */ /*! * \internal */ void CanvasContext::attachShader(QJSValue program3D, QJSValue shader3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", shader:" << shader3D.toString() << ")"; CanvasProgram *program = getAsProgram3D(program3D); CanvasShader *shader = getAsShader3D(shader3D); if (!program) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): Invalid program handle " << program3D.toString(); return; } if (!shader) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): Invalid shader handle " << shader3D.toString(); return; } program->attach(shader); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod list<Shader3D> Context3D::getAttachedShaders(Program3D program3D) * Returns the list of shaders currently attached to the given \a program3D. */ /*! * \internal */ QVariantList CanvasContext::getAttachedShaders(QJSValue program3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ")"; QVariantList shaderList;
2101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170
CanvasProgram *program = getAsProgram3D(program3D); if (!program) return shaderList; QList<CanvasShader *> shaders = program->attachedShaders(); for (QList<CanvasShader *>::const_iterator iter = shaders.constBegin(); iter != shaders.constEnd(); iter++) { CanvasShader *shader = *iter; shaderList << QVariant::fromValue(shader); } return shaderList; } /*! * \qmlmethod void Context3D::detachShader(Program3D program, Shader3D shader) * Detaches given shader object from given program object. * \a program3D specifies the program object from which to detach the shader. * \a shader3D specifies the shader object to detach. */ /*! * \internal */ void CanvasContext::detachShader(QJSValue program3D, QJSValue shader3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", shader:" << shader3D.toString() << ")"; CanvasProgram *program = getAsProgram3D(program3D); CanvasShader *shader = getAsShader3D(shader3D); if (!program) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): Invalid program handle " << program3D.toString(); return; } if (!shader) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): Invalid shader handle " << shader3D.toString(); return; } program->detach(shader); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::linkProgram(Program3D program3D) * Links the given program object. * \a program3D specifies the program to be linked. */ /*! * \internal */ void CanvasContext::linkProgram(QJSValue program3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ")"; CanvasProgram *program = getAsProgram3D(program3D);
2171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240
if (!program) return; program->link(); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::lineWidth(float width) * Specifies the width of rasterized lines. * \a width specifies the width to be used when rasterizing lines. Initial value is \c{1.0}. */ /*! * \internal */ void CanvasContext::lineWidth(float width) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(width:" << width << ")"; glLineWidth(width); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::polygonOffset(float factor, float units) * Sets scale and units used to calculate depth values. * \a factor specifies the scale factor that is used to create a variable depth offset for each * polygon. Initial value is \c{0.0}. * \a units gets multiplied by an implementation-specific value to create a constant depth offset. * Initial value is \c{0.0}. */ /*! * \internal */ void CanvasContext::polygonOffset(float factor, float units) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(factor:" << factor << ", units:" << units << ")"; glPolygonOffset(factor, units); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::pixelStorei(glEnums pname, int param) * Set the pixel storage modes. * \a pname specifies the name of the parameter to be set. \c {Context3D.PACK_ALIGNMENT} affects the * packing of pixel data into memory. \c {Context3D.UNPACK_ALIGNMENT} affects the unpacking of pixel * data from memory. \c {Context3D.UNPACK_FLIP_Y_WEBGL} is initially \c false, but once set, in any * subsequent calls to \l texImage2D or \l texSubImage2D, the source data is flipped along the * vertical axis. \c {Context3D.UNPACK_PREMULTIPLY_ALPHA_WEBGL} is initially \c false, but once set, * in any subsequent calls to \l texImage2D or \l texSubImage2D, the alpha channel of the source * data, is multiplied into the color channels during the data transfer. Initial value is \c false * and any non-zero value is interpreted as \c true. * * \a param specifies the value that \a pname is set to. */ /*! * \internal */ void CanvasContext::pixelStorei(glEnums pname, int param) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(pname:" << glEnumToString(pname) << ", param:" << param << ")";
2241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310
switch (pname) { case UNPACK_FLIP_Y_WEBGL: m_unpackFlipYEnabled = (param != 0); break; case UNPACK_PREMULTIPLY_ALPHA_WEBGL: m_unpackPremultiplyAlphaEnabled = (param != 0); break; case UNPACK_COLORSPACE_CONVERSION_WEBGL: // Intentionally ignored break; default: glPixelStorei(GLenum(pname), param); logAllGLErrors(__FUNCTION__); break; } } /*! * \qmlmethod void Context3D::hint(glEnums target, glEnums mode) * Set implementation-specific hints. * \a target \c Context3D.GENERATE_MIPMAP_HINT is accepted. * \a mode \c{Context3D.FASTEST}, \c{Context3D.NICEST}, and \c{Context3D.DONT_CARE} are accepted. */ /*! * \internal */ void CanvasContext::hint(glEnums target, glEnums mode) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ",mode:" << glEnumToString(mode) << ")"; switch (target) { case FRAGMENT_SHADER_DERIVATIVE_HINT_OES: if (m_standardDerivatives) { glHint(GLenum(target), GLenum(mode)); logAllGLErrors(__FUNCTION__); } else { m_error = INVALID_ENUM; } break; default: glHint(GLenum(target), GLenum(mode)); logAllGLErrors(__FUNCTION__); break; } } /*! * \qmlmethod void Context3D::enable(glEnums cap) * Enable server side GL capabilities. * \a cap specifies a constant indicating a GL capability. */ /*! * \internal */ void CanvasContext::enable(glEnums cap) { QString str = QString(__FUNCTION__); str += QStringLiteral("(cap:") + glEnumToString(cap) + QStringLiteral(")"); qCDebug(canvas3drendering).nospace() << str; glEnable(cap); logAllGLErrors(str); } /*! * \qmlmethod bool Context3D::isEnabled(glEnums cap) * Returns whether a capability is enabled.
2311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380
* \a cap specifies a constant indicating a GL capability. */ /*! * \internal */ bool CanvasContext::isEnabled(glEnums cap) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(cap:" << glEnumToString(cap) << ")"; return glIsEnabled(cap); } /*! * \qmlmethod void Context3D::disable(glEnums cap) * Disable server side GL capabilities. * \a cap specifies a constant indicating a GL capability. */ /*! * \internal */ void CanvasContext::disable(glEnums cap) { QString str = QString(__FUNCTION__); str += QStringLiteral("(cap:") + glEnumToString(cap) + QStringLiteral(")"); qCDebug(canvas3drendering).nospace() << str; glDisable(cap); logAllGLErrors(str); } /*! * \qmlmethod void Context3D::blendColor(float red, float green, float blue, float alpha) * Set the blend color. * \a red, \a green, \a blue and \a alpha specify the components of \c{Context3D.BLEND_COLOR}. */ /*! * \internal */ void CanvasContext::blendColor(float red, float green, float blue, float alpha) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(red:" << red << ", green:" << green << ", blue:" << blue << ", alpha:" << alpha << ")"; glBlendColor(red, green, blue, alpha); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::blendEquation(glEnums mode) * Sets the equation used for both the RGB blend equation and the alpha blend equation * \a mode specifies how source and destination colors are to be combined. Must be * \c{Context3D.FUNC_ADD}, \c{Context3D.FUNC_SUBTRACT} or \c{Context3D.FUNC_REVERSE_SUBTRACT}. */ /*! * \internal */ void CanvasContext::blendEquation(glEnums mode) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(mode:" << glEnumToString(mode) << ")"; glBlendEquation(GLenum(mode)); logAllGLErrors(__FUNCTION__); }
2381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450
/*! * \qmlmethod void Context3D::blendEquationSeparate(glEnums modeRGB, glEnums modeAlpha) * Set the RGB blend equation and the alpha blend equation separately. * \a modeRGB specifies how the RGB components of the source and destination colors are to be * combined. Must be \c{Context3D.FUNC_ADD}, \c{Context3D.FUNC_SUBTRACT} or * \c{Context3D.FUNC_REVERSE_SUBTRACT}. * \a modeAlpha specifies how the alpha component of the source and destination colors are to be * combined. Must be \c{Context3D.FUNC_ADD}, \c{Context3D.FUNC_SUBTRACT}, or * \c{Context3D.FUNC_REVERSE_SUBTRACT}. */ /*! * \internal */ void CanvasContext::blendEquationSeparate(glEnums modeRGB, glEnums modeAlpha) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(modeRGB:" << glEnumToString(modeRGB) << ", modeAlpha:" << glEnumToString(modeAlpha) << ")"; glBlendEquationSeparate(GLenum(modeRGB), GLenum(modeAlpha)); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::blendFunc(glEnums sfactor, glEnums dfactor) * Sets the pixel arithmetic. * \a sfactor specifies how the RGBA source blending factors are computed. Must be * \c{Context3D.ZERO}, \c{Context3D.ONE}, \c{Context3D.SRC_COLOR}, * \c{Context3D.ONE_MINUS_SRC_COLOR}, * \c{Context3D.DST_COLOR}, \c{Context3D.ONE_MINUS_DST_COLOR}, \c{Context3D.SRC_ALPHA}, * \c{Context3D.ONE_MINUS_SRC_ALPHA}, \c{Context3D.DST_ALPHA}, \c{Context3D.ONE_MINUS_DST_ALPHA}, * \c{Context3D.CONSTANT_COLOR}, \c{Context3D.ONE_MINUS_CONSTANT_COLOR}, * \c{Context3D.CONSTANT_ALPHA}, * \c{Context3D.ONE_MINUS_CONSTANT_ALPHA} or \c{Context3D.SRC_ALPHA_SATURATE}. Initial value is * \c{Context3D.ONE}. * \a dfactor Specifies how the RGBA destination blending factors are computed. Must be * \c{Context3D.ZERO}, \c{Context3D.ONE}, \c{Context3D.SRC_COLOR}, * \c{Context3D.ONE_MINUS_SRC_COLOR}, * \c{Context3D.DST_COLOR}, \c{Context3D.ONE_MINUS_DST_COLOR}, \c{Context3D.SRC_ALPHA}, * \c{Context3D.ONE_MINUS_SRC_ALPHA}, \c{Context3D.DST_ALPHA}, \c{Context3D.ONE_MINUS_DST_ALPHA}, * \c{Context3D.CONSTANT_COLOR}, \c{Context3D.ONE_MINUS_CONSTANT_COLOR}, * \c{Context3D.CONSTANT_ALPHA} or * \c{Context3D.ONE_MINUS_CONSTANT_ALPHA}. Initial value is \c{Context3D.ZERO}. */ /*! * \internal */ void CanvasContext::blendFunc(glEnums sfactor, glEnums dfactor) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(sfactor:" << glEnumToString(sfactor) << ", dfactor:" << glEnumToString(dfactor) << ")"; if (((sfactor == CONSTANT_COLOR || sfactor == ONE_MINUS_CONSTANT_COLOR) && (dfactor == CONSTANT_ALPHA || dfactor == ONE_MINUS_CONSTANT_ALPHA)) || ((dfactor == CONSTANT_COLOR || dfactor == ONE_MINUS_CONSTANT_COLOR) && (sfactor == CONSTANT_ALPHA || sfactor == ONE_MINUS_CONSTANT_ALPHA))) { m_error = INVALID_OPERATION; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_OPERATION illegal combination"; return; } glBlendFunc(GLenum(sfactor), GLenum(dfactor)); logAllGLErrors(__FUNCTION__); } /*!
2451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
* \qmlmethod void Context3D::blendFuncSeparate(glEnums srcRGB, glEnums dstRGB, glEnums srcAlpha, glEnums dstAlpha) * Sets the pixel arithmetic for RGB and alpha components separately. * \a srcRGB specifies how the RGB source blending factors are computed. Must be \c{Context3D.ZERO}, * \c{Context3D.ONE}, \c{Context3D.SRC_COLOR}, \c{Context3D.ONE_MINUS_SRC_COLOR}, * \c{Context3D.DST_COLOR}, * \c{Context3D.ONE_MINUS_DST_COLOR}, \c{Context3D.SRC_ALPHA}, \c{Context3D.ONE_MINUS_SRC_ALPHA}, * \c{Context3D.DST_ALPHA}, \c{Context3D.ONE_MINUS_DST_ALPHA}, \c{Context3D.CONSTANT_COLOR}, * \c{Context3D.ONE_MINUS_CONSTANT_COLOR}, \c{Context3D.CONSTANT_ALPHA}, * \c{Context3D.ONE_MINUS_CONSTANT_ALPHA} or \c{Context3D.SRC_ALPHA_SATURATE}. Initial value is * \c{Context3D.ONE}. * \a dstRGB Specifies how the RGB destination blending factors are computed. Must be * \c{Context3D.ZERO}, \c{Context3D.ONE}, \c{Context3D.SRC_COLOR}, \c{Context3D.ONE_MINUS_SRC_COLOR}, * \c{Context3D.DST_COLOR}, \c{Context3D.ONE_MINUS_DST_COLOR}, \c{Context3D.SRC_ALPHA}, * \c{Context3D.ONE_MINUS_SRC_ALPHA}, \c{Context3D.DST_ALPHA}, \c{Context3D.ONE_MINUS_DST_ALPHA}, * \c{Context3D.CONSTANT_COLOR}, \c{Context3D.ONE_MINUS_CONSTANT_COLOR}, * \c{Context3D.CONSTANT_ALPHA} or * \c{Context3D.ONE_MINUS_CONSTANT_ALPHA}. Initial value is \c{Context3D.ZERO}. * \a srcAlpha specifies how the alpha source blending factors are computed. Must be * \c{Context3D.ZERO}, \c{Context3D.ONE}, \c{Context3D.SRC_COLOR}, * \c{Context3D.ONE_MINUS_SRC_COLOR}, * \c{Context3D.DST_COLOR}, \c{Context3D.ONE_MINUS_DST_COLOR}, \c{Context3D.SRC_ALPHA}, * \c{Context3D.ONE_MINUS_SRC_ALPHA}, \c{Context3D.DST_ALPHA}, \c{Context3D.ONE_MINUS_DST_ALPHA}, * \c{Context3D.CONSTANT_COLOR}, \c{Context3D.ONE_MINUS_CONSTANT_COLOR}, * \c{Context3D.CONSTANT_ALPHA}, * \c{Context3D.ONE_MINUS_CONSTANT_ALPHA} or \c{Context3D.SRC_ALPHA_SATURATE}. Initial value is * \c{Context3D.ONE}. * \a dstAlpha Specifies how the alpha destination blending factors are computed. Must be * \c{Context3D.ZERO}, \c{Context3D.ONE}, \c{Context3D.SRC_COLOR}, * \c{Context3D.ONE_MINUS_SRC_COLOR}, * \c{Context3D.DST_COLOR}, \c{Context3D.ONE_MINUS_DST_COLOR}, \c{Context3D.SRC_ALPHA}, * \c{Context3D.ONE_MINUS_SRC_ALPHA}, \c{Context3D.DST_ALPHA}, \c{Context3D.ONE_MINUS_DST_ALPHA}, * \c{Context3D.CONSTANT_COLOR}, \c{Context3D.ONE_MINUS_CONSTANT_COLOR}, * \c{Context3D.CONSTANT_ALPHA} or * \c{Context3D.ONE_MINUS_CONSTANT_ALPHA}. Initial value is \c{Context3D.ZERO}. */ /*! * \internal */ void CanvasContext::blendFuncSeparate(glEnums srcRGB, glEnums dstRGB, glEnums srcAlpha, glEnums dstAlpha) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(srcRGB:" << glEnumToString(srcRGB) << ", dstRGB:" << glEnumToString(dstRGB) << ", srcAlpha:" << glEnumToString(srcAlpha) << ", dstAlpha:" << glEnumToString(dstAlpha) << ")"; if (((srcRGB == CONSTANT_COLOR || srcRGB == ONE_MINUS_CONSTANT_COLOR ) && (dstRGB == CONSTANT_ALPHA || dstRGB == ONE_MINUS_CONSTANT_ALPHA )) || ((dstRGB == CONSTANT_COLOR || dstRGB == ONE_MINUS_CONSTANT_COLOR ) && (srcRGB == CONSTANT_ALPHA || srcRGB == ONE_MINUS_CONSTANT_ALPHA ))) { m_error = INVALID_OPERATION; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_OPERATION illegal combination"; return; } glBlendFuncSeparate(GLenum(srcRGB), GLenum(dstRGB), GLenum(srcAlpha), GLenum(dstAlpha)); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod variant Context3D::getProgramParameter(Program3D program3D, glEnums paramName) * Return the value for the passed \a paramName given the passed \a program3D. The type returned is * the natural type for the requested paramName. * \a paramName must be \c{Context3D.DELETE_STATUS}, \c{Context3D.LINK_STATUS}, * \c{Context3D.VALIDATE_STATUS}, \c{Context3D.ATTACHED_SHADERS}, \c{Context3D.ACTIVE_ATTRIBUTES} or * \c{Context3D.ACTIVE_UNIFORMS}. */
2521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590
/*! * \internal */ QVariant CanvasContext::getProgramParameter(QJSValue program3D, glEnums paramName) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", paramName:" << glEnumToString(paramName) << ")"; CanvasProgram *program = getAsProgram3D(program3D); if (!program) return 0; switch(paramName) { case DELETE_STATUS: // Intentional flow through case LINK_STATUS: // Intentional flow through case VALIDATE_STATUS: { GLint value = 0; glGetProgramiv(program->id(), GLenum(paramName), &value); logAllGLErrors(__FUNCTION__); qCDebug(canvas3drendering).nospace() << " getProgramParameter returns " << value; return QVariant::fromValue(value == GL_TRUE); } case ATTACHED_SHADERS: // Intentional flow through case ACTIVE_ATTRIBUTES: // Intentional flow through case ACTIVE_UNIFORMS: { GLint value = 0; glGetProgramiv(program->id(), GLenum(paramName), &value); logAllGLErrors(__FUNCTION__); qCDebug(canvas3drendering).nospace() << " getProgramParameter returns " << value; return QVariant::fromValue(value); } default: { m_error = INVALID_ENUM; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_ENUM illegal parameter name "; return QVariant::fromValue(0); } } } /*! * \qmlmethod Shader3D Context3D::createShader(glEnums type) * Creates a shader of \a type. Must be either \c Context3D.VERTEX_SHADER or * \c{Context3D.FRAGMENT_SHADER}. */ /*! * \internal */ QJSValue CanvasContext::createShader(glEnums type) { switch (type) { case VERTEX_SHADER: qCDebug(canvas3drendering).nospace() << "Context3D::createShader(VERTEX_SHADER)"; return m_engine->newQObject(new CanvasShader(QOpenGLShader::Vertex, this)); case FRAGMENT_SHADER: qCDebug(canvas3drendering).nospace() << "Context3D::createShader(FRAGMENT_SHADER)"; return m_engine->newQObject(new CanvasShader(QOpenGLShader::Fragment, this)); default: qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM unknown shader type:" << glEnumToString(type); m_error = INVALID_ENUM; return m_engine->newObject();
2591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660
} } /*! * \qmlmethod bool Context3D::isShader(Object anyObject) * Returns true if the given object is a valid Shader3D object. * \a anyObject is the object that is to be verified as a valid shader. */ /*! * \internal */ bool CanvasContext::isShader(QJSValue anyObject) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(anyObject:" << anyObject.toString() << ")"; CanvasShader *shader3D = getAsShader3D(anyObject); if (!shader3D) return false; return glIsShader(shader3D->id()); } /*! * \internal */ CanvasShader *CanvasContext::getAsShader3D(QJSValue shader3D) const { if (!isOfType(shader3D, "QtCanvas3D::CanvasShader")) return 0; CanvasShader *shader = static_cast<CanvasShader *>(shader3D.toQObject()); if (!shader->isAlive()) return 0; return shader; } /*! * \qmlmethod void Context3D::deleteShader(Shader3D shader) * Deletes the given shader as if by calling \c{glDeleteShader()}. * Calling this method repeatedly on the same object has no side effects. * \a shader is the Shader3D to be deleted. */ /*! * \internal */ void CanvasContext::deleteShader(QJSValue shader3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(shader:" << shader3D.toString() << ")"; CanvasShader *shader = getAsShader3D(shader3D); if (shader) { shader->del(); logAllGLErrors(__FUNCTION__); } else { m_error = INVALID_VALUE; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": invalid shader handle:" << shader3D.toString(); } } /*! * \qmlmethod void Context3D::shaderSource(Shader3D shader, string shaderSource) * Replaces the shader source code in the given shader object.
2661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730
* \a shader specifies the shader object whose source code is to be replaced. * \a shaderSource specifies the source code to be loaded in to the shader. */ /*! * \internal */ void CanvasContext::shaderSource(QJSValue shader3D, const QString &shaderSource) { QString modSource = "#version 120 \n#define precision \n"+ shaderSource; if (m_isOpenGLES2) modSource = shaderSource; qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(shader:" << shader3D.toString() << ", shaderSource" << ")" << endl << modSource << endl; CanvasShader *shader = getAsShader3D(shader3D); if (!shader) { m_error = INVALID_VALUE; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": invalid shader handle:" << shader3D.toString(); return; } shader->setSourceCode(modSource); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod string Context3D::getShaderSource(Shader3D shader) * Returns the source code string from the \a shader object. */ /*! * \internal */ QJSValue CanvasContext::getShaderSource(QJSValue shader3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(shader:" << shader3D.toString() << ")"; CanvasShader *shader = getAsShader3D(shader3D); if (!shader) { m_error = INVALID_VALUE; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ <<": invalid shader handle:" << shader3D.toString(); return m_engine->newObject(); } return QJSValue(QString(shader->qOGLShader()->sourceCode())); } /*! * \qmlmethod void Context3D::compileShader(Shader3D shader) * Compiles the given \a shader object. */ /*! * \internal */ void CanvasContext::compileShader(QJSValue shader3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(shader:" << shader3D.toString() << ")"; CanvasShader *shader = getAsShader3D(shader3D); if (!shader) { m_error = INVALID_VALUE;
2731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800
qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": invalid shader handle:" << shader3D.toString(); return; } shader->qOGLShader()->compileSourceCode(shader->sourceCode()); logAllGLErrors(__FUNCTION__); } /*! * \internal */ CanvasUniformLocation *CanvasContext::getAsUniformLocation3D(QJSValue anyObject) const { if (!isOfType(anyObject, "QtCanvas3D::CanvasUniformLocation")) return 0; CanvasUniformLocation *uniformLocation = static_cast<CanvasUniformLocation *>(anyObject.toQObject()); // TODO: Should uniform locations be killed and checked for "isAlive" when program is // deleted? return uniformLocation; } /*! * \qmlmethod void Context3D::uniform1i(UniformLocation3D location3D, int x) * Sets the single integer value given in \a x to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform1i(QJSValue location3D, int x) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", x:" << x << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; glUniform1i(locationObj->id(), x); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform1iv(UniformLocation3D location3D, Int32Array array) * Sets the integer array given in \a array to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform1iv(QJSValue location3D, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", array:" << array.toString() << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; // Check if we have a JavaScript array if (array.isArray()) { uniform1fva(locationObj, array.toVariant().toList()); return;
2801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870
} QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Int32Array) return; glUniform1iv(locationObj->id(), typedArray->length(), (int *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform1f(UniformLocation3D location3D, float x) * Sets the single float value given in \a x to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform1f(QJSValue location3D, float x) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", x:" << x << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; glUniform1f(locationObj->id(), x); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform1fvt(UniformLocation3D location3D, Object array) * Sets the float array given in \a array to the given uniform \a location3D. \a array must be * a JavaScript \c Array object or a \c Float32Array object. */ /*! * \internal */ void CanvasContext::uniform1fv(QJSValue location3D, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", array:" << array.toString() << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; // Check if we have a JavaScript array if (array.isArray()) { uniform1fva(locationObj, array.toVariant().toList()); return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array)
2871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940
return; glUniform1fv(locationObj->id(), typedArray->length(), (float *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform2f(UniformLocation3D location3D, float x, float y) * Sets the two float values given in \a x and \a y to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform2f(QJSValue location3D, float x, float y) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", x:" << x << ", y:" << y << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; glUniform2f(locationObj->id(), x, y); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform2fv(UniformLocation3D location3D, Float32Array array) * Sets the float array given in \a array to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform2fv(QJSValue location3D, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", array:" << array.toString() << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; // Check if we have a JavaScript array if (array.isArray()) { uniform2fva(locationObj, array.toVariant().toList()); return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; glUniform2fv(locationObj->id(), typedArray->length() / 2, (float *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); }
2941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010
/*! * \qmlmethod void Context3D::uniform2i(UniformLocation3D location3D, int x, int y) * Sets the two integer values given in \a x and \a y to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform2i(QJSValue location3D, int x, int y) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", x:" << x << ", y:" << y << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; glUniform2i(locationObj->id(), x, y); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform2iv(UniformLocation3D location3D, Int32Array array) * Sets the integer array given in \a array to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform2iv(QJSValue location3D, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", array:" << array.toString() << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; // Check if we have a JavaScript array if (array.isArray()) { uniform2iva(locationObj, array.toVariant().toList()); return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Int32Array) return; glUniform2iv(locationObj->id(), typedArray->length() / 2, (int *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform3f(UniformLocation3D location3D, float x, float y, float z) * Sets the three float values given in \a x , \a y and \a z to the given uniform \a location3D. */ /*! * \internal */
3011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080
void CanvasContext::uniform3f(QJSValue location3D, float x, float y, float z) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", x:" << x << ", y:" << y << ", z:" << z << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; glUniform3f(locationObj->id(), x, y, z); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform3fv(UniformLocation3D location3D, Float32Array array) * Sets the float array given in \a array to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform3fv(QJSValue location3D, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", array:" << array.toString() << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; // Check if we have a JavaScript array if (array.isArray()) { uniform3fva(locationObj, array.toVariant().toList()); return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) { return; } glUniform3fv(locationObj->id(), typedArray->length() / 3, (float *) typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform3i(UniformLocation3D location3D, int x, int y, int z) * Sets the three integer values given in \a x , \a y and \a z to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform3i(QJSValue location3D, int x, int y, int z) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", x:" << x << ", y:" << y << ", z:" << z
3081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150
<< ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; glUniform3i(locationObj->id(), x, y, z); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform3iv(UniformLocation3D location3D, Int32Array array) * Sets the integer array given in \a array to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform3iv(QJSValue location3D, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", array:" << array.toString() << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; // Check if we have a JavaScript array if (array.isArray()) { uniform3iva(locationObj, array.toVariant().toList()); return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Int32Array) { return; } glUniform3iv(locationObj->id(), typedArray->length() / 3, (int *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform4f(UniformLocation3D location3D, float x, float y, float z, float w) * Sets the four float values given in \a x , \a y , \a z and \a w to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform4f(QJSValue location3D, float x, float y, float z, float w) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", x:" << x << ", y:" << y << ", z:" << z << ", w:" << w << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; glUniform4f(locationObj->id(), x, y, z, w); logAllGLErrors(__FUNCTION__);
3151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220
} /*! * \qmlmethod void Context3D::uniform4fv(UniformLocation3D location3D, Float32Array array) * Sets the float array given in \a array to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform4fv(QJSValue location3D, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", array:" << array.toString() << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; // Check if we have a JavaScript array if (array.isArray()) { uniform4fva(locationObj, array.toVariant().toList()); return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; glUniform4fv(locationObj->id(), typedArray->length() / 4, (float *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform4i(UniformLocation3D location3D, int x, int y, int z, int w) * Sets the four integer values given in \a x , \a y , \a z and \a w to the given uniform * \a location3D. */ /*! * \internal */ void CanvasContext::uniform4i(QJSValue location3D, int x, int y, int z, int w) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", x:" << x << ", y:" << y << ", z:" << z << ", w:" << w << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; glUniform4i(locationObj->id(), x, y, z, w); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniform4iv(UniformLocation3D location3D, Int32Array array) * Sets the integer array given in \a array to the given uniform \a location3D. */ /*!
3221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290
* \internal */ void CanvasContext::uniform4iv(QJSValue location3D, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", array:" << array.toString() << ")"; CanvasUniformLocation *locationObj = getAsUniformLocation3D(location3D); if (!locationObj) return; // Check if we have a JavaScript array if (array.isArray()) { uniform4iva(locationObj, array.toVariant().toList()); return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Int32Array) return; glUniform4iv(locationObj->id(), typedArray->length() / 4, (int *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \internal */ void CanvasContext::uniform1fva(CanvasUniformLocation *location3D, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D << ", array:" << array << ")"; float *arrayData = new float[array.length()]; ArrayUtils::fillFloatArrayFromVariantList(array, arrayData); glUniform1fv(location3D->id(), array.count(), arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \internal */ void CanvasContext::uniform2fva(CanvasUniformLocation *location3D, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D << ", array:" << array << ")"; float *arrayData = new float[array.length()]; ArrayUtils::fillFloatArrayFromVariantList(array, arrayData); glUniform2fv(location3D->id(), array.count() / 2, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \internal */ void CanvasContext::uniform3fva(CanvasUniformLocation *location3D, QVariantList array)
3291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360
{ qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D << ", array:" << array << ")"; float *arrayData = new float[array.length()]; ArrayUtils::fillFloatArrayFromVariantList(array, arrayData); glUniform3fv(location3D->id(), array.count() / 3, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \internal */ void CanvasContext::uniform4fva(CanvasUniformLocation *location3D, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D << ", array:" << array << ")"; float *arrayData = new float[array.count()]; ArrayUtils::fillFloatArrayFromVariantList(array, arrayData); glUniform4fv(location3D->id(), array.count() / 4, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \internal */ void CanvasContext::uniform1iva(CanvasUniformLocation *location3D, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D << ", array:" << array << ")"; int *arrayData = new int[array.length()]; ArrayUtils::fillIntArrayFromVariantList(array, arrayData); glUniform1iv(location3D->id(), array.count(), arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \internal */ void CanvasContext::uniform2iva(CanvasUniformLocation *location3D, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D << ", array:" << array << ")"; int *arrayData = new int[array.length()]; ArrayUtils::fillIntArrayFromVariantList(array, arrayData); glUniform2iv(location3D->id(), array.count() / 2, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \internal */ void CanvasContext::uniform3iva(CanvasUniformLocation *location3D, QVariantList array) {
3361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430
qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D << ", array:" << array << ")"; int *arrayData = new int[array.length()]; ArrayUtils::fillIntArrayFromVariantList(array, arrayData); glUniform3iv(location3D->id(), array.count() / 3, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \qmlmethod void Context3D::uniform4iva(UniformLocation3D location3D, list<variant> array) * Sets the integer array given as JavasScript \a array to the given uniform \a location3D. */ /*! * \internal */ void CanvasContext::uniform4iva(CanvasUniformLocation *location3D, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D << ", array:" << array << ")"; int *arrayData = new int[array.length()]; ArrayUtils::fillIntArrayFromVariantList(array, arrayData); glUniform4iv(location3D->id(), array.length() / 4, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \qmlmethod void Context3D::vertexAttrib1f(int indx, float x) * Sets the single float value given in \a x to the generic vertex attribute index specified * by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib1f(unsigned int indx, float x) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", x:" << x << ")"; glVertexAttrib1f(indx, x); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::vertexAttrib1fv(int indx, Float32Array array) * Sets the float array given in \a array to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib1fv(unsigned int indx, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", array:" << array.toString() << ")"; // Check if we have a JavaScript array if (array.isArray()) { vertexAttrib1fva(indx, array.toVariant().toList());
3431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500
return; } // Check if we have a Float32Array QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; glVertexAttrib1fv(indx, (float *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::vertexAttrib2f(int indx, float x, float y) * Sets the two float values given in \a x and \a y to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib2f(unsigned int indx, float x, float y) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", x:" << x << ", y:" << y << ")"; glVertexAttrib2f(indx, x, y); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::vertexAttrib2fv(int indx, Float32Array array) * Sets the float array given in \a array to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib2fv(unsigned int indx, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", array:" << array.toString() << ")"; // Check if we have a JavaScript array if (array.isArray()) { vertexAttrib2fva(indx, array.toVariant().toList()); return; } // Check if we have a Float32Array QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; glVertexAttrib2fv(indx, (float *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::vertexAttrib3f(int indx, float x, float y, float z) * Sets the three float values given in \a x , \a y and \a z to the generic vertex attribute index * specified by \a indx. */
3501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570
/*! * \internal */ void CanvasContext::vertexAttrib3f(unsigned int indx, float x, float y, float z) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", x:" << x << ", y:" << y << ", z:" << z << ")"; glVertexAttrib3f(indx, x, y, z); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::vertexAttrib3fv(int indx, Float32Array array) * Sets the float array given in \a array to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib3fv(unsigned int indx, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", array:" << array.toString() << ")"; // Check if we have a JavaScript array if (array.isArray()) { vertexAttrib3fva(indx, array.toVariant().toList()); return; } // Check if we have a Float32Array QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; glVertexAttrib3fv(indx, (float *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::vertexAttrib4f(int indx, float x, float y, float z, float w) * Sets the four float values given in \a x , \a y , \a z and \a w to the generic vertex attribute * index specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib4f(unsigned int indx, float x, float y, float z, float w) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", x:" << x << ", y:" << y << ", z:" << z << ", w:" << w << ")"; glVertexAttrib4f(indx, x, y, z, w); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::vertexAttrib4fv(int indx, Float32Array array)
3571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640
* Sets the float array given in \a array to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib4fv(unsigned int indx, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", array:" << array.toString() << ")"; // Check if we have a JavaScript array if (array.isArray()) { vertexAttrib4fva(indx, array.toVariant().toList()); return; } // Check if we have a Float32Array QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!typedArray || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; glVertexAttrib4fv(indx, (float *)typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod int Context3D::getShaderParameter(Shader3D shader, glEnums pname) * Returns the value of the passed \a pname for the given \a shader. * \a pname must be one of \c{Context3D.SHADER_TYPE}, \c Context3D.DELETE_STATUS and * \c{Context3D.COMPILE_STATUS}. */ /*! * \internal */ int CanvasContext::getShaderParameter(QJSValue shader3D, glEnums pname) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(shader:" << shader3D.toString() << ", pname:"<< glEnumToString(pname) << ")"; CanvasShader *shader = getAsShader3D(shader3D); if (!shader) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ <<": invalid shader handle:" << shader3D.toString(); return 0; } switch (pname) { case SHADER_TYPE: { GLint shaderType = 0; glGetShaderiv( shader->qOGLShader()->shaderId(), GL_SHADER_TYPE, &shaderType); logAllGLErrors(__FUNCTION__); return shaderType; } case DELETE_STATUS: { bool isDeleted = !shader->isAlive(); qCDebug(canvas3drendering).nospace() << " getShaderParameter returns " << isDeleted; return (isDeleted ? GL_TRUE : GL_FALSE); } case COMPILE_STATUS: { bool isCompiled = shader->qOGLShader()->isCompiled(); qCDebug(canvas3drendering).nospace() << " getShaderParameter returns " << isCompiled; return (isCompiled ? GL_TRUE : GL_FALSE); } default: {
3641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710
qCWarning(canvas3drendering) << "getShaderParameter() : UNSUPPORTED parameter name " << glEnumToString(pname); return 0; } } } /*! * \qmlmethod Buffer3D Context3D::createBuffer() * Creates a Buffer3D object and initializes it with a buffer object name as if \c glGenBuffers() * was called. */ /*! * \internal */ QJSValue CanvasContext::createBuffer() { CanvasBuffer *newBuffer = new CanvasBuffer(this); logAllGLErrors(__FUNCTION__); m_idToCanvasBufferMap[newBuffer->id()] = newBuffer; QJSValue value = m_engine->newQObject(newBuffer); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << ":" << value.toString() << " = " << newBuffer; return value; } /*! * \qmlmethod UniformLocation3D Context3D::getUniformLocation(Program3D program3D, string name) * Returns UniformLocation3D object that represents the location3D of a specific uniform variable * with the given \a name within the given \a program3D object. * Returns \c null if name doesn't correspond to a uniform variable. */ /*! * \internal */ QJSValue CanvasContext::getUniformLocation(QJSValue program3D, const QString &name) { CanvasProgram *program = getAsProgram3D(program3D); if (!program) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", name:" << name << "):-1"; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "WARNING: Invalid Program3D reference " << program; return 0; } int index = program->uniformLocation(name); logAllGLErrors(__FUNCTION__); if (index < 0) { return 0; } CanvasUniformLocation *location3D = new CanvasUniformLocation(index, this); location3D->setName(name); QJSValue value = m_engine->newQObject(location3D); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", name:" << value.toString() << "):" << location3D; return value; } /*! * \qmlmethod int Context3D::getAttribLocation(Program3D program3D, string name) * Returns location3D of the given attribute variable \a name in the given \a program3D. */
3711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780
/*! * \internal */ int CanvasContext::getAttribLocation(QJSValue program3D, const QString &name) { CanvasProgram *program = getAsProgram3D(program3D); if (!program) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", name:" << name << "):-1"; qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID Program3D reference " << program; return -1; } else { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", name:" << name << "):" << program->attributeLocation(name); } return program->attributeLocation(name); } /*! * \qmlmethod void Context3D::bindAttribLocation(Program3D program3D, int index, string name) * Binds the attribute \a index with the attribute variable \a name in the given \a program3D. */ /*! * \internal */ void CanvasContext::bindAttribLocation(QJSValue program3D, int index, const QString &name) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", index:" << index << ", name:" << name << ")"; CanvasProgram *program = getAsProgram3D(program3D); if (!program) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID Program3D reference " << program; return; } program->bindAttributeLocation(index, name); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::enableVertexAttribArray(int index) * Enables the vertex attribute array at \a index. */ /*! * \internal */ void CanvasContext::enableVertexAttribArray(int index) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(index:" << index << ")"; glEnableVertexAttribArray(index); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::disableVertexAttribArray(int index) * Disables the vertex attribute array at \a index. */
3781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850
/*! * \internal */ void CanvasContext::disableVertexAttribArray(int index) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(index:" << index << ")"; glDisableVertexAttribArray(index); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniformMatrix2fv(UniformLocation3D location3D, bool transpose, Value array) * Converts the float array given in \a array to a 2x2 matrix and sets it to the given * uniform at \a uniformLocation. Applies \a transpose if set to \c{true}. */ /*! * \internal */ void CanvasContext::uniformMatrix2fv(QJSValue location3D, bool transpose, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(uniformLocation:" << location3D.toString() << ", transpose:" << transpose << ", array:" << array.toString() <<")"; if (!isOfType(location3D, "QtCanvas3D::CanvasUniformLocation")) return; CanvasUniformLocation *locationObj = static_cast<CanvasUniformLocation *>(location3D.toQObject()); // Check if we have a JavaScript array if (array.isArray()) { uniformMatrix2fva(locationObj, transpose, array.toVariant().toList()); return; } // We should have a Float32Array QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!m_currentProgram || !typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "numMatrices:" << (typedArray->length() / 4); int uniformLocation = locationObj->id(); float *arrayData = (float *)typedArray->arrayData()->data(); int numMatrices = typedArray->length() / 4; glUniformMatrix2fv(uniformLocation, numMatrices, transpose, arrayData); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniformMatrix3fv(UniformLocation3D location3D, bool transpose, Value array) * Converts the float array given in \a array to a 3x3 matrix and sets it to the given * uniform at \a uniformLocation. Applies \a transpose if set to \c{true}. */ /*! * \internal */ void CanvasContext::uniformMatrix3fv(QJSValue location3D, bool transpose, QJSValue array) {
3851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920
qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", transpose:" << transpose << ", array:" << array.toString() <<")"; if (!isOfType(location3D, "QtCanvas3D::CanvasUniformLocation")) return; CanvasUniformLocation *locationObj = static_cast<CanvasUniformLocation *>(location3D.toQObject()); // Check if we have a JavaScript array if (array.isArray()) { uniformMatrix3fva(locationObj, transpose, array.toVariant().toList()); return; } // We should have a Float32Array QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array)); if (!m_currentProgram || !typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "numMatrices:" << (typedArray->length() / 9); int uniformLocation = locationObj->id(); float *arrayData = (float *)typedArray->arrayData()->data(); int numMatrices = typedArray->length() / 9; glUniformMatrix3fv(uniformLocation, numMatrices, transpose, arrayData); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::uniformMatrix4fv(UniformLocation3D location3D, bool transpose, Value array) * Converts the float array given in \a array to a 4x4 matrix and sets it to the given * uniform at \a uniformLocation. Applies \a transpose if set to \c{true}. */ /*! * \internal */ void CanvasContext::uniformMatrix4fv(QJSValue location3D, bool transpose, QJSValue array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << location3D.toString() << ", transpose:" << transpose << ", array:" << array.toString() << ")"; if (!isOfType(location3D, "QtCanvas3D::CanvasUniformLocation")) return; CanvasUniformLocation *locationObj = static_cast<CanvasUniformLocation *>(location3D.toQObject()); // Check if we have a JavaScript array if (array.isArray()) { uniformMatrix4fva(locationObj, transpose,array.toVariant().toList()); return; } // We should have a Float32Array QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, array));
3921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990
if (!m_currentProgram || !typedArray || !locationObj || typedArray->arrayType() != QV4::Heap::TypedArray::Float32Array) return; qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "numMatrices:" << (typedArray->length() / 16); int uniformLocation = locationObj->id(); float *arrayData = (float *)typedArray->arrayData()->data(); int numMatrices = typedArray->length() / 16; glUniformMatrix4fv(uniformLocation, numMatrices, transpose, arrayData); logAllGLErrors(__FUNCTION__); } /*! * \internal */ void CanvasContext::uniformMatrix4fva(CanvasUniformLocation *uniformLocation, bool transpose, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << uniformLocation << ", transpose:" << transpose << ", array:" << array << ")"; if (!m_currentProgram || !uniformLocation) return; int location3D = uniformLocation->id(); int size = array.count(); float *arrayData = new float[size]; int numMatrices = size / 16; ArrayUtils::fillFloatArrayFromVariantList(array, arrayData); glUniformMatrix4fv(location3D, numMatrices, transpose, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \internal */ void CanvasContext::uniformMatrix3fva(CanvasUniformLocation *uniformLocation, bool transpose, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << uniformLocation << ", transpose:" << transpose << ", array:" << array << ")"; if (!m_currentProgram || !uniformLocation) return; int location3D = uniformLocation->id(); int size = array.count(); float *arrayData = new float[size]; int numMatrices = size / 9; ArrayUtils::fillFloatArrayFromVariantList(array, arrayData); glUniformMatrix3fv(location3D, numMatrices, transpose, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; }
3991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060
/*! * \internal */ void CanvasContext::uniformMatrix2fva(CanvasUniformLocation *uniformLocation, bool transpose, QVariantList array) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(location3D:" << uniformLocation << ", transpose:" << transpose << ", array:" << array << ")"; if (!m_currentProgram || !uniformLocation) return; int location3D = uniformLocation->id(); int size = array.count(); float *arrayData = new float[size]; int numMatrices = size / 4; ArrayUtils::fillFloatArrayFromVariantList(array, arrayData); glUniformMatrix2fv(location3D, numMatrices, transpose, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \qmlmethod void Context3D::vertexAttribPointer(int indx, int size, glEnums type, bool normalized, int stride, long offset) * Sets the currently bound array buffer to the vertex attribute at the index passed at \a indx. * \a size is the number of components per attribute. \a stride specifies the byte offset between * consecutive vertex attributes. \a offset specifies the byte offset to the first vertex attribute * in the array. If int values should be normalized, set \a normalized to \c{true}. */ /*! * \internal */ void CanvasContext::vertexAttribPointer(int indx, int size, glEnums type, bool normalized, int stride, long offset) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx:" << indx << ", size: " << size << ", type:" << glEnumToString(type) << ", normalized:" << normalized << ", stride:" << stride << ", offset:" << offset << ")"; glVertexAttribPointer(indx, size, GLenum(type), normalized, stride, (GLvoid *)offset); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::bufferData(glEnums target, long size, glEnums usage) * Sets the size of the \a target buffer to \a size. Target buffer must be either * \c{Context3D.ARRAY_BUFFER} or \c{Context3D.ELEMENT_ARRAY_BUFFER}. \a usage sets the usage pattern * of the data, and must be one of \c{Context3D.STREAM_DRAW}, \c{Context3D.STATIC_DRAW}, or * \c{Context3D.DYNAMIC_DRAW}. */ /*! * \internal */ void CanvasContext::bufferData(glEnums target, long size, glEnums usage) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target)
4061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130
<< ", size:" << size << ", usage:" << glEnumToString(usage) << ")"; switch (target) { case ARRAY_BUFFER: if (!m_currentArrayBuffer) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION called with no ARRAY_BUFFER bound"; m_error = INVALID_OPERATION; return; } break; case ELEMENT_ARRAY_BUFFER: if (!m_currentElementArrayBuffer) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION called with no " << "ELEMENT_ARRAY_BUFFER bound"; m_error = INVALID_OPERATION; return; } break; default: qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM unknown target"; m_error = INVALID_ENUM; return; } glBufferData(GLenum(target), size, (GLvoid *) 0, GLenum(usage)); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::bufferData(glEnums target, value data, glEnums usage) * Writes the \a data held in \c{ArrayBufferView} or \c{ArrayBuffer} to the \a target buffer. * Target buffer must be either \c{Context3D.ARRAY_BUFFER } or \c{Context3D.ELEMENT_ARRAY_BUFFER}. * \a usage sets the usage pattern of the data, and must be one of \c{Context3D.STREAM_DRAW}, * \c{Context3D.STATIC_DRAW}, or \c{Context3D.DYNAMIC_DRAW}. */ /*! * \internal */ void CanvasContext::bufferData(glEnums target, QJSValue data, glEnums usage) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", data:" << data.toString() << ", usage:" << glEnumToString(usage) << ")"; if (data.isNull()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_VALUE called with null data"; m_error = INVALID_VALUE; return; } if (target != ARRAY_BUFFER && target != ELEMENT_ARRAY_BUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM target must be either ARRAY_BUFFER" << " or ELEMENT_ARRAY_BUFFER."; m_error = INVALID_ENUM; return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, data));
4131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200
QV4::Scoped<QV4::ArrayBuffer> arrayBuffer(scope, QJSValuePrivate::convertedToValue(m_v4engine, data)); if (typedArray) { glBufferData(GLenum(target), typedArray->byteLength(), (GLvoid *) typedArray->arrayData()->data(), GLenum(usage)); logAllGLErrors(__FUNCTION__); } else if (arrayBuffer) { glBufferData(GLenum(target), arrayBuffer->byteLength(), (GLvoid *) arrayBuffer->data(), GLenum(usage)); logAllGLErrors(__FUNCTION__); } else { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE data must be either" << "TypedArray or ArrayBuffer"; m_error = INVALID_VALUE; return; } } /*! * \qmlmethod void Context3D::bufferSubData(glEnums target, int offset, value data) * Writes the \a data held in \c{ArrayBufferView} or \c{ArrayBuffer} starting from \a offset to the * \a target buffer. Target buffer must be either \c Context3D.ARRAY_BUFFER or * \c{Context3D.ELEMENT_ARRAY_BUFFER}. */ /*! * \internal */ void CanvasContext::bufferSubData(glEnums target, int offset, QJSValue data) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", offset:"<< offset << ", data:" << data.toString() << ")"; if (target != ARRAY_BUFFER && target != ELEMENT_ARRAY_BUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM target must be either ARRAY_BUFFER" << " or ELEMENT_ARRAY_BUFFER."; m_error = INVALID_ENUM; return; } if (data.isNull()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": INVALID_VALUE called with null data"; m_error = INVALID_VALUE; return; } QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::TypedArray> typedArray(scope, QJSValuePrivate::convertedToValue(m_v4engine, data)); QV4::Scoped<QV4::ArrayBuffer> arrayBuffer(scope, QJSValuePrivate::convertedToValue(m_v4engine, data)); if (typedArray) { glBufferSubData(GLenum(target), offset, typedArray->byteLength(), (GLvoid *) typedArray->arrayData()->data()); logAllGLErrors(__FUNCTION__); } else if (arrayBuffer) { glBufferSubData(GLenum(target),
4201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270
offset, arrayBuffer->byteLength(), (GLvoid *) arrayBuffer->data()); logAllGLErrors(__FUNCTION__); } else { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE data must be either" << "TypedArray or ArrayBuffer"; m_error = INVALID_VALUE; return; } } /*! * \qmlmethod value Context3D::getBufferParameter(glEnums target, glEnums pname) * Returns the value for the passed \a pname of the \a target. Target * must be either \c Context3D.ARRAY_BUFFER or \c{Context3D.ELEMENT_ARRAY_BUFFER}. pname must be * either \c Context3D.BUFFER_SIZE or \c{Context3D.BUFFER_USAGE}. */ /*! * \internal */ QJSValue CanvasContext::getBufferParameter(glEnums target, glEnums pname) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", pname" << glEnumToString(pname) << ")"; if (target != ARRAY_BUFFER && target != ELEMENT_ARRAY_BUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM target must be either ARRAY_BUFFER" << " or ELEMENT_ARRAY_BUFFER."; m_error = INVALID_ENUM; return m_engine->newObject(); } switch (pname) { case BUFFER_SIZE: case BUFFER_USAGE: GLint data; glGetBufferParameteriv(GLenum(target), GLenum(pname), &data); logAllGLErrors(__FUNCTION__); return QJSValue(data); default: break; } qCWarning(canvas3drendering) << "getBufferParameter() : UNKNOWN pname"; m_error = INVALID_ENUM; return m_engine->newObject(); } /*! * \qmlmethod bool Context3D::isBuffer(Object anyObject) * Returns \c true if the given \a anyObect is a valid Buffer3D object and \c false otherwise. */ /*! * \internal */ bool CanvasContext::isBuffer(QJSValue anyObject) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(anyObject:" << anyObject.toString() << ")"; CanvasBuffer *buffer = getAsBuffer3D(anyObject); if (!buffer) return false;
4271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340
return glIsBuffer(buffer->id()); } /*! * \internal */ CanvasBuffer *CanvasContext::getAsBuffer3D(QJSValue anyObject) const { if (!isOfType(anyObject, "QtCanvas3D::CanvasBuffer")) return 0; CanvasBuffer *buffer = static_cast<CanvasBuffer *>(anyObject.toQObject()); if (!buffer->isAlive()) return 0; return buffer; } /*! * \qmlmethod void Context3D::deleteBuffer(Buffer3D buffer3D) * Deletes the \a buffer3D. Has no effect if the Buffer3D object has been deleted already. */ /*! * \internal */ void CanvasContext::deleteBuffer(QJSValue buffer3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(buffer:" << buffer3D.toString() << ")"; CanvasBuffer *bufferObj = getAsBuffer3D(buffer3D); if (!bufferObj) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ": WARNING invalid buffer target" << buffer3D.toString(); return; } m_idToCanvasBufferMap.remove(bufferObj->id()); bufferObj->del(); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod glEnums Context3D::getError() * Returns the error value, if any. */ /*! * \internal */ CanvasContext::glEnums CanvasContext::getError() { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__; glEnums retVal = m_error; m_error = NO_ERROR; if (retVal == NO_ERROR) retVal = glEnums(glGetError()); return retVal; } /*! * \qmlmethod variant Context3D::getParameter(glEnums pname) * Returns the value for the given \a pname. pname must be one of \c{Context3D.RED_BITS}, * \c{Context3D.GREEN_BITS}, \c{Context3D.BLUE_BITS}, \c{Context3D.ALPHA_BITS}, * \c{Context3D.DEPTH_BITS}, \c{Context3D.STENCIL_BITS}, \c{Context3D.MAX_TEXTURE_IMAGE_UNITS}, * \c{Context3D.MAX_VERTEX_TEXTURE_IMAGE_UNITS}, \c{Context3D.MAX_TEXTURE_SIZE}, * \c{Context3D.MAX_CUBE_MAP_TEXTURE_SIZE}, \c{Context3D.MAX_VERTEX_UNIFORM_VECTORS} * (not supported in OpenGL ES2), \c{Context3D.RENDERER}, \c{Context3D.SHADING_LANGUAGE_VERSION}, * \c{Context3D.VENDOR}, \c{Context3D.VERSION}, \c{Context3D.UNMASKED_VENDOR_WEBGL}, or
4341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410
* \c{Context3D.UNMASKED_RENDERER_WEBGL}. */ /*! * \internal */ QJSValue CanvasContext::getParameter(glEnums pname) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "( pname:" << glEnumToString(pname) << ")"; // TODO: Implement these: // CURRENT_PROGRAM m_currentProgram // ELEMENT_ARRAY_BUFFER_BINDING m_currentElementArrayBuffer // FRAMEBUFFER_BINDING WebGLFramebuffer // RENDERBUFFER_BINDING WebGLRenderbuffer // ARRAY_BUFFER_BINDING m_currentArrayBuffer // TEXTURE_BINDING_2D m_currentTexture2D // TEXTURE_BINDING_CUBE_MAP m_currentTextureCubeMap switch (pname) { // GLint values // Intentional flow through case MAX_COMBINED_TEXTURE_IMAGE_UNITS: case MAX_FRAGMENT_UNIFORM_VECTORS: case MAX_RENDERBUFFER_SIZE: case MAX_VARYING_VECTORS: case MAX_VERTEX_ATTRIBS: case MAX_VERTEX_TEXTURE_IMAGE_UNITS: #if defined(QT_OPENGL_ES_2) case MAX_VERTEX_UNIFORM_VECTORS: #endif case PACK_ALIGNMENT: case SAMPLE_BUFFERS: case SAMPLES: case STENCIL_BACK_REF: case STENCIL_CLEAR_VALUE: case STENCIL_REF: case SUBPIXEL_BITS: case UNPACK_ALIGNMENT: case RED_BITS: case GREEN_BITS: case BLUE_BITS: case ALPHA_BITS: case DEPTH_BITS: case STENCIL_BITS: case MAX_TEXTURE_IMAGE_UNITS: case MAX_TEXTURE_SIZE: case MAX_CUBE_MAP_TEXTURE_SIZE: { GLint value; glGetIntegerv(pname, &value); logAllGLErrors(__FUNCTION__); return QJSValue(int(value)); } // GLuint values // Intentional flow through case STENCIL_BACK_VALUE_MASK: case STENCIL_BACK_WRITEMASK: case STENCIL_VALUE_MASK: case STENCIL_WRITEMASK: { GLint value; glGetIntegerv(pname, &value); logAllGLErrors(__FUNCTION__); return QJSValue(uint(value)); } case FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480
if (m_standardDerivatives) { GLint value; glGetIntegerv(pname, &value); logAllGLErrors(__FUNCTION__); return QJSValue(value); } m_error = INVALID_ENUM; return QJSValue(QJSValue::NullValue); #if !defined(QT_OPENGL_ES_2) case MAX_VERTEX_UNIFORM_VECTORS: { GLint value; glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &value); logAllGLErrors(__FUNCTION__); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "():" << value; return QJSValue(value); } #endif // GLboolean values // Intentional flow through case BLEND: case CULL_FACE: case DEPTH_TEST: case DEPTH_WRITEMASK: case DITHER: case POLYGON_OFFSET_FILL: case SAMPLE_COVERAGE_INVERT: case SCISSOR_TEST: case STENCIL_TEST: { GLboolean value; glGetBooleanv(pname, &value); logAllGLErrors(__FUNCTION__); return QJSValue(bool(value)); } case UNPACK_FLIP_Y_WEBGL: return QJSValue(m_unpackFlipYEnabled); case UNPACK_PREMULTIPLY_ALPHA_WEBGL: return QJSValue(m_unpackPremultiplyAlphaEnabled); // GLenum values // Intentional flow through case ACTIVE_TEXTURE: case BLEND_DST_ALPHA: case BLEND_DST_RGB: case BLEND_EQUATION_ALPHA: case BLEND_EQUATION_RGB: case BLEND_SRC_ALPHA: case BLEND_SRC_RGB: case CULL_FACE_MODE: case DEPTH_FUNC: case FRONT_FACE: case GENERATE_MIPMAP_HINT: case STENCIL_BACK_FAIL: case STENCIL_BACK_FUNC: case STENCIL_BACK_PASS_DEPTH_FAIL: case STENCIL_BACK_PASS_DEPTH_PASS: case STENCIL_FAIL: case STENCIL_FUNC: case STENCIL_PASS_DEPTH_FAIL: case STENCIL_PASS_DEPTH_PASS: { GLint value; glGetIntegerv(pname, &value); logAllGLErrors(__FUNCTION__); return QJSValue(glEnums(value)); } case IMPLEMENTATION_COLOR_READ_FORMAT: return QJSValue(QJSValue::UndefinedValue); case IMPLEMENTATION_COLOR_READ_TYPE:
4481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550
return QJSValue(QJSValue::UndefinedValue); case UNPACK_COLORSPACE_CONVERSION_WEBGL: return QJSValue(BROWSER_DEFAULT_WEBGL); // Float32Array (with 2 elements) // Intentional flow through case ALIASED_LINE_WIDTH_RANGE: case ALIASED_POINT_SIZE_RANGE: case DEPTH_RANGE: { QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::ArrayBuffer> buffer(scope, m_v4engine->memoryManager->alloc<QV4::ArrayBuffer>( m_v4engine, sizeof(float) * 2)); glGetFloatv(pname, (float *) buffer->data()); logAllGLErrors(__FUNCTION__); QV4::ScopedFunctionObject constructor(scope, m_v4engine->typedArrayCtors[ QV4::Heap::TypedArray::Float32Array]); QV4::ScopedCallData callData(scope, 1); callData->args[0] = buffer; return QJSValue(m_v4engine, constructor->construct(callData)); } // Float32Array (with 4 values) // Intentional flow through case BLEND_COLOR: case COLOR_CLEAR_VALUE: { QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::ArrayBuffer> buffer(scope, m_v4engine->memoryManager->alloc<QV4::ArrayBuffer>( m_v4engine, sizeof(float) * 4)); glGetFloatv(pname, (float *) buffer->data()); logAllGLErrors(__FUNCTION__); QV4::ScopedFunctionObject constructor(scope, m_v4engine->typedArrayCtors[ QV4::Heap::TypedArray::Float32Array]); QV4::ScopedCallData callData(scope, 1); callData->args[0] = buffer; return QJSValue(m_v4engine, constructor->construct(callData)); } // Int32Array (with 2 elements) case MAX_VIEWPORT_DIMS: { QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::ArrayBuffer> buffer(scope, m_v4engine->memoryManager->alloc<QV4::ArrayBuffer>( m_v4engine, sizeof(int) * 2)); glGetIntegerv(pname, (int *) buffer->data()); logAllGLErrors(__FUNCTION__); QV4::ScopedFunctionObject constructor(scope, m_v4engine->typedArrayCtors[ QV4::Heap::TypedArray::Int32Array]); QV4::ScopedCallData callData(scope, 1); callData->args[0] = buffer; return QJSValue(m_v4engine, constructor->construct(callData)); } break; // Int32Array (with 4 elements) // Intentional flow through case SCISSOR_BOX: case VIEWPORT: { QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::ArrayBuffer> buffer(scope,
4551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620
m_v4engine->memoryManager->alloc<QV4::ArrayBuffer>( m_v4engine, sizeof(int) * 4)); glGetIntegerv(pname, (int *) buffer->data()); logAllGLErrors(__FUNCTION__); QV4::ScopedFunctionObject constructor(scope, m_v4engine->typedArrayCtors[ QV4::Heap::TypedArray::Int32Array]); QV4::ScopedCallData callData(scope, 1); callData->args[0] = buffer; return QJSValue(m_v4engine, constructor->construct(callData)); } // sequence<GLboolean> (with 4 values) // Intentional flow through case COLOR_WRITEMASK: { GLboolean values[4]; glGetBooleanv(COLOR_WRITEMASK, values); logAllGLErrors(__FUNCTION__); QJSValue arrayValue = m_engine->newArray(4); arrayValue.setProperty(0, values[0]); arrayValue.setProperty(1, values[1]); arrayValue.setProperty(2, values[2]); arrayValue.setProperty(3, values[3]); return arrayValue; } // GLfloat values // Intentional flow through case DEPTH_CLEAR_VALUE: case LINE_WIDTH: case POLYGON_OFFSET_FACTOR: case POLYGON_OFFSET_UNITS: case SAMPLE_COVERAGE_VALUE: { GLfloat value; glGetFloatv(pname, &value); logAllGLErrors(__FUNCTION__); return QJSValue(float(value)); } // DomString values // Intentional flow through case RENDERER: case SHADING_LANGUAGE_VERSION: case VENDOR: case VERSION: { const GLubyte *text = glGetString(pname); logAllGLErrors(__FUNCTION__); QString qtext = QString::fromLatin1((const char *)text); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "():" << qtext; return QJSValue(qtext); } case UNMASKED_VENDOR_WEBGL: { const GLubyte *text = glGetString(GL_VENDOR); logAllGLErrors(__FUNCTION__); QString qtext = QString::fromLatin1((const char *)text); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "():" << qtext; return QJSValue(qtext); } case UNMASKED_RENDERER_WEBGL: { const GLubyte *text = glGetString(GL_VENDOR); logAllGLErrors(__FUNCTION__); QString qtext = QString::fromLatin1((const char *)text); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "():" << qtext; return QJSValue(qtext); } case COMPRESSED_TEXTURE_FORMATS: { GLint numFormats; glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
4621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690
if (numFormats > 0) { QV4::Scope scope(m_v4engine); QV4::Scoped<QV4::ArrayBuffer> buffer(scope, m_v4engine->memoryManager->alloc<QV4::ArrayBuffer>( m_v4engine, sizeof(int) * numFormats)); glGetIntegerv(pname, (int *) buffer->data()); logAllGLErrors(__FUNCTION__); QV4::ScopedFunctionObject constructor(scope, m_v4engine->typedArrayCtors[ QV4::Heap::TypedArray::Int32Array]); QV4::ScopedCallData callData(scope, 1); callData->args[0] = buffer; return QJSValue(m_v4engine, constructor->construct(callData)); } } default: { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "(): UNIMPLEMENTED PARAMETER NAME" << glEnumToString(pname); return QJSValue(QJSValue::NullValue); } } return QJSValue(QJSValue::NullValue); } /*! * \qmlmethod string Context3D::getShaderInfoLog(Shader3D shader) * Returns the info log string of the given \a shader. */ /*! * \internal */ QJSValue CanvasContext::getShaderInfoLog(QJSValue shader3D) const { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(shader3D:" << shader3D.toString() << ")"; CanvasShader *shader = getAsShader3D(shader3D); if (!shader) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << "WARNING: invalid shader handle:" << shader3D.toString(); return m_engine->newObject(); } return QJSValue(shader->qOGLShader()->log()); } /*! * \qmlmethod string Context3D::getProgramInfoLog(Program3D program3D) * Returns the info log string of the given \a program3D. */ /*! * \internal */ QString CanvasContext::getProgramInfoLog(QJSValue program3D) const { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ")"; CanvasProgram *program = getAsProgram3D(program3D); if (!program) return QString(); return program->log(); } /*!
4691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760
* \qmlmethod void Context3D::bindBuffer(glEnums target, Buffer3D buffer3D) * Binds the given \a buffer3D to the given \a target. Target must be either * \c Context3D.ARRAY_BUFFER or \c{Context3D.ELEMENT_ARRAY_BUFFER}. If the \a buffer3D given is * \c{null}, the current buffer bound to the target is unbound. */ /*! * \internal */ void CanvasContext::bindBuffer(glEnums target, QJSValue buffer3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target:" << glEnumToString(target) << ", buffer:" << buffer3D.toString() << ")"; if (target != ARRAY_BUFFER && target != ELEMENT_ARRAY_BUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM target must be either ARRAY_BUFFER or" << "ELEMENT_ARRAY_BUFFER."; m_error = INVALID_ENUM; return; } CanvasBuffer *buffer = getAsBuffer3D(buffer3D); if (buffer) { if (target == ARRAY_BUFFER) { if (buffer->target() == CanvasBuffer::UNINITIALIZED) buffer->setTarget(CanvasBuffer::ARRAY_BUFFER); if (buffer->target() != CanvasBuffer::ARRAY_BUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION can't rebind " << "ELEMENT_ARRAY_BUFFER as ARRAY_BUFFER"; m_error = INVALID_OPERATION; return; } m_currentArrayBuffer = buffer; } else { if (buffer->target() == CanvasBuffer::UNINITIALIZED) buffer->setTarget(CanvasBuffer::ELEMENT_ARRAY_BUFFER); if (buffer->target() != CanvasBuffer::ELEMENT_ARRAY_BUFFER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION can't rebind " << "ARRAY_BUFFER as ELEMENT_ARRAY_BUFFER"; m_error = INVALID_OPERATION; return; } m_currentElementArrayBuffer = buffer; } glBindBuffer(GLenum(target), buffer->id()); logAllGLErrors(__FUNCTION__); } else { glBindBuffer(GLenum(target), 0); logAllGLErrors(__FUNCTION__); } } // TODO: Is this function useful? We don't offer a way to query the status. /*! * \qmlmethod void Context3D::validateProgram(Program3D program3D) * Validates the given \a program3D. The validation status is stored into the state of the shader * program container in \a program3D. */ /*! * \internal */ void CanvasContext::validateProgram(QJSValue program3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__
4761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830
<< "(program3D:" << program3D.toString() << ")"; CanvasProgram *program = getAsProgram3D(program3D); if (program) program->validateProgram(); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::useProgram(Program3D program) * Installs the given \a program3D as a part of the current rendering state. */ /*! * \internal */ void CanvasContext::useProgram(QJSValue program3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ")"; CanvasProgram *program = getAsProgram3D(program3D); m_currentProgram = program; if (!program || !program->isLinked()) return; program->bind(); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::clear(glEnums flags) * Clears the given \a flags. */ /*! * \internal */ void CanvasContext::clear(glEnums flags) { if (!((QLoggingCategory &) canvas3drendering()).isDebugEnabled()) { QString flagStr; if (flags && COLOR_BUFFER_BIT != 0) flagStr.append(" COLOR_BUFFER_BIT "); if (flags && DEPTH_BUFFER_BIT != 0) flagStr.append(" DEPTH_BUFFER_BIT "); if (flags && STENCIL_BUFFER_BIT != 0) flagStr.append(" STENCIL_BUFFER_BIT "); qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(flags:" << flagStr << ")"; } glClear(flags); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::cullFace(glEnums mode) * Sets the culling to \a mode. Must be one of \c{Context3D.FRONT}, \c{Context3D.BACK}, * or \c{Context3D.FRONT_AND_BACK}. Defaults to \c{Context3D.BACK}. */ /*! * \internal */ void CanvasContext::cullFace(glEnums mode) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(mode:" << glEnumToString(mode) << ")"; glCullFace(mode); logAllGLErrors(__FUNCTION__);
4831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900
} /*! * \qmlmethod void Context3D::frontFace(glEnums mode) * Sets the front face drawing to \a mode. Must be either \c Context3D.CW * or \c{Context3D.CCW}. Defaults to \c{Context3D.CCW}. */ /*! * \internal */ void CanvasContext::frontFace(glEnums mode) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(mode:" << glEnumToString(mode) << ")"; glFrontFace(mode); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::depthMask(bool flag) * Enables or disables the depth mask based on \a flag. Defaults to \c{true}. */ /*! * \internal */ void CanvasContext::depthMask(bool flag) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(flag:" << flag << ")"; if (flag) glDepthMask(GL_TRUE); else glDepthMask(GL_FALSE); logAllGLErrors(__FUNCTION__); } // TODO: Why are all the enums for this commented out? /*! * \qmlmethod void Context3D::depthFunc(glEnums func) * Sets the depth function to \a func. Must be one of \c{Context3D.NEVER}, \c{Context3D.LESS}, * \c{Context3D.EQUAL}, \c{Context3D.LEQUAL}, \c{Context3D.GREATER}, \c{Context3D.NOTEQUAL}, * \c{Context3D.GEQUAL}, or \c{Context3D.ALWAYS}. Defaults to \c{Context3D.LESS}. */ /*! * \internal */ void CanvasContext::depthFunc(glEnums func) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(func:" << glEnumToString(func) << ")"; glDepthFunc(GLenum(func)); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::depthRange(float zNear, float zFar) * Sets the depth range between \a zNear and \a zFar. Values are clamped to \c{[0, 1]}. \a zNear * must be less or equal to \a zFar. zNear Range defaults to \c{[0, 1]}. */ /*! * \internal */ void CanvasContext::depthRange(float zNear, float zFar) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(zNear:" << zNear << ", zFar:" << zFar << ")"; glDepthRangef(GLclampf(zNear), GLclampf(zFar)); logAllGLErrors(__FUNCTION__);
4901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970
} /*! * \qmlmethod void Context3D::clearStencil(int stencil) * Sets the clear value for the stencil buffer to \a stencil. Defaults to \c{0}. */ /*! * \internal */ void CanvasContext::clearStencil(int stencil) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(stencil:" << stencil << ")"; glClearStencil(stencil); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::colorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha) * Enables or disables the writing of colors to the frame buffer based on \a maskRed, \a maskGreen, * \a maskBlue and \a maskAlpha. All default to \c{true}. */ /*! * \internal */ void CanvasContext::colorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(maskRed:" << maskRed << ", maskGreen:" << maskGreen << ", maskBlue:" << maskBlue << ", maskAlpha:" << maskAlpha << ")"; glColorMask(maskRed, maskGreen, maskBlue, maskAlpha); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::clearDepth(float depth) * Sets the clear value for the depth buffer to \a depth. Must be between \c{[0, 1]}. Defaults * to \c{1}. */ /*! * \internal */ void CanvasContext::clearDepth(float depth) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(depth:" << depth << ")"; glClearDepthf(depth); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::clearColor(float red, float green, float blue, float alpha) * Sets the clear values for the color buffers with \a red, \a green, \a blue and \a alpha. Values * must be between \c{[0, 1]}. All default to \c{0}. */ /*! * \internal */ void CanvasContext::clearColor(float red, float green, float blue, float alpha) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(red:" << red << ", green:" << green << ", blue:" << blue << ", alpha:" << alpha << ")"; glClearColor(red, green, blue, alpha); logAllGLErrors(__FUNCTION__); }
4971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040
/*! * \qmlmethod Context3D::viewport(int x, int y, int width, int height) * Defines the affine transformation from normalized x and y device coordinates to window * coordinates within the drawing buffer. * \a x defines the left edge of the viewport. * \a y defines the bottom edge of the viewport. * \a width defines the width of the viewport. * \a height defines the height of the viewport. */ /*! * \internal */ void CanvasContext::viewport(int x, int y, int width, int height) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(x:" << x << ", y:" << y << ", width:" << width << ", height:" << height << ")"; glViewport(x, y, width, height); logAllGLErrors(__FUNCTION__); m_glViewportRect.setX(x); m_glViewportRect.setY(y); m_glViewportRect.setWidth(width); m_glViewportRect.setHeight(height); } /*! * \qmlmethod void Context3D::drawArrays(glEnums mode, int first, int count) * Renders the geometric primitives held in the currently bound array buffer starting from \a first * up to \a count using \a mode for drawing. Mode can be one of: * \list * \li \c{Context3D.POINTS} * \li \c{Context3D.LINES} * \li \c{Context3D.LINE_LOOP} * \li \c{Context3D.LINE_STRIP} * \li \c{Context3D.TRIANGLES} * \li \c{Context3D.TRIANGLE_STRIP} * \li \c{Context3D.TRIANGLE_FAN} * \endlist */ /*! * \internal */ void CanvasContext::drawArrays(glEnums mode, int first, int count) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(mode:" << glEnumToString(mode) << ", first:" << first << ", count:" << count << ")"; glDrawArrays(mode, first, count); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::drawElements(glEnums mode, int count, glEnums type, long offset) * Renders the number of geometric elements given in \a count held in the currently bound element * array buffer using \a mode for drawing. Mode can be one of: * \list * \li \c{Context3D.POINTS} * \li \c{Context3D.LINES} * \li \c{Context3D.LINE_LOOP} * \li \c{Context3D.LINE_STRIP} * \li \c{Context3D.TRIANGLES} * \li \c{Context3D.TRIANGLE_STRIP} * \li \c{Context3D.TRIANGLE_FAN} * \endlist * * \a type specifies the element type and can be one of:
5041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110
* \list * \li \c Context3D.UNSIGNED_BYTE * \li \c{Context3D.UNSIGNED_SHORT} * \endlist * * \a offset specifies the location3D where indices are stored. */ /*! * \internal */ void CanvasContext::drawElements(glEnums mode, int count, glEnums type, long offset) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(mode:" << glEnumToString(mode) << ", count:" << count << ", type:" << glEnumToString(type) << ", offset:" << offset << ")"; glDrawElements(GLenum(mode), count, GLenum(type), (GLvoid*)offset); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::readPixels(int x, int y, long width, long height, glEnums format, glEnums type, ArrayBufferView pixels) * Returns the pixel data in the rectangle specified by \a x, \a y, \a width and \a height of the * frame buffer in \a pixels using \a format (must be \c{Context3D.RGBA}) and \a type * (must be \c{Context3D.UNSIGNED_BYTE}). */ /*! * \internal */ void CanvasContext::readPixels(int x, int y, long width, long height, glEnums format, glEnums type, QJSValue pixels) { if (format != RGBA) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM format must be RGBA."; m_error = INVALID_ENUM; return; } if (type != UNSIGNED_BYTE) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM type must be UNSIGNED_BYTE."; m_error = INVALID_ENUM; return; } if (pixels.isNull()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE pixels was null."; m_error = INVALID_VALUE; return; } uchar *bufferPtr = getAsUint8ArrayRawPtr(pixels); if (!bufferPtr) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION pixels must be Uint8Array."; m_error = INVALID_OPERATION; return; } glReadPixels(x, y, width, height, format, type, bufferPtr); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod ActiveInfo3D Context3D::getActiveAttrib(Program3D program3D, uint index) * Returns information about the given active attribute variable defined by \a index for the given * \a program3D.
5111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180
* \sa ActiveInfo3D */ /*! * \internal */ CanvasActiveInfo *CanvasContext::getActiveAttrib(QJSValue program3D, uint index) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", index:" << index << ")"; CanvasProgram *program = getAsProgram3D(program3D); if (!program) return 0; char *name = new char[512]; GLsizei length = 0; int size = 0; GLenum type = 0; glGetActiveAttrib(program->id(), index, 512, &length, &size, &type, name); logAllGLErrors(__FUNCTION__); QString strName(name); delete [] name; return new CanvasActiveInfo(size, CanvasContext::glEnums(type), strName); } /*! * \qmlmethod ActiveInfo3D Context3D::getActiveUniform(Program3D program3D, uint index) * Returns information about the given active uniform variable defined by \a index for the given * \a program3D. * \sa ActiveInfo3D */ /*! * \internal */ CanvasActiveInfo *CanvasContext::getActiveUniform(QJSValue program3D, uint index) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program3D:" << program3D.toString() << ", index:" << index << ")"; CanvasProgram *program = getAsProgram3D(program3D); if (!program) return 0; char *name = new char[512]; GLsizei length = 0; int size = 0; GLenum type = 0; glGetActiveUniform(program->id(), index, 512, &length, &size, &type, name); logAllGLErrors(__FUNCTION__); QString strName(name); delete [] name; return new CanvasActiveInfo(size, CanvasContext::glEnums(type), strName); } /*! * \qmlmethod void Context3D::stencilFunc(glEnums func, int ref, uint mask) * Sets front and back function \a func and reference value \a ref for stencil testing. * Also sets the \a mask value that is ANDed with both reference and stored stencil value when * the test is done. \a func is initially set to \c{Context3D.ALWAYS} and can be one of: * \list * \li \c{Context3D.NEVER} * \li \c{Context3D.LESS} * \li \c{Context3D.LEQUAL} * \li \c{Context3D.GREATER} * \li \c{Context3D.GEQUAL} * \li \c{Context3D.EQUAL} * \li \c{Context3D.NOTEQUAL} * \li \c{Context3D.ALWAYS}
5181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250
* \endlist */ /*! * \internal */ void CanvasContext::stencilFunc(glEnums func, int ref, uint mask) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(func:" << glEnumToString(func) << ", ref:" << ref << ", mask:" << mask << ")"; glStencilFunc(GLenum(func), ref, mask); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::stencilFuncSeparate(glEnums face, glEnums func, int ref, uint mask) * Sets front and/or back (defined by \a face) function \a func and reference value \a ref for * stencil testing. Also sets the \a mask value that is ANDed with both reference and stored stencil * value when the test is done. \a face can be one of: * \list * \li \c{Context3D.FRONT} * \li \c{Context3D.BACK} * \li \c{Context3D.FRONT_AND_BACK} * \endlist * \a func is initially set to \c{Context3D.ALWAYS} and can be one of: * \list * \li \c{Context3D.NEVER} * \li \c{Context3D.LESS} * \li \c{Context3D.LEQUAL} * \li \c{Context3D.GREATER} * \li \c{Context3D.GEQUAL} * \li \c{Context3D.EQUAL} * \li \c{Context3D.NOTEQUAL} * \li \c{Context3D.ALWAYS} * \endlist */ /*! * \internal */ void CanvasContext::stencilFuncSeparate(glEnums face, glEnums func, int ref, uint mask) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(face:" << glEnumToString(face) << ", func:" << glEnumToString(func) << ", ref:" << ref << ", mask:" << mask << ")"; glStencilFuncSeparate(GLenum(face), GLenum(func), ref, mask); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::stencilMask(uint mask) * Controls the front and back writing of individual bits in the stencil planes. \a mask defines * the bit mask to enable and disable writing of individual bits in the stencil planes. */ /*! * \internal */ void CanvasContext::stencilMask(uint mask) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(mask:" << mask << ")"; glStencilMask(mask); logAllGLErrors(__FUNCTION__); }
5251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320
/*! * \qmlmethod void Context3D::stencilMaskSeparate(glEnums face, uint mask) * Controls the front and/or back writing (defined by \a face) of individual bits in the stencil * planes. \a mask defines the bit mask to enable and disable writing of individual bits in the * stencil planes. \a face can be one of: * \list * \li \c{Context3D.FRONT} * \li \c{Context3D.BACK} * \li \c{Context3D.FRONT_AND_BACK} * \endlist */ /*! * \internal */ void CanvasContext::stencilMaskSeparate(glEnums face, uint mask) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(face:" << glEnumToString(face) << ", mask:" << mask << ")"; glStencilMaskSeparate(GLenum(face), mask); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::stencilOp(glEnums sfail, glEnums zfail, glEnums zpass) * Sets the front and back stencil test actions for failing the test \a zfail and passing the test * \a zpass. \a sfail, \a zfail and \a zpass are initially set to \c{Context3D.KEEP} and can be one * of: * \list * \li \c{Context3D.KEEP} * \li \c{Context3D.ZERO} * \li \c{Context3D.GL_REPLACE} * \li \c{Context3D.GL_INCR} * \li \c{Context3D.GL_INCR_WRAP} * \li \c{Context3D.GL_DECR} * \li \c{Context3D.GL_DECR_WRAP} * \li \c{Context3D.GL_INVERT} * \endlist */ /*! * \internal */ void CanvasContext::stencilOp(glEnums sfail, glEnums zfail, glEnums zpass) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(sfail:" << glEnumToString(sfail) << ", zfail:" << glEnumToString(zfail) << ", zpass:" << glEnumToString(zpass) << ")"; glStencilOp(GLenum(sfail), GLenum(zfail), GLenum(zpass)); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::stencilOpSeparate(glEnums face, glEnums fail, glEnums zfail, glEnums zpass) * Sets the front and/or back (defined by \a face) stencil test actions for failing the test * \a zfail and passing the test \a zpass. \a face can be one of: * \list * \li \c{Context3D.FRONT} * \li \c{Context3D.BACK} * \li \c{Context3D.FRONT_AND_BACK} * \endlist * * \a sfail, \a zfail and \a zpass are initially set to \c{Context3D.KEEP} and can be one of: * \list * \li \c{Context3D.KEEP} * \li \c{Context3D.ZERO} * \li \c{Context3D.GL_REPLACE}
5321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390
* \li \c{Context3D.GL_INCR} * \li \c{Context3D.GL_INCR_WRAP} * \li \c{Context3D.GL_DECR} * \li \c{Context3D.GL_DECR_WRAP} * \li \c{Context3D.GL_INVERT} * \endlist */ /*! * \internal */ void CanvasContext::stencilOpSeparate(glEnums face, glEnums fail, glEnums zfail, glEnums zpass) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(face:" << glEnumToString(face) << ", fail:" << glEnumToString(fail) << ", zfail:" << glEnumToString(zfail) << ", zpass:" << glEnumToString(zpass) << ")"; glStencilOpSeparate(GLenum(face), GLenum(fail), GLenum(zfail), GLenum(zpass)); logAllGLErrors(__FUNCTION__); } /*! * \qmlmethod void Context3D::vertexAttrib1fva(int indx, list<variant> values) * Sets the array of float values given in \a values to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib1fva(uint indx, QVariantList values) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx" << indx << ", values:" << values << ")"; if (!m_currentProgram) return; int size = values.count(); float *arrayData = new float[size]; ArrayUtils::fillFloatArrayFromVariantList(values, arrayData); glVertexAttrib1fv(indx, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \qmlmethod void Context3D::vertexAttrib2fva(int indx, list<variant> values) * Sets the array of float values given in \a values to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib2fva(uint indx, QVariantList values) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx" << indx << ", values:" << values << ")"; if (!m_currentProgram) return; int size = values.count(); float *arrayData = new float[size];
5391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460
ArrayUtils::fillFloatArrayFromVariantList(values, arrayData); glVertexAttrib2fv(indx, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \qmlmethod void Context3D::vertexAttrib3fva(int indx, list<variant> values) * Sets the array of float values given in \a values to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib3fva(uint indx, QVariantList values) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx" << indx << ", values:" << values << ")"; if (!m_currentProgram) return; int size = values.count(); float *arrayData = new float[size]; ArrayUtils::fillFloatArrayFromVariantList(values, arrayData); glVertexAttrib3fv(indx, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \qmlmethod void Context3D::vertexAttrib4fva(int indx, list<variant> values) * Sets the array of float values given in \a values to the generic vertex attribute index * specified by \a indx. */ /*! * \internal */ void CanvasContext::vertexAttrib4fva(uint indx, QVariantList values) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(indx" << indx << ", values:" << values << ")"; if (!m_currentProgram) return; int size = values.count(); float *arrayData = new float[size]; ArrayUtils::fillFloatArrayFromVariantList(values, arrayData); glVertexAttrib4fv(indx, arrayData); logAllGLErrors(__FUNCTION__); delete [] arrayData; } /*! * \qmlmethod int Context3D::getFramebufferAttachmentParameter(glEnums target, glEnums attachment, glEnums pname) * Returns information specified by \a pname about given \a attachment of a framebuffer object * bound to the given \a target. */
5461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530
/*! * \internal */ int CanvasContext::getFramebufferAttachmentParameter(glEnums target, glEnums attachment, glEnums pname) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target" << glEnumToString(target) << ", attachment:" << glEnumToString(attachment) << ", pname:" << glEnumToString(pname) << ")"; GLint parameter; glGetFramebufferAttachmentParameteriv(target, attachment, pname, &parameter); logAllGLErrors(__FUNCTION__); return parameter; } /*! * \qmlmethod int Context3D::getRenderbufferParameter(glEnums target, glEnums pname) * Returns information specified by \a pname of a renderbuffer object * bound to the given \a target. */ /*! * \internal */ int CanvasContext::getRenderbufferParameter(glEnums target, glEnums pname) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target" << glEnumToString(target) << ", pname:" << glEnumToString(pname) << ")"; GLint parameter; glGetRenderbufferParameteriv(target, pname, &parameter); logAllGLErrors(__FUNCTION__); return parameter; } /*! * \qmlmethod variant Context3D::getTexParameter(glEnums target, glEnums pname) * Returns parameter specified by the \a pname of a texture object * bound to the given \a target. \a pname must be one of: * \list * \li \c{Context3D.TEXTURE_MAG_FILTER} * \li \c{Context3D.TEXTURE_MIN_FILTER} * \li \c{Context3D.TEXTURE_WRAP_S} * \li \c{Context3D.TEXTURE_WRAP_T} * \endlist */ /*! * \internal */ QVariant CanvasContext::getTexParameter(glEnums target, glEnums pname) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(target" << glEnumToString(target) << ", pname:" << glEnumToString(pname) << ")"; GLint parameter = 0; if (!m_currentTexture2D) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No current texture bound"; m_error = INVALID_OPERATION; } else if (!m_currentTexture2D->isAlive()) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION Currently bound texture is deleted"; m_error = INVALID_OPERATION; } else { switch (pname) {
5531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600
case TEXTURE_MAG_FILTER: // Intentional flow through case TEXTURE_MIN_FILTER: // Intentional flow through case TEXTURE_WRAP_S: // Intentional flow through case TEXTURE_WRAP_T: glGetTexParameteriv(target, pname, &parameter); logAllGLErrors(__FUNCTION__); break; default: // Intentional flow through qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM invalid pname "<< glEnumToString(pname) << " must be one of: TEXTURE_MAG_FILTER, " << "TEXTURE_MIN_FILTER, TEXTURE_WRAP_S or TEXTURE_WRAP_T"; m_error = INVALID_ENUM; break; } } return QVariant::fromValue(parameter); } /*! * \qmlmethod int Context3D::getVertexAttribOffset(int index, glEnums pname) * Returns the offset of the specified generic vertex attribute pointer \a index. \a pname must be * \c{Context3D.VERTEX_ATTRIB_ARRAY_POINTER} * \list * \li \c{Context3D.TEXTURE_MAG_FILTER} * \li \c{Context3D.TEXTURE_MIN_FILTER} * \li \c{Context3D.TEXTURE_WRAP_S} * \li \c{Context3D.TEXTURE_WRAP_T} * \endlist */ /*! * \internal */ uint CanvasContext::getVertexAttribOffset(uint index, glEnums pname) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(index" << index << ", pname:" << glEnumToString(pname) << ")"; uint offset = 0; if (pname != VERTEX_ATTRIB_ARRAY_POINTER) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM pname must be " << "VERTEX_ATTRIB_ARRAY_POINTER"; m_error = INVALID_ENUM; return 0; } if (index >= m_maxVertexAttribs) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE index must be smaller than " << m_maxVertexAttribs; m_error = INVALID_VALUE; return 0; } glGetVertexAttribPointerv(index, GLenum(pname), (GLvoid**) &offset); logAllGLErrors(__FUNCTION__); return offset; } /*! * \qmlmethod variant Context3D::getVertexAttrib(int index, glEnums pname)
5601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670
* Returns the requested parameter \a pname of the specified generic vertex attribute pointer * \a index. The type returned is dependent on the requested \a pname, as shown in the table: * \table * \header * \li pname * \li Returned Type * \row * \li \c{Context3D.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING} * \li \c{CanvasBuffer} * \row * \li \c{Context3D.VERTEX_ATTRIB_ARRAY_ENABLED} * \li \c{boolean} * \row * \li \c{Context3D.VERTEX_ATTRIB_ARRAY_SIZE} * \li \c{int} * \row * \li \c{Context3D.VERTEX_ATTRIB_ARRAY_STRIDE} * \li \c{int} * \row * \li \c{Context3D.VERTEX_ATTRIB_ARRAY_TYPE} * \li \c{glEnums} * \row * \li \c{Context3D.VERTEX_ATTRIB_ARRAY_NORMALIZED} * \li \c{boolean} * \row * \li \c{Context3D.CURRENT_VERTEX_ATTRIB} * \li \c{sequence<float>} (with 4 elements) * \endtable */ /*! * \internal */ QJSValue CanvasContext::getVertexAttrib(uint index, glEnums pname) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(index" << index << ", pname:" << glEnumToString(pname) << ")"; if (index >= MAX_VERTEX_ATTRIBS) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_VALUE index must be smaller than " << "MAX_VERTEX_ATTRIBS = " << MAX_VERTEX_ATTRIBS; m_error = INVALID_VALUE; } else { switch (pname) { case VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { GLint value = 0; glGetVertexAttribiv(index, GLenum(pname), &value); logAllGLErrors(__FUNCTION__); if (value == 0 || !m_idToCanvasBufferMap.contains(value)) return m_engine->newObject(); return m_engine->newQObject(m_idToCanvasBufferMap[value]); } break; case VERTEX_ATTRIB_ARRAY_ENABLED: { GLint value = 0; glGetVertexAttribiv(index, GLenum(pname), &value); logAllGLErrors(__FUNCTION__); return QJSValue(bool(value)); } break; case VERTEX_ATTRIB_ARRAY_SIZE: { GLint value = 0; glGetVertexAttribiv(index, GLenum(pname), &value); logAllGLErrors(__FUNCTION__); return QJSValue(value); } break;
5671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740
case VERTEX_ATTRIB_ARRAY_STRIDE: { GLint value = 0; glGetVertexAttribiv(index, GLenum(pname), &value); logAllGLErrors(__FUNCTION__); return QJSValue(value); } break; case VERTEX_ATTRIB_ARRAY_TYPE: { GLint value = 0; glGetVertexAttribiv(index, GLenum(pname), &value); logAllGLErrors(__FUNCTION__); return QJSValue(value); } case VERTEX_ATTRIB_ARRAY_NORMALIZED: { GLint value = 0; glGetVertexAttribiv(index, GLenum(pname), &value); logAllGLErrors(__FUNCTION__); return QJSValue(bool(value)); } case CURRENT_VERTEX_ATTRIB: { // TODO: Should be Float32Array GLfloat values[4]; glGetVertexAttribfv(index, GLenum(pname), values); logAllGLErrors(__FUNCTION__); QJSValue array = m_engine->newArray(4); array.setProperty(0, values[0]); array.setProperty(1, values[1]); array.setProperty(2, values[2]); array.setProperty(3, values[3]); return array; } default: qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_ENUM pname " << pname; m_error = INVALID_ENUM; } } return m_engine->newObject(); } /*! * \qmlmethod variant Context3D::getUniform(Program3D program, UniformLocation3D location3D) * Returns the uniform value at the given \a location3D in the \a program. * The type returned is dependent on the uniform type, as shown in the table: * \table * \header * \li Data Type * \li Returned Type * \row * \li boolean * \li sequence<boolean> (with 1 element) * \row * \li int * \li sequence<int> (with 1 element) * \row * \li float * \li sequence<float> (with 1 element) * \row * \li vec2 * \li sequence<float> (with 2 elements) * \row * \li vec3 * \li sequence<float> (with 3 elements) * \row * \li vec4 * \li sequence<float> (with 4 elements) * \row * \li ivec2
5741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810
* \li sequence<int> (with 2 elements) * \row * \li ivec3 * \li sequence<int> (with 3 elements) * \row * \li ivec4 * \li sequence<int> (with 4 elements) * \row * \li bvec2 * \li sequence<boolean> (with 2 elements) * \row * \li bvec3 * \li sequence<boolean> (with 3 elements) * \row * \li bvec4 * \li sequence<boolean> (with 4 elements) * \row * \li mat2 * \li sequence<float> (with 4 elements) * \row * \li mat3 * \li sequence<float> (with 9 elements) * \row * \li mat4 * \li sequence<float> (with 16 elements) * \row * \li sampler2D * \li sequence<int> (with 1 element) * \row * \li samplerCube * \li sequence<int> (with 1 element) * \endtable */ /*! * \internal */ QVariant CanvasContext::getUniform(QJSValue program3D, QJSValue location3D) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(program" << program3D.toString() << ", location3D:" << location3D.toString() << ")"; CanvasProgram *program = getAsProgram3D(program3D); CanvasUniformLocation *location = getAsUniformLocation3D(location3D); if (!program) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No program was specified"; m_error = INVALID_OPERATION; } else if (!location) { qCWarning(canvas3drendering) << "Context3D::" << __FUNCTION__ << ":INVALID_OPERATION No location3D was specified"; m_error = INVALID_OPERATION; } else { uint programId = program->id(); uint locationId = location->id(); CanvasActiveInfo *info = getActiveUniform(program3D, locationId); int numValues = 4; switch (info->type()) { case SAMPLER_2D: // Intentional flow through case SAMPLER_CUBE: // Intentional flow through case INT: { GLint value = 0; glGetUniformiv(programId, locationId, &value); logAllGLErrors(__FUNCTION__); return QVariant::fromValue(value);
5811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880
} case INT_VEC2: numValues--; // Intentional flow through case INT_VEC3: numValues--; // Intentional flow through case INT_VEC4: { numValues--; GLint *value = new GLint[numValues]; glGetUniformiv(programId, locationId, value); logAllGLErrors(__FUNCTION__); QList<float> intList; for (int i = 0; i < numValues; i++) intList << value[i]; // TODO: Should return Int32Array return QVariant::fromValue(intList); } case FLOAT: { GLfloat value = 0; glGetUniformfv(programId, locationId, &value); logAllGLErrors(__FUNCTION__); return QVariant::fromValue(value); } case FLOAT_VEC2: numValues--; // Intentional flow through case FLOAT_VEC3: numValues--; // Intentional flow through case FLOAT_VEC4: { numValues--; GLfloat *value = new GLfloat[numValues]; glGetUniformfv(programId, locationId, value); logAllGLErrors(__FUNCTION__); QList<float> floatList; for (int i = 0; i < numValues; i++) floatList << value[i]; // TODO: Should return Float32Array return QVariant::fromValue(floatList); } case BOOL: { GLint value = 0; glGetUniformiv(programId, locationId, &value); logAllGLErrors(__FUNCTION__); return QVariant::fromValue(bool(value)); } case BOOL_VEC2: numValues--; // Intentional flow through case BOOL_VEC3: numValues--; // Intentional flow through case BOOL_VEC4: { numValues--; GLint *value = new GLint[numValues]; glGetUniformiv(programId, locationId, value); logAllGLErrors(__FUNCTION__); QList<bool> boolList; for (int i = 0; i < numValues; i++) boolList << value[i]; return QVariant::fromValue(boolList);
5881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950
} case FLOAT_MAT2: numValues--; // Intentional flow through case FLOAT_MAT3: numValues--; // Intentional flow through case FLOAT_MAT4: { numValues = numValues * numValues; GLfloat *value = new GLfloat[numValues]; glGetUniformfv(programId, locationId, value); logAllGLErrors(__FUNCTION__); QList<float> floatList; for (int i = 0; i < numValues; i++) floatList << value[i]; // TODO: Should return Float32Array return QVariant::fromValue(floatList); } default: break; } } return QVariant(); } /*! * \qmlmethod list<variant> Context3D::getSupportedExtensions() * Returns an array of the extension strings supported by this implementation */ /*! * \internal */ QVariantList CanvasContext::getSupportedExtensions() { qCDebug(canvas3drendering).nospace() << Q_FUNC_INFO; QVariantList list; list.append(QVariant::fromValue(QStringLiteral("QTCANVAS3D_gl_state_dump"))); if (!m_isOpenGLES2 || (m_context->format().majorVersion() >= 3 || m_extensions.contains("OES_standard_derivatives"))) { list.append(QVariant::fromValue(QStringLiteral("OES_standard_derivatives"))); } return list; } /*! * \internal */ bool CanvasContext::isOfType(const QJSValue &value, const QString &classname) const { if (!value.isQObject()) { return false; } QObject *obj = value.toQObject(); if (!obj) return false; if (!obj->inherits(classname.toLocal8Bit().constData())) { return false; }
5951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987
return true; } /*! * \qmlmethod variant Context3D::getExtension(string name) * \return object if given \a name matches a supported extension. * Otherwise returns \c{null}. The returned object may contain constants and/or functions provided * by the extension, but at minimum a unique object is returned. * Case-insensitive \a name of the extension to be returned. */ /*! * \internal */ QVariant CanvasContext::getExtension(const QString &name) { qCDebug(canvas3drendering).nospace() << "Context3D::" << __FUNCTION__ << "(name:" << name << ")"; QString upperCaseName = name.toUpper(); if (upperCaseName == QStringLiteral("QTCANVAS3D_GL_STATE_DUMP")) { if (!m_stateDumpExt) m_stateDumpExt = new CanvasGLStateDump(m_context, this); return QVariant::fromValue(m_stateDumpExt); } else if (upperCaseName == QStringLiteral("OES_STANDARD_DERIVATIVES")) { if (!m_standardDerivatives) m_standardDerivatives = new QObject(this); return QVariant::fromValue(m_standardDerivatives); } return QVariant(QVariant::Int); } QT_CANVAS3D_END_NAMESPACE QT_END_NAMESPACE