]> git.tdb.fi Git - libs/gl.git/commitdiff
Use persistent cameras in effects
authorMikko Rasa <tdb@tdb.fi>
Sun, 18 Apr 2021 07:23:04 +0000 (10:23 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 18 Apr 2021 07:23:04 +0000 (10:23 +0300)
This allows implementing per-camera caching of culling and sorting in
scenes, and is also required for some Vulkan-related things.

source/effects/environmentmap.cpp
source/effects/environmentmap.h
source/effects/shadowmap.cpp
source/effects/shadowmap.h

index 1448c49cfd844165770b5c330b2091f1b437ef49..d9812c49bc0943d508b2f50ee4b5348c8dcd3fde 100644 (file)
@@ -23,19 +23,22 @@ EnvironmentMap::EnvironmentMap(Resources &resources, unsigned s, Renderable &r,
        depth_buf.storage(DEPTH_COMPONENT32F, size, size);
        for(unsigned i=0; i<6; ++i)
        {
-               fbo[i].attach(COLOR_ATTACHMENT0, env_tex, TextureCube::enumerate_faces(i), 0);
-               fbo[i].attach(DEPTH_ATTACHMENT, depth_buf);
-               fbo[i].require_complete();
+               TextureCubeFace face = TextureCube::enumerate_faces(i);
+               faces[i].fbo.attach(COLOR_ATTACHMENT0, env_tex, face, 0);
+               faces[i].fbo.attach(DEPTH_ATTACHMENT, depth_buf);
+               faces[i].fbo.require_complete();
+               faces[i].camera.set_look_direction(TextureCube::get_face_direction(face));
+               faces[i].camera.set_up_direction(TextureCube::get_t_direction(face));
+               faces[i].camera.set_field_of_view(Geometry::Angle<float>::right());
+               faces[i].camera.set_aspect_ratio(1);
+               faces[i].camera.set_depth_clip(0.1, 100);
        }
-
-       camera.set_field_of_view(Geometry::Angle<float>::right());
-       camera.set_aspect_ratio(1);
-       camera.set_depth_clip(0.1, 100);
 }
 
 void EnvironmentMap::set_depth_clip(float n, float f)
 {
-       camera.set_depth_clip(n, f);
+       for(unsigned i=0; i<6; ++i)
+               faces[i].camera.set_depth_clip(n, f);
 }
 
 void EnvironmentMap::set_update_interval(unsigned i)
@@ -74,17 +77,15 @@ void EnvironmentMap::setup_frame(Renderer &renderer)
        Renderer::Exclude exclude1(renderer, renderable);
        Renderer::Exclude exclude2(renderer, *this);
 
-       camera.set_position(matrix->column(3).slice<3>(0));
+       Vector3 center = matrix->column(3).slice<3>(0);
 
-       BindRestore bind_fbo(fbo[0]);
+       BindRestore bind_fbo(faces[0].fbo);
        for(unsigned i=0; i<6; ++i)
        {
-               TextureCubeFace face = TextureCube::enumerate_faces(i);
-               fbo[i].bind();
-               fbo[i].clear();
-               camera.set_look_direction(TextureCube::get_face_direction(face));
-               camera.set_up_direction(TextureCube::get_t_direction(face));
-               renderer.set_camera(camera);
+               faces[i].camera.set_position(center);
+               faces[i].fbo.bind();
+               faces[i].fbo.clear();
+               renderer.set_camera(faces[i].camera);
                renderer.render(environment);
        }
 }
index a13bea3faeeea6eaea41e1d594700c48437a16b1..56c76c459f2b6d84811fb52aeea9cea3c16a4587 100644 (file)
@@ -27,13 +27,18 @@ environment.
 class EnvironmentMap: public Effect
 {
 private:
+       struct Face
+       {
+               Framebuffer fbo;
+               Camera camera;
+       };
+
        unsigned size;
        Renderable &environment;
        TextureCube env_tex;
        Renderbuffer depth_buf;
-       Framebuffer fbo[6];
+       Face faces[6];
        const Sampler &sampler;
-       Camera camera;
        mutable ProgramData shdata;
        bool rendered;
        unsigned update_interval;
index 41a97f806b1da20480374f98fe99ac2e1071ed7a..0af9327132cf88c8222b31e11d2846329219f605 100644 (file)
@@ -59,15 +59,14 @@ void ShadowMap::setup_frame(Renderer &renderer)
        rendered = true;
        renderable.setup_frame(renderer);
 
-       Camera camera;
-       camera.set_object_matrix(*light.get_matrix());
-       camera.set_position(target);
+       shadow_camera.set_object_matrix(*light.get_matrix());
+       shadow_camera.set_position(target);
        // TODO support point and spot lights with a frustum projection.
        // Omnidirectional lights also need a cube shadow map.
-       camera.set_orthographic(radius*2, radius*2);
-       camera.set_depth_clip(-radius, radius);
+       shadow_camera.set_orthographic(radius*2, radius*2);
+       shadow_camera.set_depth_clip(-radius, radius);
 
-       shadow_matrix = camera.get_object_matrix();
+       shadow_matrix = shadow_camera.get_object_matrix();
        shadow_matrix.scale(radius*2, radius*2, -radius*2);
        shadow_matrix.translate(-0.5, -0.5, depth_bias/size-0.5);
        shadow_matrix.invert();
@@ -77,7 +76,7 @@ void ShadowMap::setup_frame(Renderer &renderer)
        fbo.clear(DEPTH_BUFFER_BIT);
 
        Renderer::Push push(renderer);
-       renderer.set_camera(camera);
+       renderer.set_camera(shadow_camera);
 
        renderer.render(renderable, "shadow");
 }
index 9fc0f4497ac1f160d18062c54bcdf616f80dd99c..d7b4eef970160f34503bb51ed23096991a4035f7 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_GL_SHADOWMAP_H_
 #define MSP_GL_SHADOWMAP_H_
 
+#include "camera.h"
 #include "effect.h"
 #include "framebuffer.h"
 #include "programdata.h"
@@ -25,6 +26,7 @@ private:
        unsigned size;
        const Light &light;
        Framebuffer fbo;
+       Camera shadow_camera;
        Matrix shadow_matrix;
        Texture2D depth_buf;
        const Sampler &sampler;