我是OpenGL的新手,所以我从一开始就开始了。我做的第一件事是使用旧方式显示基本的2D纹理(使用glBegin()和glEnd())并且它起作用。然后我尝试改进我的代码以便将来能够使用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);
}
我所有的都是黑屏。一切都是二维的(我的项目不需要3D),我暂时不使用VBO和VAO,我试图让它先工作。 LoadGLTexture()似乎可以工作,因为我之前已经使用过它。使用顶点和片段着色器并使用片段着色器中的颜色。
由于
答案 0 :(得分:1)
program->setUniformValue("tex", tex);
tex
变量是纹理的句柄,而您需要设置纹理单元。将其改为
glActiveTexture(GL_TEXTURE0);
program->setUniformValue("tex", 0);
答案 1 :(得分:1)
在答案和评论中陈述的其他问题中,您的职位和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
。