创建立方体贴图 unsigned int textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); int width, height, nrChannels; unsigned char *data; ? for(unsigned int i = 0; i < textures_faces.size(); i++) { ? ? data = stbi_load(textures_faces[i].c_str(), &width, &height, &nrChannels, 0); ? ? glTexImage2D( ? ? ? ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,? ? ? ? ? 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data ? ? ); } 绑定六个面 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_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); 同样的设置
总结 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; }
不过片段着色器就有所不同 in vec3 textureDir; // 代表3D纹理坐标的方向向量 uniform samplerCube cubemap; // 立方体贴图的纹理采样器
void main() { ? ? ? ? ? ?? ? ? FragColor = texture(cubemap, textureDir); }
示例: 加载天空盒子 在有之前那个函数的情况下 shader省略 float skyboxVertices[] = { ? ? ? ? // positions ? ? ? ? ? ? ? ? ? -1.0f, ?1.0f, -1.0f, ? ? ? ? -1.0f, -1.0f, -1.0f, ? ? ? ? ?1.0f, -1.0f, -1.0f, ? ? ? ? ?1.0f, -1.0f, -1.0f, ? ? ? ? ?1.0f, ?1.0f, -1.0f, ? ? ? ? -1.0f, ?1.0f, -1.0f,
? ? ? ? -1.0f, -1.0f, ?1.0f, ? ? ? ? -1.0f, -1.0f, -1.0f, ? ? ? ? -1.0f, ?1.0f, -1.0f, ? ? ? ? -1.0f, ?1.0f, -1.0f, ? ? ? ? -1.0f, ?1.0f, ?1.0f, ? ? ? ? -1.0f, -1.0f, ?1.0f,
? ? ? ? ?1.0f, -1.0f, -1.0f, ? ? ? ? ?1.0f, -1.0f, ?1.0f, ? ? ? ? ?1.0f, ?1.0f, ?1.0f, ? ? ? ? ?1.0f, ?1.0f, ?1.0f, ? ? ? ? ?1.0f, ?1.0f, -1.0f, ? ? ? ? ?1.0f, -1.0f, -1.0f,
? ? ? ? -1.0f, -1.0f, ?1.0f, ? ? ? ? -1.0f, ?1.0f, ?1.0f, ? ? ? ? ?1.0f, ?1.0f, ?1.0f, ? ? ? ? ?1.0f, ?1.0f, ?1.0f, ? ? ? ? ?1.0f, -1.0f, ?1.0f, ? ? ? ? -1.0f, -1.0f, ?1.0f,
? ? ? ? -1.0f, ?1.0f, -1.0f, ? ? ? ? ?1.0f, ?1.0f, -1.0f, ? ? ? ? ?1.0f, ?1.0f, ?1.0f, ? ? ? ? ?1.0f, ?1.0f, ?1.0f, ? ? ? ? -1.0f, ?1.0f, ?1.0f, ? ? ? ? -1.0f, ?1.0f, -1.0f,
? ? ? ? -1.0f, -1.0f, -1.0f, ? ? ? ? -1.0f, -1.0f, ?1.0f, ? ? ? ? ?1.0f, -1.0f, -1.0f, ? ? ? ? ?1.0f, -1.0f, -1.0f, ? ? ? ? -1.0f, -1.0f, ?1.0f, ? ? ? ? ?1.0f, -1.0f, ?1.0f ? ? }; 先创建VAO。VBO绑定 ?unsigned int skyboxVAO, skyboxVBO; ? ? glGenVertexArrays(1, &skyboxVAO); ? ? glGenBuffers(1, &skyboxVBO); ? ? glBindVertexArray(skyboxVAO); ? ? glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO); ? ? glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW); ? ? glEnableVertexAttribArray(0); ? ? glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); 然后加载纹理 vector<std::string> faces { ? ? "right.jpg", ? ? "left.jpg", ? ? "top.jpg", ? ? "bottom.jpg", ? ? "front.jpg", ? ? "back.jpg" }; unsigned int cubemapTexture = loadCubemap(faces); 创建纹理,别忘了setInt ?skyboxShader.use(); ?skyboxShader.setInt("skybox", 0); 然后设置深度测试模式,设置参数,设置纹理,开始绘制,设回纹理 ? ? ? ? lDepthFunc(GL_LEQUAL); ? ? ? ? skyboxShader.use(); ? ? ? ? skyboxShader.setMat4("projection", projection); ? ? ? ? skyboxShader.setMat4("view", glm::mat4(glm::mat3(camera.GetViewMatrix()))); ? ? ? ? glBindVertexArray(skyboxVAO); ? ? ? ? glActiveTexture(GL_TEXTURE0); ? ? ? ? glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); ? ? ? ? glDrawArrays(GL_TRIANGLES, 0, 36); ? ? ? ? glDepthFunc(GL_LESS);
OVER 顶点着色器 #version 330 core layout (location = 0) in vec3 aPos;
out vec3 TexCoords;
uniform mat4 projection; uniform mat4 view;
void main() { ? ? ?TexCoords = aPos; ? ? ?vec4 pos = projection * view * vec4(aPos,1.0);//常规操作 ? ? ?gl_Position = pos.xyww;//Z项设为深度为1 } 片段着色器 #version 330 core out vec4 FragColor;
in vec3 TexCoords;
uniform samplerCube skybox;
void main() { ?? ?FragColor = texture(skybox, TexCoords);//TexCoords是位置 }
|