Megatron300
Megatron300

Reputation: 239

Qt/OpenGL Trying to display a 2D texture

I'm quite new at OpenGL, so I've started from the beginning. The first thing I did was to display a basic 2D texture using the old way (With glBegin() and glEnd()) and it worked. Then I tried to improve my code to be able to use VBO and VAO in the future, so I had to use Shaders. I managed to use Shaders with colors, but I'm having trouble with texture.

Here is my code :

glwidget.h

#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QDebug>
#include <QOpenGLTexture>
#include <GL/gl.h>
#include <QGLFunctions>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>



class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit GLWidget(QWidget *parent = 0);

    void initializeGL();
    void paintGL();
    void resizeGL(int w, int h);
    void LoadGLTextures();

private :

    QOpenGLShaderProgram *program;
    GLuint tex;


public slots:



private slots:



};

#endif // GLWIDGET_H

glwidget.cpp

#include "glwidget.h"


GLWidget::GLWidget(QWidget *parent) :
        QOpenGLWidget(parent)
{

}

void GLWidget::LoadGLTextures(){

    QImage img;

    if(!img.load("C:\\Users\\Adrien\\Desktop\\open3.bmp")){

        qDebug()<<"Image loading failed";
    }

    QImage t = (img.convertToFormat(QImage::Format_RGBA8888)).mirrored();

    glGenTextures(1, &tex);

    glBindTexture(GL_TEXTURE_2D, tex);

        glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glBindTexture( GL_TEXTURE_2D, 0);



}

void GLWidget::initializeGL(){

    initializeOpenGLFunctions();

    glClear(GL_COLOR_BUFFER_BIT);

    glEnable(GL_TEXTURE_2D);
    LoadGLTextures();

    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vsrc =
        "#version 150 core\n"
        "in vec2 in_Vertex;\n"
        "in vec2 vertTexCoord;\n"
        "out vec2 fragTexCoord;\n"
        "void main(void)\n"
        "{\n"
        "    gl_Position = vec4(in_Vertex, 0.0, 1.0);\n"
        "    fragTexCoord = vertTexCoord;\n"
        "}\n";
    vshader->compileSourceCode(vsrc);

    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fsrc =
            "#version 150 core\n"
            "uniform sampler2D tex;\n"
            "in vec2 fragTexCoord;\n"
            "void main(void)\n"
            "{\n"
            "    gl_FragColor = texture2D(tex,fragTexCoord);\n"
            "}\n";
    fshader->compileSourceCode(fsrc);

    program = new QOpenGLShaderProgram;
    program->addShader(vshader);
    program->addShader(fshader);

    program->link();
    program->bind();
    program->setUniformValue("tex", tex);

}

void GLWidget::paintGL(){

    glClear(GL_COLOR_BUFFER_BIT);

    program->bind();
    {
        float vertices[] = {-1.0,-1.0,  1.0,-1.0,  1.0,1.0,  -1.0,1.0};

        float coordTexture[] = {0.0,0.0,  1.0,0.0,  1.0,1.0,  0.0,1.0};

        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
        glEnableVertexAttribArray(0);

        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, coordTexture);
        glEnableVertexAttribArray(2);

        glBindTexture(GL_TEXTURE_2D, tex);

        glDrawArrays(GL_QUADS, 0, 4);

        glBindTexture(GL_TEXTURE_2D, 0);

        glDisableVertexAttribArray(2);
        glDisableVertexAttribArray(0);


    }
    program->release();

}

void GLWidget::resizeGL(int w, int h){

    glViewport(0, 0, (GLint)w, (GLint)h);

}

All I have is a black screen. Everything is in 2D (I won't need 3D for my project), I'm not using VBO and VAO for the moment, I'm trying to get this to work first. The LoadGLTexture() seems to work since I already used it before. The vertex and fragment shaders were used and worked with colors in the fragment shaders.

Thanks

Upvotes: 2

Views: 3963

Answers (2)

SurvivalMachine
SurvivalMachine

Reputation: 8356

Among other problems stated in answers and comments, your position and texcoord attribute locations are wrong:

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, coordTexture);

The first parameter is the location. It's assigned by the driver and you're just assuming that those locations are valid. To fix that, query the locations from the shader:

GLint vertexLocation = glGetAttribLocation( shaderProgram, "in_Vertex" );
GLint texcoordLocation = glGetAttribLocation( shaderProgram, "vertTexCoord" );

Then give those values to glVertexAttribPointer's first parameter and glEnableVertexAttribArray.

Upvotes: 2

rwols
rwols

Reputation: 3078

program->setUniformValue("tex", tex);

The tex variable is a handle to a texture, while you need to set the texture unit. Change it into

glActiveTexture(GL_TEXTURE0);
program->setUniformValue("tex", 0);

Upvotes: 2

Related Questions