在OpenGL中,samplerCube
是用于采样立方体贴图的类型,而 samplerCubeArray
是用于采样立方体贴图数组的类型。你的问题在于使用了 samplerCube
数组,但没有正确地传递和绑定立方体贴图数组。
解决方案
使用 samplerCubeArray:
你需要使用 samplerCubeArray
类型来采样立方体贴图数组。samplerCubeArray
允许你在一个统一的采样器中处理多个立方体贴图。
绑定立方体贴图数组:
你需要将多个立方体贴图绑定到一个纹理数组中,并使用 samplerCubeArray
进行采样。
具体步骤
1. 创建和绑定立方体贴图数组
首先,创建一个立方体贴图数组,并将每个立方体贴图绑定到数组中。
GLuint depthCubeMapArray;
glGenTextures(1, &depthCubeMapArray);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, depthCubeMapArray);
// 为每个立方体贴图分配内存
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT, width, height, 4 * 6, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// 绑定每个立方体贴图到数组中
for (int i = 0; i < 4; ++i) {
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubeMaps[i]);
for (int face = 0; face < 6; ++face) {
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, i * 6 + face, 0, 0, width, height);
}
}
2. 在着色器中使用 samplerCubeArray
在着色器中,使用 samplerCubeArray
类型来采样立方体贴图数组。
#version 330 core
uniform samplerCubeArray depthMap;
in vec3 fragPos;
void main() {
// 采样立方体贴图数组
float depth = texture(depthMap, vec4(fragPos, 0)).r;
// 其他处理...
}
3. 传递纹理单元
在C++代码中,将立方体贴图数组绑定到一个纹理单元,并传递给着色器。
// 激活纹理单元
glActiveTexture(GL_TEXTURE1);
// 绑定立方体贴图数组纹理
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, depthCubeMapArray);
shader.setInt("depthMap", 1);
完整代码示例
C++代码
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
GLuint depthCubeMaps[4];
GLuint depthCubeMapArray;
void init() {
// 创建4个立方体贴图
glGenTextures(4, depthCubeMaps);
for (int i = 0; i < 4; ++i) {
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubeMaps[i]);
// 为每个立方体贴图分配内存
for (int face = 0; face < 6; ++face) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
// 设置纹理参数
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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);
}
// 创建立方体贴图数组
glGenTextures(1, &depthCubeMapArray);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, depthCubeMapArray);
// 为每个立方体贴图分配内存
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT, width, height, 4 * 6, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// 绑定每个立方体贴图到数组中
for (int i = 0; i < 4; ++i) {
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubeMaps[i]);
for (int face = 0; face < 6; ++face) {
glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, i * 6 + face, 0, 0, width, height);
}
}
}
void render() {
// 激活纹理单元
glActiveTexture(GL_TEXTURE1);
// 绑定立方体贴图数组纹理
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, depthCubeMapArray);
shader.setInt("depthMap", 1);
// 渲染场景...
}
着色器代码
#version 330 core
uniform samplerCubeArray depthMap;
in vec3 fragPos;
void main() {
// 采样立方体贴图数组
float depth = texture(depthMap, vec4(fragPos, 0)).r;
// 其他处理...
}
总结
通过使用 samplerCubeArray
类型和绑定立方体贴图数组,你可以正确地传递和采样多个立方体贴图。确保在C++代码中正确创建和绑定立方体贴图数组,并在着色器中使用 samplerCubeArray
进行采样。