开发环境
vs2015 +qt5
结果
使用Qt中自带的QOpenGLTexture 类来实现纹理贴图
实现步骤
- 增加QOpenGLTexture指针
- 添加纹理图片,实例化指针
- 修改shader
- 调用shader
具体实现与代码
1 增加QOpenGLTexture指针
在 openscene.hpp中引入QOpenGLTexture头文件,并增加指针,在构造函数和析构函数中初始化和删除指针
#include <QOpenGLTexture> //头文件
QOpenGLTexture *textures; //指针
textures = nullptr; //构造函数
if (textures) //析构函数
delete textures;
2 添加纹理图片,实例化指针
添加一张图片,我选用的是Qt例子中的一张,路径为 imgParh
在initializeGL()中增加
//添加纹理信息 对应图片路径
textures = new QOpenGLTexture(QImage(QString("images/side1.png")).mirrored());
由于需要更改坐标,initializeGL函数修改如下(只列出修改部分,其他部分参考上一篇):
//带有纹理的正方体
GLfloat vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
//因为不同面用不同的纹理,因此不需要EBO
// VAO VBO
/* 创建相关对象 */
glGenVertexArrays(NumVAOGw, &IDVAO[0]);
glGenBuffers(NumVBOGw, &IDVBO[0]);
/* 显示立方体 */
glBindVertexArray(IDVAO[0]); //开始记录状态信息
glBindBuffer(GL_ARRAY_BUFFER, IDVBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);//结束记录状态信息
//添加纹理信息
textures = new QOpenGLTexture(QImage(QString("images/side2.png")).mirrored());
3 修改shader
simple.vert
#version 330 core
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec2 vTexcoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec2 Texcoord;
void main()
{
gl_Position = projection * view * model * vec4(vPosition, 1.0);
Texcoord = vTexcoord;
}
simple.frag
#version 330 core
in vec2 Texcoord;
uniform sampler2D texture1;
out vec4 fColor;
void main()
{
fColor = texture(texture1,Texcoord);
}
由于上一篇代码坐标的片段着色器用的是物体的,因此修改着色器之前应该新建一个着色器,并修改绘制坐标的shader
3 调用shder
在paintGL中绘制物体
textures->bind();
//渲染彩色正方体
shaderCube.bind();
QMatrix4x4 view;
QMatrix4x4 projection;
QMatrix4x4 model;
view.lookAt(cameraPos, worldCentrol, cameraUp);
projection.perspective(45.0f, 4.0f / 3.0f, 0.1f, 100000.0f);
model.translate(transVec);
model.rotate(pitch, 1.0f, 0.0f, 0.0f); //按住左键,上下拖动鼠标让立方体绕x轴旋转
model.rotate(yaw, 0.0f, 1.0f, 0.0f); //按住左键,左右拖动鼠标让立方体绕y轴旋转
shaderCube.setUniformValue("view", view);
shaderCube.setUniformValue("projection", projection);
shaderCube.setUniformValue("model", model);
glBindVertexArray(IDVAO[0]);
glDrawArrays(GL_TRIANGLES, 0, 36);
下一篇 OpenGL+Qt界面(五) 天空和地面的设计 待完成
参考
QOpenGLTexture 文档 不过个人觉得Qt官方的纹理demo 并不是很好,直接用在VS上会出错,我在这里也浪费了很多时间。
learnOpengl的纹理 代码简单易懂,不过用的不是Qt的纹理类函数。