Qt/OpenGL 试图显示 2D 纹理
Posted
技术标签:
【中文标题】Qt/OpenGL 试图显示 2D 纹理【英文标题】:Qt/OpenGL Trying to display a 2D texture 【发布时间】:2016-07-25 11:37:04 【问题描述】:我是 OpenGL 的新手,所以我从头开始。我做的第一件事是使用旧方法(使用 glBegin() 和 glEnd())显示基本的 2D 纹理,它工作。然后我尝试改进我的代码以便将来能够使用 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);
我只有黑屏。一切都是 2D 的(我的项目不需要 3D),我暂时不使用 VBO 和 VAO,我试图让它首先工作。 LoadGLTexture() 似乎可以工作,因为我之前已经使用过它。顶点和片段着色器被使用并与片段着色器中的颜色一起工作。
谢谢
【问题讨论】:
每次 gl 调用后调用 glGetError。如果发生错误,请记录。还要检查着色器编译错误,记录着色器编译器的输出。发布日志。 【参考方案1】:在答案和 cmets 中陈述的其他问题中,您的 position 和 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
。
【讨论】:
啊是的好电话。 OP 使用 3.1 版本可能是明智的,并且只对属性使用显式布局。 非常感谢,对下面 rwols 给出的修正进行了修正。我现在更明白了。【参考方案2】:program->setUniformValue("tex", tex);
tex
变量是纹理的句柄,而您需要设置纹理单元。改成
glActiveTexture(GL_TEXTURE0);
program->setUniformValue("tex", 0);
【讨论】:
以上是关于Qt/OpenGL 试图显示 2D 纹理的主要内容,如果未能解决你的问题,请参考以下文章