diff --git a/demo/data/normals_vert.glsl b/demo/data/normals_vert.glsl index 36a36b7f534169b78154ba6a7280183234f19d70..56fb7caf41884801fe46535c46872709937c791f 100644 --- a/demo/data/normals_vert.glsl +++ b/demo/data/normals_vert.glsl @@ -12,7 +12,7 @@ uniform mat4 model; void main() { - gl_Position = view * model * vec4(aPos, 1.0); + gl_Position = view * model * vec4(aPos, 1.0); mat3 normalMatrix = mat3(transpose(inverse(view * model))); vs_out.normal = normalize(vec3(vec4(normalMatrix * aNormal, 0.0))); } diff --git a/fggl/gfx/ogl/renderer.cpp b/fggl/gfx/ogl/renderer.cpp index e95da195a8e0f373a82ceb212c3f18c13120d9f7..8a9b1fe2fbfcd998e4d0d9013a8d8ef373bf9ea4 100644 --- a/fggl/gfx/ogl/renderer.cpp +++ b/fggl/gfx/ogl/renderer.cpp @@ -178,6 +178,7 @@ namespace fggl::gfx { m_cache->load(ShaderConfig::named("phong")); m_cache->load(ShaderConfig::named("redbook/lighting")); m_cache->load(ShaderConfig::named("redbook/debug")); + m_cache->load(ShaderConfig::named("normals", true)); // rendering helpers m_canvasRenderer = std::make_unique<ogl4::CanvasRenderer>(fonts); diff --git a/fggl/gfx/ogl4/models.cpp b/fggl/gfx/ogl4/models.cpp index bacdc59c38ddaf3d243e4e4563981db5192f4cdd..189ccec1b32cc1184d6aec8fd7f5628b33ecf075 100644 --- a/fggl/gfx/ogl4/models.cpp +++ b/fggl/gfx/ogl4/models.cpp @@ -282,6 +282,58 @@ namespace fggl::gfx::ogl4 { } } + static void forward_normal_pass(const entity::EntityID& camera, const fggl::entity::EntityManager& world, std::shared_ptr<ogl::Shader> shader) { + // enable required OpenGL state + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + // enable depth testing + glEnable(GL_DEPTH_TEST); + + // set-up camera matrices + const auto &camTransform = world.get<fggl::math::Transform>(camera); + const auto &camComp = world.get<fggl::gfx::Camera>(camera); + + const math::mat4 projectionMatrix = + glm::perspective(camComp.fov, camComp.aspectRatio, camComp.nearPlane, camComp.farPlane); + const math::mat4 viewMatrix = glm::lookAt(camTransform.origin(), camComp.target, camTransform.up()); + + ogl::Location modelUniform = shader->uniform("model"); + ogl::Location viewUniform = shader->uniform("view"); + ogl::Location projUniform = shader->uniform("projection"); + + shader->use(); + shader->setUniformMtx(projUniform, projectionMatrix); + shader->setUniformMtx(viewUniform, viewMatrix); + + auto renderables = world.find<StaticModel>(); + for (const auto &entity : renderables) { + + // ensure that the model pipeline actually exists... + const auto &model = world.get<StaticModel>(entity); + + // set model transform + const auto &transform = world.get<math::Transform>(entity); + shader->setUniformMtx(modelUniform, transform.model()); + + // render model + auto vao = model.vao; + vao->bind(); + + model.vertexData->bind(); + if (model.restartIndex != NO_RESTART_IDX) { + glEnable(GL_PRIMITIVE_RESTART); + glPrimitiveRestartIndex(model.restartIndex); + } + + auto *elements = model.elements.get(); + vao->drawElements(*elements, model.drawType, model.elementCount); + if (model.restartIndex != NO_RESTART_IDX) { + glDisable(GL_PRIMITIVE_RESTART); + } + } + } + void StaticModelRenderer::renderModelsForward(const entity::EntityManager &world) { // fetch cameras we will need to render with @@ -297,6 +349,11 @@ namespace fggl::gfx::ogl4 { for (const auto &cameraEnt : cameras) { //TODO should be clipping this to only visible objects forward_camera_pass(cameraEnt, world); + + // enable rendering normals + if ( m_renderNormals ) { + forward_normal_pass(cameraEnt, world, m_shaders->get("normals")); + } } } diff --git a/include/fggl/gfx/ogl4/models.hpp b/include/fggl/gfx/ogl4/models.hpp index 42241dce6de66403c6d72b3a34fe2d220f5a96e3..625f0f01a1976c5fb1057a4a0e6500f7ca87f6e2 100644 --- a/include/fggl/gfx/ogl4/models.hpp +++ b/include/fggl/gfx/ogl4/models.hpp @@ -91,6 +91,8 @@ namespace fggl::gfx::ogl4 { renderModelsForward(world); } + bool m_renderNormals = true; + private: #ifdef FGGL_ALLOW_DEFERRED_UPLOAD