1 // OpenGL Immediate Mode Transition Kit
15 triangleStrip = 0x0005,
22 static int beginCount;
23 static GLIMTKMode beginMode = unset;
24 static bool vertexColorValues = false;
25 static int numCoords = 2; // Number of coordinates per vertex
26 static int vertexOffset = 2; // Offset of vertex info
28 static struct FloatGLAB : GLAB
30 uint count; // Count of vertices
31 uint size; // Size in vertices
32 int stride; // Number of floats per vertex
34 uint bufSize; // Size in bytes of VBO
36 static inline float * ensure(uint extraVertices)
38 if(count + extraVertices >= size)
40 size = size ? (size + size/2) : Max(count + extraVertices, 6);
41 pointer = renew pointer float[size * stride];
43 return pointer + count * stride;
46 static inline void upload()
48 uint bufSize = count * stride * sizeof(float);
49 if(bufSize > this.bufSize)
51 this.bufSize = bufSize;
52 GLAB::allocate(bufSize, null, dynamicDraw);
54 GLAB::upload(0, bufSize, verticesBuf.pointer);
57 static inline void free()
67 FloatGLAB verticesBuf { stride = 4 };
68 FloatGLAB normalsBuf { stride = 3 };
70 void glimtkTerminate()
76 public void glimtkRecti(int a, int b, int c, int d)
86 public void glimtkBegin(GLIMTKMode mode)
89 vertexColorValues = false;
93 verticesBuf.count = 0;
94 verticesBuf.stride = 4;
98 public void glimtkTexCoord2f(float x, float y)
100 int stride = verticesBuf.stride;
101 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
102 float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1);
108 buf[0] = buf[-4*stride];
109 buf[1] = buf[-4*stride+1];
111 buf[0] = buf[-3*stride];
112 buf[1] = buf[-3*stride+1];
117 public void glimtkTexCoord2i(int x, int y) { glimtkTexCoord2f((float)x, (float)y); }
118 public void glimtkTexCoord2d(double x, double y) { glimtkTexCoord2f((float)x, (float)y); }
119 public void glimtkTexCoord2fv(float * a) { glimtkTexCoord2f(a[0], a[1]); }
121 public void glimtkVertex2f(float x, float y)
124 verticesBuf.stride = vertexOffset + numCoords;
126 int stride = verticesBuf.stride;
127 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
128 float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + vertexOffset;
135 buf[0] = buf[-4*stride];
136 buf[1] = buf[-4*stride+1];
138 buf[0] = buf[-3*stride];
139 buf[1] = buf[-3*stride+1];
140 verticesBuf.count+=2;
145 public void glimtkVertex2i(int x, int y) { glimtkVertex2f((float)x, (float)y); }
146 public void glimtkVertex2d(double x, double y) { glimtkVertex2f((float)x, (float)y); }
148 public void glimtkVertex3f( float x, float y, float z )
151 verticesBuf.stride = vertexOffset + numCoords;
153 int stride = verticesBuf.stride;
154 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
155 float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + vertexOffset;
163 buf[0] = buf[-4*stride];
164 buf[1] = buf[-4*stride+1];
165 buf[2] = buf[-4*stride+2];
167 buf[0] = buf[-3*stride];
168 buf[1] = buf[-3*stride+1];
169 buf[2] = buf[-3*stride+2];
170 verticesBuf.count+=2;
176 public void glimtkVertex3d( double x, double y, double z ) { glimtkVertex3f((float)x, (float)y, (float)z); }
177 public void glimtkVertex3fv( float* coords ) { glimtkVertex3f(coords[0], coords[1], coords[2]); }
178 public void glimtkVertex3dv( double* coords ) { glimtkVertex3f((float)coords[0], (float)coords[1], (float)coords[2]); }
180 public void glimtkColor4f(float r, float g, float b, float a)
182 if(beginMode != unset)
184 // Called within glBegin()/glEnd()
185 vertexColorValues = true;
187 verticesBuf.stride = vertexOffset + numCoords;
189 int stride = verticesBuf.stride;
190 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
191 float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + 2;
192 buf[0] = r, buf[1] = g, buf[2] = b, buf[3] = a;
197 buf[0] = buf[-4*stride];
198 buf[1] = buf[-4*stride+1];
199 buf[2] = buf[-4*stride+2];
200 buf[3] = buf[-4*stride+3];
202 buf[0] = buf[-3*stride];
203 buf[1] = buf[-3*stride+1];
204 buf[2] = buf[-3*stride+2];
205 buf[3] = buf[-3*stride+3];
211 #if ENABLE_GL_SHADERS
213 shader_color(r, g, b, a);
219 glColor4f(r, g, b, a);
222 float color[4] = { r, g, b, a };
223 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
224 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
231 public void glimtkColor3f( float r, float g, float b ) { glimtkColor4f(r, g, b, 1.0f); }
232 public void glimtkColor4ub(byte r, byte g, byte b, byte a) { glimtkColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f); }
233 public void glimtkColor4fv(float * a) { glimtkColor4f(a[0], a[1], a[2], a[3]); }
236 public void glimtkNormal3f(float x, float y, float z)
238 normalsBuf.count = verticesBuf.count;
240 int stride = normalsBuf.stride;
241 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
242 float * buf = normalsBuf.ensure(quadsAdd ? 3 : 1) + 2;
244 buf[0] = x, buf[1] = y, buf[2] = z;
249 buf[0] = buf[-4*stride];
250 buf[1] = buf[-4*stride+1];
251 buf[2] = buf[-4*stride+2];
253 buf[0] = buf[-3*stride];
254 buf[1] = buf[-3*stride+1];
255 buf[2] = buf[-3*stride+2];
256 normalsBuf.count += 2;
260 public void glimtkNormal3d(double x, double y, double z) { glimtkNormal3f((float)x, (float)y, (float)z); }
261 public void glimtkNormal3fv(float * coords) { glimtkNormal3f(coords[0], coords[1], coords[2]); }
262 public void glimtkNormal3fd(double * coords) { glimtkNormal3f((float)coords[0], (float)coords[1], (float)coords[2]); }
265 public void glimtkEnd()
267 GLIMTKMode mode = beginMode;
270 if(mode == quads) mode = triangles;
271 else if(mode == polygon) mode = triangleFan;
274 GLEnableClientState(TEXCOORDS);
276 if(glCaps_vertexBuffer)
278 verticesBuf.upload();
279 verticesBuf.use(texCoord, 2, GL_FLOAT, verticesBuf.stride * sizeof(float), 0);
282 noAB.use(texCoord, 2, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer);
284 if(vertexColorValues)
286 GLEnableClientState(COLORS);
287 if(glCaps_vertexBuffer)
288 verticesBuf.use(color, 4, GL_FLOAT, verticesBuf.stride * sizeof(float), (void *)(2 * sizeof(float)));
290 noAB.use(color, 4, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer + 2);
292 #if ENABLE_GL_SHADERS
294 shader_setPerVertexColor(true);
298 if(glCaps_vertexBuffer)
299 verticesBuf.use(vertex, numCoords, GL_FLOAT, verticesBuf.stride * sizeof(float), (void *)(vertexOffset * sizeof(float)));
301 noAB.use(vertex, numCoords, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer + vertexOffset);
303 if(normalsBuf.count && normalsBuf.count == verticesBuf.count)
305 GLEnableClientState(NORMALS);
306 if(glCaps_vertexBuffer)
309 normalsBuf.use(normal, 3, GL_FLOAT, 3*sizeof(float), 0);
312 noAB.use(normal, 3, GL_FLOAT, 3*sizeof(float),normalsBuf.pointer);
316 glDrawArrays(mode, 0, verticesBuf.count);
319 GLDisableClientState(NORMALS);
320 if(vertexColorValues)
322 GLDisableClientState(COLORS);
324 #if ENABLE_GL_SHADERS
326 shader_setPerVertexColor(false);
330 GLDisableClientState(TEXCOORDS);
332 normalsBuf.count = 0;
333 vertexColorValues = false;