ecere: Added missing namespaces
[sdk] / ecere / src / gfx / drivers / gl3 / immediate.ec
1 // OpenGL Immediate Mode Transition Kit
2 import "glab"
3 import "defaultShader"
4
5 #include "gl123es.h"
6
7 namespace gfx::drivers;
8
9 public enum GLIMTKMode
10 {
11    unset          =     -1,
12    points         = 0x0000,
13    lines          = 0x0001,
14    lineLoop       = 0x0002,
15    lineStrip      = 0x0003,
16    triangles      = 0x0004,
17    triangleStrip  = 0x0005,
18    triangleFan    = 0x0006,
19    quads          = 0x0007,
20    quadStrip      = 0x0008,
21    polygon        = 0x0009
22 };
23
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
29
30 static struct FloatGLAB : GLAB
31 {
32    uint count;       // Count of vertices
33    uint size;        // Size in vertices
34    int stride;      // Number of floats per vertex
35    float * pointer;
36    uint bufSize;     // Size in bytes of VBO
37
38    static inline float * ensure(uint extraVertices)
39    {
40       if(count + extraVertices >= size)
41       {
42          size = size ? (size + size/2) : Max(count + extraVertices, 6);
43          pointer = renew pointer float[size * stride];
44       }
45       return pointer + count * stride;
46    }
47
48    static inline void upload()
49    {
50       uint bufSize = count * stride * sizeof(float);
51       if(bufSize > this.bufSize)
52       {
53          this.bufSize = bufSize;
54          GLAB::allocate(bufSize, null, dynamicDraw);
55       }
56       GLAB::upload(0, bufSize, verticesBuf.pointer);
57    }
58
59    static inline void free()
60    {
61       bufSize = 0;
62       count = 0;
63       size = 0;
64       delete pointer;
65       GLAB::free();
66    }
67 };
68
69 FloatGLAB verticesBuf { stride = 4 };
70 FloatGLAB normalsBuf { stride = 3 };
71
72 void glimtkTerminate()
73 {
74    verticesBuf.free();
75    normalsBuf.free();
76 }
77
78 public void glimtkRecti(int a, int b, int c, int d)
79 {
80    glimtkBegin(quads);
81    glimtkVertex2i(a, b);
82    glimtkVertex2i(a, d);
83    glimtkVertex2i(c, d);
84    glimtkVertex2i(c, b);
85    glimtkEnd();
86 }
87
88 public void glimtkBegin(GLIMTKMode mode)
89 {
90    beginMode = mode;
91    vertexColorValues = false;
92    beginCount = 0;
93    vertexOffset = 2;
94
95    verticesBuf.count = 0;
96    verticesBuf.stride = 4;
97    numCoords = 2;
98 }
99
100 public void glimtkTexCoord2f(float x, float y)
101 {
102    int stride = verticesBuf.stride;
103    bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
104    float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1);
105    buf[0] = x;
106    buf[1] = y;
107    buf += stride;
108    if(quadsAdd)
109    {
110       buf[0] = buf[-4*stride];
111       buf[1] = buf[-4*stride+1];
112       buf += stride;
113       buf[0] = buf[-3*stride];
114       buf[1] = buf[-3*stride+1];
115       buf += stride;
116    }
117 }
118
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]); }
122
123 public void glimtkVertex2f(float x, float y)
124 {
125    numCoords = 2;
126    verticesBuf.stride = vertexOffset + numCoords;
127    {
128       int stride = verticesBuf.stride;
129       bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
130       float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + vertexOffset;
131       buf[0] = x;
132       buf[1] = y;
133       verticesBuf.count++;
134       if(quadsAdd)
135       {
136          buf += stride;
137          buf[0] = buf[-4*stride];
138          buf[1] = buf[-4*stride+1];
139          buf += stride;
140          buf[0] = buf[-3*stride];
141          buf[1] = buf[-3*stride+1];
142          verticesBuf.count+=2;
143       }
144    }
145    beginCount++;
146 }
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); }
149
150 public void glimtkVertex3f( float x, float y, float z )
151 {
152    numCoords = 3;
153    verticesBuf.stride = vertexOffset + numCoords;
154    {
155       int stride = verticesBuf.stride;
156       bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
157       float * buf = verticesBuf.ensure(quadsAdd ? 3 : 1) + vertexOffset;
158       buf[0] = x;
159       buf[1] = y;
160       buf[2] = z;
161       verticesBuf.count++;
162       if(quadsAdd)
163       {
164          buf += stride;
165          buf[0] = buf[-4*stride];
166          buf[1] = buf[-4*stride+1];
167          buf[2] = buf[-4*stride+2];
168          buf += stride;
169          buf[0] = buf[-3*stride];
170          buf[1] = buf[-3*stride+1];
171          buf[2] = buf[-3*stride+2];
172          verticesBuf.count+=2;
173       }
174    }
175    beginCount++;
176 }
177
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]); }
181
182 public void glimtkColor4f(float r, float g, float b, float a)
183 {
184    if(beginMode != unset)
185    {
186       // Called within glBegin()/glEnd()
187       vertexColorValues = true;
188       vertexOffset = 6;
189       verticesBuf.stride = vertexOffset + numCoords;
190       {
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;
195
196          if(quadsAdd)
197          {
198             buf += stride;
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];
203             buf += stride;
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];
208          }
209       }
210    }
211    else
212    {
213 #if ENABLE_GL_SHADERS
214       if(glCaps_shaders)
215          defaultShader.setColor(r, g, b, a);
216 #endif
217
218 #if ENABLE_GL_FFP
219       if(!glCaps_shaders)
220       {
221          glColor4f(r, g, b, a);
222          if(lightingEnabled)
223          {
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);
227          }
228       }
229 #endif
230    }
231 }
232
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]); }
236
237
238 public void glimtkNormal3f(float x, float y, float z)
239 {
240    normalsBuf.count = verticesBuf.count;
241    {
242       int stride = normalsBuf.stride;
243       bool quadsAdd = beginMode == quads && !glCaps_quads && ((beginCount % 4) == 3);
244       float * buf = normalsBuf.ensure(quadsAdd ? 3 : 1) + 2;
245
246       buf[0] = x, buf[1] = y, buf[2] = z;
247       normalsBuf.count++;
248
249       if(quadsAdd)
250       {
251          buf[0] = buf[-4*stride];
252          buf[1] = buf[-4*stride+1];
253          buf[2] = buf[-4*stride+2];
254          buf += stride;
255          buf[0] = buf[-3*stride];
256          buf[1] = buf[-3*stride+1];
257          buf[2] = buf[-3*stride+2];
258          normalsBuf.count += 2;
259       }
260    }
261 }
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]); }
265
266
267 public void glimtkEnd()
268 {
269    GLIMTKMode mode = beginMode;
270    if(!glCaps_quads)
271    {
272       if(mode == quads)        mode = triangles;
273       else if(mode == polygon) mode = triangleFan;
274    }
275
276    GLEnableClientState(TEXCOORDS);
277
278    if(glCaps_vertexBuffer)
279    {
280       verticesBuf.upload();
281       verticesBuf.use(texCoord, 2, GL_FLOAT, verticesBuf.stride * sizeof(float), 0);
282    }
283    else
284       noAB.use(texCoord, 2, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer);
285
286    if(vertexColorValues)
287    {
288       GLEnableClientState(COLORS);
289       if(glCaps_vertexBuffer)
290          verticesBuf.use(color, 4, GL_FLOAT, verticesBuf.stride * sizeof(float), (void *)(2 * sizeof(float)));
291       else
292          noAB.use(color, 4, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer + 2);
293
294 #if ENABLE_GL_SHADERS
295       if(glCaps_shaders)
296          defaultShader.setPerVertexColor(true);
297 #endif
298    }
299
300    if(glCaps_vertexBuffer)
301       verticesBuf.use(vertex, numCoords, GL_FLOAT, verticesBuf.stride * sizeof(float), (void *)(vertexOffset * sizeof(float)));
302    else
303       noAB.use(vertex, numCoords, GL_FLOAT, verticesBuf.stride * sizeof(float), verticesBuf.pointer + vertexOffset);
304
305    if(normalsBuf.count && normalsBuf.count == verticesBuf.count)
306    {
307       GLEnableClientState(NORMALS);
308       if(glCaps_vertexBuffer)
309       {
310          normalsBuf.upload();
311          normalsBuf.use(normal, 3, GL_FLOAT, 3*sizeof(float), 0);
312       }
313       else
314          noAB.use(normal, 3, GL_FLOAT, 3*sizeof(float),normalsBuf.pointer);
315    }
316
317    GLFlushMatrices();
318    glDrawArrays(mode, 0, verticesBuf.count);
319
320    if(normalsBuf.count)
321       GLDisableClientState(NORMALS);
322    if(vertexColorValues)
323    {
324       GLDisableClientState(COLORS);
325
326 #if ENABLE_GL_SHADERS
327       if(glCaps_shaders)
328          defaultShader.setPerVertexColor(false);
329 #endif
330
331    }
332    GLDisableClientState(TEXCOORDS);
333
334    normalsBuf.count = 0;
335    vertexColorValues = false;
336    numCoords = 2;
337    beginMode = unset;
338 }