GCC Code Coverage Report


Directory: src/gate/
File: src/gate/graphics/gl_apis.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 0 332 0.0%
Functions: 0 42 0.0%
Branches: 0 177 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28 #include "gate/graphics/gl_apis.h"
29
30 #include "gate/debugging.h"
31 #include "gate/mathematics.h"
32
33 #if (defined(GATE_SYS_WIN) && !defined(GATE_SYS_WINCE) && !defined(GATE_SYS_WINSTORE) && !defined(GATE_SYS_WIN16)) || (defined(GATE_SYS_POSIX) && !defined(GATE_SYS_OPENBSD) && !defined(GATE_SYS_BEOS))
34 # define GATE_GRAPHICS_GL_OPENGL
35 #else
36 # define GATE_GARPHICS_GL_NOIMPL
37 #endif
38
39 #if defined(GATE_GRAPHICS_GL_OPENGL)
40
41 #include "gate/graphics/platform/opengl_apis.h"
42
43
44 #if defined(GATE_SYS_WIN) && !defined(GATE_SYS_WINCE)
45 # define GATE_GL_API_WINAPI 1
46 #elif defined(GATE_SYS_DARWIN)
47 # define GATE_GL_API_GLUT 1
48 #else
49 # define GATE_GL_API_EGL 1
50 #endif
51
52
53
54 gate_result_t gate_gl_api_init()
55 {
56 return gate_gl_api_load_functions();
57 }
58
59 void gate_gl_api_color3(gate_real32_t r, gate_real32_t g, gate_real32_t b)
60 {
61 gate_gl_api_color4(r, g, b, 1.0f);
62 }
63 void gate_gl_api_color4(gate_real32_t r, gate_real32_t g, gate_real32_t b, gate_real32_t a)
64 {
65 gate_gl_api.glColor4f(r, g, b, a);
66 }
67 void gate_gl_api_color3b(gate_uint8_t r, gate_uint8_t g, gate_uint8_t b)
68 {
69 gate_gl_api_color4b(r, g, b, 255);
70 }
71 void gate_gl_api_color4b(gate_uint8_t r, gate_uint8_t g, gate_uint8_t b, gate_uint8_t a)
72 {
73 gate_gl_api.glColor4f((gate_real32_t)r / 255.0f,
74 (gate_real32_t)g / 255.0f,
75 (gate_real32_t)b / 255.0f,
76 (gate_real32_t)a / 255.0f);
77 }
78
79 void gate_gl_api_vertexpointer(gate_size_t coord_count, gate_real32_t const* ptr_coords)
80 {
81 gate_gl_api.glVertexPointer((GLint)coord_count, GL_FLOAT, 0, ptr_coords);
82 }
83
84 void gate_gl_api_texcoordpointer(gate_size_t coord_count, gate_real32_t const* ptr_coords)
85 {
86 gate_gl_api.glTexCoordPointer((GLint)coord_count, GL_FLOAT, 0, ptr_coords);
87 }
88
89 void gate_gl_api_shademodel(gate_gl_api_shademodel_t model)
90 {
91 GLenum value = 0;
92 switch (model)
93 {
94 case gate_gl_api_shademodel_flat: value = GL_FLAT; break;
95 case gate_gl_api_shademodel_smooth: value = GL_SMOOTH; break;
96 }
97 gate_gl_api.glShadeModel(value);
98 }
99
100 static GLenum resolve_blend_function(gate_gl_api_blend_t blend_function)
101 {
102 switch (blend_function)
103 {
104 case gate_gl_api_blend_zero: return GL_ZERO;
105 case gate_gl_api_blend_one: return GL_ONE;
106 case gate_gl_api_blend_src_color: return GL_SRC_COLOR;
107 case gate_gl_api_blend_one_minus_src_color: return GL_ONE_MINUS_SRC_COLOR;
108 case gate_gl_api_blend_src_alpha: return GL_SRC_ALPHA;
109 case gate_gl_api_blend_one_minus_src_alpha: return GL_ONE_MINUS_SRC_ALPHA;
110 case gate_gl_api_blend_dst_alpha: return GL_DST_ALPHA;
111 case gate_gl_api_blend_one_minus_dst_alpha: return GL_ONE_MINUS_DST_ALPHA;
112 case gate_gl_api_blend_dst_color: return GL_DST_COLOR;
113 case gate_gl_api_blend_one_minus_dst_color: return GL_ONE_MINUS_DST_COLOR;
114 case gate_gl_api_blend_src_alpha_saturate: return GL_SRC_ALPHA_SATURATE;
115 }
116 return 0;
117 }
118
119 void gate_gl_api_blendfunc(gate_gl_api_blend_t blend_func_src, gate_gl_api_blend_t blend_func_dst)
120 {
121 gate_gl_api.glBlendFunc(resolve_blend_function(blend_func_src), resolve_blend_function(blend_func_dst));
122 }
123
124 void gate_gl_api_clearcolor(gate_real32_t r, gate_real32_t g, gate_real32_t b, gate_real32_t a)
125 {
126 gate_gl_api.glClearColor(r, g, b, a);
127 }
128
129 void gate_gl_api_cleardepth(gate_real32_t depth)
130 {
131 gate_gl_api.glClearDepth(depth);
132 }
133
134 static GLenum translate_capability(gate_gl_api_capability_t capability)
135 {
136 switch (capability)
137 {
138 case gate_gl_api_capability_alpha_test: return GL_ALPHA_TEST;
139 #if defined(GL_AUTO_NORMAL)
140 case gate_gl_api_capability_auto_normal: return GL_AUTO_NORMAL;
141 #endif
142 case gate_gl_api_capability_blend: return GL_BLEND;
143 //case gate_gl_api_capability_clip_plane: return GL_CLIP_PLANEi;
144 case gate_gl_api_capability_color_logic_op: return GL_COLOR_LOGIC_OP;
145 case gate_gl_api_capability_color_material: return GL_COLOR_MATERIAL;
146 case gate_gl_api_capability_cull_face: return GL_CULL_FACE;
147 case gate_gl_api_capability_depth_test: return GL_DEPTH_TEST;
148 case gate_gl_api_capability_dither: return GL_DITHER;
149 case gate_gl_api_capability_fog: return GL_FOG;
150 #if defined(GL_INDEX_LOGIC_OP)
151 case gate_gl_api_capability_index_logic_op: return GL_INDEX_LOGIC_OP;
152 #endif
153 //case gate_gl_api_capability_light: return GL_LIGHTi;
154 case gate_gl_api_capability_lighting: return GL_LIGHTING;
155 case gate_gl_api_capability_line_smooth: return GL_LINE_SMOOTH;
156 #if defined(GL_LINE_STIPPLE)
157 case gate_gl_api_capability_line_stipple: return GL_LINE_STIPPLE;
158 #endif
159 #if defined(GL_LOGIC_OP)
160 case gate_gl_api_capability_logic_op: return GL_LOGIC_OP;
161 #endif
162 #if defined(GL_MAP1_COLOR_4)
163 case gate_gl_api_capability_map1_color_4: return GL_MAP1_COLOR_4;
164 #endif
165 #if defined(GL_MAP1_INDEX)
166 case gate_gl_api_capability_map1_index: return GL_MAP1_INDEX;
167 #endif
168 #if defined(GL_MAP1_NORMAL)
169 case gate_gl_api_capability_map1_normal: return GL_MAP1_NORMAL;
170 #endif
171 #if defined(GL_MAP1_TEXTURE_COORD_1)
172 case gate_gl_api_capability_map1_texture_coord_1: return GL_MAP1_TEXTURE_COORD_1;
173 #endif
174 #if defined(GL_MAP1_TEXTURE_COORD_2)
175 case gate_gl_api_capability_map1_texture_coord_2: return GL_MAP1_TEXTURE_COORD_2;
176 #endif
177 #if defined(GL_MAP1_TEXTURE_COORD_3)
178 case gate_gl_api_capability_map1_texture_coord_3: return GL_MAP1_TEXTURE_COORD_3;
179 #endif
180 #if defined(GL_MAP1_TEXTURE_COORD_4)
181 case gate_gl_api_capability_map1_texture_coord_4: return GL_MAP1_TEXTURE_COORD_4;
182 #endif
183 #if defined(GL_MAP1_VERTEX_3)
184 case gate_gl_api_capability_map1_vertex_3: return GL_MAP1_VERTEX_3;
185 #endif
186 #if defined(GL_MAP1_VERTEX_4)
187 case gate_gl_api_capability_map1_vertex_4: return GL_MAP1_VERTEX_4;
188 #endif
189 #if defined(GL_MAP2_COLOR_4)
190 case gate_gl_api_capability_map2_color_4: return GL_MAP2_COLOR_4;
191 #endif
192 #if defined(GL_MAP2_INDEX)
193 case gate_gl_api_capability_map2_index: return GL_MAP2_INDEX;
194 #endif
195 #if defined(GL_MAP2_NORMAL)
196 case gate_gl_api_capability_map2_normal: return GL_MAP2_NORMAL;
197 #endif
198 #if defined(GL_MAP2_TEXTURE_COORD_1)
199 case gate_gl_api_capability_map2_texture_coord_1: return GL_MAP2_TEXTURE_COORD_1;
200 #endif
201 #if defined(GL_MAP2_TEXTURE_COORD_2)
202 case gate_gl_api_capability_map2_texture_coord_2: return GL_MAP2_TEXTURE_COORD_2;
203 #endif
204 #if defined(GL_MAP2_TEXTURE_COORD_3)
205 case gate_gl_api_capability_map2_texture_coord_3: return GL_MAP2_TEXTURE_COORD_3;
206 #endif
207 #if defined(GL_MAP2_TEXTURE_COORD_4)
208 case gate_gl_api_capability_map2_texture_coord_4: return GL_MAP2_TEXTURE_COORD_4;
209 #endif
210 #if defined(GL_MAP2_VERTEX_3)
211 case gate_gl_api_capability_map2_vertex_3: return GL_MAP2_VERTEX_3;
212 #endif
213 #if defined(GL_MAP2_VERTEX_4)
214 case gate_gl_api_capability_map2_vertex_4: return GL_MAP2_VERTEX_4;
215 #endif
216 case gate_gl_api_capability_normalize: return GL_NORMALIZE;
217 case gate_gl_api_capability_point_smooth: return GL_POINT_SMOOTH;
218 case gate_gl_api_capability_polygon_offset_fill: return GL_POLYGON_OFFSET_FILL;
219 #if defined(GL_POLYGON_OFFSET_LINE)
220 case gate_gl_api_capability_polygon_offset_line: return GL_POLYGON_OFFSET_LINE;
221 #endif
222 #if defined(GL_POLYGON_OFFSET_POINT)
223 case gate_gl_api_capability_polygon_offset_point: return GL_POLYGON_OFFSET_POINT;
224 #endif
225 #if defined(GL_POLYGON_SMOOTH)
226 case gate_gl_api_capability_polygon_smooth: return GL_POLYGON_SMOOTH;
227 #endif
228 #if defined(GL_POLYGON_STIPPLE)
229 case gate_gl_api_capability_polygon_stipple: return GL_POLYGON_STIPPLE;
230 #endif
231 case gate_gl_api_capability_scissor_test: return GL_SCISSOR_TEST;
232 case gate_gl_api_capability_stencil_test: return GL_STENCIL_TEST;
233 #if defined(GL_TEXTURE_1D)
234 case gate_gl_api_capability_texture_1d: return GL_TEXTURE_1D;
235 #endif
236 case gate_gl_api_capability_texture_2d: return GL_TEXTURE_2D;
237 #if defined(GL_TEXTURE_GEN_Q)
238 case gate_gl_api_capability_texture_gen_q: return GL_TEXTURE_GEN_Q;
239 #endif
240 #if defined(GL_TEXTURE_GEN_R)
241 case gate_gl_api_capability_texture_gen_r: return GL_TEXTURE_GEN_R;
242 #endif
243 #if defined(GL_TEXTURE_GEN_S)
244 case gate_gl_api_capability_texture_gen_s: return GL_TEXTURE_GEN_S;
245 #endif
246 #if defined(GL_TEXTURE_GEN_T)
247 case gate_gl_api_capability_texture_gen_t: return GL_TEXTURE_GEN_T;
248 #endif
249 default: return 0;
250 }
251 }
252
253
254 void gate_gl_api_enable(gate_gl_api_capability_t capability)
255 {
256 gate_gl_api.glEnable(translate_capability(capability));
257 }
258
259 void gate_gl_api_disable(gate_gl_api_capability_t capability)
260 {
261 gate_gl_api.glDisable(translate_capability(capability));
262 }
263
264 void gate_gl_api_depthfunc(gate_gl_api_depth_t depth_function)
265 {
266 GLenum value = 0;
267 switch (depth_function)
268 {
269 case gate_gl_api_depth_never: value = GL_NEVER; break;
270 case gate_gl_api_depth_less: value = GL_LESS; break;
271 case gate_gl_api_depth_lequal: value = GL_LEQUAL; break;
272 case gate_gl_api_depth_equal: value = GL_EQUAL; break;
273 case gate_gl_api_depth_greater: value = GL_GREATER; break;
274 case gate_gl_api_depth_notequal:value = GL_NOTEQUAL;break;
275 case gate_gl_api_depth_gequal: value = GL_GEQUAL; break;
276 case gate_gl_api_depth_always: value = GL_ALWAYS; break;
277 }
278 gate_gl_api.glDepthFunc(value);
279 }
280
281 void gate_gl_api_depthmask(gate_bool_t enabled)
282 {
283 gate_gl_api.glDepthMask(enabled ? GL_TRUE : GL_FALSE);
284 }
285
286 void gate_gl_api_hint(gate_gl_api_hint_t hint_type, gate_gl_api_hintmode_t hint_mode)
287 {
288 GLenum ht = 0, hm = 0;
289 switch (hint_type)
290 {
291 case gate_gl_api_hint_fog_hint: ht = GL_FOG_HINT; break;
292 case gate_gl_api_hint_line_smooth_hint: ht = GL_LINE_SMOOTH_HINT; break;
293 case gate_gl_api_hint_perspective_correction_hint: ht = GL_PERSPECTIVE_CORRECTION_HINT;break;
294 case gate_gl_api_hint_point_smooth_hint: ht = GL_POINT_SMOOTH_HINT; break;
295 #if defined(GL_POLYGON_SMOOTH_HINT)
296 case gate_gl_api_hint_polygon_smooth_hint: ht = GL_POLYGON_SMOOTH_HINT; break;
297 #endif
298 default: ht = 0; break;
299 }
300
301 switch (hint_mode)
302 {
303 case gate_gl_api_hintmode_fastest: hm = GL_FASTEST; break;
304 case gate_gl_api_hintmode_nicest: hm = GL_NICEST; break;
305 case gate_gl_api_hintmode_dont_care: hm = GL_DONT_CARE; break;
306 }
307
308 gate_gl_api.glHint(ht, hm);
309 }
310
311 void gate_gl_api_viewport(gate_int32_t x, gate_int32_t y, gate_int32_t width, gate_int32_t height)
312 {
313 gate_gl_api.glViewport(x, y, width, height);
314 }
315
316 void gate_gl_api_matrixmode(gate_gl_api_matrixmode_t matrix_mode)
317 {
318 GLenum mm = 0;
319 switch (matrix_mode)
320 {
321 case gate_gl_api_matrixmode_modelview: mm = GL_MODELVIEW; break;
322 case gate_gl_api_matrixmode_projection: mm = GL_PROJECTION; break;
323 case gate_gl_api_matrixmode_texture: mm = GL_TEXTURE; break;
324 }
325 gate_gl_api.glMatrixMode(mm);
326 }
327
328 void gate_gl_api_loadidentity()
329 {
330 gate_gl_api.glLoadIdentity();
331 }
332
333 void gate_gl_api_multmatrix(gate_real32_t const matrix[16])
334 {
335 gate_gl_api.glMultMatrixf(matrix);
336 }
337
338 void gate_gl_api_translate(gate_real32_t x, gate_real32_t y, gate_real32_t z)
339 {
340 gate_gl_api.glTranslatef(x, y, z);
341 }
342
343 void gate_gl_api_rotate(gate_real32_t angle, gate_real32_t x, gate_real32_t y, gate_real32_t z)
344 {
345 gate_gl_api.glRotatef(angle, x, y, z);
346 }
347
348
349 void gate_gl_api_flush()
350 {
351 gate_gl_api.glFlush();
352 }
353
354 void gate_gl_api_finish()
355 {
356 gate_gl_api.glFinish();
357 }
358
359 void gate_gl_api_clear(unsigned clear_bits)
360 {
361 GLbitfield bf = 0;
362
363 if (clear_bits & gate_gl_api_clearbit_color_buffer_bit)
364 {
365 bf |= GL_COLOR_BUFFER_BIT;
366 }
367 if (clear_bits & gate_gl_api_clearbit_depth_buffer_bit)
368 {
369 bf |= GL_DEPTH_BUFFER_BIT;
370 }
371 if (clear_bits & gate_gl_api_clearbit_accum_buffer_bit)
372 {
373 #if defined(GL_ACCUM_BUFFER_BIT)
374 bf |= GL_ACCUM_BUFFER_BIT;
375 #endif
376 }
377 if (clear_bits & gate_gl_api_clearbit_stencil_buffer_bit)
378 {
379 bf |= GL_STENCIL_BUFFER_BIT;
380 }
381 gate_gl_api.glClear(bf);
382 }
383
384 void gate_gl_api_perspective(gate_real32_t fovy, gate_real32_t aspect, gate_real32_t znear, gate_real32_t zfar)
385 {
386 gate_real32_t f = (gate_real32_t)(1.0 / gate_math_tan(gate_math_deg2rad(fovy) / 2.0));
387 GLfloat a = f / aspect;
388 GLfloat m[16];
389 m[0] = a; m[1] = 0; m[2] = 0; m[3] = 0;
390 m[4] = 0; m[5] = f; m[6] = 0; m[7] = 0;
391 m[8] = 0; m[9] = 0; m[10] = (zfar + znear) / (znear - zfar); m[11] = -1.0f;
392 m[12] = 0; m[13] = 0; m[14] = (2.0f * zfar * znear) / (znear - zfar); m[15] = 0;
393 gate_gl_api.glMultMatrixf(m);
394 }
395
396
397 static void math_cross_prod(float x1, float y1, float z1, float x2, float y2, float z2, float res[3])
398 {
399 res[0] = y1 * z2 - y2 * z1;
400 res[1] = x2 * z1 - x1 * z2;
401 res[2] = x1 * y2 - x2 * y1;
402 }
403
404 /* https://www.khronos.org/message_boards/showthread.php/4991-The-Solution-for-gluLookAt%28%29-Function!!!! */
405 /* https://community.khronos.org/t/the-solution-for-glulookat-function/521 */
406
407 static double square(double const arg)
408 {
409 return arg * arg;
410 }
411
412
413 void gate_gl_api_lookat(gate_real32_t eyeX, gate_real32_t eyeY, gate_real32_t eyeZ,
414 gate_real32_t lookX, gate_real32_t lookY, gate_real32_t lookZ,
415 gate_real32_t upX, gate_real32_t upY, gate_real32_t upZ)
416 {
417 float f[3];
418 float fMag;
419 float upMag;
420 float s[3], u[3];
421 float M[16];
422
423
424 f[0] = lookX - eyeX;
425 f[1] = lookY - eyeY;
426 f[2] = lookZ - eyeZ;
427
428 fMag = (float)gate_math_sqrt(square(f[0]) + square(f[1]) + square(f[2]));
429 upMag = (float)gate_math_sqrt(square(upX) + square(upY) + square(upZ));
430
431 if (fMag != 0)
432 {
433 f[0] = f[0] / fMag;
434 f[1] = f[1] / fMag;
435 f[2] = f[2] / fMag;
436 }
437
438 if (upMag != 0)
439 {
440 upX = upX / upMag;
441 upY = upY / upMag;
442 upZ = upZ / upMag;
443 }
444
445 math_cross_prod(f[0], f[1], f[2], upX, upY, upZ, s);
446 math_cross_prod(s[0], s[1], s[2], f[0], f[1], f[2], u);
447
448 M[0] = s[0]; M[1] = u[0]; M[2] = -f[0]; M[3] = 0;
449 M[4] = s[1]; M[5] = u[1]; M[6] = -f[1]; M[7] = 0;
450 M[8] = s[2]; M[9] = u[2]; M[10] = -f[2]; M[11] = 0;
451 M[12] = 0; M[13] = 0; M[14] = 0; M[15] = 1;
452
453 gate_gl_api.glMultMatrixf(M);
454 gate_gl_api.glTranslatef(-eyeX, -eyeY, -eyeZ);
455 }
456
457 void gate_gl_api_ortho(gate_real32_t left, gate_real32_t right, gate_real32_t bottom, gate_real32_t top, gate_real32_t near_val, gate_real32_t far_val)
458 {
459 gate_gl_api.glOrtho(left, right, bottom, top, near_val, far_val);
460 }
461
462
463 static GLenum translate_clientstate(gate_gl_api_clientstate_t client_state)
464 {
465 switch (client_state)
466 {
467 case gate_gl_api_clientstate_color_array: return GL_COLOR_ARRAY;
468 #if defined(GL_EDGE_FLAG_ARRAY)
469 case gate_gl_api_clientstate_edge_flag_array: return GL_EDGE_FLAG_ARRAY;
470 #endif
471 #if defined(GL_INDEX_ARRAY)
472 case gate_gl_api_clientstate_index_array: return GL_INDEX_ARRAY;
473 #endif
474 case gate_gl_api_clientstate_normal_array: return GL_NORMAL_ARRAY;
475 case gate_gl_api_clientstate_texture_coord_array: return GL_TEXTURE_COORD_ARRAY;
476 case gate_gl_api_clientstate_vertex_array: return GL_VERTEX_ARRAY;
477 default: return 0;
478 }
479 }
480
481 void gate_gl_api_enableclientstate(gate_gl_api_clientstate_t state)
482 {
483 gate_gl_api.glEnableClientState(translate_clientstate(state));
484 }
485
486 void gate_gl_api_disableclientstate(gate_gl_api_clientstate_t state)
487 {
488 gate_gl_api.glDisableClientState(translate_clientstate(state));
489 }
490
491 static GLenum translate_draw_mode(gate_gl_api_drawmode_t draw_mode)
492 {
493 GLenum ret = 0;
494 switch (draw_mode)
495 {
496 case gate_gl_api_drawmode_points: ret = GL_POINTS; break;
497 case gate_gl_api_drawmode_lines: ret = GL_LINES; break;
498 case gate_gl_api_drawmode_line_loop: ret = GL_LINE_LOOP; break;
499 case gate_gl_api_drawmode_line_strip: ret = GL_LINE_STRIP; break;
500 case gate_gl_api_drawmode_triangles: ret = GL_TRIANGLES; break;
501 case gate_gl_api_drawmode_triangle_strip: ret = GL_TRIANGLE_STRIP; break;
502 case gate_gl_api_drawmode_triangle_fan: ret = GL_TRIANGLE_FAN; break;
503 #if defined(GL_QUADS)
504 case gate_gl_api_drawmode_quads: ret = GL_QUADS; break;
505 #endif
506 #if defined(GL_QUAD_STRIP)
507 case gate_gl_api_drawmode_quad_strip: ret = GL_QUAD_STRIP; break;
508 #endif
509 #if defined(GL_POLYGON)
510 case gate_gl_api_drawmode_polygon: ret = GL_POLYGON; break;
511 #endif
512 default: ret = 0; break;
513 }
514 return ret;
515 }
516
517 void gate_gl_api_drawarrays(gate_gl_api_drawmode_t draw_mode, int index, size_t count)
518 {
519 gate_gl_api.glDrawArrays(translate_draw_mode(draw_mode), (GLint)index, (GLsizei)count);
520 }
521
522 void* gate_gl_api_createtexture(gate_gl_api_pixelformat_t pixel_format,
523 gate_uint32_t width, gate_uint32_t height, void const* data)
524 {
525 GLenum format;
526 GLenum datatype;
527 GLuint tex;
528 GLenum paramFilter = GL_LINEAR;
529 GLint internalFormat =
530 #if defined(GL_RGBA8)
531 GL_RGBA8;
532 #elif defined(GL_RGB8)
533 GL_RGB8;
534 #else
535 GL_RGBA;
536 #endif
537
538 switch (pixel_format)
539 {
540 case gate_gl_api_pixelformat_rgb:
541 {
542 format = GL_RGB;
543 datatype = GL_UNSIGNED_BYTE;
544 break;
545 }
546 case gate_gl_api_pixelformat_rgba:
547 {
548 format = GL_RGBA;
549 datatype = GL_UNSIGNED_BYTE;
550 break;
551 }
552 default:
553 {
554 /* not supported */
555 return 0;
556 }
557 }
558
559 gate_gl_api.glEnable(GL_TEXTURE_2D);
560 gate_gl_api.glGenTextures(1, &tex);
561 gate_gl_api.glBindTexture(GL_TEXTURE_2D, tex);
562
563 gate_gl_api.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, paramFilter);
564 gate_gl_api.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, paramFilter);
565
566 gate_gl_api.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
567 gate_gl_api.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
568
569 gate_gl_api.glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, datatype, data);
570 gate_gl_api.glDisable(GL_TEXTURE_2D);
571
572 return (void*)(gate_uintptr_t)(tex);
573 }
574
575 void gate_gl_api_deletetexture(void* texture_id)
576 {
577 GLuint tex = (GLuint)(gate_uintptr_t)(texture_id);
578 gate_gl_api.glDeleteTextures(1, &tex);
579 }
580
581 void gate_gl_api_bindtexture(void* texture_id)
582 {
583 GLuint tex = (GLuint)(gate_uintptr_t)texture_id;
584 gate_gl_api.glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
585 gate_gl_api.glBindTexture(GL_TEXTURE_2D, tex);
586 }
587
588 void gate_gl_api_cullface(gate_gl_api_cullface_t mode)
589 {
590 GLenum value = GL_FRONT_AND_BACK;
591 switch (mode)
592 {
593 case gate_gl_api_cullface_front: value = GL_FRONT; break;
594 case gate_gl_api_cullface_back: value = GL_BACK; break;
595 case gate_gl_api_cullface_front_and_back: value = GL_FRONT_AND_BACK; break;
596 }
597 gate_gl_api.glCullFace(value);
598 }
599
600
601
602 #if defined(GATE_GL_API_WINAPI)
603
604 #include "gate/graphics/platform/opengl_winapi_impl.h"
605
606 #endif /* GATE_GL_API_WINAPI */
607
608
609 #if defined(GATE_GL_API_EGL)
610 # if defined(GATE_SYS_WINCE)
611 typedef ptrdiff_t intptr_t;
612 # endif
613 # include "EGL/egl.h"
614 # include "gate/libraries.h"
615 # include "gate/threading.h"
616
617 # if defined(GATE_SYS_WIN)
618 # define GATE_GL_EGL_LIBNAME "libEGL.dll"
619 # else
620 # define GATE_GL_EGL_LIBNAME "libEGL.so"
621 # endif
622
623
624 typedef struct gate_egl
625 {
626 EGLBoolean(EGLAPIENTRY* ChooseConfig) (EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config);
627 EGLBoolean(EGLAPIENTRY* CopyBuffers) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
628 EGLContext(EGLAPIENTRY* CreateContext) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list);
629 EGLSurface(EGLAPIENTRY* CreatePbufferSurface) (EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list);
630 EGLSurface(EGLAPIENTRY* CreatePixmapSurface) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list);
631 EGLSurface(EGLAPIENTRY* CreateWindowSurface) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list);
632 EGLBoolean(EGLAPIENTRY* DestroyContext) (EGLDisplay dpy, EGLContext ctx);
633 EGLBoolean(EGLAPIENTRY* DestroySurface) (EGLDisplay dpy, EGLSurface surface);
634 EGLBoolean(EGLAPIENTRY* GetConfigAttrib) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value);
635 EGLBoolean(EGLAPIENTRY* GetConfigs) (EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config);
636 EGLDisplay(EGLAPIENTRY* GetCurrentDisplay) (void);
637 EGLSurface(EGLAPIENTRY* GetCurrentSurface) (EGLint readdraw);
638 EGLDisplay(EGLAPIENTRY* GetDisplay) (EGLNativeDisplayType display_id);
639 EGLint(EGLAPIENTRY* GetError) (void);
640 __eglMustCastToProperFunctionPointerType(EGLAPIENTRY* GetProcAddress) (const char* procname);
641 EGLBoolean(EGLAPIENTRY* Initialize) (EGLDisplay dpy, EGLint* major, EGLint* minor);
642 EGLBoolean(EGLAPIENTRY* MakeCurrent) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
643 EGLBoolean(EGLAPIENTRY* QueryContext) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value);
644 const char* (EGLAPIENTRY* QueryString) (EGLDisplay dpy, EGLint name);
645 EGLBoolean(EGLAPIENTRY* QuerySurface) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value);
646 EGLBoolean(EGLAPIENTRY* SwapBuffers) (EGLDisplay dpy, EGLSurface surface);
647 EGLBoolean(EGLAPIENTRY* Terminate) (EGLDisplay dpy);
648 EGLBoolean(EGLAPIENTRY* WaitGL) (void);
649 EGLBoolean(EGLAPIENTRY* WaitNative) (EGLint engine);
650 } gate_egl_t;
651
652 static gate_egl_t egl = GATE_INIT_EMPTY;
653 static volatile gate_bool_t egl_loaded = false;
654
655
656 static gate_result_t gate_egl_load_functions()
657 {
658 static gate_string_t egl_lib_name = GATE_STRING_INIT_STATIC(GATE_GL_EGL_LIBNAME);
659 gate_result_t ret = GATE_RESULT_FAILED;
660 static gate_library_t egl_lib = NULL;
661
662 do
663 {
664 if (egl_loaded)
665 {
666 ret = GATE_RESULT_OK;
667 break;
668 }
669
670 if (egl_lib == NULL)
671 {
672 ret = gate_library_open(&egl_lib_name, &egl_lib, GATE_LIBRARY_FLAG_DEFAULT);
673 GATE_BREAK_IF_FAILED(ret);
674 }
675
676 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglChooseConfig", &egl.ChooseConfig));
677 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglCopyBuffers", &egl.CopyBuffers));
678 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglCreateContext", &egl.CreateContext));
679 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglCreatePbufferSurface", &egl.CreatePbufferSurface));
680 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglCreatePixmapSurface", &egl.CreatePixmapSurface));
681 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglCreateWindowSurface", &egl.CreateWindowSurface));
682 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglDestroyContext", &egl.DestroyContext));
683 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglDestroySurface", &egl.DestroySurface));
684 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglGetConfigAttrib", &egl.GetConfigAttrib));
685 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglGetConfigs", &egl.GetConfigs));
686 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglGetCurrentDisplay", &egl.GetCurrentDisplay));
687 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglGetCurrentSurface", &egl.GetCurrentSurface));
688 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglGetDisplay", &egl.GetDisplay));
689 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglGetError", &egl.GetError));
690 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglGetProcAddress", &egl.GetProcAddress));
691 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglInitialize", &egl.Initialize));
692 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglMakeCurrent", &egl.MakeCurrent));
693 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglQueryContext", &egl.QueryContext));
694 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglQueryString", &egl.QueryString));
695 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglQuerySurface", &egl.QuerySurface));
696 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglSwapBuffers", &egl.SwapBuffers));
697 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglTerminate", &egl.Terminate));
698 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglWaitGL", &egl.WaitGL));
699 GATE_BREAK_IF_FAILED(ret = gate_library_get_function_name(egl_lib, "eglWaitNative", &egl.WaitNative));
700
701 egl_loaded = true;
702 ret = GATE_RESULT_OK;
703 } while (0);
704 return ret;
705 }
706
707 #if defined(GATE_SYS_WINCE)
708
709 #elif defined(GATE_SYS_ANDROID)
710
711 #include "gate/graphics/platform/opengl_android_impl.h"
712
713 #else
714
715 #include "gate/graphics/platform/opengl_xlib_impl.h"
716
717 #endif
718
719 #endif /* GATE_GL_API_EGL */
720
721 #endif /* GATE_GRAPHICS_GL_OPENGL */
722
723
724
725 #if defined(GATE_GL_API_GLUT)
726
727
728 gate_result_t gate_gl_surface_init(gate_gl_surface_t* surface)
729 {
730 (void)surface;
731 return GATE_RESULT_NOTIMPLEMENTED;
732 }
733 gate_result_t gate_gl_surface_uninit(gate_gl_surface_t* surface)
734 {
735 (void)surface;
736 return GATE_RESULT_NOTIMPLEMENTED;
737 }
738 gate_result_t gate_gl_surface_open(gate_gl_surface_t* surface, gate_gl_surface_type_t type,
739 gate_uint32_t width, gate_uint32_t height, gate_enumint_t flags)
740 {
741 (void)surface;
742 (void)type;
743 (void)width;
744 (void)height;
745 (void)flags;
746 return GATE_RESULT_NOTIMPLEMENTED;
747 }
748 gate_result_t gate_gl_surface_close(gate_gl_surface_t* surface)
749 {
750 (void)surface;
751 return GATE_RESULT_NOTIMPLEMENTED;
752 }
753 gate_result_t gate_gl_surface_resize(gate_gl_surface_t* surface, gate_uint32_t width, gate_uint32_t height)
754 {
755 (void)surface;
756 (void)width;
757 (void)height;
758 return GATE_RESULT_NOTIMPLEMENTED;
759 }
760 gate_result_t gate_gl_surface_get_size(gate_gl_surface_t* surface, gate_uint32_t* width, gate_uint32_t* height)
761 {
762 (void)surface;
763 (void)width;
764 (void)height;
765 return GATE_RESULT_NOTIMPLEMENTED;
766 }
767 gate_result_t gate_gl_surface_print_image(gate_gl_surface_t* surface, gate_rasterimage_t* target_image)
768 {
769 (void)surface;
770 (void)target_image;
771 return GATE_RESULT_NOTIMPLEMENTED;
772 }
773 gate_result_t gate_gl_surface_run_event_loop(gate_gl_surface_t* surface,
774 gate_gl_surface_events_t* event_callbacks, void* user_param)
775 {
776 (void)surface;
777 (void)event_callbacks;
778 (void)user_param;
779 return GATE_RESULT_NOTIMPLEMENTED;
780 }
781 gate_result_t gate_gl_surface_exit_event_loop(gate_gl_surface_t* surface)
782 {
783 (void)surface;
784 return GATE_RESULT_NOTIMPLEMENTED;
785 }
786 gate_result_t gate_gl_surface_swap_buffers(gate_gl_surface_t* surface)
787 {
788 (void)surface;
789 return GATE_RESULT_NOTIMPLEMENTED;
790 }
791
792 #endif /* GATE_GL_API_GLUT */
793
794
795
796 #if defined(GATE_GARPHICS_GL_NOIMPL)
797
798
799 gate_result_t gate_gl_surface_init(gate_gl_surface_t* surface)
800 {
801 (void)surface;
802 return GATE_RESULT_NOTIMPLEMENTED;
803 }
804 gate_result_t gate_gl_surface_uninit(gate_gl_surface_t* surface)
805 {
806 (void)surface;
807 return GATE_RESULT_NOTIMPLEMENTED;
808 }
809 gate_result_t gate_gl_surface_open(gate_gl_surface_t* surface, gate_gl_surface_type_t type,
810 gate_uint32_t width, gate_uint32_t height, gate_enumint_t flags)
811 {
812 (void)surface;
813 (void)type;
814 (void)width;
815 (void)height;
816 (void)flags;
817 return GATE_RESULT_NOTIMPLEMENTED;
818 }
819 gate_result_t gate_gl_surface_close(gate_gl_surface_t* surface)
820 {
821 (void)surface;
822 return GATE_RESULT_NOTIMPLEMENTED;
823 }
824 gate_result_t gate_gl_surface_resize(gate_gl_surface_t* surface, gate_uint32_t width, gate_uint32_t height)
825 {
826 (void)surface;
827 (void)width;
828 (void)height;
829 return GATE_RESULT_NOTIMPLEMENTED;
830 }
831 gate_result_t gate_gl_surface_get_size(gate_gl_surface_t* surface, gate_uint32_t* width, gate_uint32_t* height)
832 {
833 (void)surface;
834 (void)width;
835 (void)height;
836 return GATE_RESULT_NOTIMPLEMENTED;
837 }
838 gate_result_t gate_gl_surface_print_image(gate_gl_surface_t* surface, gate_rasterimage_t* target_image)
839 {
840 (void)surface;
841 (void)target_image;
842 return GATE_RESULT_NOTIMPLEMENTED;
843 }
844 gate_result_t gate_gl_surface_run_event_loop(gate_gl_surface_t* surface,
845 gate_gl_surface_events_t* event_callbacks, void* user_param)
846 {
847 (void)surface;
848 (void)event_callbacks;
849 (void)user_param;
850 return GATE_RESULT_NOTIMPLEMENTED;
851 }
852 gate_result_t gate_gl_surface_exit_event_loop(gate_gl_surface_t* surface)
853 {
854 (void)surface;
855 return GATE_RESULT_NOTIMPLEMENTED;
856 }
857 gate_result_t gate_gl_surface_swap_buffers(gate_gl_surface_t* surface)
858 {
859 (void)surface;
860 return GATE_RESULT_NOTIMPLEMENTED;
861 }
862
863
864
865 gate_result_t gate_gl_api_init()
866 {
867 return GATE_RESULT_NOTIMPLEMENTED;
868 }
869
870 void gate_gl_api_color3(gate_real32_t r, gate_real32_t g, gate_real32_t b)
871 {
872 (void)r;
873 (void)g;
874 (void)b;
875 }
876 void gate_gl_api_color4(gate_real32_t r, gate_real32_t g, gate_real32_t b, gate_real32_t a)
877 {
878 (void)r;
879 (void)g;
880 (void)b;
881 (void)a;
882 }
883 void gate_gl_api_color3b(gate_uint8_t r, gate_uint8_t g, gate_uint8_t b)
884 {
885 (void)r;
886 (void)g;
887 (void)b;
888 }
889 void gate_gl_api_color4b(gate_uint8_t r, gate_uint8_t g, gate_uint8_t b, gate_uint8_t a)
890 {
891 (void)r;
892 (void)g;
893 (void)b;
894 (void)a;
895 }
896 void gate_gl_api_vertexpointer(gate_size_t coord_count, gate_real32_t const* ptr_coords)
897 {
898 (void)coord_count;
899 (void)ptr_coords;
900 }
901 void gate_gl_api_texcoordpointer(gate_size_t coord_count, gate_real32_t const* ptr_coords)
902 {
903 (void)coord_count;
904 (void)ptr_coords;
905 }
906 void gate_gl_api_shademodel(gate_gl_api_shademodel_t model)
907 {
908 (void)model;
909 }
910 void gate_gl_api_blendfunc(gate_gl_api_blend_t blend_func_src, gate_gl_api_blend_t blend_func_dst)
911 {
912 (void)blend_func_src;
913 (void)blend_func_dst;
914 }
915 void gate_gl_api_clearcolor(gate_real32_t r, gate_real32_t g, gate_real32_t b, gate_real32_t a)
916 {
917 (void)r;
918 (void)g;
919 (void)b;
920 (void)a;
921 }
922 void gate_gl_api_cleardepth(gate_real32_t depth)
923 {
924 (void)depth;
925 }
926 void gate_gl_api_enable(gate_gl_api_capability_t capability)
927 {
928 (void)capability;
929 }
930 void gate_gl_api_disable(gate_gl_api_capability_t capability)
931 {
932 (void)capability;
933 }
934 void gate_gl_api_depthfunc(gate_gl_api_depth_t depth_function)
935 {
936 (void)depth_function;
937 }
938 void gate_gl_api_depthmask(gate_bool_t enabled)
939 {
940 (void)enabled;
941 }
942 void gate_gl_api_hint(gate_gl_api_hint_t hint_type, gate_gl_api_hintmode_t hint_mode)
943 {
944 (void)hint_type;
945 (void)hint_mode;
946 }
947 void gate_gl_api_viewport(gate_int32_t x, gate_int32_t y, gate_int32_t width, gate_int32_t height)
948 {
949 (void)x;
950 (void)y;
951 (void)width;
952 (void)height;
953 }
954 void gate_gl_api_matrixmode(gate_gl_api_matrixmode_t matrix_mode)
955 {
956 (void)matrix_mode;
957 }
958 void gate_gl_api_loadidentity()
959 {
960 }
961 void gate_gl_api_multmatrix(gate_real32_t const matrix[16])
962 {
963 (void)matrix;
964 }
965 void gate_gl_api_translate(gate_real32_t x, gate_real32_t y, gate_real32_t z)
966 {
967 (void)x;
968 (void)y;
969 (void)z;
970 }
971 void gate_gl_api_rotate(gate_real32_t angle, gate_real32_t x, gate_real32_t y, gate_real32_t z)
972 {
973 (void)angle;
974 (void)x;
975 (void)y;
976 (void)z;
977 }
978 void gate_gl_api_flush()
979 {
980
981 }
982 void gate_gl_api_finish()
983 {
984
985 }
986 void gate_gl_api_clear(unsigned clear_bits)
987 {
988 (void)clear_bits;
989 }
990 void gate_gl_api_perspective(gate_real32_t fovy, gate_real32_t aspect, gate_real32_t znear, gate_real32_t zfar)
991 {
992 (void)fovy;
993 (void)aspect;
994 (void)znear;
995 (void)zfar;
996 }
997 void gate_gl_api_lookat(gate_real32_t eyeX, gate_real32_t eyeY, gate_real32_t eyeZ,
998 gate_real32_t lookX, gate_real32_t lookY, gate_real32_t lookZ,
999 gate_real32_t upX, gate_real32_t upY, gate_real32_t upZ)
1000 {
1001 (void)eyeX;
1002 (void)eyeY;
1003 (void)eyeZ;
1004 (void)lookX;
1005 (void)lookY;
1006 (void)lookZ;
1007 (void)upX;
1008 (void)upY;
1009 (void)upZ;
1010 }
1011 void gate_gl_api_ortho(gate_real32_t left, gate_real32_t right, gate_real32_t bottom, gate_real32_t top,
1012 gate_real32_t near_val, gate_real32_t far_val)
1013 {
1014 (void)left;
1015 (void)right;
1016 (void)bottom;
1017 (void)top;
1018 (void)near_val;
1019 (void)far_val;
1020 }
1021 void gate_gl_api_enableclientstate(gate_gl_api_clientstate_t state)
1022 {
1023 (void)state;
1024 }
1025 void gate_gl_api_disableclientstate(gate_gl_api_clientstate_t state)
1026 {
1027 (void)state;
1028 }
1029 void gate_gl_api_drawarrays(gate_gl_api_drawmode_t draw_mode, int index, size_t count)
1030 {
1031 (void)draw_mode;
1032 (void)index;
1033 (void)count;
1034 }
1035 void* gate_gl_api_createtexture(gate_gl_api_pixelformat_t pixel_format, gate_uint32_t width, gate_uint32_t height,
1036 void const* data)
1037 {
1038 (void)pixel_format;
1039 (void)width;
1040 (void)height;
1041 (void)data;
1042 return NULL;
1043 }
1044 void gate_gl_api_deletetexture(void* texture_id)
1045 {
1046 (void)texture_id;
1047 }
1048 void gate_gl_api_bindtexture(void* texture_id)
1049 {
1050 (void)texture_id;
1051 }
1052 void gate_gl_api_cullface(gate_gl_api_cullface_t mode)
1053 {
1054 (void)mode;
1055 }
1056
1057 #endif /* GATE_GRAPHICS_GL_OPENGL */
1058
1059