[英]Qt/OpenGL Trying to display a 2D texture
我是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(),所以它似乎可以正常工作。 使用了顶点着色器和片段着色器,并使用了片段着色器中的颜色。
谢谢
program->setUniformValue("tex", tex);
tex
变量是纹理的句柄 ,而您需要设置纹理单位 。 改成
glActiveTexture(GL_TEXTURE0);
program->setUniformValue("tex", 0);
在答案和评论中提到的其他问题中,您的位置和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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.