// qopenglshaderprogram.sip generated by MetaSIP
//
// This file is part of the QtOpenGL Python extension module.
//
// Copyright (c) 2025 Riverbank Computing Limited <info@riverbankcomputing.com>
// 
// This file is part of PyQt6.
// 
// This file may be used under the terms of the GNU General Public License
// version 3.0 as published by the Free Software Foundation and appearing in
// the file LICENSE included in the packaging of this file.  Please review the
// following information to ensure the GNU General Public License version 3.0
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
// 
// If you do not wish to use this file under the terms of the GPL version 3.0
// then you may purchase a commercial license.  For more information contact
// info@riverbankcomputing.com.
// 
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.


class QOpenGLShader : public QObject
{
%TypeHeaderCode
#include <qopenglshaderprogram.h>
%End

public:
    enum ShaderTypeBit /BaseType=Flag/
    {
        Vertex,
        Fragment,
        Geometry,
        TessellationControl,
        TessellationEvaluation,
        Compute,
    };

    typedef QFlags<QOpenGLShader::ShaderTypeBit> ShaderType;
    QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent /TransferThis/ = 0);
    virtual ~QOpenGLShader();
    QOpenGLShader::ShaderType shaderType() const;
    bool compileSourceCode(const QByteArray &source);
    bool compileSourceCode(const QString &source);
    bool compileSourceFile(const QString &fileName);
    QByteArray sourceCode() const;
    bool isCompiled() const;
    QString log() const;
    GLuint shaderId() const;
    static bool hasOpenGLShaders(QOpenGLShader::ShaderType type, QOpenGLContext *context = 0);
};

class QOpenGLShaderProgram : public QObject
{
%TypeHeaderCode
#include <qopenglshaderprogram.h>
%End

public:
    explicit QOpenGLShaderProgram(QObject *parent /TransferThis/ = 0);
    virtual ~QOpenGLShaderProgram();
    bool addShader(QOpenGLShader *shader);
    void removeShader(QOpenGLShader *shader);
    QList<QOpenGLShader *> shaders() const;
    bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray &source);
    bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString &source);
    bool addShaderFromSourceFile(QOpenGLShader::ShaderType type, const QString &fileName);
    void removeAllShaders();
    virtual bool link();
    bool isLinked() const;
    QString log() const;
    bool bind();
    void release();
    GLuint programId() const;
    void bindAttributeLocation(const QByteArray &name, int location);
    void bindAttributeLocation(const QString &name, int location);
    int attributeLocation(const QByteArray &name) const;
    int attributeLocation(const QString &name) const;
    void setAttributeValue(int location, GLfloat value);
    void setAttributeValue(int location, GLfloat x, GLfloat y);
    void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z);
    void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setAttributeValue(int location, const QVector2D &value);
    void setAttributeValue(int location, const QVector3D &value);
    void setAttributeValue(int location, const QVector4D &value);
    void setAttributeValue(int location, const QColor &value);
    void setAttributeValue(const char *name, GLfloat value);
    void setAttributeValue(const char *name, GLfloat x, GLfloat y);
    void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z);
    void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setAttributeValue(const char *name, const QVector2D &value);
    void setAttributeValue(const char *name, const QVector3D &value);
    void setAttributeValue(const char *name, const QVector4D &value);
    void setAttributeValue(const char *name, const QColor &value);
    void setAttributeArray(int location, SIP_PYOBJECT values /TypeHint="PYQT_SHADER_ATTRIBUTE_ARRAY"/);
%MethodCode
        const GLfloat *values;
        int tsize;
        
        values = qpyopengl_attribute_array(a1, sipSelf, PyLong_FromLong(a0), &tsize,
                &sipError);
        
        if (values)
            sipCpp->setAttributeArray(a0, values, tsize);
%End

    void setAttributeArray(const char *name, SIP_PYOBJECT values /TypeHint="PYQT_SHADER_ATTRIBUTE_ARRAY"/);
%MethodCode
        const GLfloat *values;
        int tsize;
        
        values = qpyopengl_attribute_array(a1, sipSelf, PyBytes_FromString(a0),
                &tsize, &sipError);
        
        if (values)
            sipCpp->setAttributeArray(a0, values, tsize);
%End

    void setAttributeBuffer(int location, GLenum type, int offset, int tupleSize, int stride = 0);
    void setAttributeBuffer(const char *name, GLenum type, int offset, int tupleSize, int stride = 0);
    void enableAttributeArray(int location);
    void enableAttributeArray(const char *name);
    void disableAttributeArray(int location);
    void disableAttributeArray(const char *name);
    int uniformLocation(const QByteArray &name) const;
    int uniformLocation(const QString &name) const;
    void setUniformValue(int location, GLint value /Constrained/);
    void setUniformValue(int location, GLfloat value /Constrained/);
    void setUniformValue(int location, GLfloat x, GLfloat y);
    void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z);
    void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setUniformValue(int location, const QVector2D &value);
    void setUniformValue(int location, const QVector3D &value);
    void setUniformValue(int location, const QVector4D &value);
    void setUniformValue(int location, const QColor &color);
    void setUniformValue(int location, const QPoint &point);
    void setUniformValue(int location, const QPointF &point);
    void setUniformValue(int location, const QSize &size);
    void setUniformValue(int location, const QSizeF &size);
    void setUniformValue(int location, const QMatrix2x2 &value);
    void setUniformValue(int location, const QMatrix2x3 &value);
    void setUniformValue(int location, const QMatrix2x4 &value);
    void setUniformValue(int location, const QMatrix3x2 &value);
    void setUniformValue(int location, const QMatrix3x3 &value);
    void setUniformValue(int location, const QMatrix3x4 &value);
    void setUniformValue(int location, const QMatrix4x2 &value);
    void setUniformValue(int location, const QMatrix4x3 &value);
    void setUniformValue(int location, const QMatrix4x4 &value);
    void setUniformValue(int location, const QTransform &value);
    void setUniformValue(const char *name, GLint value /Constrained/);
    void setUniformValue(const char *name, GLfloat value /Constrained/);
    void setUniformValue(const char *name, GLfloat x, GLfloat y);
    void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z);
    void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setUniformValue(const char *name, const QVector2D &value);
    void setUniformValue(const char *name, const QVector3D &value);
    void setUniformValue(const char *name, const QVector4D &value);
    void setUniformValue(const char *name, const QColor &color);
    void setUniformValue(const char *name, const QPoint &point);
    void setUniformValue(const char *name, const QPointF &point);
    void setUniformValue(const char *name, const QSize &size);
    void setUniformValue(const char *name, const QSizeF &size);
    void setUniformValue(const char *name, const QMatrix2x2 &value);
    void setUniformValue(const char *name, const QMatrix2x3 &value);
    void setUniformValue(const char *name, const QMatrix2x4 &value);
    void setUniformValue(const char *name, const QMatrix3x2 &value);
    void setUniformValue(const char *name, const QMatrix3x3 &value);
    void setUniformValue(const char *name, const QMatrix3x4 &value);
    void setUniformValue(const char *name, const QMatrix4x2 &value);
    void setUniformValue(const char *name, const QMatrix4x3 &value);
    void setUniformValue(const char *name, const QMatrix4x4 &value);
    void setUniformValue(const char *name, const QTransform &value);
    void setUniformValueArray(int location, SIP_PYOBJECT values /TypeHint="PYQT_SHADER_UNIFORM_VALUE_ARRAY"/);
%MethodCode
        const void *values;
        const sipTypeDef *array_type;
        int array_len, tsize;
        
        values = qpyopengl_uniform_value_array(a1, sipSelf, PyLong_FromLong(a0),
                    &array_type, &array_len, &tsize, &sipError);
        
        if (values)
        {
            if (array_type == sipType_QVector2D)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QVector2D *>(values), array_len);
            else if (array_type == sipType_QVector3D)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QVector3D *>(values), array_len);
            else if (array_type == sipType_QVector4D)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QVector4D *>(values), array_len);
            else if (array_type == sipType_QMatrix2x2)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix2x2 *>(values), array_len);
            else if (array_type == sipType_QMatrix2x3)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix2x3 *>(values), array_len);
            else if (array_type == sipType_QMatrix2x4)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix2x4 *>(values), array_len);
            else if (array_type == sipType_QMatrix3x2)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix3x2 *>(values), array_len);
            else if (array_type == sipType_QMatrix3x3)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix3x3 *>(values), array_len);
            else if (array_type == sipType_QMatrix3x4)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix3x4 *>(values), array_len);
            else if (array_type == sipType_QMatrix4x2)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix4x2 *>(values), array_len);
            else if (array_type == sipType_QMatrix4x3)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix4x3 *>(values), array_len);
            else if (array_type == sipType_QMatrix4x4)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix4x4 *>(values), array_len);
            else
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const GLfloat *>(values), array_len, tsize);
        }
%End

    void setUniformValueArray(const char *name, SIP_PYOBJECT values /TypeHint="PYQT_SHADER_UNIFORM_VALUE_ARRAY"/);
%MethodCode
        const void *values;
        const sipTypeDef *array_type;
        int array_len, tsize;
        
        values = qpyopengl_uniform_value_array(a1, sipSelf, PyBytes_FromString(a0),
                    &array_type, &array_len, &tsize, &sipError);
        
        if (values)
        {
            if (array_type == sipType_QVector2D)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QVector2D *>(values), array_len);
            else if (array_type == sipType_QVector3D)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QVector3D *>(values), array_len);
            else if (array_type == sipType_QVector4D)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QVector4D *>(values), array_len);
            else if (array_type == sipType_QMatrix2x2)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix2x2 *>(values), array_len);
            else if (array_type == sipType_QMatrix2x3)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix2x3 *>(values), array_len);
            else if (array_type == sipType_QMatrix2x4)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix2x4 *>(values), array_len);
            else if (array_type == sipType_QMatrix3x2)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix3x2 *>(values), array_len);
            else if (array_type == sipType_QMatrix3x3)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix3x3 *>(values), array_len);
            else if (array_type == sipType_QMatrix3x4)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix3x4 *>(values), array_len);
            else if (array_type == sipType_QMatrix4x2)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix4x2 *>(values), array_len);
            else if (array_type == sipType_QMatrix4x3)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix4x3 *>(values), array_len);
            else if (array_type == sipType_QMatrix4x4)
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const QMatrix4x4 *>(values), array_len);
            else
                sipCpp->setUniformValueArray(a0,
                        reinterpret_cast<const GLfloat *>(values), array_len, tsize);
        }
%End

    static bool hasOpenGLShaderPrograms(QOpenGLContext *context = 0);
    int maxGeometryOutputVertices() const;
    void setPatchVertexCount(int count);
    int patchVertexCount() const;
    void setDefaultOuterTessellationLevels(const QList<float> &levels);
    QList<float> defaultOuterTessellationLevels() const;
    void setDefaultInnerTessellationLevels(const QList<float> &levels);
    QList<float> defaultInnerTessellationLevels() const;
    bool create();
    bool addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray &source);
    bool addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString &source);
    bool addCacheableShaderFromSourceFile(QOpenGLShader::ShaderType type, const QString &fileName);
};

%ModuleHeaderCode
#include "qpyopengl_api.h"
%End

%InitialisationCode
qpyopengl_init();
%End

%TypeHintCode
# Convenient aliases for complicated OpenGL types.
PYQT_OPENGL_ARRAY = typing.Union[typing.Sequence[int], typing.Sequence[float],
        PyQt6.sip.Buffer, None]
PYQT_OPENGL_BOUND_ARRAY = typing.Union[typing.Sequence[int],
        typing.Sequence[float], PyQt6.sip.Buffer, int, None]
PYQT_SHADER_ATTRIBUTE_ARRAY = typing.Union[typing.Sequence[QtGui.QVector2D],
        typing.Sequence[QtGui.QVector3D], typing.Sequence[QtGui.QVector4D],
        typing.Sequence[typing.Sequence[float]]]
PYQT_SHADER_UNIFORM_VALUE_ARRAY = typing.Union[
        typing.Sequence[QtGui.QVector2D], typing.Sequence[QtGui.QVector3D],
        typing.Sequence[QtGui.QVector4D], typing.Sequence[QtGui.QMatrix2x2],
        typing.Sequence[QtGui.QMatrix2x3], typing.Sequence[QtGui.QMatrix2x4],
        typing.Sequence[QtGui.QMatrix3x2], typing.Sequence[QtGui.QMatrix3x3],
        typing.Sequence[QtGui.QMatrix3x4], typing.Sequence[QtGui.QMatrix4x2],
        typing.Sequence[QtGui.QMatrix4x3], typing.Sequence[QtGui.QMatrix4x4],
        typing.Sequence[typing.Sequence[float]]]
%End
