首页 文章

无法显示OpenGL纹理[关闭]

提问于
浏览
0

我一直在尝试使用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派生对象,初始化和paint方法如下所示:

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

但是,这只会让我看到一个空白的屏幕 . 我需要设置一些视口吗?我几天前才开始使用OpenGL,所以在这方面我很开心 . 我在Linux上使用qt版本5.4和OpenGL 4.3 .

1 回答

  • 3

    电话

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

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

    我对 QOpenGLWidget 并不熟悉 . 但是,我认为在构造函数中创建纹理可能是一个坏主意,因为GL上下文可能在那时不可用(或者至少不是最新的线程) . 你应该把那些东西移到 initializeGL() .

相关问题