Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. OpengGL Shader Program fails
Forum Updated to NodeBB v4.3 + New Features

OpengGL Shader Program fails

Scheduled Pinned Locked Moved Game Development
28 Posts 7 Posters 15.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sasmaster
    wrote on last edited by
    #1

    I am trying to write a modern OpenGL (programmable pipeline) program.Qt OpenGL examples show only the fixed pipeline implementation.The documentation on how to initialize Shader Program is very poor.This is the best example on how to setup a shader program and load shaders they have:http://doc.trolltech.com/4.6/qglshaderprogram.html#details This is not very descriptive as one can see. I tried to follow this doc and cann't get the Shader program working .Getting segmentation error when the program tries to assign attributes to the shaders.I think the problem is that I access the context in the wrong way.But I can't find any reference on how to setup or retrieve the rendering context.My code goes like this:

    @
    static GLfloat const triangleVertices[] = {
    60.0f, 10.0f, 0.0f,
    110.0f, 110.0f, 0.0f,
    10.0f, 110.0f, 0.0f
    };

    QColor color(0, 255, 0, 255);
    int vertexLocation =0;
    int matrixLocation =0;
    int colorLocation =0;
    QGLShaderProgram *pprogram=0;
    void OpenGLWrapper::initShaderProgram(){
    QGLContext context(QGLFormat::defaultFormat());

    QGLShaderProgram program(context.currentContext());
    pprogram=&program;
    program.addShaderFromSourceCode(QGLShader::Vertex,
     "attribute highp vec4 vertex;\n"
     "attribute mediump mat4 matrix;\n"
     "void main(void)\n"
     "{\n"
     "   gl_Position = matrix * vertex;\n"
     "}");
     program.addShaderFromSourceCode(QGLShader::Fragment,
     "uniform mediump vec4 color;\n"
     "void main(void)\n"
     "{\n"
     "   gl_FragColor = color;\n"
     "}");
     program.link();
     program.bind();
    

    vertexLocation= pprogram->attributeLocation("vertex");
    matrixLocation= pprogram->attributeLocation("matrix");
    colorLocation= pprogram->uniformLocation("color");
    }

    @

    And here is the rendering loop: void OpenGLWrapper::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    @

     QMatrix4x4 pmvMatrix;
     pmvMatrix.ortho(rect());
    
    pprogram->enableAttributeArray(vertexLocation);
    pprogram->setAttributeArray(vertexLocation, triangleVertices, 3);
    pprogram->setUniformValue(matrixLocation, pmvMatrix);
    pprogram->setUniformValue(colorLocation, color);
    
    glDrawArrays(GL_TRIANGLES, 0, 3);
    
    pprogram->disableAttributeArray(vertexLocation);
    

    }
    @
    Now I can see that the program variable gets no value.So probably the pointer is being assigned to the null object.So how do I initialize the shader program in a right way?
    Anybody has can help with this setup? Thanks a lot .

    1 Reply Last reply
    0
    • L Offline
      L Offline
      ludde
      wrote on last edited by
      #2

      The code above will not work. Not because of anything to do with OpenGL or Qt, but because of C++. You are creating an object on the stack, program, which will be destroyed when you exit the function. So pprogram will point to a shader program that has already been destroyed.

      If you need to have access to the program from more than one place, you should probably create it using new, and keep a pointer to it in a member variable.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        sasmaster
        wrote on last edited by
        #3

        Yes you are right .I found this mistake.I removed the pointer and tried to work with the shader program variable directly.Now the program runs with no errors.But the viewport is empty.It could be really helpful if Qt team could put an example of OpenGL 3x setup.
        Thanks.

        1 Reply Last reply
        0
        • Z Offline
          Z Offline
          ZapB
          wrote on last edited by
          #4

          Have read of this "thread":http://developer.qt.nokia.com/forums/viewthread/4856/

          Nokia Certified Qt Specialist
          Interested in hearing about Qt related work

          1 Reply Last reply
          0
          • S Offline
            S Offline
            sasmaster
            wrote on last edited by
            #5

            Thanks for this thread.So it seems that in Qt 4.7 there is a bug? Anybody has an idea when it is going to be fixed?

            1 Reply Last reply
            0
            • Z Offline
              Z Offline
              ZapB
              wrote on last edited by
              #6

              I've not checked but it may already be fixed in 4.7.4. If not then you may need to build a 4.8.0 pre-release and try that. What version are you using?

              Nokia Certified Qt Specialist
              Interested in hearing about Qt related work

              1 Reply Last reply
              0
              • S Offline
                S Offline
                sasmaster
                wrote on last edited by
                #7

                I am using 4.7.4. ...And I am getting an empty screen in GL

                1 Reply Last reply
                0
                • Z Offline
                  Z Offline
                  ZapB
                  wrote on last edited by
                  #8

                  As long as you specify to use the CompatibilityProfile it should work anyway. Maybe the bug is elsewhere is your code? Can you provide a small compilable example please?

                  Nokia Certified Qt Specialist
                  Interested in hearing about Qt related work

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    sasmaster
                    wrote on last edited by
                    #9

                    Here it is .Pretty same as of the guy in the above mentioned thread:
                    Window class ,calls the OpenGLWrapper widget:
                    @
                    Window::Window()
                    {
                    QGLFormat fmt;
                    fmt.setVersion(3,3);
                    fmt.setProfile(QGLFormat::CompatibilityProfile);
                    fmt.setSampleBuffers(true);
                    glWidget=new OpenGLWrapper(fmt);

                    .....

                    @
                    OpenGLWrapper:
                    @

                    #include<QtGui>

                    #include<math.h>
                    #include<QGLShaderProgram>
                    #include "openglwrapper.h"
                    #include "GL/glext.h"
                    #include "qtlogo.h"

                    #ifndef GL_MULTISAMPLE
                    #define GL_MULTISAMPLE 0x809D
                    #endif
                    bool OpenGLWrapper::USE_SHADERS = 1;
                    static GLfloat const triangleVertices[] = {
                    60.0f, 10.0f, 0.0f,
                    110.0f, 110.0f, 0.0f,
                    10.0f, 110.0f, 0.0f
                    };
                    OpenGLWrapper::OpenGLWrapper(const QGLFormat & format,QWidget *parent):QGLWidget(format,parent),mShaderProgram(this)
                    {

                    logo=0;
                    xRot=0;
                    yRot=0;
                    zRot=0;
                    qtGreen = QColor::fromCmykF(0.10, 0.78, 1.0, 0.0);
                    qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
                    

                    }

                    void OpenGLWrapper::initShaderProgram(){

                    mShaderProgram.addShaderFromSourceCode(QGLShader::Vertex,
                    "#version 330\n"
                    "in highp vec4 vertex;\n"
                    "in mediump mat4 matrix;\n"
                    "void main(void)\n"
                    "{\n"
                    " gl_Position = matrix * vertex;\n"
                    "}");
                    mShaderProgram.addShaderFromSourceCode(QGLShader::Fragment,
                    "#version 330\n"
                    "uniform mediump vec4 color;\n"
                    "out mediump vec4 out_color;\n"
                    "void main(void)\n"
                    "{\n"
                    " out_color = color;\n"
                    "}");
                    bool linked= mShaderProgram.link();
                    bool binded= mShaderProgram.bind();
                    if(linked&&binded){
                    qDebug()<<binded<<"and"<<linked;
                    }

                    }

                    QSize OpenGLWrapper::minimumSizeHint()const{
                    return QSize(50,50);
                    }
                    QSize OpenGLWrapper::sizeHint()const{
                    return QSize(400,400);
                    }
                    static void qNormalizeAngle(int &angle){
                    while (angle < 0)
                    angle += 360 * 16;
                    while (angle > 360 * 16)
                    angle -= 360 * 16;
                    }

                    void OpenGLWrapper::setXRotation(int angle){
                    qNormalizeAngle(angle);
                    if(angle!=xRot){
                    xRot=angle;
                    emit xRotationChanged(angle);
                    updateGL();
                    }
                    }
                    void OpenGLWrapper::setYRotation(int angle)
                    {
                    qNormalizeAngle(angle);
                    if (angle != yRot) {
                    yRot = angle;
                    emit yRotationChanged(angle);
                    updateGL();
                    }
                    }

                    void OpenGLWrapper::setZRotation(int angle)
                    {
                    qNormalizeAngle(angle);
                    if (angle != zRot) {
                    zRot = angle;
                    emit zRotationChanged(angle);
                    updateGL();
                    }

                    }
                    void OpenGLWrapper::initializeGL()
                    {
                    qglClearColor(qtPurple.dark());

                    logo = new QtLogo(this, 64);
                    logo->setColor(qtGreen.lighter());
                    
                    glEnable(GL_DEPTH_TEST);
                    glEnable(GL_CULL_FACE);
                    glShadeModel(GL_SMOOTH);
                    glEnable(GL_LIGHTING);
                    glEnable(GL_LIGHT0);
                    glEnable(GL_MULTISAMPLE);
                    static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
                    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
                    initShaderProgram();
                    
                    
                       printGLString();
                    

                    }

                    void OpenGLWrapper::paintGL()
                    {
                    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    QMatrix4x4 pmvMatrix;
                    pmvMatrix.ortho(rect());
                    int vertexLocation = mShaderProgram.attributeLocation("vertex");
                    int matrixLocation = mShaderProgram.attributeLocation("matrix");
                    int colorLocation = mShaderProgram.uniformLocation("color");

                    mShaderProgram.enableAttributeArray(vertexLocation);
                    mShaderProgram.setAttributeArray(vertexLocation, triangleVertices,3);
                    mShaderProgram.setUniformValue(matrixLocation, pmvMatrix);
                    mShaderProgram.setUniformValue(colorLocation,QColor(0, 255, 0, 255));

                    glDrawArrays(GL_TRIANGLES, 0, 3);
                    

                    mShaderProgram.disableAttributeArray(vertexLocation);

                    }
                    void OpenGLWrapper::printGLString()
                    {
                    const char* version = reinterpret_cast<const char *>(glGetString(GL_VERSION));
                    qDebug() << "GL_VERSION:" << version;

                    }

                    void OpenGLWrapper::resizeGL(int width, int height)
                    {
                    int side = qMin(width, height);
                    glViewport((width - side) / 2, (height - side) / 2, side, side);

                    glMatrixMode(GL_PROJECTION);
                    glLoadIdentity();
                    

                    #ifdef QT_OPENGL_ES_1
                    glOrthof(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
                    #else
                    glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
                    #endif
                    glMatrixMode(GL_MODELVIEW);
                    }

                    void OpenGLWrapper::mousePressEvent(QMouseEvent *event)
                    {
                    lastPos = event->pos();
                    }

                    void OpenGLWrapper::mouseMoveEvent(QMouseEvent *event)
                    {
                    int dx = event->x() - lastPos.x();
                    int dy = event->y() - lastPos.y();

                    if (event->buttons() & Qt::LeftButton) {
                        setXRotation(xRot + 8 * dy);
                        setYRotation(yRot + 8 * dx);
                    } else if (event->buttons() & Qt::RightButton) {
                        setXRotation(xRot + 8 * dy);
                        setZRotation(zRot + 8 * dx);
                    }
                    lastPos = event->pos();
                    

                    }

                    OpenGLWrapper::~OpenGLWrapper(){

                    }

                    @

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      minimoog77
                      wrote on last edited by
                      #10

                      [quote author="sasmaster" date="1315900787"]I am trying to write a modern OpenGL (programmable pipeline) program.Qt OpenGL examples show only the fixed pipeline implementation.The documentation on how to initialize Shader Program is very poor.[/quote]

                      No, it's not poor. You should learn how to setup rendering pipeline in OpenGL. This is not Qt fault.

                      BTW, did you bind attribute location?

                      And usually there is error report from graphic driver why something failed.

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        sasmaster
                        wrote on last edited by
                        #11

                        The code I am using here to pass attributes into shaders is taken from the "not poor" "docs":http://doc.qt.nokia.com/latest/qglshaderprogram.html of Qt.

                        Regarding the attributes location binding ,I think this does this work in Qt :
                        @
                        int vertexLocation = mShaderProgram.attributeLocation("vertex");
                        int matrixLocation = mShaderProgram.attributeLocation("matrix");
                        int colorLocation = mShaderProgram.uniformLocation("color");

                        @
                        Yes this is slightly different from how it is done in "raw" OpenGL .May be you can point me where I am wrong ? Also the Dude from here http://developer.qt.nokia.com/forums/viewthread/4856/ does it the same way.

                        I am getting no shader program errors either .Everything compiles and runs OK .But the display is empty.

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          AndrewJacob
                          wrote on last edited by
                          #12

                          What is the reason of getting empty screen in GL ?

                          [url=http://www.rtaflooring.com]Bamboo Flooring[/url]

                          1 Reply Last reply
                          0
                          • S Offline
                            S Offline
                            sasmaster
                            wrote on last edited by
                            #13

                            That is the question of this post :)

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              AndrewJacob
                              wrote on last edited by
                              #14

                              Yes it is but what is the code about ?

                              [url=http://www.rtaflooring.com]Bamboo Flooring[/url]

                              1 Reply Last reply
                              0
                              • S Offline
                                S Offline
                                sasmaster
                                wrote on last edited by
                                #15

                                Triangle.

                                1 Reply Last reply
                                0
                                • M Offline
                                  M Offline
                                  minimoog77
                                  wrote on last edited by
                                  #16

                                  [quote author="sasmaster" date="1316083047"]
                                  I am getting no shader program errors either .Everything compiles and runs OK .But the display is empty.[/quote]

                                  Sorry for lateness, I am looking at your code, first question, why did you enable GL_LIGHTING/GL_LIGHT? That's fixed pipeline stuff.

                                  Second look, GL_MODELVIEW and GL_PROJECTION matrices, you don't have that also in programmable pipeline. You have to do it yourself in vertex shader. Yes, there is option to set the matrices and access them in shader, but all of the multiplying you have to do it yourself.

                                  1 Reply Last reply
                                  0
                                  • S Offline
                                    S Offline
                                    sasmaster
                                    wrote on last edited by
                                    #17

                                    Those are remnants from my previous trials.I don't think those influence the modern pipeline as I am using a compatibility mode .So those should be discarded by the OpenGL. Regarding the matrices ,you can see that I load a orthogonal projection matrix into the vertex shader on each render loop. Still nothing works.If anybody could put a full example on how to write a OpenGL 3x in Qt it could be really helpful to many people I believe :)

                                    1 Reply Last reply
                                    0
                                    • M Offline
                                      M Offline
                                      minimoog77
                                      wrote on last edited by
                                      #18

                                      Hey, I have example, http://minimoog.wordpress.com/2010/05/10/transfverteksi/ Oh, I am sorry it's in my native language (if it is for somebody interesting I would translate/write in english) but code is simple for understanding http://dl.dropbox.com/u/6108964/QtGL2.zip

                                      BR.

                                      1 Reply Last reply
                                      0
                                      • S Offline
                                        S Offline
                                        sasmaster
                                        wrote on last edited by
                                        #19

                                        He He ,very resembles Russian which I know :) .Is it wrapped with Qt? Thanks a lot .I will check it out!

                                        1 Reply Last reply
                                        0
                                        • M Offline
                                          M Offline
                                          minimoog77
                                          wrote on last edited by
                                          #20

                                          Also you can use it for learning basic usage of VBO. :)

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved