欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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参数是立方体贴图的参数

相关标签: opengl