简体   繁体   English

Qt / OpenGL尝试显示2D纹理

[英]Qt/OpenGL Trying to display a 2D texture

I'm quite new at OpenGL, so I've started from the beginning. 我是OpenGL的新手,所以我从头开始。 The first thing I did was to display a basic 2D texture using the old way (With glBegin() and glEnd()) and it worked. 我要做的第一件事是使用旧方法(使用glBegin()和glEnd())显示基本的2D纹理,并且它可以正常工作。 Then I tried to improve my code to be able to use VBO and VAO in the future, so I had to use Shaders. 然后,我尝试改进代码,以便将来可以使用VBO和VAO,因此我不得不使用Shaders。 I managed to use Shaders with colors, but I'm having trouble with texture. 我设法将着色器与颜色配合使用,但是在纹理方面遇到了麻烦。

Here is my code : 这是我的代码:

glwidget.h 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 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. 一切都以2D形式进行(我的项目不需要3D),我暂时不使用VBO和VAO,我正在尝试使其首先工作。 The LoadGLTexture() seems to work since I already used it before. 由于我之前已经使用过LoadGLTexture(),所以它似乎可以正常工作。 The vertex and fragment shaders were used and worked with colors in the fragment shaders. 使用了顶点着色器和片段着色器,并使用了片段着色器中的颜色。

Thanks 谢谢

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

The tex variable is a handle to a texture, while you need to set the texture unit . tex变量是纹理的句柄 ,而您需要设置纹理单位 Change it into 改成

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

Among other problems stated in answers and comments, your position and texcoord attribute locations are wrong: 在答案和评论中提到的其他问题中,您的位置和texcoord属性位置错误:

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 . 然后将这些值提供给glVertexAttribPointer的第一个参数和glEnableVertexAttribArray

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM