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_matrix_mode(int mode)
53 void gaw_load_identity(void)
58 void gaw_load_matrix(const float *m)
63 void gaw_mult_matrix(const float *m)
68 void gaw_push_matrix(void)
73 void gaw_pop_matrix(void)
78 void gaw_get_modelview(float *m)
80 glGetFloatv(GL_MODELVIEW_MATRIX, m);
83 void gaw_get_projection(float *m)
85 glGetFloatv(GL_PROJECTION_MATRIX, m);
88 void gaw_translate(float x, float y, float z)
90 glTranslatef(x, y, z);
93 void gaw_rotate(float angle, float x, float y, float z)
95 glRotatef(angle, x, y, z);
98 void gaw_scale(float sx, float sy, float sz)
100 glScalef(sx, sy, sz);
103 void gaw_ortho(float l, float r, float b, float t, float n, float f)
105 glOrtho(l, r, b, t, n, f);
108 void gaw_frustum(float l, float r, float b, float t, float n, float f)
110 glFrustum(l, r, b, t, n, f);
113 void gaw_perspective(float vfov, float aspect, float znear, float zfar)
115 gluPerspective(vfov, aspect, znear, zfar);
120 glPushAttrib(GL_ENABLE_BIT);
123 void gaw_restore(void)
128 void gaw_enable(int st)
132 glEnable(GL_CULL_FACE);
135 glEnable(GL_DEPTH_TEST);
138 glEnable(GL_ALPHA_TEST);
150 glEnable(GL_LIGHTING);
165 glEnable(GL_TEXTURE_1D);
168 glEnable(GL_TEXTURE_2D);
175 void gaw_disable(int st)
179 glDisable(GL_CULL_FACE);
182 glDisable(GL_DEPTH_TEST);
185 glDisable(GL_ALPHA_TEST);
194 glDisable(GL_DITHER);
197 glDisable(GL_LIGHTING);
200 glDisable(GL_LIGHT0);
203 glDisable(GL_LIGHT1);
206 glDisable(GL_LIGHT2);
209 glDisable(GL_LIGHT3);
212 glDisable(GL_TEXTURE_1D);
215 glDisable(GL_TEXTURE_2D);
222 void gaw_depth_func(int func)
224 glDepthFunc(func + GL_NEVER);
227 void gaw_blend_func(int src, int dest)
229 static const int glbf[] = {GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};
230 glBlendFunc(glbf[src], glbf[dest]);
233 void gaw_alpha_func(int func, float ref)
235 glAlphaFunc(func + GL_NEVER, ref);
238 void gaw_clear_color(float r, float g, float b, float a)
240 glClearColor(r, g, b, a);
243 void gaw_clear(unsigned int flags)
245 unsigned int glflags = 0;
246 if(flags & GAW_COLORBUF) {
247 glflags |= GL_COLOR_BUFFER_BIT;
249 if(flags & GAW_DEPTHBUF) {
250 glflags |= GL_DEPTH_BUFFER_BIT;
252 if(flags & GAW_STENCILBUF) {
253 glflags |= GL_STENCIL_BUFFER_BIT;
258 void gaw_depth_mask(int mask)
263 void gaw_vertex_array(int nelem, int stride, const void *ptr)
265 vertex_nelem = nelem;
266 vertex_stride = stride;
270 void gaw_normal_array(int stride, const void *ptr)
272 normal_stride = stride;
276 void gaw_texcoord_array(int nelem, int stride, const void *ptr)
278 texcoord_nelem = nelem;
279 texcoord_stride = stride;
283 void gaw_color_array(int nelem, int stride, const void *ptr)
286 color_stride = stride;
290 static int glprim[] = {GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS, GL_QUAD_STRIP};
292 void gaw_draw(int prim, int nverts)
294 glEnableClientState(GL_VERTEX_ARRAY);
295 glVertexPointer(vertex_nelem, GL_FLOAT, vertex_stride, vertex_ptr);
297 glEnableClientState(GL_NORMAL_ARRAY);
298 glNormalPointer(GL_FLOAT, normal_stride, normal_ptr);
301 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
302 glTexCoordPointer(texcoord_nelem, GL_FLOAT, texcoord_stride, texcoord_ptr);
305 glEnableClientState(GL_COLOR_ARRAY);
306 glTexCoordPointer(color_nelem, GL_FLOAT, color_stride, color_ptr);
309 glDrawArrays(glprim[prim], 0, nverts);
311 glDisableClientState(GL_VERTEX_ARRAY);
312 glDisableClientState(GL_NORMAL_ARRAY);
313 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
314 glDisableClientState(GL_COLOR_ARRAY);
317 void gaw_draw_indexed(int prim, const unsigned int *idxarr, int nidx)
319 glEnableClientState(GL_VERTEX_ARRAY);
320 glVertexPointer(3, GL_FLOAT, 0, vertex_ptr);
322 glEnableClientState(GL_NORMAL_ARRAY);
323 glNormalPointer(GL_FLOAT, 0, normal_ptr);
326 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
327 glTexCoordPointer(2, GL_FLOAT, 0, texcoord_ptr);
330 glEnableClientState(GL_COLOR_ARRAY);
331 glTexCoordPointer(color_nelem, GL_FLOAT, color_stride, color_ptr);
334 glDrawElements(glprim[prim], nidx, GL_UNSIGNED_INT, idxarr);
336 glDisableClientState(GL_VERTEX_ARRAY);
337 glDisableClientState(GL_NORMAL_ARRAY);
338 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
339 glDisableClientState(GL_COLOR_ARRAY);
342 void gaw_begin(int prim)
344 glBegin(glprim[prim]);
352 void gaw_color3f(float r, float g, float b)
357 void gaw_color4f(float r, float g, float b, float a)
359 glColor4f(r, g, b, a);
362 void gaw_color3ub(int r, int g, int b)
367 void gaw_normal(float x, float y, float z)
372 void gaw_texcoord1f(float u)
377 void gaw_texcoord2f(float u, float v)
382 void gaw_vertex2f(float x, float y)
387 void gaw_vertex3f(float x, float y, float z)
392 void gaw_vertex4f(float x, float y, float z, float w)
394 glVertex4f(x, y, z, w);
397 void gaw_rect(float x1, float y1, float x2, float y2)
399 glRectf(x1, y1, x2, y2);
402 void gaw_pointsize(float sz)
407 void gaw_linewidth(float w)
412 int gaw_compile_begin(void)
414 int dlist = glGenLists(1);
415 glNewList(dlist, GL_COMPILE);
419 void gaw_compile_end(void)
424 void gaw_draw_compiled(int id)
429 void gaw_free_compiled(int id)
431 glDeleteLists(id, 1);
434 void gaw_mtl_diffuse(float r, float g, float b, float a)
441 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, v);
444 void gaw_mtl_specular(float r, float g, float b, float shin)
451 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v);
452 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin);
455 void gaw_mtl_emission(float r, float g, float b)
462 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, v);
465 void gaw_texenv_sphmap(int enable)
468 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
469 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
470 glEnable(GL_TEXTURE_GEN_S);
471 glEnable(GL_TEXTURE_GEN_T);
473 glDisable(GL_TEXTURE_GEN_S);
474 glDisable(GL_TEXTURE_GEN_T);
478 unsigned int gaw_create_tex1d(int texfilter)
481 glGenTextures(1, &tex);
482 glBindTexture(GL_TEXTURE_1D, tex);
483 gaw_texfilter1d(texfilter);
487 unsigned int gaw_create_tex2d(int texfilter)
490 glGenTextures(1, &tex);
491 glBindTexture(GL_TEXTURE_2D, tex);
492 gaw_texfilter2d(texfilter);
496 void gaw_destroy_tex(unsigned int tex)
498 glDeleteTextures(1, &tex);
501 void gaw_bind_tex1d(int tex)
503 glBindTexture(GL_TEXTURE_1D, tex);
506 void gaw_bind_tex2d(int tex)
508 glBindTexture(GL_TEXTURE_2D, tex);
511 void gaw_texfilter1d(int texfilter)
515 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
516 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
520 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
521 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
525 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
526 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
534 void gaw_texfilter2d(int texfilter)
538 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
539 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
543 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
544 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
548 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
557 static int glwrap(int wrap)
559 if(have_edgeclamp == -1) {
561 glextstr = strdup_nf((char*)glGetString(GL_EXTENSIONS));
563 have_edgeclamp = strstr(glextstr, "SGIS_texture_edge_clamp") != 0;
569 return GL_CLAMP_TO_EDGE;
582 void gaw_texwrap1d(int wrap)
584 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, glwrap(wrap));
587 void gaw_texwrap2d(int uwrap, int vwrap)
589 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glwrap(uwrap));
590 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glwrap(vwrap));
594 static const int glfmt[] = {GL_LUMINANCE, GL_RGB, GL_RGBA};
596 void gaw_tex1d(int ifmt, int xsz, int fmt, void *pix)
598 gluBuild1DMipmaps(GL_TEXTURE_1D, glfmt[ifmt], xsz, glfmt[fmt], GL_UNSIGNED_BYTE, pix);
601 void gaw_tex2d(int ifmt, int xsz, int ysz, int fmt, void *pix)
603 gluBuild2DMipmaps(GL_TEXTURE_2D, glfmt[ifmt], xsz, ysz, glfmt[fmt], GL_UNSIGNED_BYTE, pix);
606 void gaw_subtex2d(int lvl, int x, int y, int xsz, int ysz, int fmt, void *pix)
608 glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, xsz, ysz, glfmt[fmt], GL_UNSIGNED_BYTE, pix);
611 void gaw_set_tex1d(unsigned int texid)
614 glEnable(GL_TEXTURE_1D);
615 glBindTexture(GL_TEXTURE_1D, texid);
617 glDisable(GL_TEXTURE_1D);
621 void gaw_set_tex2d(unsigned int texid)
624 glEnable(GL_TEXTURE_2D);
625 glBindTexture(GL_TEXTURE_2D, texid);
627 glDisable(GL_TEXTURE_2D);
631 void gaw_ambient(float r, float g, float b)
638 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
641 void gaw_light_dir(int idx, float x, float y, float z)
648 glLightfv(GL_LIGHT0 + idx, GL_POSITION, pos);
652 void gaw_light_color(int idx, float r, float g, float b, float s)
659 glLightfv(GL_LIGHT0 + idx, GL_DIFFUSE, color);
660 glLightfv(GL_LIGHT0 + idx, GL_SPECULAR, color);
663 void gaw_lighting_fast(void)
665 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
666 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
670 void gaw_fog_color(float r, float g, float b)
677 glFogfv(GL_FOG_COLOR, col);
680 void gaw_fog_linear(float z0, float z1)
682 glFogi(GL_FOG_MODE, GL_LINEAR);
683 glFogf(GL_FOG_START, z0);
684 glFogf(GL_FOG_END, z1);
687 void gaw_fog_fast(void)
689 glHint(GL_FOG_HINT, GL_FASTEST);
692 void gaw_poly_wire(void)
694 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
697 void gaw_poly_flat(void)
699 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
700 glShadeModel(GL_FLAT);
703 void gaw_poly_gouraud(void)
705 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
706 glShadeModel(GL_SMOOTH);