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;
143 gldecoder_delete(decoder);
146 int GlState::decode(const char *data, unsigned len)
148 return gldecoder_decode(decoder, data, len);
151 const TextureState &GlState::get_texture(unsigned id) const
153 TextureMap::const_iterator i = textures.find(id);
154 if(i==textures.end())
155 throw runtime_error("Unknown texture");
159 const BufferState &GlState::get_buffer(unsigned id) const
161 BufferMap::const_iterator i = buffers.find(id);
163 throw runtime_error("Unknown buffer");
167 const BufferBindingState &GlState::get_buffer_binding(GLenum target, unsigned index) const
169 if(target==GL_UNIFORM_BUFFER)
170 return uniform_bind_points[index];
171 throw runtime_error("This buffer target does not have indexed binding points");
174 const ArrayState &GlState::get_array(GLenum array) const
176 if(array==GL_VERTEX_ARRAY)
178 else if(array==GL_NORMAL_ARRAY)
180 else if(array==GL_COLOR_ARRAY)
182 else if(array==GL_TEXTURE_COORD_ARRAY)
183 return texcoord_arrays[client_active_tex];
185 throw logic_error("Invalid array");
188 const ArrayState &GlState::get_texture_coord_array(unsigned index) const
190 return texcoord_arrays[index];
193 const ArrayState &GlState::get_attrib_array(unsigned index) const
195 map<unsigned, ArrayState>::const_iterator i = attrib_arrays.find(index);
196 if(i!=attrib_arrays.end())
199 // XXX Return a dummy?
200 throw runtime_error("Unknown attribute array");
203 const BufferState *GlState::get_current_buffer(GLenum target) const
205 return const_cast<GlState *>(this)->get_current_buffer(target);
208 bool &GlState::get_boolean_state(GLenum state)
210 if(state==GL_VERTEX_ARRAY)
211 return vertex_array.enabled;
212 else if(state==GL_NORMAL_ARRAY)
213 return normal_array.enabled;
214 else if(state==GL_COLOR_ARRAY)
215 return color_array.enabled;
216 else if(state==GL_TEXTURE_COORD_ARRAY)
217 return texcoord_arrays[client_active_tex].enabled;
223 TextureState *GlState::get_current_texture(GLenum target)
225 return texunits[active_tex].get_current_texture(target);
228 BufferState *GlState::get_buffer_object(unsigned id)
230 BufferMap::iterator i = buffers.find(id);
231 return (i==buffers.end() ? 0 : &i->second);
234 BufferState *GlState::get_current_buffer(GLenum target)
236 if(target==GL_ARRAY_BUFFER)
238 else if(target==GL_ELEMENT_ARRAY_BUFFER)
239 return element_buffer;
240 else if(target==GL_UNIFORM_BUFFER)
241 return uniform_buffer;
245 BufferBindingState *GlState::get_buffer_binding(GLenum target, unsigned index)
247 if(target==GL_UNIFORM_BUFFER)
248 return &uniform_bind_points[index];
252 void GlState::set_current_texture(GLenum target, unsigned id)
254 TexUnitState &unit = texunits[active_tex];
255 TextureState *tex = 0;
262 tex->target = target;
264 else if(tex->target!=target)
267 unit.set_current_texture(target, tex);
270 void GlState::set_current_buffer(GLenum target, unsigned id)
272 BufferState *buf = 0;
280 if(target==GL_ARRAY_BUFFER)
282 else if(target==GL_ELEMENT_ARRAY_BUFFER)
283 element_buffer = buf;
284 else if(target==GL_UNIFORM_BUFFER)
285 uniform_buffer = buf;
288 ArrayState &GlState::get_attrib_array(unsigned index)
290 map<unsigned, ArrayState>::iterator i = attrib_arrays.find(index);
291 if(i!=attrib_arrays.end())
294 ArrayState &array = attrib_arrays[index];
302 void GlState::glEnableClientState(void *user_data, GLenum state)
304 reinterpret_cast<GlState *>(user_data)->get_boolean_state(state) = true;
307 void GlState::glDisableClientState(void *user_data, GLenum state)
309 reinterpret_cast<GlState *>(user_data)->get_boolean_state(state) = false;
312 void GlState::glEnableVertexAttribArray(void *user_data, unsigned index)
314 reinterpret_cast<GlState *>(user_data)->attrib_arrays[index].enabled = true;
317 void GlState::glDisableVertexAttribArray(void *user_data, unsigned index)
319 reinterpret_cast<GlState *>(user_data)->attrib_arrays[index].enabled = false;
324 void GlState::glColor3f(void *user_data, float r, float g, float b)
325 { glColor4f(user_data, r, g, b, 1.0f); }
327 void GlState::glColor4f(void *user_data, float r, float g, float b, float a)
329 Vector4 &color = reinterpret_cast<GlState *>(user_data)->color;
336 void GlState::glNormal3f(void *user_data, float x, float y, float z)
338 Vector3 &normal = reinterpret_cast<GlState *>(user_data)->normal;
344 void GlState::glTexCoord1f(void *user_data, float s)
345 { glTexCoord4f(user_data, s, 0.0f, 0.0f, 1.0f); }
347 void GlState::glTexCoord2f(void *user_data, float s, float t)
348 { glTexCoord4f(user_data, s, t, 0.0f, 1.0f); }
350 void GlState::glTexCoord3f(void *user_data, float s, float t, float p)
351 { glTexCoord4f(user_data, s, t, p, 1.0f); }
353 void GlState::glTexCoord4f(void *user_data, float s, float t, float p, float q)
355 unsigned index = reinterpret_cast<GlState *>(user_data)->active_tex;
356 glMultiTexCoord4f(user_data, index, s, t, p, q);
359 void GlState::glMultiTexCoord4f(void *user_data, unsigned index, float s, float t, float p, float q)
361 Vector4 &texcoord = reinterpret_cast<GlState *>(user_data)->texcoord[index];
370 void GlState::glActiveTexture(void *user_data, unsigned index)
372 reinterpret_cast<GlState *>(user_data)->active_tex = index-GL_TEXTURE0;
375 void GlState::glBindTexture(void *user_data, GLenum target, unsigned id)
377 reinterpret_cast<GlState *>(user_data)->set_current_texture(target, id);
380 void GlState::glTexImage2D(void *user_data, GLenum target, int level, int ifmt, int width, int height, int, GLenum, GLenum, const void *)
382 if(TextureState *tex = reinterpret_cast<GlState *>(user_data)->get_current_texture(target))
383 tex->set_image_2d(level, ifmt, width, height);
386 void GlState::glTexParameteri(void *user_data, GLenum target, GLenum param, int value)
387 { glTexParameteriv(user_data, target, param, &value); }
389 void GlState::glTexParameteriv(void *user_data, GLenum target, GLenum param, const int *values)
391 if(TextureState *tex = reinterpret_cast<GlState *>(user_data)->get_current_texture(target))
392 tex->set_parameter(param, values);
395 void GlState::glDeleteTextures(void *user_data, int count, const unsigned *ids)
397 for(int i=0; i<count; ++i)
398 reinterpret_cast<GlState *>(user_data)->textures.erase(ids[i]);
403 void GlState::glVertexPointer(void *user_data, int size, GLenum type, int stride, const void *data)
405 GlState *self = reinterpret_cast<GlState *>(user_data);
406 self->vertex_array.set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
409 void GlState::glNormalPointer(void *user_data, GLenum type, int stride, const void *data)
411 GlState *self = reinterpret_cast<GlState *>(user_data);
412 self->normal_array.set(3, type, true, stride, self->array_buffer, reinterpret_cast<long>(data));
415 void GlState::glColorPointer(void *user_data, int size, GLenum type, int stride, const void *data)
417 GlState *self = reinterpret_cast<GlState *>(user_data);
418 self->color_array.set(size, type, true, stride, self->array_buffer, reinterpret_cast<long>(data));
421 void GlState::glClientActiveTexture(void *user_data, unsigned index)
423 reinterpret_cast<GlState *>(user_data)->client_active_tex = index-GL_TEXTURE0;
426 void GlState::glTexCoordPointer(void *user_data, int size, GLenum type, int stride, const void *data)
428 GlState *self = reinterpret_cast<GlState *>(user_data);
429 self->texcoord_arrays[self->client_active_tex].set(size, type, false, stride, self->array_buffer, reinterpret_cast<long>(data));
432 void GlState::glVertexAttribPointer(void *user_data, unsigned index, int size, GLenum type, unsigned char norm, int stride, const void *data)
434 GlState *self = reinterpret_cast<GlState *>(user_data);
435 self->get_attrib_array(index).set(size, type, norm, stride, self->array_buffer, reinterpret_cast<long>(data));
440 void GlState::glBindBuffer(void *user_data, GLenum target, unsigned id)
441 { reinterpret_cast<GlState *>(user_data)->set_current_buffer(target, id); }
443 void GlState::glBindBufferBase(void *user_data, GLenum target, unsigned index, unsigned id)
445 if(BufferState *buffer = reinterpret_cast<GlState *>(user_data)->get_buffer_object(id))
446 glBindBufferRange(user_data, target, index, id, 0, buffer->size);
449 void GlState::glBindBufferRange(void *user_data, GLenum target, unsigned index, unsigned id, int offset, int size)
451 GlState *self = reinterpret_cast<GlState *>(user_data);
452 if(BufferBindingState *binding = self->get_buffer_binding(target, index))
454 binding->buffer = self->get_buffer_object(id);
455 binding->offset = offset;
456 binding->size = size;
460 void GlState::glBufferData(void *user_data, GLenum target, int size, const void *data, GLenum usage)
462 if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
463 buf->set_data(size, data, usage);
466 void GlState::glBufferSubData(void *user_data, GLenum target, int offset, int size, const void *data)
468 if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->get_current_buffer(target))
469 buf->set_sub_data(offset, size, data);
472 void GlState::glDeleteBuffers(void *user_data, int count, const unsigned *ids)
474 for(int i=0; i<count; ++i)
475 reinterpret_cast<GlState *>(user_data)->buffers.erase(ids[i]);
478 void GlState::glDrawElements(void *user_data, GLenum, int, GLenum type, const void *)
480 if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
481 buf->content.update_elements(type);
484 void GlState::glDrawRangeElements(void *user_data, GLenum, unsigned, unsigned, int, GLenum type, const void *)
486 if(BufferState *buf = reinterpret_cast<GlState *>(user_data)->element_buffer)
487 buf->content.update_elements(type);