Reputation: 664
For some reason in my project my depth testing is not working. I have made sure it is enabled and it doesn't work. I know this because I can see certain faces being drawn over each other and different objects (cubes) in the scene are drawn over each other.
I am using the default framebuffer, so there should be depth. I also check gl_FragCoord.z and it returned the correct depth. I've went through my code thoroughly for ages, searched dozens of google pages and I still can't find the answer.
Here is the code presented in order of execution that is relevant to this question:
Init()
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);
}
and another function that runs on repeat: 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);
}
}
I have looked at lots of pages and I have done all the recommendations:
Any help if welcome. I hope this is enough code, if its not I'll give any requested code. Most of the functions not shown are pretty self explanatory. Also if you think all the code is fine above, please tell me in the comments so I know that the issue is not there.
I am obviously also using c++ and glew. I am also using SFML for my window. Thanks for any answers
EDIT: Code responsible for creating sfml window:
Program::Program()
:settings(24, 8, 4, 3, 0),
window(sf::VideoMode(Options::width, Options::height), "OpenGL", sf::Style::Default, settings)
{
Init();
}
Vertex shader for lights:
#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);
}
Declaration of window and settings
sf::RenderWindow window;
sf::ContextSettings settings;
Upvotes: 2
Views: 272
Reputation: 171117
The problem is that in C++, members of a class are initialised in the order of their declaration, not in the order they are listed in any constructor's mem-initialiser list.
If you turn on enough warnings in your compiler, it should warn you that in the Program
constructor you've shown, settings
will be initialised after window
. Which is precisely your problem, as settings
is used before it gets the values you specified for it. Swap the order of the members in the class to resolve it.
The reason for the rule is that a fundamental C++ rule is "objects of automatic storage duration are always destroyed in the exact opposite order of their construction." A class's destructor therefore needs one order in which to destroy the members, regardless of which constructor was used to create the object. The order is therefore fixed to be that of declaration. Note that order of declaration is also used to control creation/destruction order in other contexts (such as function-local variables), so using it here is consistent.
Upvotes: 3