]> git.tdb.fi Git - libs/gl.git/commitdiff
Replace ProgramData copy constructor with a more explicit copy function
authorMikko Rasa <tdb@tdb.fi>
Sat, 13 Nov 2021 14:56:32 +0000 (16:56 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 14 Nov 2021 09:47:47 +0000 (11:47 +0200)
The copy constructor left so many members uncopied that it was rather
questionable as copy constructor.  This makes it more clear that only
uniform values are being copied.

demos/desertpillars/source/desertpillars.cpp
source/materials/rendermethod.cpp
source/materials/technique.cpp
source/render/camera.cpp
source/render/camera.h
source/render/programdata.cpp
source/render/programdata.h

index dd801e29001e117836cc2cf81745392612b39901..62a4455896300b22c9f77a3b8452ac6bf4eb26a6 100644 (file)
@@ -26,7 +26,6 @@ DesertPillars::DesertPillars(int, char **):
        keyboard(window),
        resources(&res_mgr),
        view(window),
-       camera(resources.get<GL::Camera>("Camera.camera")),
        lighting(resources.get<GL::Lighting>("Desert.lightn")),
        sphere(resources.get<GL::Object>("Sphere.object")),
        sphere_morph(0.0f),
@@ -60,6 +59,7 @@ DesertPillars::DesertPillars(int, char **):
        content.add(*env_map);
        content.add(flare);
 
+       camera.copy_parameters(resources.get<GL::Camera>("Camera.camera"));
        camera.set_debug_name("Main camera");
 
        view.set_content(sequence.get());
index 0302a9934e75ac3c3d143155a5746c522139ff13..5c838ef945624629483ea2fff992b1564285137a 100644 (file)
@@ -38,7 +38,11 @@ void RenderMethod::maybe_create_material_shader()
        shprog = material->create_compatible_shader(extra_spec);
 
        if(shdata)
-               shdata = new ProgramData(*shdata, shprog);
+       {
+               RefPtr<ProgramData> old_shdata = shdata;
+               shdata = new ProgramData(shprog);
+               shdata->copy_uniforms(*old_shdata);
+       }
 
        shprog_from_material = true;
 }
@@ -47,7 +51,13 @@ void RenderMethod::set_shader_program(const Program *prog, const ProgramData *da
 {
        shprog = prog;
        shprog_from_material = false;
-       shdata = (data ? new ProgramData(*data) : 0);
+       if(data)
+       {
+               shdata = new ProgramData;
+               shdata->copy_uniforms(*data);
+       }
+       else
+               shdata = 0;
        maybe_create_material_shader();
 }
 
@@ -194,7 +204,11 @@ void RenderMethod::Loader::shader(const string &n)
        obj.shprog = &get_collection().get<Program>(n);
        obj.shprog_from_material = false;
        if(obj.shdata)
-               obj.shdata = new ProgramData(*obj.shdata, obj.shprog);
+       {
+               RefPtr<ProgramData> old_shdata = obj.shdata;
+               obj.shdata = new ProgramData(obj.shprog);
+               obj.shdata->copy_uniforms(*old_shdata);
+       }
 }
 
 void RenderMethod::Loader::texture(const string &n)
@@ -216,7 +230,11 @@ void RenderMethod::Loader::uniforms()
        if(!obj.shdata)
                obj.shdata = new ProgramData(obj.shprog);
        else if(obj.shdata.refcount()>1)
-               obj.shdata = new ProgramData(*obj.shdata);
+       {
+               RefPtr<ProgramData> old_shdata = obj.shdata;
+               obj.shdata = new ProgramData;
+               obj.shdata->copy_uniforms(*old_shdata);
+       }
        load_sub(*obj.shdata);
 }
 
index 60eba997c05f2f0cd386039e59acd3c77bef1d45..163cbec60f0003245631fca2f503a9cdfc0cea5c 100644 (file)
@@ -79,7 +79,10 @@ bool Technique::replace_uniforms(const ProgramData &shdata)
                                continue;
 
                        if(!new_shdata)
-                               new_shdata = new ProgramData(*kvp.second.get_shader_data());
+                       {
+                               new_shdata = new ProgramData;
+                               new_shdata->copy_uniforms(*kvp.second.get_shader_data());
+                       }
 
                        new_shdata->copy_uniform(shdata, tag);
                        replaced = true;
index 8f681a74bd19d843130e8bdccea6272e5808d506..3ace92b9ecb7166de54fa20b33f07c943997dae1 100644 (file)
@@ -13,6 +13,23 @@ Camera::Camera()
        update_object_matrix();
 }
 
+void Camera::copy_parameters(const Camera &source)
+{
+       fov = source.fov;
+       height = source.height;
+       aspect = source.aspect;
+       clip_near = source.clip_near;
+       clip_far = source.clip_far;
+       frustum_x = source.frustum_x;
+       frustum_y = source.frustum_y;
+       rotate = source.rotate;
+       position = source.position;
+       look_dir = source.look_dir;
+       up_dir = source.up_dir;
+       update_projection_matrix();
+       update_object_matrix();
+}
+
 void Camera::set_field_of_view(const Geometry::Angle<float> &f)
 {
        fov = f;
index ed81a9511b3fcd9640fa4170f5adf28c23091a34..cb9b4ce19423e36cdf126303a6e0b197eeb2ff69 100644 (file)
@@ -61,6 +61,8 @@ private:
 public:
        Camera();
 
+       void copy_parameters(const Camera &);
+
        /** Sets the camera projection to perspective, characterised by the vertical
        field of view.  Horizontal FoV is computed with the aspect ratio. */
        void set_field_of_view(const Geometry::Angle<float> &);
index cfd2c0f5257b0d45d341ff15119805ea96038474..a908284b3abae9de3e8f177b8165daf084ff6eba 100644 (file)
@@ -20,46 +20,6 @@ ProgramData::ProgramData(const Program *p):
        tied_program(p)
 { }
 
-// Blocks are intentionally left uncopied
-ProgramData::ProgramData(const ProgramData &other):
-       tied_program(other.tied_program),
-       uniforms(other.uniforms),
-       uniform_data(other.uniform_data),
-       generation(other.generation)
-{ }
-
-ProgramData::ProgramData(const ProgramData &other, const Program *p):
-       tied_program(p)
-{
-       if(tied_program)
-       {
-               for(const TaggedUniform &u: other.uniforms)
-                       validate_tag(u.tag);
-       }
-
-       uniforms = other.uniforms;
-       uniform_data = other.uniform_data;
-}
-
-ProgramData &ProgramData::operator=(const ProgramData &other)
-{
-       tied_program = other.tied_program;
-
-       uniforms = other.uniforms;
-       uniform_data = other.uniform_data;
-
-       for(SharedBlock &b: blocks)
-               delete b.block;
-       blocks.clear();
-       programs.clear();
-
-       last_buffer_block = 0;
-       buffer = 0;
-       dirty = 0;
-
-       return *this;
-}
-
 ProgramData::ProgramData(ProgramData &&other):
        tied_program(other.tied_program),
        uniforms(move(other.uniforms)),
@@ -482,6 +442,12 @@ void ProgramData::copy_uniform(const ProgramData &source, Tag tag)
        uniform(tag, tu.type, tu.array_size, source.uniform_data.data()+tu.data_offset);
 }
 
+void ProgramData::copy_uniforms(const ProgramData &source)
+{
+       for(const TaggedUniform &u: source.uniforms)
+               uniform(u.tag, u.type, u.array_size, source.uniform_data.data()+u.data_offset);
+}
+
 int ProgramData::find_uniform_index(Tag tag) const
 {
        auto i = lower_bound_member(uniforms, tag, &TaggedUniform::tag);
index 53f48a6be5cefe14f5a316a78177daff6de54d4b..f1c5996eb910e3e51368571472e94e6902d12bec 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GL_PROGRAMDATA_H_
 
 #include <stdexcept>
+#include <msp/core/noncopyable.h>
 #include <msp/datafile/objectloader.h>
 #include "datatype.h"
 #include "matrix.h"
@@ -35,7 +36,7 @@ programs have the same layout, the same block is used for them.
 The class is optimized for an access pattern where the set of uniforms and
 programs stays constants, with only the values changing.
 */
-class ProgramData
+class ProgramData: public NonCopyable
 {
 public:
        class Loader: public DataFile::ObjectLoader<ProgramData>
@@ -162,9 +163,6 @@ private:
 
 public:
        ProgramData(const Program * = 0);
-       ProgramData(const ProgramData &);
-       ProgramData(const ProgramData &, const Program *);
-       ProgramData &operator=(const ProgramData &);
        ProgramData(ProgramData &&);
        ~ProgramData();
 
@@ -248,6 +246,7 @@ public:
 
        std::vector<Tag> get_uniform_tags() const;
        void copy_uniform(const ProgramData &, Tag);
+       void copy_uniforms(const ProgramData &);
 
 private:
        int find_uniform_index(Tag) const;