]> git.tdb.fi Git - libs/gl.git/blob - source/renderpass.cpp
Improve pipeline render target management
[libs/gl.git] / source / renderpass.cpp
1 #include <msp/datafile/collection.h>
2 #include <msp/strings/format.h>
3 #include "error.h"
4 #include "material.h"
5 #include "renderpass.h"
6 #include "program.h"
7 #include "programdata.h"
8 #include "texenv.h"
9 #include "texture.h"
10 #include "texture2d.h"
11 #include "texturing.h"
12
13 using namespace std;
14
15 namespace Msp {
16 namespace GL {
17
18 RenderPass::RenderPass():
19         shprog(0),
20         shdata(0),
21         material(0),
22         texturing(0)
23 { }
24
25 RenderPass::RenderPass(const RenderPass &other):
26         shprog(other.shprog),
27         shdata(other.shdata ? new ProgramData(*other.shdata) : 0),
28         material(other.material),
29         texturing(other.texturing ? new Texturing(*other.texturing) : 0),
30         tex_names(other.tex_names)
31 { }
32
33 RenderPass::~RenderPass()
34 {
35         delete texturing;
36 }
37
38 void RenderPass::set_shader_program(const Program *prog, const ProgramData *data)
39 {
40         shprog = prog;
41         shdata = data;
42         shdata.keep();
43 }
44
45 void RenderPass::set_material(const Material *mat)
46 {
47         material = mat;
48         material.keep();
49 }
50
51 void RenderPass::set_texture(unsigned index, const Texture *tex)
52 {
53         if(!texturing)
54                 texturing = new Texturing;
55
56         texturing->attach(index, *tex);
57 }
58
59 int RenderPass::get_texture_index(const string &n) const
60 {
61         map<string, unsigned>::const_iterator i = tex_names.find(n);
62         if(i==tex_names.end())
63                 return -1;
64         return i->second;
65 }
66
67
68 RenderPass::Loader::Loader(RenderPass &p):
69         DataFile::CollectionObjectLoader<RenderPass>(p, 0)
70 {
71         init();
72 }
73
74 RenderPass::Loader::Loader(RenderPass &p, Collection &c):
75         DataFile::CollectionObjectLoader<RenderPass>(p, &c)
76 {
77         init();
78 }
79
80 void RenderPass::Loader::init()
81 {
82         add("shader",   &RenderPass::shprog);
83         add("material", &Loader::material_inline);
84         add("material", &Loader::material);
85         add("texunit",  &Loader::texunit);
86         add("texunit",  &Loader::texunit_named);
87         add("uniforms", &Loader::uniforms);
88 }
89
90 void RenderPass::Loader::material_inline()
91 {
92         RefPtr<Material> mat = new Material;
93         load_sub(*mat);
94         obj.material = mat;
95 }
96
97 void RenderPass::Loader::material(const string &name)
98 {
99         obj.material = &get_collection().get<Material>(name);
100         obj.material.keep();
101 }
102
103 void RenderPass::Loader::texunit(unsigned i)
104 {
105         if(!obj.texturing)
106                 obj.texturing = new Texturing;
107         TextureLoader ldr(*obj.texturing, i, coll);
108         load_sub_with(ldr);
109 }
110
111 void RenderPass::Loader::texunit_named(unsigned i, const string &n)
112 {
113         texunit(i);
114         obj.tex_names[n] = i;
115 }
116
117 void RenderPass::Loader::uniforms()
118 {
119         if(!obj.shprog)
120                 throw invalid_operation("RenderPass::Loader::uniforms");
121         RefPtr<ProgramData> shd = new ProgramData;
122         load_sub(*shd);
123         obj.shdata = shd;
124 }
125
126
127 RenderPass::TextureLoader::TextureLoader(Texturing &t, unsigned i, Collection *c):
128         DataFile::CollectionObjectLoader<Texturing>(t, c),
129         index(i)
130 {
131         add("texture",   &TextureLoader::texture);
132         add("texture2d", &TextureLoader::texture2d);
133 }
134
135 void RenderPass::TextureLoader::finish()
136 {
137         if(tex)
138         {
139                 if(env)
140                         obj.attach(index, *tex, *env);
141                 else
142                         obj.attach(index, *tex);
143                 tex.release();
144                 env.release();
145         }
146 }
147
148 void RenderPass::TextureLoader::texenv()
149 {
150         throw runtime_error("TexEnvs can't be loaded yet");
151         /*env = new TexEnv;
152         load_sub(*env);*/
153 }
154
155 void RenderPass::TextureLoader::texture(const string &name)
156 {
157         tex = &get_collection().get<Texture>(name);
158         tex.keep();
159 }
160
161 void RenderPass::TextureLoader::texture2d()
162 {
163         tex = new Texture2D;
164         load_sub(static_cast<Texture2D &>(*tex));
165 }
166
167 } // namespace GL
168 } // namespace Msp