diff --git a/src/context3d.cpp b/src/context3d.cpp index 1ed9d686dafc9586e346f604a2d4aabe124d2478..4b4acf3f6017d9913d32d34cba6678d313292e0d 100644 --- a/src/context3d.cpp +++ b/src/context3d.cpp @@ -1691,7 +1691,7 @@ void CanvasContext::deleteProgram(CanvasProgram *program) /*! * \qmlmethod void Context3D::attachShader(Program3D program, Shader3D shader) - * Deletes the given program as if by calling \c{glDeleteProgram()}. + * Attaches the given \a shader object to the given \a program object. * Calling this method repeatedly on the same object has no side effects. * \a program is the Program3D to be deleted. */ @@ -1704,9 +1704,37 @@ void CanvasContext::attachShader(CanvasProgram *program, CanvasShader *shader) if (!program || !shader || !program->isAlive()) return; - program->qOGLProgram()->addShader(shader->qOGLShader()); + program->attach(shader); +} + +/*! + * \qmlmethod list<Shader3D> Context3D::getAttachedShaders(Program3D program) + * Returns the list of shaders currently attached to the given \a program. + */ +/*! + * \internal + */ +QVariantList CanvasContext::getAttachedShaders(CanvasProgram *program) +{ + if (m_logAllCalls) qDebug() << "Context3D::" << __FUNCTION__ + << "(program:" << program << ")"; + + QVariantList shaderList; + 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. @@ -1722,7 +1750,7 @@ void CanvasContext::detachShader(CanvasProgram *program, CanvasShader *shader) if (!program || !shader || !program->isAlive()) return; - program->qOGLProgram()->removeShader(shader->qOGLShader()); + program->detach(shader); } /*! @@ -1739,7 +1767,7 @@ void CanvasContext::linkProgram(CanvasProgram *program) if (!program || !program->isAlive()) return; - program->qOGLProgram()->link(); + program->link(); } /*! @@ -2025,7 +2053,7 @@ QVariant CanvasContext::getProgramParameter(CanvasProgram *program, glEnums para // Intentional flow through case VALIDATE_STATUS: { GLint value = 0; - glGetProgramiv(program->qOGLProgram()->programId(), GLenum(paramName), &value); + glGetProgramiv(program->id(), GLenum(paramName), &value); if (m_logAllCalls) qDebug() << " getProgramParameter returns " << value; return QVariant::fromValue(value == GL_TRUE); } @@ -2035,7 +2063,7 @@ QVariant CanvasContext::getProgramParameter(CanvasProgram *program, glEnums para // Intentional flow through case ACTIVE_UNIFORMS: { GLint value = 0; - glGetProgramiv(program->qOGLProgram()->programId(), GLenum(paramName), &value); + glGetProgramiv(program->id(), GLenum(paramName), &value); if (m_logAllCalls) qDebug() << " getProgramParameter returns " << value; return QVariant::fromValue(value); } @@ -2762,7 +2790,7 @@ CanvasUniformLocation *CanvasContext::getUniformLocation(CanvasProgram *program, return 0; } - int index = program->qOGLProgram()->uniformLocation(name); + int index = program->uniformLocation(name); if (index < 0) { //if (m_logAllErrors) qDebug() << "Context3D::" << __FUNCTION__ << ": INVALID name " << name; return 0; @@ -2791,10 +2819,10 @@ int CanvasContext::getAttribLocation(CanvasProgram *program, const QString &name if (m_logAllErrors) qDebug() << "Context3D::" << __FUNCTION__ << ": INVALID Program3D reference " << program; return -1; } else { - if (m_logAllCalls) qDebug() << "Context3D::" << __FUNCTION__ << "(" <<program<< ", " <<name << "):" << program->qOGLProgram()->attributeLocation(name); + if (m_logAllCalls) qDebug() << "Context3D::" << __FUNCTION__ << "(" <<program<< ", " <<name << "):" << program->attributeLocation(name); } - return program->qOGLProgram()->attributeLocation(name); + return program->attributeLocation(name); } /*! @@ -2812,7 +2840,7 @@ void CanvasContext::bindAttribLocation(CanvasProgram *program, int index, const return; } - program->qOGLProgram()->bindAttributeLocation(name, index); + program->bindAttributeLocation(index, name); } /*! @@ -3420,7 +3448,7 @@ QString CanvasContext::getProgramInfoLog(CanvasProgram *program) const return QString(); // Returning a copy, V4VM takes ownership - return program->qOGLProgram()->log(); + return program->log(); } /*! @@ -3502,9 +3530,9 @@ void CanvasContext::useProgram(CanvasProgram *program) << "(program:" << program << ")"; // TODO: Check if this is ok m_currentProgram = program; - if (!program || !program->qOGLProgram()->isLinked()) + if (!program || !program->isLinked()) return; - program->qOGLProgram()->bind(); + program->bind(); } /*! diff --git a/src/context3d_p.h b/src/context3d_p.h index 7c56758ba1a8d25820edf1e913360428d1841461..d69cc818173a2d4a1de840911b0746dbc32a6cf5 100644 --- a/src/context3d_p.h +++ b/src/context3d_p.h @@ -1153,7 +1153,7 @@ public: Q_INVOKABLE CanvasActiveInfo *getActiveAttrib(CanvasProgram *program, uint index); Q_INVOKABLE CanvasActiveInfo *getActiveUniform(CanvasProgram *program, uint index); - + Q_INVOKABLE QVariantList getAttachedShaders(CanvasProgram *program); QString glEnumToString(glEnums value) const; float devicePixelRatio(); @@ -1164,9 +1164,9 @@ public: QRect glViewportRect() const; GLuint currentFramebuffer(); + /* TODO: Add these missing functions - sequence<WebGLShader>? getAttachedShaders(WebGLProgram program); any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname); any getRenderbufferParameter(GLenum target, GLenum pname); any getTexParameter(GLenum target, GLenum pname); diff --git a/src/program3d.cpp b/src/program3d.cpp index eb5e3694aae62935802d7ae9aefc5c381afbc2ea..275a7c1e89a5acf13199b512b01c966c60ba21f4 100644 --- a/src/program3d.cpp +++ b/src/program3d.cpp @@ -75,6 +75,17 @@ int CanvasProgram::uniformLocation(const QString &name) return m_program->uniformLocation(name); } +/*! + * \internal + */ +int CanvasProgram::attributeLocation(const QString &name) +{ + if (!m_program) + return -1; + + return m_program->attributeLocation(name); +} + /*! * \internal */ @@ -86,9 +97,71 @@ bool CanvasProgram::isAlive() /*! * \internal */ -QOpenGLShaderProgram *CanvasProgram::qOGLProgram() +void CanvasProgram::attach(CanvasShader *shader) +{ + if (m_attachedShaders.count(shader) == 0) { + m_attachedShaders.append(shader); + m_program->addShader(shader->qOGLShader()); + } +} + +/*! + * \internal + */ +void CanvasProgram::detach(CanvasShader *shader) +{ + if (m_attachedShaders.count(shader) > 0) { + m_attachedShaders.removeOne(shader); + m_program->removeShader(shader->qOGLShader()); + } +} + +/*! + * \internal + */ +const QList<CanvasShader *> &CanvasProgram::attachedShaders() const +{ + return m_attachedShaders; +} + +/*! + * \internal + */ +void CanvasProgram::link() +{ + if (m_program) + m_program->link(); +} + +/*! + * \internal + */ +bool CanvasProgram::isLinked() +{ + if (!m_program) + return false; + + return m_program->isLinked(); +} + +/*! + * \internal + */ +void CanvasProgram::bind() +{ + if (m_program) + m_program->bind(); +} + +/*! + * \internal + */ +void CanvasProgram::bindAttributeLocation(int index, const QString &name) { - return m_program; + if (!m_program) + return; + + m_program->bindAttributeLocation(name, index); } /*! @@ -98,6 +171,7 @@ void CanvasProgram::del() { delete m_program; m_program = 0; + m_attachedShaders.clear(); } /*! @@ -125,6 +199,17 @@ int CanvasProgram::id() return m_program->programId(); } +/*! + * \internal + */ +QString CanvasProgram::log() +{ + if (!m_program) + return ""; + + return m_program->log(); +} + /*! * \internal */ diff --git a/src/program3d_p.h b/src/program3d_p.h index e730df46a4e6bbebca0980a43f339004955124c5..23127ce6059b81de64d870913893ee8b2171b3be 100644 --- a/src/program3d_p.h +++ b/src/program3d_p.h @@ -49,10 +49,12 @@ #include "context3d_p.h" #include "abstractobject3d_p.h" +#include "shader3d_p.h" #include <QtGui/QOpenGLFunctions> #include <QtGui/QOpenGLShaderProgram> #include <QDebug> +#include <QList> class CanvasProgram : public CanvasAbstractObject, protected QOpenGLFunctions { @@ -64,16 +66,27 @@ public: virtual ~CanvasProgram(); int uniformLocation(const QString &name); + int attributeLocation(const QString &name); void del(); bool isAlive(); void validateProgram(); - QOpenGLShaderProgram *qOGLProgram(); int id(); + void link(); + bool isLinked(); + void bind(); + void bindAttributeLocation(int index, const QString &name); + + void attach(CanvasShader *shader); + void detach(CanvasShader *shader); + const QList<CanvasShader *> &attachedShaders() const; + + QString log(); friend QDebug operator<< (QDebug d, const CanvasProgram *program); private: QOpenGLShaderProgram *m_program; + QList<CanvasShader *> m_attachedShaders; signals: void idChanged(int id);