]> git.tdb.fi Git - libs/gl.git/blob - source/object.cpp
Support collectionless loading of Technique and RenderPass
[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         technique(0),
29         own_mesh(false),
30         own_technique(false)
31 { }
32
33 Object::~Object()
34 {
35         if(own_technique)
36                 delete technique;
37         if(own_mesh)
38                 delete meshes[0];
39 }
40
41 void Object::render(const Tag &tag) const
42 {
43         const RenderPass *pass=get_pass(tag);
44         if(!pass)
45                 return;
46
47         Bind bind(*pass);
48         meshes[0]->draw();
49 }
50
51 void Object::render(const ObjectInstance &inst, const Tag &tag) const
52 {
53         const RenderPass *pass=get_pass(tag);
54         if(!pass)
55                 return;
56
57         Bind bind(*pass);
58         render_instance(inst, tag);
59         meshes[0]->draw();
60 }
61
62 const RenderPass *Object::get_pass(const Tag &tag) const
63 {
64         if(!technique->has_pass(tag))
65                 return 0;
66         return &technique->get_pass(tag);
67 }
68
69 void Object::render_instance(const ObjectInstance &inst, const Tag &tag) const
70 {
71         inst.setup_render(tag);
72         unsigned lod=min<unsigned>(inst.get_level_of_detail(), meshes.size()-1);
73         meshes[lod]->draw();
74         inst.finish_render(tag);
75 }
76
77
78 Object::Loader::Loader(Object &o):
79         DataFile::CollectionObjectLoader<Object>(o, 0)
80 {
81         init();
82 }
83
84 Object::Loader::Loader(Object &o, Collection &c):
85         DataFile::CollectionObjectLoader<Object>(o, &c)
86 {
87         init();
88 }
89
90 void Object::Loader::init()
91 {
92         allow_pointer_reload=false;
93
94         add("lod_mesh", &Loader::lod_mesh);
95         add("mesh",     static_cast<void (Loader::*)()>(&Loader::mesh));
96         add("mesh",     static_cast<void (Loader::*)(const std::string &)>(&Loader::mesh));
97         add("technique", &Loader::technique);
98         add("technique", &Object::technique);
99 }
100
101 void Object::Loader::lod_mesh(unsigned l, const string &n)
102 {
103         obj.meshes.resize(l+1, 0);
104         obj.meshes[l]=get_collection().get<Mesh>(n);
105 }
106
107 void Object::Loader::mesh()
108 {
109         if(obj.meshes[0])
110                 throw InvalidState("A mesh is already loaded");
111
112         RefPtr<Mesh> msh=new Mesh;
113         load_sub(*msh);
114         obj.meshes[0]=msh.release();
115         obj.own_mesh=true;
116 }
117
118 void Object::Loader::mesh(const std::string &n)
119 {
120         if(obj.meshes[0])
121                 throw InvalidState("A mesh is already loaded");
122
123         obj.meshes[0]=get_collection().get<Mesh>(n);
124 }
125
126 void Object::Loader::technique()
127 {
128         RefPtr<Technique> tech=new Technique;
129         if(coll)
130                 load_sub(*tech, get_collection());
131         else
132                 load_sub(*tech);
133         obj.technique=tech.release();
134         obj.own_technique=true;
135 }
136
137 } // namespace GL
138 } // namespace Msp