12 float normalize<GLubyte>(GLubyte v)
16 float normalize<GLbyte>(GLbyte v)
17 { return (2*v+1)/255.0f; }
19 template<typename T, void (*func)(void *, float)>
20 void wrap_normalized(void *user_data, T v0)
21 { func(user_data, v0); }
23 template<typename T, void (*func)(void *, float, float)>
24 void wrap_normalized(void *user_data, T v0, T v1)
25 { func(user_data, v0, v1); }
27 template<typename T, void (*func)(void *, float, float, float)>
28 void wrap_normalized(void *user_data, T v0, T v1, T v2)
29 { func(user_data, v0, v1, v2); }
31 template<typename T, void (*func)(void *, float, float, float, float)>
32 void wrap_normalized(void *user_data, T v0, T v1, T v2, T v3)
33 { func(user_data, v0, v1, v2, v3); }
35 template<typename T, void (*func)(void *, T)>
36 void wrap_array(void *user_data, const T *v)
37 { func(user_data, v[0]); }
39 template<typename T, void (*func)(void *, T, T)>
40 void wrap_array(void *user_data, const T *v)
41 { func(user_data, v[0], v[1]); }
43 template<typename T, void (*func)(void *, T, T, T)>
44 void wrap_array(void *user_data, const T *v)
45 { func(user_data, v[0], v[1], v[2]); }
47 template<typename T, void (*func)(void *, T, T, T, T)>
48 void wrap_array(void *user_data, const T *v)
49 { func(user_data, v[0], v[1], v[2], v[3]); }
60 x(0), y(0), z(0), w(1)
65 decoder(gldecoder_new(this, NULL)),
71 uniform_bind_points(64)
73 vertex_array.kind = GL_VERTEX_ARRAY;
74 normal_array.kind = GL_NORMAL_ARRAY;
75 color_array.kind = GL_COLOR_ARRAY;
76 for(unsigned i=0; i<8; ++i)
78 texcoord_arrays[i].kind = GL_TEXTURE_COORD_ARRAY;
79 texcoord_arrays[i].index = i;
82 decoder->glEnableClientState = glEnableClientState;
83 decoder->glDisableClientState = glDisableClientState;
84 decoder->glEnableVertexAttribArray = glEnableVertexAttribArray;
85 decoder->glEnableVertexAttribArrayARB = glEnableVertexAttribArray;
86 decoder->glDisableVertexAttribArray = glDisableVertexAttribArray;
87 decoder->glDisableVertexAttribArrayARB = glDisableVertexAttribArray;
89 decoder->glColor3ub = wrap_normalized<GLubyte, glColor3f>;
90 decoder->glColor3ubv = wrap_array<GLubyte, wrap_normalized<GLubyte, glColor3f> >;
91 decoder->glColor4ub = wrap_normalized<GLubyte, glColor4f>;
92 decoder->glColor4ubv = wrap_array<GLubyte, wrap_normalized<GLubyte, glColor4f> >;
93 decoder->glColor3f = glColor3f;
94 decoder->glColor3fv = wrap_array<float, glColor3f>;
95 decoder->glColor4f = glColor4f;
96 decoder->glColor4fv = wrap_array<float, glColor4f>;
97 decoder->glTexCoord1f = glTexCoord1f;
98 decoder->glTexCoord1fv = wrap_array<float, glTexCoord1f>;
99 decoder->glTexCoord2f = glTexCoord2f;
100 decoder->glTexCoord2fv = wrap_array<float, glTexCoord2f>;
101 decoder->glTexCoord3f = glTexCoord3f;
102 decoder->glTexCoord3fv = wrap_array<float, glTexCoord3f>;
103 decoder->glTexCoord4f = glTexCoord4f;
104 decoder->glTexCoord4fv = wrap_array<float, glTexCoord4f>;
105 decoder->glNormal3f = glNormal3f;
106 decoder->glNormal3fv = wrap_array<float, glNormal3f>;
108 decoder->glActiveTexture = glActiveTexture;
109 decoder->glActiveTextureARB = glActiveTexture;
110 decoder->glBindTexture = glBindTexture;
111 decoder->glTexImage2D = glTexImage2D;
112 decoder->glTexParameteri = glTexParameteri;
113 decoder->glTexParameteriv = glTexParameteriv;
114 decoder->glDeleteTextures = glDeleteTextures;
116 decoder->glVertexPointer = glVertexPointer;
117 decoder->glNormalPointer = glNormalPointer;
118 decoder->glColorPointer = glColorPointer;
119 decoder->glClientActiveTexture = glClientActiveTexture;
120 decoder->glClientActiveTextureARB = glClientActiveTexture;
121 decoder->glTexCoordPointer = glTexCoordPointer;
122 decoder->glVertexAttribPointer = glVertexAttribPointer;
123 decoder->glVertexAttribPointerARB = glVertexAttribPointer;
125 decoder->glBindBuffer = glBindBuffer;
126 decoder->glBindBufferARB = glBindBuffer;
127 decoder->glBindBufferBase = glBindBufferBase;
128 decoder->glBindBufferRange = glBindBufferRange;
129 decoder->glBufferData = glBufferData;
130 decoder->glBufferDataARB = glBufferData;
131 decoder->glBufferSubData = glBufferSubData;
132 decoder->glBufferSubDataARB = glBufferSubData;
133 decoder->glDeleteBuffers = glDeleteBuffers;
134 decoder->glDeleteBuffersARB = glDeleteBuffers;
136 decoder->glDrawElements = glDrawElements;
137 decoder->glDrawRangeElements = glDrawRangeElements;
138 decoder->glDrawRangeElementsEXT = glDrawRangeElements;
140 decoder->glCreateShader = glCreateShader;
141 decoder->glCreateShaderObjectARB = glCreateShader;
142 decoder->glShaderSource = glShaderSource;
143 decoder->glShaderSourceARB = glShaderSource;
144 decoder->glCompileShader = glCompileShader;
145 decoder->glCompileShaderARB = glCompileShader;
146 decoder->glGetShaderiv = glGetShaderiv;
147 decoder->glGetShaderInfoLog = glGetShaderInfoLog;
148 decoder->glDeleteShader = glDeleteShader;
149 decoder->glCreateProgram = glCreateProgram;
150 decoder->glCreateProgramObjectARB = glCreateProgram;
151 decoder->glAttachShader = glAttachShader;
152 decoder->glAttachObjectARB = glAttachShader;
153 decoder->glLinkProgram = glLinkProgram;
154 decoder->glLinkProgramARB = glLinkProgram;
155 decoder->glGetProgramiv = glGetProgramiv;
156 decoder->glGetProgramInfoLog = glGetProgramInfoLog;
157 decoder->glDeleteObjectARB = glDeleteObjectARB;
158 decoder->glGetObjectParameterivARB = glGetObjectParameterivARB;
159 decoder->glGetInfoLogARB = glGetInfoLogARB;
164 gldecoder_delete(decoder);
167 int GlState::decode(const char *data, unsigned len)
169 return gldecoder_decode(decoder, data, len);
172 const TextureState &GlState::get_texture(unsigned id) const
174 TextureMap::const_iterator i = textures.find(id);
175 if(i==textures.end())
176 throw runtime_error("Unknown texture");
180 const BufferState &GlState::get_buffer(unsigned id) const
182 BufferMap::const_iterator i = buffers.find(id);
184 throw runtime_error("Unknown buffer");
188 const BufferBindingState &GlState::get_buffer_binding(GLenum target, unsigned index) const
190 if(target==GL_UNIFORM_BUFFER)
191 return uniform_bind_points[index];
192 throw runtime_error("This buffer target does not have indexed binding points");
195 const ArrayState &GlState::get_array(GLenum array) const
197 if(array==GL_VERTEX_ARRAY)
199 else if(array==GL_NORMAL_ARRAY)
201 else if(array==GL_COLOR_ARRAY)
203 else if(array==GL_TEXTURE_COORD_ARRAY)
204 return texcoord_arrays[client_active_tex];
206 throw logic_error("Invalid array");
209 const ArrayState &GlState::get_texture_coord_array(unsigned index) const
211 return texcoord_arrays[index];
214 const ArrayState &GlState::get_attrib_array(unsigned index) const
216 map<unsigned, ArrayState>::const_iterator i = attrib_arrays.find(index);
217 if(i!=attrib_arrays.end())
220 // XXX Return a dummy?
221 throw runtime_error("Unknown attribute array");
224 const ShaderState &GlState::get_shader(unsigned id) const
226 ShaderMap::const_iterator i = shaders.find(id);
228 throw runtime_error("Unknown shader");
232 const ProgramState &GlState::get_program(unsigned id) const
234 ProgramMap::const_iterator i = programs.find(id);
235 if(i==programs.end())
236 throw runtime_error("Unknown program");
240 const BufferState *GlState::get_current_buffer(GLenum target) const
242 return const_cast<GlState *>(this)->get_current_buffer(target);
245 bool &GlState::get_boolean_state(GLenum state)
247 if(state==GL_VERTEX_ARRAY)
248 return vertex_array.enabled;
249 else if(state==GL_NORMAL_ARRAY)
250 return normal_array.enabled;
251 else if(state==GL_COLOR_ARRAY)
252 return color_array.enabled;
253 else if(state==GL_TEXTURE_COORD_ARRAY)
254 return texcoord_arrays[client_active_tex].enabled;
260 TextureState *GlState::get_current_texture(GLenum target)
262 return texunits[active_tex].get_current_texture(target);
265 BufferState *GlState::get_buffer_object(unsigned id)
267 BufferMap::iterator i = buffers.find(id);
268 return (i==buffers.end() ? 0 : &i->second);
271 BufferState *GlState::get_current_buffer(GLenum target)
273 if(target==GL_ARRAY_BUFFER)
275 else if(target==GL_ELEMENT_ARRAY_BUFFER)
276 return element_buffer;
277 else if(target==GL_UNIFORM_BUFFER)
278 return uniform_buffer;
282 BufferBindingState *GlState::get_buffer_binding(GLenum target, unsigned index)
284 if(target==GL_UNIFORM_BUFFER)
285 return &uniform_bind_points[index];
289 void GlState::set_current_texture(GLenum target, unsigned id)
291 TexUnitState &unit = texunits[active_tex];
292 TextureState *tex = 0;
299 tex->target = target;
301 else if(tex->target!=target)
304 unit.set_current_texture(target, tex);
307 void GlState::set_current_buffer(GLenum target, unsigned id)
309 BufferState *buf = 0;
317 if(target==GL_ARRAY_BUFFER)
319 else if(target==GL_ELEMENT_ARRAY_BUFFER)
320 element_buffer = buf;
321 else if(target==GL_UNIFORM_BUFFER)
322 uniform_buffer = buf;
325 ArrayState &GlState::get_attrib_array(unsigned index)
327 map<unsigned, ArrayState>::iterator i = attrib_arrays.find(index);
328 if(i!=attrib_arrays.end())
331 ArrayState &array = attrib_arrays[index];
337 ShaderState *GlState::get_shader(unsigned id, bool create)
339 ShaderMap::iterator i = shaders.find(id);
340 if(i==shaders.end() && create)
342 i = shaders.insert(ShaderMap::value_type(id, ShaderState())).first;
345 return (i!=shaders.end() ? &i->second : 0);
348 void GlState::delete_shader(unsigned id)
350 ShaderMap::iterator i = shaders.find(id);
354 for(ProgramMap::const_iterator j=programs.begin(); j!=programs.end(); ++j)
356 const vector<ShaderState *> &prog_shaders = j->second.shaders;
357 for(vector<ShaderState *>::const_iterator k=prog_shaders.begin(); k!=prog_shaders.end(); ++k)
360 i->second.pending_delete = true;
368 void GlState::delete_program(unsigned id)
370 ProgramMap::iterator i = programs.find(id);
371 if(i==programs.end())
374 vector<ShaderState *> prog_shaders = i->second.shaders;
376 for(vector<ShaderState *>::const_iterator j=prog_shaders.begin(); j!=prog_shaders.end(); ++j)
377 if((*j)->pending_delete)
378 delete_shader((*j)->id);
381 ProgramState *GlState::get_program(unsigned id, bool create)
383 ProgramMap::iterator i = programs.find(id);
384 if(i==programs.end() && create)
386 i = programs.insert(ProgramMap::value_type(id, ProgramState())).first;
389 return (i!=programs.end() ? &i->second : 0);
394 void GlState::glEnableClientState(void *user_data, GLenum state)
396 reinterpret_cast<GlState *>(user_data)->get_boolean_state(state) = true;
399 void GlState::glDisableClientState(void *user_data, GLenum state)
401 reinterpret_cast<GlState *>(user_data)->get_boolean_state(state) = false;
404 void GlState::glEnableVertexAttribArray(void *user_data, unsigned index)
406 reinterpret_cast<GlState *>(user_data)->attrib_arrays[index].enabled = true;
409 void GlState::glDisableVertexAttribArray(void *user_data, unsigned index)
411 reinterpret_cast<GlState *>(user_data)->attrib_arrays[index].enabled = false;
416 void GlState::glColor3f(void *user_data, float r, float g, float b)
417 { glColor4f(user_data, r, g, b, 1.0f); }
419 void GlState::glColor4f(void *user_data, float r, float g, float b, float a)
421 Vector4 &color = reinterpret_cast<GlState *>(user_data)->color;
428 void GlState::glNormal3f(void *user_data, float x, float y, float z)
430 Vector3 &normal = reinterpret_cast<GlState *>(user_data)->normal;
436 void GlState::glTexCoord1f(void *user_data, float s)
437 { glTexCoord4f(user_data, s, 0.0f, 0.0f, 1.0f); }
439 void GlState::glTexCoord2f(void *user_data, float s, float t)
440 { glTexCoord4f(user_data, s, t, 0.0f, 1.0f); }
442 void GlState::glTexCoord3f(void *user_data, float s, float t, float p)
443 { glTexCoord4f(user_data, s, t, p, 1.0f); }
445 void GlState::glTexCoord4f(void *user_data, float s, float t, float p, float q)
447 unsigned index = reinterpret_cast<GlState *>(user_data)->active_tex;
448 glMultiTexCoord4f(user_data, index, s, t, p, q);
451 void GlState::glMultiTexCoord4f(void *user_data, unsigned index, float s, float t, float p, float q)
453 Vector4 &texcoord = reinterpret_cast<GlState *>(user_data)->texcoord[index];
462 void GlState::glActiveTexture(void *user_data, unsigned index)
464 reinterpret_cast<GlState *>(user_data)->active_tex = index-GL_TEXTURE0;
467 void GlState::glBindTexture(void *user_data, GLenum target, unsigned id)
469 reinterpret_cast<GlState *>(user_data)->set_current_texture(target, id);
472 void GlState::glTexImage2D(void *user_data, GLenum target, int level, int ifmt, int width, int height, int, GLenum, GLenum, const void *)
474 if(TextureState *tex = reinterpret_cast<GlState *>(user_data)->get_current_texture(target))
475 tex->set_image_2d(level, ifmt, width, height);
478 void GlState::glTexParameteri(void *user_data, GLenum target, GLenum param, int value)
479 { glTexParameteriv(user_data, target, param, &value); }
481 void GlState::glTexParameteriv(void *user_data, GLenum target, GLenum param, const int *values)
483 if(TextureState *tex = reinterpret_cast<GlState *>(user_data)->get_current_texture(target))
484 tex->set_parameter(param, values);
487 void GlState::glDeleteTextures(void *user_data, int count, const unsigned *ids)
489 for(int i=0; i<count; ++i)
490 reinterpret_cast<GlState *>(user_data)->textures.erase(ids[i]);
495 void GlState::glVertexPointer(void *user_data, int size, GLenum type, int stride, const void *data)
497 GlState *self = reinterpret_cast<GlState *>(user_data);
498 self->vertex_array.set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
501 void GlState::glNormalPointer(void *user_data, GLenum type, int stride, const void *data)
503 GlState *self = reinterpret_cast<GlState *>(user_data);
504 self->normal_array.set(3, type, true, stride, self->array_buffer, reinterpret_cast<long>(data));
507 void GlState::glColorPointer(void *user_data, int size, GLenum type, int stride, const void *data)
509 GlState *self = reinterpret_cast<GlState *>(user_data);
510 self->color_array.set(size, type, true, stride, self->array_buffer, reinterpret_cast<long>(data));
513 void GlState::glClientActiveTexture(void *user_data, unsigned index)
515 reinterpret_cast<GlState *>(user_data)->client_active_tex = index-GL_TEXTURE0;
518 void GlState::glTexCoordPointer(void *user_data, int size, GLenum type, int stride, const void *data)
520 GlState *self = reinterpret_cast<GlState *>(user_data);
521 self->texcoord_arrays[self->client_active_tex].set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
524 void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, unsigned char norm, int stride, const void *data)
526 GlState *self = reinterpret_cast<GlState *>(user_data);
527 self->get_attrib_array(index).set(size, type, norm, stride, self->array_buffer, reinterpret_cast<long>(data));
532 void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id)
533 { reinterpret_cast<GlState *>(user_data)->set_current_buffer(target, id); }
535 void GlState::glBindBufferBase(void *user_data, GLenum target, unsigned index, unsigned id)
537 if(BufferState *buffer = reinterpret_cast<GlState *>(user_data)->get_buffer_object(id))
538 glBindBufferRange(user_data, target, index, id, 0, buffer->size);
541 void GlState::glBindBufferRange(void *user_data, GLenum target, unsigned index, unsigned id, int offset, int size)
543 GlState *self = reinterpret_cast<GlState *>(user_data);
544 if(BufferBindingState *binding = self->get_buffer_binding(target, index))
546 binding->buffer = self->get_buffer_object(id);
547 binding->offset = offset;
548 binding->size = size;
552 void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage)
554 if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
555 buf->set_data(size, data, usage);
558 void GlState::glBufferSubData(void *user_data, GLenum target, int offset, int size, const void *data)
560 if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
561 buf->set_sub_data(offset, size, data);
564 void GlState::glDeleteBuffers(void *user_data, int count, const unsigned *ids)
566 for(int i=0; i<count; ++i)
567 reinterpret_cast<GlState *>(user_data)->buffers.erase(ids[i]);
570 void GlState::glDrawElements(void *user_data, GLenum, int, GLenum type, const void *)
572 if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
573 buf->content.update_elements(type);
576 void GlState::glDrawRangeElements(void *user_data, GLenum, unsigned, unsigned, int, GLenum type, const void *)
578 if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
579 buf->content.update_elements(type);
584 void GlState::glCreateShader(void *user_data, unsigned id, GLenum type)
586 if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, true))
590 void GlState::glShaderSource(void *user_data, unsigned id, int count, const char **str, const int *length)
592 if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, false))
594 shader->source.clear();
595 for(int i=0; i<count; ++i)
597 if(!length || length[i]<0)
598 shader->source.push_back(str[i]);
600 shader->source.push_back(string(str[i], length[i]));
602 shader->source_changed = true;
606 void GlState::glCompileShader(void *user_data, unsigned id)
608 if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, false))
609 shader->source_changed = false;
612 void GlState::glGetShaderiv(void *user_data, unsigned id, GLenum pname, int *param)
614 if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, false))
616 if(pname==GL_COMPILE_STATUS)
617 shader->compile_status = *param;
621 void GlState::glGetShaderInfoLog(void *user_data, unsigned id, int, int *, char *log)
623 if(ShaderState *shader = reinterpret_cast<GlState *>(user_data)->get_shader(id, false))
624 shader->info_log = log;
627 void GlState::glDeleteShader(void *user_data, unsigned id)
629 reinterpret_cast<GlState *>(user_data)->delete_shader(id);
632 void GlState::glCreateProgram(void *user_data, unsigned id)
634 reinterpret_cast<GlState *>(user_data)->get_program(id, true);
637 void GlState::glAttachShader(void *user_data, unsigned prog_id, unsigned shader_id)
639 GlState *self = reinterpret_cast<GlState *>(user_data);
640 if(ProgramState *prog = self->get_program(prog_id, false))
641 if(ShaderState *shader = self->get_shader(shader_id, false))
642 prog->shaders.push_back(shader);
645 void GlState::glLinkProgram(void *user_data, unsigned id)
647 if(ProgramState *program = reinterpret_cast<GlState *>(user_data)->get_program(id, false))
648 program->shaders_changed = false;
651 void GlState::glGetProgramiv(void *user_data, unsigned id, GLenum pname, int *param)
653 if(ProgramState *program = reinterpret_cast<GlState *>(user_data)->get_program(id, false))
655 if(pname==GL_LINK_STATUS)
656 program->link_status = *param;
660 void GlState::glGetProgramInfoLog(void *user_data, unsigned id, int, int *, char *log)
662 if(ProgramState *program = reinterpret_cast<GlState *>(user_data)->get_program(id, false))
663 program->info_log = log;
666 void GlState::glDeleteProgram(void *user_data, unsigned id)
668 reinterpret_cast<GlState *>(user_data)->delete_program(id);
671 void GlState::glDeleteObjectARB(void *user_data, unsigned id)
673 GlState *self = reinterpret_cast<GlState *>(user_data);
674 if(self->shaders.count(id))
675 self->delete_shader(id);
676 else if(self->programs.count(id))
677 self->delete_program(id);
680 void GlState::glGetObjectParameterivARB(void *user_data, unsigned id, GLenum pname, int *param)
682 GlState *self = reinterpret_cast<GlState *>(user_data);
683 if(self->shaders.count(id))
684 glGetShaderiv(user_data, id, pname, param);
685 else if(self->programs.count(id))
686 glGetProgramiv(user_data, id, pname, param);
689 void GlState::glGetInfoLogARB(void *user_data, unsigned id, int bufsize, int *length, char *log)
691 GlState *self = reinterpret_cast<GlState *>(user_data);
692 if(self->shaders.count(id))
693 glGetShaderInfoLog(user_data, id, bufsize, length, log);
694 else if(self->programs.count(id))
695 glGetProgramInfoLog(user_data, id, bufsize, length, log);