diff --git a/examples/canvas3d/texturedcube/qml/texturedcube/main.qml b/examples/canvas3d/texturedcube/qml/texturedcube/main.qml index 7645f2158c9b4c8c510b8b4943dc0a1888827b3a..f159c88ad27b62fb837d886d7349588e58f84ecf 100644 --- a/examples/canvas3d/texturedcube/qml/texturedcube/main.qml +++ b/examples/canvas3d/texturedcube/qml/texturedcube/main.qml @@ -59,7 +59,6 @@ Item { property double xRotAnim: 0 property double yRotAnim: 0 property double zRotAnim: 0 - property bool isRunning: true //! [1] // Emitted when one time initializations should happen diff --git a/src/buffer3d.cpp b/src/buffer3d.cpp index 576f4a7eca67f0db1f9eb2b7a3ef432d295e6b75..1f5992fc4287c3b5f66420e779ad09ce59f2df71 100644 --- a/src/buffer3d.cpp +++ b/src/buffer3d.cpp @@ -55,12 +55,26 @@ */ CanvasBuffer::CanvasBuffer(QObject *parent) : CanvasAbstractObject(parent), + QOpenGLFunctions(), m_bindTarget(CanvasBuffer::UNINITIALIZED) { initializeOpenGLFunctions(); glGenBuffers(1, &m_bufferId); } +/*! + * \internal + */ +CanvasBuffer::CanvasBuffer(const CanvasBuffer& other) : + CanvasAbstractObject(), // Copying a QObject, leave it parentless.. + QOpenGLFunctions(), + m_bufferId(other.m_bufferId), + m_bindTarget(other.m_bindTarget) +{ + initializeOpenGLFunctions(); +} + + /*! * \internal */ diff --git a/src/buffer3d_p.h b/src/buffer3d_p.h index 7f808cf394b7c7a46581f4ed9a17ca1d1317ac00..5f8665243ce66601425ceb4e0319a684993330d1 100644 --- a/src/buffer3d_p.h +++ b/src/buffer3d_p.h @@ -64,6 +64,7 @@ public: }; explicit CanvasBuffer(QObject *parent = 0); + CanvasBuffer(const CanvasBuffer& other); virtual ~CanvasBuffer(); void del(); diff --git a/src/context3d.cpp b/src/context3d.cpp index b6582e3ec6ae8ba97db21f867e6173413c3b6633..6889c2802a38a394ec5e1deb90b78e469b55b32f 100644 --- a/src/context3d.cpp +++ b/src/context3d.cpp @@ -92,9 +92,15 @@ CanvasContext::CanvasContext(QOpenGLContext *context, int width, int height, QOb m_error(NO_ERROR), m_currentFramebuffer(0), m_map(EnumToStringMap::newInstance()), - m_canvas(0) + m_canvas(0), + m_maxVertexAttribs(0) { m_context = context; + + int value = 0; + glGetIntegerv(MAX_VERTEX_ATTRIBS, &value); + m_maxVertexAttribs = uint(value); + #ifndef QT_NO_DEBUG const GLubyte *version = glGetString(GL_VERSION); qDebug() << "Context3D::" << __FUNCTION__ @@ -3117,6 +3123,7 @@ int CanvasContext::getShaderParameter(CanvasShader *shader, glEnums pname) CanvasBuffer *CanvasContext::createBuffer() { CanvasBuffer *newBuffer = new CanvasBuffer(this); + m_idToCanvasBufferMap[newBuffer->id()] = newBuffer; if (m_logAllCalls) qDebug() << "Context3D::" << __FUNCTION__ << ":" << newBuffer; // Returning a pointer to QObject that has parent set @@ -3440,7 +3447,6 @@ void CanvasContext::vertexAttribPointer(int indx, int size, glEnums type, << ", offset:" << offset << ")"; - // TODO: Fix offset glVertexAttribPointer(indx, size, GLenum(type), normalized, stride, (GLvoid *)offset); } @@ -3742,6 +3748,7 @@ void CanvasContext::deleteBuffer(CanvasBuffer *buffer) return; } + m_idToCanvasBufferMap.remove(buffer->id()); buffer->del(); } @@ -4687,8 +4694,159 @@ QVariant CanvasContext::getTexParameter(glEnums target, glEnums pname) 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) +{ + if (m_logAllCalls) qDebug() << "Context3D::" << __FUNCTION__ + << "(index" << index + << ", pname:" << glEnumToString(pname) + << ")"; + + uint offset = 0; + if (pname != VERTEX_ATTRIB_ARRAY_POINTER) { + if (m_logAllErrors) qDebug() << "Context3D::" << __FUNCTION__ + << ":INVALID_ENUM pname must be " + << "VERTEX_ATTRIB_ARRAY_POINTER"; + m_error = INVALID_ENUM; + return 0; + } + + if (index >= m_maxVertexAttribs) { + if (m_logAllErrors) qDebug() << "Context3D::" << __FUNCTION__ + << ":INVALID_VALUE index must be smaller than " + << m_maxVertexAttribs; + m_error = INVALID_VALUE; + return 0; + } + + glGetVertexAttribPointerv(index, GLenum(pname), (GLvoid**) &offset); + return offset; +} + +/*! + * \qmlmethod variant Context3D::getVertexAttrib(int index, glEnums pname) + * 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 + */ +QVariant CanvasContext::getVertexAttrib(uint index, glEnums pname) +{ + if (m_logAllCalls) qDebug() << "Context3D::" << __FUNCTION__ + << "(index" << index + << ", pname:" << glEnumToString(pname) + << ")"; + + if (index >= MAX_VERTEX_ATTRIBS) { + if (m_logAllErrors) qDebug() << "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); + if (value == 0 || !m_idToCanvasBufferMap.contains(value)) + return QVariant(); + + return QVariant::fromValue(m_idToCanvasBufferMap[value]); + } + break; + case VERTEX_ATTRIB_ARRAY_ENABLED: { + GLint value = 0; + glGetVertexAttribiv(index, GLenum(pname), &value); + return QVariant::fromValue( bool(value)); + } + break; + case VERTEX_ATTRIB_ARRAY_SIZE: { + GLint value = 0; + glGetVertexAttribiv(index, GLenum(pname), &value); + return QVariant::fromValue(value); + } + break; + case VERTEX_ATTRIB_ARRAY_STRIDE: { + GLint value = 0; + glGetVertexAttribiv(index, GLenum(pname), &value); + return QVariant::fromValue(value); + } + break; + case VERTEX_ATTRIB_ARRAY_TYPE: { + GLint value = 0; + glGetVertexAttribiv(index, GLenum(pname), &value); + return QVariant::fromValue(value); + } + case VERTEX_ATTRIB_ARRAY_NORMALIZED: { + GLint value = 0; + glGetVertexAttribiv(index, GLenum(pname), &value); + return QVariant::fromValue( bool(value)); + } + case CURRENT_VERTEX_ATTRIB: { + // TODO: Should be Float32Array + GLfloat values[4]; + glGetVertexAttribfv(index, GLenum(pname), values); + + QList<float> floatList; + floatList.push_back(values[0]); + floatList.push_back(values[1]); + floatList.push_back(values[2]); + floatList.push_back(values[3]); + return QVariant::fromValue(floatList); + } + default: + if (m_logAllErrors) qDebug() << "Context3D::" << __FUNCTION__ + << ":INVALID_ENUM index must be smaller than " + << "MAX_VERTEX_ATTRIBS = " << MAX_VERTEX_ATTRIBS; + m_error = INVALID_ENUM; + } + } + + return QVariant(); +} + /*! - * \qmlmethod list<variant> Context3D::getUniform(Program3D program, UniformLocation3D location) + * \qmlmethod variant Context3D::getUniform(Program3D program, UniformLocation3D location) * Returns the uniform value at the given \a location in the \a program. * The type returned is dependent on the uniform type, as shown in the table: * \table @@ -4751,7 +4909,7 @@ QVariant CanvasContext::getTexParameter(glEnums target, glEnums pname) /*! * \internal */ -QVariantList CanvasContext::getUniform(CanvasProgram *program, CanvasUniformLocation *location) +QVariant CanvasContext::getUniform(CanvasProgram *program, CanvasUniformLocation *location) { if (m_logAllCalls) qDebug() << "Context3D::" << __FUNCTION__ << "(program" << program @@ -4779,9 +4937,11 @@ QVariantList CanvasContext::getUniform(CanvasProgram *program, CanvasUniformLoca // Intentional flow through case SAMPLER_CUBE: // Intentional flow through - case INT: - numValues--; - // Intentional flow through + case INT: { + GLint value = 0; + glGetUniformiv(programId, locationId, &value); + return QVariant::fromValue(value); + } case INT_VEC2: numValues--; // Intentional flow through @@ -4789,17 +4949,22 @@ QVariantList CanvasContext::getUniform(CanvasProgram *program, CanvasUniformLoca numValues--; // Intentional flow through case INT_VEC4: { - // TODO: Should return Int32Array + numValues--; GLint *value = new GLint[numValues]; glGetUniformiv(programId, locationId, value); - QVariantList list; + + QList<float> intList; for (int i = 0; i < numValues; i++) - list << QVariant(value[i]); - return list; + intList << value[i]; + + // TODO: Should return Int32Array + return QVariant::fromValue(intList); + } + case FLOAT: { + GLfloat value = 0; + glGetUniformfv(programId, locationId, &value); + return QVariant::fromValue(value); } - case FLOAT: - numValues--; - // Intentional flow through case FLOAT_VEC2: numValues--; // Intentional flow through @@ -4807,18 +4972,23 @@ QVariantList CanvasContext::getUniform(CanvasProgram *program, CanvasUniformLoca numValues--; // Intentional flow through case FLOAT_VEC4: { - // TODO: Should return Float32Array + numValues--; GLfloat *value = new GLfloat[numValues]; + glGetUniformfv(programId, locationId, value); - QVariantList list; - for (int i = 0; i < numValues; i++) { - list << QVariant(value[i]); - } - return list; + + 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); + return QVariant::fromValue(bool(value)); } - case BOOL: - numValues--; - // Intentional flow through case BOOL_VEC2: numValues--; // Intentional flow through @@ -4826,12 +4996,16 @@ QVariantList CanvasContext::getUniform(CanvasProgram *program, CanvasUniformLoca numValues--; // Intentional flow through case BOOL_VEC4: { + numValues--; GLint *value = new GLint[numValues]; + glGetUniformiv(programId, locationId, value); - QVariantList list; + + QList<bool> boolList; for (int i = 0; i < numValues; i++) - list << QVariant(bool(value[i])); - return list; + boolList << value[i]; + + return QVariant::fromValue(boolList); } case FLOAT_MAT2: numValues--; @@ -4841,19 +5015,21 @@ QVariantList CanvasContext::getUniform(CanvasProgram *program, CanvasUniformLoca // Intentional flow through case FLOAT_MAT4: { numValues = numValues * numValues; - // TODO: Should return Float32Array - qDebug() << "Context3D::" << __FUNCTION__ << " numValues = " << numValues; GLfloat *value = new GLfloat[numValues]; + glGetUniformfv(programId, locationId, value); - QVariantList list; + + QList<float> floatList; for (int i = 0; i < numValues; i++) - list << QVariant(value[i]); - return list; + floatList << value[i]; + + // TODO: Should return Float32Array + return QVariant::fromValue(floatList); } default: break; } } - return QVariantList(); + return QVariant(); } diff --git a/src/context3d_p.h b/src/context3d_p.h index 8e762e7280b4756622bd1f2e108d10768550c4b0..19a45c5baa6ce1dd448984a25c7357786924b824 100644 --- a/src/context3d_p.h +++ b/src/context3d_p.h @@ -1170,7 +1170,9 @@ public: Q_INVOKABLE int getFramebufferAttachmentParameter(glEnums target, glEnums attachment, glEnums pname); Q_INVOKABLE int getRenderbufferParameter(glEnums target, glEnums pname); Q_INVOKABLE QVariant getTexParameter(glEnums target, glEnums pname); - Q_INVOKABLE QVariantList getUniform(CanvasProgram *program, CanvasUniformLocation *location); + Q_INVOKABLE QVariant getUniform(CanvasProgram *program, CanvasUniformLocation *location); + Q_INVOKABLE uint getVertexAttribOffset(uint index, glEnums pname); + Q_INVOKABLE QVariant getVertexAttrib(uint index, glEnums pname); QString glEnumToString(glEnums value) const; float devicePixelRatio(); @@ -1181,12 +1183,6 @@ public: QRect glViewportRect() const; GLuint currentFramebuffer(); - /* - TODO: Add these missing functions - any getVertexAttrib(GLuint index, GLenum pname); - GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname); - */ - void setLogAllCalls(bool logCalls); bool logAllCalls() const; void setLogAllErrors(bool logErrors); @@ -1203,7 +1199,6 @@ signals: void drawingBufferHeightChanged(); private: - bool m_unpackFlipYEnabled; bool m_unpackPremultiplyAlphaEnabled; glEnums m_unpackColorspaceConversion; @@ -1212,6 +1207,7 @@ private: bool m_logAllErrors; QRect m_glViewportRect; + qreal m_devicePixelRatio; CanvasProgram *m_currentProgram; CanvasBuffer *m_currentArrayBuffer; @@ -1222,11 +1218,14 @@ private: CanvasFrameBuffer *m_currentFramebuffer; CanvasRenderBuffer *m_currentRenderbuffer; CanvasContextAttributes m_contextAttributes; + QMap<int, CanvasBuffer*> m_idToCanvasBufferMap; friend class Canvas; friend class QFBOCanvas3D; QString m_emptyString; EnumToStringMap *m_map; Canvas *m_canvas; + uint m_maxVertexAttribs; + float **m_vertexAttribPointers; }; #endif // CONTEXT3D_P_H diff --git a/src/qcanvas3d_plugin.h b/src/qcanvas3d_plugin.h index 7b7f43df3ed63264699ef2d74cad0cbe68c59186..72f9d81d2557edf4ab044721dff33391b984b5b8 100644 --- a/src/qcanvas3d_plugin.h +++ b/src/qcanvas3d_plugin.h @@ -67,6 +67,8 @@ #include <QQmlExtensionPlugin> +Q_DECLARE_METATYPE(CanvasBuffer) + QML_DECLARE_TYPE(Canvas) //QML_DECLARE_TYPE(QFBOCanvas3D) QML_DECLARE_TYPE(CanvasContext) diff --git a/src/teximage3dloader.cpp b/src/teximage3dloader.cpp index a7125f33808810627d9f67f7cf2322fc421c0129..049b14673d0f4ebaa3b2b211328a21ae6015eace 100644 --- a/src/teximage3dloader.cpp +++ b/src/teximage3dloader.cpp @@ -72,7 +72,9 @@ CanvasTextureImageLoader::CanvasTextureImageLoader(QObject *parent) : QObject(parent), m_logAllCalls(false), - m_logAllErrors(true) + m_logAllErrors(true), + m_image(0), + m_canvas(0) { }