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),
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());
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;
}
{
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();
}
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)
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);
}
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;
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;
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> &);
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)),
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);
#define MSP_GL_PROGRAMDATA_H_
#include <stdexcept>
+#include <msp/core/noncopyable.h>
#include <msp/datafile/objectloader.h>
#include "datatype.h"
#include "matrix.h"
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>
public:
ProgramData(const Program * = 0);
- ProgramData(const ProgramData &);
- ProgramData(const ProgramData &, const Program *);
- ProgramData &operator=(const ProgramData &);
ProgramData(ProgramData &&);
~ProgramData();
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;