Tôi đang cố gắng để một skybox hoạt động với OpenGL 3.3 và GLSL phiên bản 330.
Tôi không thể tìm thấy một hướng dẫn skybox OGL hoàn toàn hiện đại ở bất cứ đâu trên web, vì vậy tôi đã hiện đại hóa một cái cũ hơn (sử dụng glVertexAttribPointer()
thay vì gl_Vertex
cho các đỉnh, v.v.). Nó chủ yếu hoạt động, nhưng với 2 chi tiết chính:
Các skybox giống như các hình tam giác trên bầu trời và các kết cấu bị cong vênh và kéo dài (chúng được cho là các trường sao, tôi nhận được trong khi các dòng trên nền đen). Tôi chắc chắn 99% rằng điều này là do tôi đã không chuyển các hướng dẫn cũ hoàn toàn chính xác.
Đây là lớp skybox của tôi:
static ShaderProgram* cubeMapShader = nullptr;
static const GLfloat vertices[] =
{
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
};
Skybox::Skybox(const char* xp, const char* xn, const char* yp, const char* yn, const char* zp, const char* zn)
{
if (cubeMapShader == nullptr)
cubeMapShader = new ShaderProgram("cubemap.vert", "cubemap.frag");
texture = SOIL_load_OGL_cubemap(xp, xn, yp, yn, zp, zn, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);
glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_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);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID);
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glBindVertexArray(0);
scale = 1.0f;
}
Skybox::~Skybox()
{
}
void Skybox::Render()
{
ShaderProgram::SetActive(cubeMapShader);
glDisable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
cubeMapShader->Uniform1i("SkyTexture", 0);
cubeMapShader->UniformVec3("CameraPosition", Camera::ActiveCameraPosition());
cubeMapShader->UniformMat4("MVP", 1, GL_FALSE, Camera::GetActiveCamera()->GetProjectionMatrix() * Camera::GetActiveCamera()->GetViewMatrix() * glm::mat4(1.0));
glBindVertexArray(vaoID);
glDrawArrays(GL_QUADS, 0, 24);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
Vertex Shader:
#version 330
layout(location = 0) in vec3 Vertex;
uniform vec3 CameraPosition;
uniform mat4 MVP;
out vec3 Position;
void main()
{
Position = Vertex.xyz;
gl_Position = MVP * vec4(Vertex.xyz + CameraPosition, 1.0);
}
Mảnh vỡ mảnh:
#version 330 compatibility
uniform samplerCube SkyTexture;
in vec3 Position;
void main()
{
gl_FragColor = textureCube(SkyTexture, Position);
}
Đây là một ví dụ về các trục trặc. Nếu bất cứ ai cũng có thể xem ai biết rõ về GLSL (tôi vẫn đang học nó) hoặc skybox, tôi sẽ đánh giá cao bất kỳ trợ giúp nào bạn có thể cung cấp. Ngoài ra, kudos nếu bạn có thể dạy tôi cách sử dụng các hàm không bị phản đối trong shader mảnh để tôi không phải sử dụng cấu hình tương thích của glsl 330.
EDIT: Ngay lập tức tìm thấy vấn đề với kết cấu kéo dài: Tôi đã sử dụng Position = Vertex.xy
x
thay vìPosition = Vertex.xy
z
trong shader đỉnh. Giáo sư. Nhưng lỗi tam giác vẫn tồn tại.