OpenGL3.3立方体贴图
程序员文章站
2024-03-25 16:41:52
...
立方体贴图
立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的一个面
他的一个优点是可以通过他的坐标直接当作他的纹理坐标(一个长宽高为1的正方体盒子,以原点为中心,他的坐标就是他的纹理坐标)
如果我们有一个纹理位置的数组或者vector,我们就可以从GL_TEXTURE_CUBE_MAP_POSITIVE_X开始遍历它们,在每个迭代中对枚举值加1,遍历了整个纹理目标glTexImage2D(
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data
);
具体做法:
vector<std::string> faces
{
FileSystem::getPath("resources/textures/skybox/right.jpg"),
FileSystem::getPath("resources/textures/skybox/left.jpg"),
FileSystem::getPath("resources/textures/skybox/top.jpg"),
FileSystem::getPath("resources/textures/skybox/bottom.jpg"),
FileSystem::getPath("resources/textures/skybox/front.jpg"),
FileSystem::getPath("resources/textures/skybox/back.jpg")
};//创建一个存储纹理路径的向量
unsigned int cubemapTexture = loadCubemap(faces)//将向量带进函数
unsigned int loadCubemap(vector<std::string> faces)//函数具体实现
{
unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);//创建绑定纹理对象
int width, height, nrChannels;
for (unsigned int i = 0; i < faces.size(); i++)
{
unsigned char *data = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);//获取每张图片的纹理信息
if (data)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);//将信息传递给纹理
stbi_image_free(data);
}
else
{
std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
stbi_image_free(data);
}
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
return textureID;
}
立方体贴图实际上就是建立一个纹理贴图的类似数组的东西 可以从第一个地址开始遍历后面的纹理
首先就是建立一个以原点为中心的长度为1的正立方体 因为每个长度最大都是1 最小是0 所以可以把每个面的坐标当作纹理坐标来填写
然后通过对深度坐标的转换可以使天空盒的深度值变为1 也就是只要前面有物体就可以遮挡天空盒
再让天空盒以人物位置为中心跟随人物移动(但是网站上的什么移除位移矩阵转换 留下旋转缩放之类的矩阵就不知道是什么意思 感觉有点相反的感觉)
glReadPixels()是从OpenGL的帧缓冲区(FBO)读取像素数据,并将数据写(pack)入PBO中
采样器改为samplerCube
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);//GL_TEXTURE_CUBE_MAP参数是立方体贴图的参数