opengl-第六章:加入纹理Texture和纹理数据TextureData

目录

    • 新版本的QKEngine特性介绍
      • 系统架构图
      • 测试结果
    • 新的数据文件.dtexture
    • 纹理的绘制机制
      • 新的数据结构
        • 绑定EBO数据
        • 指定数据属性
        • 绘制数据
      • 纹理的绑定
        • 绑定到ID
        • 使用
      • Shader的设置
        • 在顶点着色器获取CPU压进去的纹理坐标
        • 将纹理坐标从顶点着色器传给片元着色器
        • 在片元着色器接收这个纹理坐标
        • 在片元着色器捕捉当前opengl状态机上的纹理状态
        • 完成纹理状态->纹理坐标的映射

新版本的QKEngine特性介绍

在新版本的引擎里面,我们进行了架构上的优化,目前引擎需要绘制的数据包括纹理数 
据,Shader程序,还有Buffer,我们统一继承自Element,然后统一在Window的循环调
用里面进行for call.

测试代码:

#include 
#include 
#include 
#include 
#include 
int main(int argc, char *argv[])
{
	BaseWindow window;

	Shader shader("vertex","fragment");
	SimpleData sd("test");
	SimpleData sd2("test2");
	TextureData sd3("test");
	Texture tt("pp.jpg",500,500);

	window.addElement(make_shared<Texture>(tt));
	window.addElement(make_shared<TextureData>(sd3));
	window.addElement(make_shared<Shader>(shader));
	
	window.run();
	return 0;
}


系统架构图

opengl-第六章:加入纹理Texture和纹理数据TextureData_第1张图片

测试结果

opengl-第六章:加入纹理Texture和纹理数据TextureData_第2张图片

新的数据文件.dtexture

现在,我们产生了新的数据文件.dtexture,该文件主要服务于EBO对象,并支持
注释'#',你可以直接通过'#'将该行或者该行之后的数据注释掉,在引擎处理里面
将会忽视掉这些数据

opengl-第六章:加入纹理Texture和纹理数据TextureData_第3张图片

纹理的绘制机制

如果要绘制纹理,需要做几个方面的准备

新的数据结构

opengl-第六章:加入纹理Texture和纹理数据TextureData_第4张图片

绑定EBO数据

注意,当我们用EBO进行绘制时需要制定VAO,VBO,然后才能绑定EBO
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, vLen * 4, this->data, GL_STATIC_DRAW);
	
	glGenBuffers(1, &EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, iLen * 4, indices, GL_STATIC_DRAW);

指定数据属性

	//指定位置属性
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	//指定颜色属性
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);
	//指定纹理坐标
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
	glEnableVertexAttribArray(2);

绘制数据

	glBindVertexArray(VAO);
	glDrawElements(GL_TRIANGLES, iLen, GL_UNSIGNED_INT, 0);

纹理的绑定

绑定到ID

这一步相当于将纹理数据绑定给ID

	string bufName = getResourcesFolder() + "Texture\\" + vName;
	glGenTextures(1, &ID);
	glBindTexture(GL_TEXTURE_2D, ID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	int w,h,nrChannels;
	unsigned char *data = stbi_load(bufName.c_str(), &w, &h, &nrChannels, 0);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	if (data)
	{
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else
	{
		std::cout << "Failed to load texture" << std::endl;
	}
	stbi_image_free(data);

使用

opengl是一个大型状态机,这个时候我们直接在画这个图之前,将当前的纹理状态设置为
该ID就可以了
glBindTexture(GL_TEXTURE_2D, ID);

Shader的设置

在顶点着色器获取CPU压进去的纹理坐标

opengl-第六章:加入纹理Texture和纹理数据TextureData_第5张图片

将纹理坐标从顶点着色器传给片元着色器

opengl-第六章:加入纹理Texture和纹理数据TextureData_第6张图片

在片元着色器接收这个纹理坐标

opengl-第六章:加入纹理Texture和纹理数据TextureData_第7张图片

在片元着色器捕捉当前opengl状态机上的纹理状态

opengl-第六章:加入纹理Texture和纹理数据TextureData_第8张图片

完成纹理状态->纹理坐标的映射

opengl-第六章:加入纹理Texture和纹理数据TextureData_第9张图片

你可能感兴趣的:(opengl,渲染管线)