深度测试根本不起作用
Depth testing is not working at all
出于某种原因,在我的项目中我的深度测试不起作用。我已确保它已启用并且不起作用。我知道这一点,因为我可以看到某些面孔被相互覆盖,场景中的不同对象(立方体)被相互覆盖。
我使用的是默认帧缓冲区,所以应该有深度。我还检查了 gl_FragCoord.z,它返回了正确的深度。我已经仔细检查了我的代码多年,搜索了几十页 google 仍然找不到答案。
以下是与此问题相关的按执行顺序呈现的代码:
初始化()
void Program::Init()
{
std::cout << "Initialising" << std::endl;
glViewport(0, 0, Options::width, Options::height);
glewExperimental = true; // Needed in core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return;
}
window.setKeyRepeatEnabled(false);
sf::Mouse::setPosition(sf::Vector2i(Options::width / 2, Options::height / 2), window);
LoadGameState(GameState::INGAME, false);
Run();
}
GLInit()
void Program::GLInit() {
lampShader = Shader("StandardVertex.shader", "LightingFragmentShader.shader");
ourShader = Shader("VertexShader.shader", "SimpleFragmentShader.shader");
screenShader = Shader("FrameVertexShader.shader", "FrameFragmentShader.shader");
skyboxShader = Shader("SkyboxVertex.shader", "SkyboxFragment.shader");
cubeDepthShader = Shader("CubeDepthVertex.shader", "CubeDepthFragment.shader", &std::string("CubeDepthGeometry.shader"));
debugDepthQuad = Shader("SimpleVertex.shader", "DepthFragment.shader");
blurShader = Shader("SimpleVertex.shader", "BloomFragment.shader");
bloomShader = Shader("SimpleVertex.shader", "FinalBloom.shader");
depthShader = Shader("VertexDepth.shader", "EmptyFragment.shader");
geometryPass = Shader("GeometryVertex.shader", "GeometryFragment.shader");
lightingPass = Shader("SimpleVertex.shader", "LightingFragment.shader");
shaderSSAO = Shader("SimpleVertex.shader", "SSAOFragment.shader");
shaderSSAOblur = Shader("SimpleVertex.shader", "SSAOBlurFragment.shader");
colliders = Shader("VertexShader.shader", "GreenFragment.shader");
glEnable(GL_DEPTH_TEST);
}
和另一个重复运行的函数:
RunGame()
void Program::RunGame()
{
scene->mainCamera.Input(Options::deltaTime, window);
if(timeSinceGameStart.getElapsedTime().asSeconds()<2)
DoLights();
if(timeSinceGameStart.getElapsedTime().asSeconds() > 5.0f)
scene->DoPhysics();
scene->CheckCollisions();
glClearColor(0.32f, 0.5f, 0.58f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
projection = glm::mat4();
view = glm::mat4();
// view/projection transformations
projection = glm::perspective(glm::radians(Options::fov), (float)Options::width / (float)Options::height, 0.1f, 100.0f);
view = scene->mainCamera.GetViewMatrix();
lampShader.use();
lampShader.setMat4("projection", projection);
lampShader.setMat4("view", view);
lampShader.setInt("setting", Options::settings);
glm::mat4 model;
for (unsigned int i = 0; i < lights.size(); i++)
{
model = glm::mat4();
model = glm::translate(model, lights[i].position);
model = glm::scale(model, glm::vec3(0.125f));
lampShader.setMat4("model", model);
lampShader.setVec3("lightColor", lights[i].colour);
Scene::renderCube();
}
if (Options::showColliders) {
colliders.use();
colliders.setMat4("projection", projection);
colliders.setMat4("view", view);
scene->RenderColliders(colliders);
}
}
我看了很多页面,我已经完成了所有的建议:
- 调用 glEnable(GL_DEPTH_TEST)
- 清除深度缓冲区
- 确保 zNear 不是一个小数字
- 不调用会禁用深度的函数,如 glDepthMask(GL_FALSE)
欢迎提供帮助。我希望这是足够的代码,如果不够,我会提供任何请求的代码。大多数未显示的功能都非常不言自明。另外如果你觉得上面所有的代码都没有问题,请在评论中告诉我,这样我就知道问题不存在了。
我显然也在使用 c++ 和 glew。我也在为我的 window 使用 SFML。
感谢您的任何回答
编辑:
负责创建sfml的代码window:
Program::Program()
:settings(24, 8, 4, 3, 0),
window(sf::VideoMode(Options::width, Options::height), "OpenGL", sf::Style::Default, settings)
{
Init();
}
灯光的顶点着色器:
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aTexCoords;
out vec3 Normal;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main()
{
Normal = transpose(inverse(mat3(model))) * aNormal;
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
声明window和设置
sf::RenderWindow window;
sf::ContextSettings settings;
问题是在 C++ 中,class 的成员是按照它们声明的顺序初始化的, 而不是 是按照它们在任何构造函数的内存中列出的顺序初始化的-初始化列表。
如果您在编译器中打开了足够多的警告,它应该警告您在您显示的 Program
构造函数中,settings
将在 window
之后初始化。这正是您的问题,因为 settings
在获取您为其指定的值之前被使用。交换class中成员的顺序来解决它。
该规则的原因是基本的 C++ 规则是 "objects of automatic storage duration are always destroyed in the exact opposite order of their construction." class 的析构函数因此需要一个顺序来销毁成员,无论使用哪个构造函数来创建物体。因此,顺序固定为声明的顺序。注意声明的顺序也用于控制其他上下文中的creation/destruction顺序(例如函数局部变量),所以这里使用它是一致的。
出于某种原因,在我的项目中我的深度测试不起作用。我已确保它已启用并且不起作用。我知道这一点,因为我可以看到某些面孔被相互覆盖,场景中的不同对象(立方体)被相互覆盖。
我使用的是默认帧缓冲区,所以应该有深度。我还检查了 gl_FragCoord.z,它返回了正确的深度。我已经仔细检查了我的代码多年,搜索了几十页 google 仍然找不到答案。
以下是与此问题相关的按执行顺序呈现的代码:
初始化()
void Program::Init()
{
std::cout << "Initialising" << std::endl;
glViewport(0, 0, Options::width, Options::height);
glewExperimental = true; // Needed in core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return;
}
window.setKeyRepeatEnabled(false);
sf::Mouse::setPosition(sf::Vector2i(Options::width / 2, Options::height / 2), window);
LoadGameState(GameState::INGAME, false);
Run();
}
GLInit()
void Program::GLInit() {
lampShader = Shader("StandardVertex.shader", "LightingFragmentShader.shader");
ourShader = Shader("VertexShader.shader", "SimpleFragmentShader.shader");
screenShader = Shader("FrameVertexShader.shader", "FrameFragmentShader.shader");
skyboxShader = Shader("SkyboxVertex.shader", "SkyboxFragment.shader");
cubeDepthShader = Shader("CubeDepthVertex.shader", "CubeDepthFragment.shader", &std::string("CubeDepthGeometry.shader"));
debugDepthQuad = Shader("SimpleVertex.shader", "DepthFragment.shader");
blurShader = Shader("SimpleVertex.shader", "BloomFragment.shader");
bloomShader = Shader("SimpleVertex.shader", "FinalBloom.shader");
depthShader = Shader("VertexDepth.shader", "EmptyFragment.shader");
geometryPass = Shader("GeometryVertex.shader", "GeometryFragment.shader");
lightingPass = Shader("SimpleVertex.shader", "LightingFragment.shader");
shaderSSAO = Shader("SimpleVertex.shader", "SSAOFragment.shader");
shaderSSAOblur = Shader("SimpleVertex.shader", "SSAOBlurFragment.shader");
colliders = Shader("VertexShader.shader", "GreenFragment.shader");
glEnable(GL_DEPTH_TEST);
}
和另一个重复运行的函数: RunGame()
void Program::RunGame()
{
scene->mainCamera.Input(Options::deltaTime, window);
if(timeSinceGameStart.getElapsedTime().asSeconds()<2)
DoLights();
if(timeSinceGameStart.getElapsedTime().asSeconds() > 5.0f)
scene->DoPhysics();
scene->CheckCollisions();
glClearColor(0.32f, 0.5f, 0.58f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
projection = glm::mat4();
view = glm::mat4();
// view/projection transformations
projection = glm::perspective(glm::radians(Options::fov), (float)Options::width / (float)Options::height, 0.1f, 100.0f);
view = scene->mainCamera.GetViewMatrix();
lampShader.use();
lampShader.setMat4("projection", projection);
lampShader.setMat4("view", view);
lampShader.setInt("setting", Options::settings);
glm::mat4 model;
for (unsigned int i = 0; i < lights.size(); i++)
{
model = glm::mat4();
model = glm::translate(model, lights[i].position);
model = glm::scale(model, glm::vec3(0.125f));
lampShader.setMat4("model", model);
lampShader.setVec3("lightColor", lights[i].colour);
Scene::renderCube();
}
if (Options::showColliders) {
colliders.use();
colliders.setMat4("projection", projection);
colliders.setMat4("view", view);
scene->RenderColliders(colliders);
}
}
我看了很多页面,我已经完成了所有的建议:
- 调用 glEnable(GL_DEPTH_TEST)
- 清除深度缓冲区
- 确保 zNear 不是一个小数字
- 不调用会禁用深度的函数,如 glDepthMask(GL_FALSE)
欢迎提供帮助。我希望这是足够的代码,如果不够,我会提供任何请求的代码。大多数未显示的功能都非常不言自明。另外如果你觉得上面所有的代码都没有问题,请在评论中告诉我,这样我就知道问题不存在了。
我显然也在使用 c++ 和 glew。我也在为我的 window 使用 SFML。 感谢您的任何回答
编辑: 负责创建sfml的代码window:
Program::Program()
:settings(24, 8, 4, 3, 0),
window(sf::VideoMode(Options::width, Options::height), "OpenGL", sf::Style::Default, settings)
{
Init();
}
灯光的顶点着色器:
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aTexCoords;
out vec3 Normal;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main()
{
Normal = transpose(inverse(mat3(model))) * aNormal;
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
声明window和设置
sf::RenderWindow window;
sf::ContextSettings settings;
问题是在 C++ 中,class 的成员是按照它们声明的顺序初始化的, 而不是 是按照它们在任何构造函数的内存中列出的顺序初始化的-初始化列表。
如果您在编译器中打开了足够多的警告,它应该警告您在您显示的 Program
构造函数中,settings
将在 window
之后初始化。这正是您的问题,因为 settings
在获取您为其指定的值之前被使用。交换class中成员的顺序来解决它。
该规则的原因是基本的 C++ 规则是 "objects of automatic storage duration are always destroyed in the exact opposite order of their construction." class 的析构函数因此需要一个顺序来销毁成员,无论使用哪个构造函数来创建物体。因此,顺序固定为声明的顺序。注意声明的顺序也用于控制其他上下文中的creation/destruction顺序(例如函数局部变量),所以这里使用它是一致的。