1 // OpenGL Immediate Mode Transition Kit
7 namespace gfx::drivers;
17 triangleStrip = 0x0005,
24 static int beginCount;
25 static GLIMTKMode beginMode = unset;
26 static bool vertexColorValues = false;
27 static int numCoords = 2; // Number of coordinates per vertex
28 static int vertexOffset = 2; // Offset of vertex info
30 static struct FloatGLAB : GLAB
32 uint count; // Count of vertices
33 uint size; // Size in vertices
34 int stride; // Number of floats per vertex
36 uint bufSize; // Size in bytes of VBO
38 static inline float * ensure(uint extraVertices)
40 if(count + extraVertices >= size)
42 size = size ? (size + size/2) : Max(count + extraVertices, 6);
43 pointer = renew pointer float[size * stride];
45 return pointer + count * stride;
48 static inline void upload()
50 uint bufSize = count * stride * sizeof(float);
51 if(bufSize > this.bufSize)
53 this.bufSize = bufSize;
54 GLAB::allocate(bufSize, null, dynamicDraw);
56 GLAB::upload(0, bufSize, verticesBuf.pointer);
59 static inline void free()
69 FloatGLAB verticesBuf { stride = 4 };
70 FloatGLAB normalsBuf { stride = 3 };
72 void glimtkTerminate()
78 public void glimtkRecti(int a, int b, int c, int d)
88 public void glimtkBegin(GLIMTKMode mode)
91 vertexColorValues = false;
95 verticesBuf.count = 0;
96 verticesBuf.stride = 4;
100 public void glimtkTexCoord2f(float x, float y)
102 int stride = verticesBuf.stride;
103 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
104 float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1);
110 buf[0] = buf[-4*stride];
111 buf[1] = buf[-4*stride+1];
113 buf[0] = buf[-3*stride];
114 buf[1] = buf[-3*stride+1];
119 public void glimtkTexCoord2i(int x, int y) { glimtkTexCoord2f((float)x, (float)y); }
120 public void glimtkTexCoord2d(double x, double y) { glimtkTexCoord2f((float)x, (float)y); }
121 public void glimtkTexCoord2fv(float * a) { glimtkTexCoord2f(a[0], a[1]); }
123 public void glimtkVertex2f(float x, float y)
126 verticesBuf.stride = vertexOffset + numCoords;
128 int stride = verticesBuf.stride;
129 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
130 float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + vertexOffset;
137 buf[0] = buf[-4*stride];
138 buf[1] = buf[-4*stride+1];
140 buf[0] = buf[-3*stride];
141 buf[1] = buf[-3*stride+1];
142 verticesBuf.count+=2;
147 public void glimtkVertex2i(int x, int y) { glimtkVertex2f((float)x, (float)y); }
148 public void glimtkVertex2d(double x, double y) { glimtkVertex2f((float)x, (float)y); }
150 public void glimtkVertex3f( float x, float y, float z )
153 verticesBuf.stride = vertexOffset + numCoords;
155 int stride = verticesBuf.stride;
156 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
157 float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + vertexOffset;
165 buf[0] = buf[-4*stride];
166 buf[1] = buf[-4*stride+1];
167 buf[2] = buf[-4*stride+2];
169 buf[0] = buf[-3*stride];
170 buf[1] = buf[-3*stride+1];
171 buf[2] = buf[-3*stride+2];
172 verticesBuf.count+=2;
178 public void glimtkVertex3d( double x, double y, double z ) { glimtkVertex3f((float)x, (float)y, (float)z); }
179 public void glimtkVertex3fv( float* coords ) { glimtkVertex3f(coords[0], coords[1], coords[2]); }
180 public void glimtkVertex3dv( double* coords ) { glimtkVertex3f((float)coords[0], (float)coords[1], (float)coords[2]); }
182 public void glimtkColor4f(float r, float g, float b, float a)
184 if(beginMode != unset)
186 // Called within glBegin()/glEnd()
187 vertexColorValues = true;
189 verticesBuf.stride = vertexOffset + numCoords;
191 int stride = verticesBuf.stride;
192 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
193 float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + 2;
194 buf[0] = r, buf[1] = g, buf[2] = b, buf[3] = a;
199 buf[0] = buf[-4*stride];
200 buf[1] = buf[-4*stride+1];
201 buf[2] = buf[-4*stride+2];
202 buf[3] = buf[-4*stride+3];
204 buf[0] = buf[-3*stride];
205 buf[1] = buf[-3*stride+1];
206 buf[2] = buf[-3*stride+2];
207 buf[3] = buf[-3*stride+3];
213 #if ENABLE_GL_SHADERS
215 defaultShader.setColor(r, g, b, a);
221 glColor4f(r, g, b, a);
224 float color[4] = { r, g, b, a };
225 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
226 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
233 public void glimtkColor3f( float r, float g, float b ) { glimtkColor4f(r, g, b, 1.0f); }
234 public void glimtkColor4ub(byte r, byte g, byte b, byte a) { glimtkColor4f(r/255.0f, g/255.0f, b/255.0f, a/255.0f); }
235 public void glimtkColor4fv(float * a) { glimtkColor4f(a[0], a[1], a[2], a[3]); }
238 public void glimtkNormal3f(float x, float y, float z)
240 normalsBuf.count = verticesBuf.count;
242 int stride = normalsBuf.stride;
243 bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
244 float * buf = normalsBuf.ensure(quadsAdd ? 3 : 1) + 2;
246 buf[0] = x, buf[1] = y, buf[2] = z;
251 buf[0] = buf[-4*stride];
252 buf[1] = buf[-4*stride+1];
253 buf[2] = buf[-4*stride+2];
255 buf[0] = buf[-3*stride];
256 buf[1] = buf[-3*stride+1];
257 buf[2] = buf[-3*stride+2];
258 normalsBuf.count += 2;
262 public void glimtkNormal3d(double x, double y, double z) { glimtkNormal3f((float)x, (float)y, (float)z); }
263 public void glimtkNormal3fv(float * coords) { glimtkNormal3f(coords[0], coords[1], coords[2]); }
264 public void glimtkNormal3fd(double * coords) { glimtkNormal3f((float)coords[0], (float)coords[1], (float)coords[2]); }
267 public void glimtkEnd()
269 GLIMTKMode mode = beginMode;
272 if(mode == quads) mode = triangles;
273 else if(mode == polygon) mode = triangleFan;
276 GLEnableClientState(TEXCOORDS);
278 if(glCaps_vertexBuffer)
280 verticesBuf.upload();
281 verticesBuf.use(texCoord, 2, GL_FLOAT, verticesBuf.stride * sizeof(float), 0);
284 noAB.use(texCoord, 2, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer);
286 if(vertexColorValues)
288 GLEnableClientState(COLORS);
289 if(glCaps_vertexBuffer)
290 verticesBuf.use(color, 4, GL_FLOAT, verticesBuf.stride * sizeof(float), (void *)(2 * sizeof(float)));
292 noAB.use(color, 4, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer + 2);
294 #if ENABLE_GL_SHADERS
296 defaultShader.setPerVertexColor(true);
300 if(glCaps_vertexBuffer)
301 verticesBuf.use(vertex, numCoords, GL_FLOAT, verticesBuf.stride * sizeof(float), (void *)(vertexOffset * sizeof(float)));
303 noAB.use(vertex, numCoords, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer + vertexOffset);
305 if(normalsBuf.count && normalsBuf.count == verticesBuf.count)
307 GLEnableClientState(NORMALS);
308 if(glCaps_vertexBuffer)
311 normalsBuf.use(normal, 3, GL_FLOAT, 3*sizeof(float), 0);
314 noAB.use(normal, 3, GL_FLOAT, 3*sizeof(float),normalsBuf.pointer);
318 glDrawArrays(mode, 0, verticesBuf.count);
321 GLDisableClientState(NORMALS);
322 if(vertexColorValues)
324 GLDisableClientState(COLORS);
326 #if ENABLE_GL_SHADERS
328 defaultShader.setPerVertexColor(false);
332 GLDisableClientState(TEXCOORDS);
334 normalsBuf.count = 0;
335 vertexColorValues = false;