opengl-第六章:加入纹理Texture和纹理数据TextureData
新版本的QKEngine特性介绍
在新版本的引擎里面,我们进行了架构上的优化,目前引擎需要绘制的数据包括纹理数 据,Shader程序,还有Buffer,我们统一继承自Element,然后统一在Window的循环调 用里面进行for call.
测试代码:
#include <BaseWindow.h> #include <Shader.h> #include <SimpleData.h> #include <TextureData.h> #include <Texture.h> 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; }
系统架构图
测试结果
新的数据文件.dtexture
现在,我们产生了新的数据文件.dtexture,该文件主要服务于EBO对象,并支持 注释#,你可以直接通过#将该行或者该行之后的数据注释掉,在引擎处理里面 将会忽视掉这些数据
纹理的绘制机制
如果要绘制纹理,需要做几个方面的准备
新的数据结构
绑定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);