ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.C
Revision: 1.32
Committed: Wed Jan 25 22:48:02 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.31: +4 -3 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include <cassert>
2
3 #include "shader.h"
4 #include "shader_vars.h"
5
6 #include <sstream>
7 #include <iomanip>
8
9 namespace shader {
10
11 using namespace std;
12
13 refcounted::~refcounted ()
14 {
15 if (refcnt)
16 abort ();
17 }
18
19 void refcounted::refcnt_destroy () const
20 {
21 if (!--refcnt)
22 delete this; // quite a bit of code...
23 }
24
25 const char str_float [] = "float";
26 const char str_vec2 [] = "vec2";
27 const char str_vec3 [] = "vec3";
28 const char str_vec4 [] = "vec4";
29 const char str_mat2 [] = "mat2";
30 const char str_mat3 [] = "mat3";
31 const char str_mat4 [] = "mat4";
32
33 const char str_sampler_1d [] = "sampler1D";
34 const char str_sampler_1d_shadow [] = "sampler1DShadow";
35 const char str_sampler_2d [] = "sampler2D";
36 const char str_sampler_2d_shadow [] = "sampler2DShadow";
37 const char str_sampler_2d_rect [] = "sampler2DRect";
38 const char str_sampler_2d_rect_shadow [] = "sampler2DRectShadow";
39 const char str_sampler_3d [] = "sampler3D";
40 const char str_sampler_3d_rect [] = "sampler3DRect";
41 const char str_sampler_cube [] = "samplerCube";
42
43 unsigned int var_i::next_id = 0;
44
45 var_i::var_i (const char *domainstr, const char *typestr)
46 : domainstr (domainstr), typestr (typestr)
47 {
48 }
49
50 var_i::~var_i ()
51 {
52 }
53
54 #if 0
55 stream_i::stream_i (const char *strtype)
56 : var_i (strtype)
57 {
58 sprintf (name, "V%d", ++next_id);
59 }
60 #endif
61
62 temporary_i::temporary_i (const char *strtype)
63 : var_i (0, strtype)
64 {
65 sprintf (name, "T%d", ++next_id);
66 }
67
68 varying_i::varying_i (const char *strtype)
69 : var_i ("varying", strtype)
70 {
71 sprintf (name, "V%d", ++next_id);
72 }
73
74 uniform_i::uniform_i (const char *strtype)
75 : var_i ("uniform", strtype)
76 {
77 sprintf (name, "U%d", ++next_id);
78 }
79
80 ////////////////////////////////////////////////////////////////////////////
81
82 void var_i::operator ()() const
83 {
84 shader_builder::cur->code << name;
85
86 if (shader_builder::cur->first (this))
87 {
88 if (domainstr)
89 shader_builder::cur->global << domainstr << ' ' << typestr << ' ' << name << ";\n";
90 else
91 shader_builder::cur->local << " " << typestr << ' ' << name << ";\n";
92 }
93 }
94
95 ////////////////////////////////////////////////////////////////////////////
96
97 int texture_units::unit_count = 8;
98 int texture_units::units[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
99
100 shader_object_i *cur = 0;
101
102 shader_object_i::shader_object_i (GLenum type)
103 : type (type)
104 {
105 id = glCreateShaderObjectARB (type);
106 assert (id);
107 }
108
109 shader_object_i::~shader_object_i ()
110 {
111 glDeleteObjectARB (id);
112 }
113
114 static string linify (const string &s)
115 {
116 ostringstream o;
117
118 int b = 0, e;
119 int l = 1;
120 do {
121 o << setw (3) << l << ": ";
122 e = s.find ('\n', b);
123 if (e == string::npos)
124 e = s.size ();
125
126 o << s.substr (b, e - b + 1);
127 b = e + 1;
128 l++;
129 } while (b < s.size ());
130
131 return o.str ();
132 }
133
134 ////////////////////////////////////////////////////////////////////////////
135
136 GLint uniform_i::location ()
137 {
138 assert (program_object_i::cur);
139
140 GLint &rid = program_object_i::cur->uloc[this];
141
142 if (!rid)
143 rid = glGetUniformLocationARB (program_object_i::cur->id, name);
144
145 return rid;
146 }
147
148 program_object_i *program_object_i::cur;
149
150 program_object_i::program_object_i ()
151 {
152 id = glCreateProgramObjectARB ();
153 assert (id);
154 }
155
156 program_object_i::~program_object_i ()
157 {
158 glDeleteProgramsARB (1, &id);
159 }
160
161 void program_object_i::link ()
162 {
163 glLinkProgramARB (id);
164
165 GLint linked;
166 glGetObjectParameterivARB (id, GL_OBJECT_LINK_STATUS_ARB, &linked);
167
168 if (!linked)
169 {
170 char infolog[8192];
171 glGetInfoLogARB (id, 8192, NULL, infolog);
172 printf ("LINK-INFOLOG<%s>\n", infolog);
173 abort ();
174 }
175
176 uloc.clear ();
177 }
178
179 void program_object_i::enable ()
180 {
181 if (this != cur)
182 {
183 glUseProgramObjectARB (id);
184 //TODO: set samplers here?
185 cur = this;
186 }
187 }
188
189 void program_object_i::disable ()
190 {
191 //TODO: clear samplers here?
192 glUseProgramObjectARB (0);
193 cur = 0;
194 }
195
196 static map<string, program_object> progcache;
197
198 program_object get_program (const string &vsh, const string &fsh)
199 {
200 string idx = vsh + "\0" + fsh;
201
202 map<string, program_object>::iterator i = progcache.find (idx);
203
204 if (i != progcache.end ())
205 return i->second;
206
207 program_object p;
208
209 if (vsh.size ())
210 {
211 vertex_shader sh;
212 p->attach (sh);
213 sh->compile (vsh);
214 }
215
216 if (fsh.size ())
217 {
218 fragment_shader sh;
219 p->attach (sh);
220 sh->compile (fsh);
221 }
222
223 p->link ();
224
225 progcache.insert (pair<string, program_object> (idx, p));
226
227 return p;
228 }
229
230 const sl_expr< sl_string<60> > sl_convert< ::vec2 >::convert (const ::vec2 &v)
231 {
232 sl_string<60> s;
233 sprintf (s.str, "vec2 (%e, %e)", v.x, v.y);
234 return s;
235 }
236
237 const sl_expr< sl_string<80> > sl_convert< ::vec3 >::convert (const ::vec3 &v)
238 {
239 sl_string<80> s;
240 sprintf (s.str, "vec3 (%e, %e, %e)", v.x, v.y, v.z);
241 return s;
242 }
243
244 const sl_expr< sl_string<100> > sl_convert< ::vec4 >::convert (const ::vec4 &v)
245 {
246 sl_string<100> s;
247 sprintf (s.str, "vec4 (%e, %e, %e, %e)", v.x, v.y, v.z, v.w);
248 return s;
249 }
250
251 shader_builder *shader_builder::cur = 0;
252
253 bool shader_builder::first (const void *p)
254 {
255 if (seen.find (p) == seen.end ())
256 {
257 seen.insert (p);
258 return true;
259 }
260
261 return false;
262 }
263
264 void shader_builder::start ()
265 {
266 cur = new shader_builder;
267 cur->code << scientific;
268 }
269
270 string shader_builder::stop ()
271 {
272 ostringstream os;
273
274 os << cur->global.str ()
275 << "\nvoid main (void)\n"
276 << "{\n"
277 << cur->local.str ()
278 << "\n"
279 << cur->code.str ()
280 << "}\n";
281
282 delete cur;
283 cur = 0;
284
285 return os.str ();
286 }
287
288 void shader_object_i::compile (const string &source)
289 {
290 const char *sptr = source.data ();
291 const int slen = source.size ();
292
293 printf ("%s\n", linify (source).c_str ());
294 glShaderSourceARB (id, 1, &sptr, &slen);
295 glCompileShaderARB (id);
296
297 GLint compiled;
298 glGetObjectParameterivARB (id, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
299
300 if (!compiled)
301 {
302 char infolog[8192];
303 glGetInfoLogARB (id, 8192, NULL, infolog);
304 printf ("%s\n", linify (source).c_str ());
305 printf ("%s\n", infolog);
306 abort ();
307 }
308 }
309
310 }
311