我一直在尝试使用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。
答案 0 :(得分: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_RGBA
和GL_BGRA
等格式。
我对QOpenGLWidget
并不熟悉。但是,我认为在构造函数中创建纹理可能是个坏主意,因为GL上下文可能在那时不可用(或者至少不是最新的线程)。您应该将这些内容移到initializeGL()
。