c++ - 无法显示 OpenGL 纹理

标签 c++ qt opengl

<分区>

我一直在尝试使用 OpenGL 将图像渲染到屏幕上,为了了解有关纹理等的更多信息,我的方法是将图像映射到纹理,然后使用 GL_QUADS 绘制它。但是,我得到的只是一个空白屏幕。

因此,纹理初始化如下:

class Texture
{
public:
    void init_texture(int rows, int cols);
    void load_texture(const Image * frame);

    GLuint      _texture_obj;

};

void Texture::init_texture(int rows, int cols)
{
    if (_texture_obj) glDeleteTextures(1, &_texture_obj);

    _texture_target = GL_TEXTURE_2D;
    glGenTextures(1, &_texture_obj);

    if (_texture_obj) {
        glBindTexture(_texture_target, _texture_obj);
        glTexImage2D(_texture_target, 0, GL_BGRA, cols, rows, 0, 
                     GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)NULL);
        glTexParameterf(_texture_target, GL_TEXTURE_MIN_FILTER, 
                        GL_LINEAR);
        glTexParameterf(_texture_target, GL_TEXTURE_MAG_FILTER, 
                        GL_LINEAR);
    }
    else {
        throw std::runtime_error("Could not create the OpenGL texture");
    }
}

void Texture::load_texture(const Image *frame)
{
    glBindTexture(GL_TEXTURE_2D, _texture_obj);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frame->cols(), 
                    frame->rows(), GL_BGRA, GL_UNSIGNED_BYTE, 
                    frame->data());
}

上面的代码初始化并加载了纹理。

为了显示纹理,我使用了一个 QOpenGLWidget 派生对象,其中的初始化和绘制方法如下所示:

class GLWidget: public QOpenGLWidget
{
public:
    GLWidget(Image *image);
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();

private:
    Texture texture;
};


void GLWidget::GLWidget(Image * image)
{
   texture.init(image->rows, image->cols);
   texture.load(image);
}

void GLWidget::initializeGL()
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
}

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

void GLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();    
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);
    glBindTexture(GL_TEXTURE_2D, texture._tex_object);
    glBegin(GL_QUADS);
        // width(), height() gives the component width and height
        glTexCoord2i(0, 0); glVertex2i(0, 0);
        glTexCoord2i(0, 1); glVertex2i(0, this->width());
        glTexCoord2i(1, 1); glVertex2i(this->height(), this->width());
        glTexCoord2i(1, 0); glVertex2i(this->height(), 0);
    glEnd();
    glDisable(GL_TEXTURE_2D);
}

但是,这只会显示一个空白屏幕。我需要设置一些视口(viewport)吗?我几天前才开始使用 OpenGL,所以在这方面还很新手。我在 Linux 上使用 qt 5.4 版和 OpenGL 4.3。

最佳答案

电话

glTexImage2D(_texture_target, 0, GL_BGRA, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)NULL);

无效,因为 GL_BGRA 不是有效的 internalFormat。你应该为此使用 GL_RGBA。请注意,internalFormat 仅定义了基本数据类型和 channel 数,实际布局完全是特定于实现的。另一方面,format 参数告诉 GL 如何解释客户端内存中的数据,因此实际上定义了 GL_RGBAGL_BGRA 等格式。

我不是很熟悉QOpenGLWidget。但是,我认为在构造函数中创建纹理可能不是一个好主意,因为此时 GL 上下文可能不可用(或者至少不是当前线程)。您应该将这些内容移入 initializeGL()

关于c++ - 无法显示 OpenGL 纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29039078/

相关文章:

c - 在 GLSL 中使用多个纹理+滤镜

c++ - 链表的复制构造函数会导致内存错误

c++ - 命名空间范围与类内范围

c++ - Windows:在没有命令提示符的情况下使用 QProcess::execute 执行 ping 命令

c++ - 没有背景的透明 SDL_Surface

c++ - 使用 glUniformMatrix4fv() 用新矩阵更新旧矩阵?

c++ - 我遇到了内存泄漏,但我不知道为什么

c++ - 在 C++ 中显示一行与单词

c++ - Qt的两个QList成员变量导致崩溃

Qt 在两个 QListWidget 之间拖放