ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.C
Revision: 1.30
Committed: Thu Nov 4 03:58:32 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.29: +7 -4 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 glAttachObjectARB (id, vsh->id);
156 glAttachObjectARB (id, fsh->id);
157 }
158
159 program_object_i::~program_object_i ()
160 {
161 glDeleteProgramsARB (1, &id);
162 }
163
164 void program_object_i::link ()
165 {
166 glLinkProgramARB (id);
167
168 GLint linked;
169 glGetObjectParameterivARB (id, GL_OBJECT_LINK_STATUS_ARB, &linked);
170
171 if (!linked)
172 {
173 char infolog[8192];
174 glGetInfoLogARB (id, 8192, NULL, infolog);
175 printf ("LINK-INFOLOG<%s>\n", infolog);
176 abort ();
177 }
178
179 uloc.clear ();
180 }
181
182 void program_object_i::enable ()
183 {
184 if (this != cur)
185 {
186 glUseProgramObjectARB (id);
187 //TODO: set samplers here?
188 cur = this;
189 }
190 }
191
192 void program_object_i::disable ()
193 {
194 //TODO: clear samplers here?
195 glUseProgramObjectARB (0);
196 cur = 0;
197 }
198
199 static map<string, program_object> progcache;
200
201 program_object get_program (const string &vsh, const string &fsh)
202 {
203 string idx = vsh + "\0" + fsh;
204
205 map<string, program_object>::iterator i = progcache.find (idx);
206
207 if (i != progcache.end ())
208 return i->second;
209
210 program_object p;
211
212 p->vsh->compile (vsh);
213 p->fsh->compile (fsh);
214 p->link ();
215
216 progcache.insert (pair<string, program_object> (idx, p));
217
218 return p;
219 }
220
221 const sl_expr< sl_string<60> > sl_convert< ::vec2 >::convert (const ::vec2 &v)
222 {
223 sl_string<60> s;
224 sprintf (s.str, "vec2 (%g, %g)", v.x, v.y);
225 return s;
226 }
227
228 const sl_expr< sl_string<80> > sl_convert< ::vec3 >::convert (const ::vec3 &v)
229 {
230 sl_string<80> s;
231 sprintf (s.str, "vec3 (%g, %g, %g)", v.x, v.y, v.z);
232 return s;
233 }
234
235 const sl_expr< sl_string<100> > sl_convert< ::vec4 >::convert (const ::vec4 &v)
236 {
237 sl_string<100> s;
238 sprintf (s.str, "vec4 (%g, %g, %g, %g)", v.x, v.y, v.z, v.w);
239 return s;
240 }
241
242 shader_builder *shader_builder::cur = 0;
243
244 bool shader_builder::first (const void *p)
245 {
246 if (seen.find (p) == seen.end ())
247 {
248 seen.insert (p);
249 return true;
250 }
251
252 return false;
253 }
254
255 void shader_builder::start ()
256 {
257 cur = new shader_builder;
258 }
259
260 string shader_builder::stop ()
261 {
262 ostringstream os;
263
264 os << cur->global.str ()
265 << "\nvoid main (void)\n"
266 << "{\n"
267 << cur->local.str ()
268 << "\n"
269 << cur->code.str ()
270 << "}\n";
271
272 delete cur;
273 cur = 0;
274
275 return os.str ();
276 }
277
278 void shader_object_i::compile (const string &source)
279 {
280 const char *sptr = source.data ();
281 const int slen = source.size ();
282
283 printf ("%s\n", linify (source).c_str ());
284 glShaderSourceARB (id, 1, &sptr, &slen);
285 glCompileShaderARB (id);
286
287 GLint compiled;
288 glGetObjectParameterivARB (id, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
289
290 if (!compiled)
291 {
292 char infolog[8192];
293 glGetInfoLogARB (id, 8192, NULL, infolog);
294 printf ("%s\n", linify (source).c_str ());
295 printf ("%s\n", infolog);
296 abort ();
297 }
298 }
299
300 }
301