]> git.tdb.fi Git - libs/gl.git/blob - source/object.cpp
Use RefPtrs in Object
[libs/gl.git] / source / object.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2007  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/datafile/collection.h>
9 #include <msp/strings/formatter.h>
10 #include "except.h"
11 #include "material.h"
12 #include "mesh.h"
13 #include "object.h"
14 #include "objectinstance.h"
15 #include "program.h"
16 #include "programdata.h"
17 #include "technique.h"
18 #include "texture.h"
19 #include "texunit.h"
20
21 using namespace std;
22
23 namespace Msp {
24 namespace GL {
25
26 Object::Object():
27         meshes(1)
28 { }
29
30 Object::~Object()
31 {
32 }
33
34 void Object::set_mesh(unsigned i, const Mesh *m)
35 {
36         if(i>meshes.size())
37                 throw InvalidParameterValue("LODs must be continuous");
38
39         if(i==meshes.size())
40                 meshes.push_back(m);
41         else
42                 meshes[i] = m;
43         meshes[i].keep();
44 }
45
46 void Object::set_technique(const Technique *t)
47 {
48         technique = t;
49         technique.keep();
50 }
51
52 void Object::render(const Tag &tag) const
53 {
54         const RenderPass *pass = get_pass(tag);
55         if(!pass)
56                 return;
57
58         Bind bind(pass);
59         meshes.front()->draw();
60 }
61
62 void Object::render(const ObjectInstance &inst, const Tag &tag) const
63 {
64         const RenderPass *pass = get_pass(tag);
65         if(!pass)
66                 return;
67
68         Bind bind(pass);
69         render_instance(inst, tag);
70 }
71
72 const RenderPass *Object::get_pass(const Tag &tag) const
73 {
74         if(!technique || !technique->has_pass(tag))
75                 return 0;
76         return &technique->get_pass(tag);
77 }
78
79 void Object::render_instance(const ObjectInstance &inst, const Tag &tag) const
80 {
81         inst.setup_render(tag);
82         unsigned lod = min<unsigned>(inst.get_level_of_detail(), meshes.size()-1);
83         meshes[lod]->draw();
84         inst.finish_render(tag);
85 }
86
87
88 Object::Loader::Loader(Object &o):
89         DataFile::CollectionObjectLoader<Object>(o, 0)
90 {
91         init();
92 }
93
94 Object::Loader::Loader(Object &o, Collection &c):
95         DataFile::CollectionObjectLoader<Object>(o, &c)
96 {
97         init();
98 }
99
100 void Object::Loader::init()
101 {
102         allow_pointer_reload = false;
103
104         add("mesh",     static_cast<void (Loader::*)()>(&Loader::mesh));
105         add("mesh",     static_cast<void (Loader::*)(unsigned)>(&Loader::mesh));
106         add("mesh",     static_cast<void (Loader::*)(const std::string &)>(&Loader::mesh));
107         add("mesh",     static_cast<void (Loader::*)(unsigned, const std::string &)>(&Loader::mesh));
108         // Deprecated alias, will be removed
109         add("lod_mesh", static_cast<void (Loader::*)(unsigned, const std::string &)>(&Loader::mesh));
110         add("technique", static_cast<void (Loader::*)()>(&Loader::technique));
111         add("technique", static_cast<void (Loader::*)(const std::string &)>(&Loader::technique));
112 }
113
114 void Object::Loader::mesh()
115 {
116         RefPtr<Mesh> msh = new Mesh;
117         load_sub(*msh);
118         obj.meshes.front() = msh;
119 }
120
121 void Object::Loader::mesh(unsigned l)
122 {
123         if(l>obj.meshes.size())
124                 throw InvalidParameterValue("LODs must be continuous");
125
126         RefPtr<Mesh> msh = new Mesh;
127         load_sub(*msh);
128         if(l==obj.meshes.size())
129                 obj.meshes.push_back(msh);
130         else
131                 obj.meshes[l] = msh;
132 }
133
134 void Object::Loader::mesh(const std::string &n)
135 {
136         obj.set_mesh(get_collection().get<Mesh>(n));
137 }
138
139 void Object::Loader::mesh(unsigned l, const string &n)
140 {
141         obj.set_mesh(l, get_collection().get<Mesh>(n));
142 }
143
144 void Object::Loader::technique()
145 {
146         RefPtr<Technique> tech = new Technique;
147         if(coll)
148                 load_sub(*tech, get_collection());
149         else
150                 load_sub(*tech);
151         obj.technique = tech;
152 }
153
154 void Object::Loader::technique(const std::string &n)
155 {
156         obj.set_technique(get_collection().get<Technique>(n));
157 }
158
159 } // namespace GL
160 } // namespace Msp