2 RetroRay - integrated standalone vintage modeller/renderer
3 Copyright (C) 2023 John Tsiombikas <nuclear@mutantstargoat.com>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
22 #if defined(WIN32) || defined(__WIN32)
26 #include <OpenGL/gl.h>
27 #include <OpenGL/glu.h>
34 static const float *vertex_ptr, *normal_ptr, *texcoord_ptr, *color_ptr;
35 static int vertex_nelem, texcoord_nelem, color_nelem;
36 static int vertex_stride, normal_stride, texcoord_stride, color_stride;
38 static char *glextstr;
39 static int have_edgeclamp = -1;
42 void gaw_viewport(int x, int y, int w, int h)
44 glViewport(x, y, w, h);
47 void gaw_get_viewport(int *vp)
49 glGetIntegerv(GL_VIEWPORT, vp);
52 void gaw_matrix_mode(int mode)
58 void gaw_load_identity(void)
63 void gaw_load_matrix(const float *m)
68 void gaw_mult_matrix(const float *m)
73 void gaw_push_matrix(void)
78 void gaw_pop_matrix(void)
83 void gaw_get_modelview(float *m)
85 glGetFloatv(GL_MODELVIEW_MATRIX, m);
88 void gaw_get_projection(float *m)
90 glGetFloatv(GL_PROJECTION_MATRIX, m);
93 void gaw_translate(float x, float y, float z)
95 glTranslatef(x, y, z);
98 void gaw_rotate(float angle, float x, float y, float z)
100 glRotatef(angle, x, y, z);
103 void gaw_scale(float sx, float sy, float sz)
105 glScalef(sx, sy, sz);
108 void gaw_ortho(float l, float r, float b, float t, float n, float f)
110 glOrtho(l, r, b, t, n, f);
113 void gaw_frustum(float l, float r, float b, float t, float n, float f)
115 glFrustum(l, r, b, t, n, f);
118 void gaw_perspective(float vfov, float aspect, float znear, float zfar)
120 gluPerspective(vfov, aspect, znear, zfar);
125 glPushAttrib(GL_ENABLE_BIT);
128 void gaw_restore(void)
133 void gaw_enable(int st)
137 glEnable(GL_CULL_FACE);
140 glEnable(GL_DEPTH_TEST);
143 glEnable(GL_ALPHA_TEST);
155 glEnable(GL_LIGHTING);
170 glEnable(GL_TEXTURE_1D);
173 glEnable(GL_TEXTURE_2D);
175 case GAW_POLYGON_OFFSET:
176 glEnable(GL_POLYGON_OFFSET_FILL);
183 void gaw_disable(int st)
187 glDisable(GL_CULL_FACE);
190 glDisable(GL_DEPTH_TEST);
193 glDisable(GL_ALPHA_TEST);
202 glDisable(GL_DITHER);
205 glDisable(GL_LIGHTING);
208 glDisable(GL_LIGHT0);
211 glDisable(GL_LIGHT1);
214 glDisable(GL_LIGHT2);
217 glDisable(GL_LIGHT3);
220 glDisable(GL_TEXTURE_1D);
223 glDisable(GL_TEXTURE_2D);
225 case GAW_POLYGON_OFFSET:
226 glDisable(GL_POLYGON_OFFSET_FILL);
233 void gaw_depth_func(int func)
235 glDepthFunc(func + GL_NEVER);
238 void gaw_blend_func(int src, int dest)
240 static const int glbf[] = {GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};
241 glBlendFunc(glbf[src], glbf[dest]);
244 void gaw_alpha_func(int func, float ref)
246 glAlphaFunc(func + GL_NEVER, ref);
249 void gaw_zoffset(float offs)
251 glPolygonOffset(1, offs);
254 void gaw_clear_color(float r, float g, float b, float a)
256 glClearColor(r, g, b, a);
259 void gaw_clear(unsigned int flags)
261 unsigned int glflags = 0;
262 if(flags & GAW_COLORBUF) {
263 glflags |= GL_COLOR_BUFFER_BIT;
265 if(flags & GAW_DEPTHBUF) {
266 glflags |= GL_DEPTH_BUFFER_BIT;
268 if(flags & GAW_STENCILBUF) {
269 glflags |= GL_STENCIL_BUFFER_BIT;
274 void gaw_depth_mask(int mask)
279 void gaw_vertex_array(int nelem, int stride, const void *ptr)
281 vertex_nelem = nelem;
282 vertex_stride = stride;
286 void gaw_normal_array(int stride, const void *ptr)
288 normal_stride = stride;
292 void gaw_texcoord_array(int nelem, int stride, const void *ptr)
294 texcoord_nelem = nelem;
295 texcoord_stride = stride;
299 void gaw_color_array(int nelem, int stride, const void *ptr)
302 color_stride = stride;
306 static int glprim[] = {GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS, GL_QUAD_STRIP};
308 void gaw_draw(int prim, int nverts)
310 glEnableClientState(GL_VERTEX_ARRAY);
311 glVertexPointer(vertex_nelem, GL_FLOAT, vertex_stride, vertex_ptr);
313 glEnableClientState(GL_NORMAL_ARRAY);
314 glNormalPointer(GL_FLOAT, normal_stride, normal_ptr);
317 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
318 glTexCoordPointer(texcoord_nelem, GL_FLOAT, texcoord_stride, texcoord_ptr);
321 glEnableClientState(GL_COLOR_ARRAY);
322 glTexCoordPointer(color_nelem, GL_FLOAT, color_stride, color_ptr);
325 glDrawArrays(glprim[prim], 0, nverts);
327 glDisableClientState(GL_VERTEX_ARRAY);
328 glDisableClientState(GL_NORMAL_ARRAY);
329 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
330 glDisableClientState(GL_COLOR_ARRAY);
333 void gaw_draw_indexed(int prim, const unsigned int *idxarr, int nidx)
335 glEnableClientState(GL_VERTEX_ARRAY);
336 glVertexPointer(3, GL_FLOAT, 0, vertex_ptr);
338 glEnableClientState(GL_NORMAL_ARRAY);
339 glNormalPointer(GL_FLOAT, 0, normal_ptr);
342 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
343 glTexCoordPointer(2, GL_FLOAT, 0, texcoord_ptr);
346 glEnableClientState(GL_COLOR_ARRAY);
347 glTexCoordPointer(color_nelem, GL_FLOAT, color_stride, color_ptr);
350 glDrawElements(glprim[prim], nidx, GL_UNSIGNED_INT, idxarr);
352 glDisableClientState(GL_VERTEX_ARRAY);
353 glDisableClientState(GL_NORMAL_ARRAY);
354 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
355 glDisableClientState(GL_COLOR_ARRAY);
358 void gaw_begin(int prim)
360 glBegin(glprim[prim]);
368 void gaw_color3f(float r, float g, float b)
373 void gaw_color4f(float r, float g, float b, float a)
375 glColor4f(r, g, b, a);
378 void gaw_color3ub(int r, int g, int b)
383 void gaw_normal(float x, float y, float z)
388 void gaw_texcoord1f(float u)
393 void gaw_texcoord2f(float u, float v)
398 void gaw_vertex2f(float x, float y)
403 void gaw_vertex3f(float x, float y, float z)
408 void gaw_vertex4f(float x, float y, float z, float w)
410 glVertex4f(x, y, z, w);
413 void gaw_rect(float x1, float y1, float x2, float y2)
415 glRectf(x1, y1, x2, y2);
418 void gaw_pointsize(float sz)
423 void gaw_linewidth(float w)
428 int gaw_compile_begin(void)
430 int dlist = glGenLists(1);
431 glNewList(dlist, GL_COMPILE);
435 void gaw_compile_end(void)
440 void gaw_draw_compiled(int id)
445 void gaw_free_compiled(int id)
447 glDeleteLists(id, 1);
450 void gaw_mtl_diffuse(float r, float g, float b, float a)
457 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, v);
460 void gaw_mtl_specular(float r, float g, float b, float shin)
467 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v);
468 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin);
471 void gaw_mtl_emission(float r, float g, float b)
478 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, v);
481 void gaw_texenv_sphmap(int enable)
484 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
485 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
486 glEnable(GL_TEXTURE_GEN_S);
487 glEnable(GL_TEXTURE_GEN_T);
489 glDisable(GL_TEXTURE_GEN_S);
490 glDisable(GL_TEXTURE_GEN_T);
494 unsigned int gaw_create_tex1d(int texfilter)
497 glGenTextures(1, &tex);
498 glBindTexture(GL_TEXTURE_1D, tex);
499 gaw_texfilter1d(texfilter);
503 unsigned int gaw_create_tex2d(int texfilter)
506 glGenTextures(1, &tex);
507 glBindTexture(GL_TEXTURE_2D, tex);
508 gaw_texfilter2d(texfilter);
512 void gaw_destroy_tex(unsigned int tex)
514 glDeleteTextures(1, &tex);
517 void gaw_bind_tex1d(int tex)
519 glBindTexture(GL_TEXTURE_1D, tex);
522 void gaw_bind_tex2d(int tex)
524 glBindTexture(GL_TEXTURE_2D, tex);
527 void gaw_texfilter1d(int texfilter)
531 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
532 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
536 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
537 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
541 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
542 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
550 void gaw_texfilter2d(int texfilter)
554 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
555 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
559 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
560 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
564 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
565 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
573 static int glwrap(int wrap)
575 if(have_edgeclamp == -1) {
577 glextstr = strdup_nf((char*)glGetString(GL_EXTENSIONS));
579 have_edgeclamp = strstr(glextstr, "SGIS_texture_edge_clamp") != 0;
585 return GL_CLAMP_TO_EDGE;
598 void gaw_texwrap1d(int wrap)
600 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, glwrap(wrap));
603 void gaw_texwrap2d(int uwrap, int vwrap)
605 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glwrap(uwrap));
606 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glwrap(vwrap));
610 static const int glfmt[] = {GL_LUMINANCE, GL_RGB, GL_RGBA};
612 void gaw_tex1d(int ifmt, int xsz, int fmt, void *pix)
614 gluBuild1DMipmaps(GL_TEXTURE_1D, glfmt[ifmt], xsz, glfmt[fmt], GL_UNSIGNED_BYTE, pix);
617 void gaw_tex2d(int ifmt, int xsz, int ysz, int fmt, void *pix)
619 gluBuild2DMipmaps(GL_TEXTURE_2D, glfmt[ifmt], xsz, ysz, glfmt[fmt], GL_UNSIGNED_BYTE, pix);
622 void gaw_subtex2d(int lvl, int x, int y, int xsz, int ysz, int fmt, void *pix)
624 glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, xsz, ysz, glfmt[fmt], GL_UNSIGNED_BYTE, pix);
627 void gaw_set_tex1d(unsigned int texid)
630 glEnable(GL_TEXTURE_1D);
631 glBindTexture(GL_TEXTURE_1D, texid);
633 glDisable(GL_TEXTURE_1D);
637 void gaw_set_tex2d(unsigned int texid)
640 glEnable(GL_TEXTURE_2D);
641 glBindTexture(GL_TEXTURE_2D, texid);
643 glDisable(GL_TEXTURE_2D);
647 void gaw_ambient(float r, float g, float b)
654 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
657 void gaw_light_dir(int idx, float x, float y, float z)
664 glLightfv(GL_LIGHT0 + idx, GL_POSITION, pos);
668 void gaw_light_color(int idx, float r, float g, float b, float s)
675 glLightfv(GL_LIGHT0 + idx, GL_DIFFUSE, color);
676 glLightfv(GL_LIGHT0 + idx, GL_SPECULAR, color);
679 void gaw_lighting_fast(void)
681 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
682 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
686 void gaw_fog_color(float r, float g, float b)
693 glFogfv(GL_FOG_COLOR, col);
696 void gaw_fog_linear(float z0, float z1)
698 glFogi(GL_FOG_MODE, GL_LINEAR);
699 glFogf(GL_FOG_START, z0);
700 glFogf(GL_FOG_END, z1);
703 void gaw_fog_fast(void)
705 glHint(GL_FOG_HINT, GL_FASTEST);
708 void gaw_poly_wire(void)
710 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
713 void gaw_poly_flat(void)
715 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
716 glShadeModel(GL_FLAT);
719 void gaw_poly_gouraud(void)
721 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
722 glShadeModel(GL_SMOOTH);