Qt / OpenGL尝试显示2D纹理

时间:2016-07-25 11:37:04

标签: c++ qt opengl

我是OpenGL的新手,所以我从一开始就开始了。我做的第一件事是使用旧方式显示基本的2D纹理(使用glBegin()和glEnd())并且它起作用。然后我尝试改进我的代码以便将来能够使用VBO和VAO,所以我不得不使用着色器。我设法使用Shaders颜色,但我遇到纹理问题。

这是我的代码:

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);

}

我所有的都是黑屏。一切都是二维的(我的项目不需要3D),我暂时不使用VBO和VAO,我试图让它先工作。 LoadGLTexture()似乎可以工作,因为我之前已经使用过它。使用顶点和片段着色器并使用片段着色器中的颜色。

由于

2 个答案:

答案 0 :(得分:1)

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

tex变量是纹理的句柄,而您需要设置纹理单元。将其改为

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

答案 1 :(得分:1)

在答案和评论中陈述的其他问题中,您的职位和texcoord属性位置是错误的:

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

第一个参数是位置。它是由司机指定的,您只是假设这些位置有效。要解决此问题,请从着色器查询位置:

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

然后将这些值提供给glVertexAttribPointer的第一个参数glEnableVertexAttribArray