1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
3 *
4 *
5 * PrBoom: a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11 * Copyright 2005, 2006 by
12 * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 * 02111-1307, USA.
28 *
29 * DESCRIPTION:
30 * Thanks Roman "Vortex" Marchenko
31 *---------------------------------------------------------------------
32 */
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include <stdio.h>
39
40 #include <SDL.h>
41 #include "gl_opengl.h"
42
43 #include "doomtype.h"
44 #include "lprintf.h"
45
46 #define isExtensionSupported(ext) strstr(extensions, ext)
47
48 int gl_version;
49
50 static dboolean gl_compatibility_mode;
51
52 int GLEXT_CLAMP_TO_EDGE = GL_CLAMP;
53 int gl_max_texture_size = 0;
54
55 // obsolete?
56 int gl_use_paletted_texture = 0;
57 int gl_use_shared_texture_palette = 0;
58 int gl_paletted_texture = 0;
59 int gl_shared_texture_palette = 0;
60
61 dboolean gl_ext_texture_filter_anisotropic = false;
62 dboolean gl_arb_texture_non_power_of_two = false;
63 dboolean gl_arb_multitexture = false;
64 dboolean gl_arb_texture_compression = false;
65 dboolean gl_ext_framebuffer_object = false;
66 dboolean gl_ext_packed_depth_stencil = false;
67 dboolean gl_ext_blend_color = false;
68 dboolean gl_use_stencil = false;
69 dboolean gl_ext_arb_vertex_buffer_object = false;
70 dboolean gl_arb_pixel_buffer_object = false;
71
72 // cfg values
73 int gl_ext_texture_filter_anisotropic_default;
74 int gl_arb_texture_non_power_of_two_default;
75 int gl_arb_multitexture_default;
76 int gl_arb_texture_compression_default;
77 int gl_ext_framebuffer_object_default;
78 int gl_ext_packed_depth_stencil_default;
79 int gl_ext_blend_color_default;
80 int gl_use_stencil_default;
81 int gl_ext_arb_vertex_buffer_object_default;
82 int gl_arb_pixel_buffer_object_default;
83
84 int active_texture_enabled[32];
85 int clieant_active_texture_enabled[32];
86
87 // obsolete?
88 PFNGLCOLORTABLEEXTPROC GLEXT_glColorTableEXT = NULL;
89
90 /* EXT_framebuffer_object */
91 PFNGLBINDFRAMEBUFFEREXTPROC GLEXT_glBindFramebufferEXT = NULL;
92 PFNGLGENFRAMEBUFFERSEXTPROC GLEXT_glGenFramebuffersEXT = NULL;
93 PFNGLGENRENDERBUFFERSEXTPROC GLEXT_glGenRenderbuffersEXT = NULL;
94 PFNGLBINDRENDERBUFFEREXTPROC GLEXT_glBindRenderbufferEXT = NULL;
95 PFNGLRENDERBUFFERSTORAGEEXTPROC GLEXT_glRenderbufferStorageEXT = NULL;
96 PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC GLEXT_glFramebufferRenderbufferEXT = NULL;
97 PFNGLFRAMEBUFFERTEXTURE2DEXTPROC GLEXT_glFramebufferTexture2DEXT = NULL;
98 PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC GLEXT_glCheckFramebufferStatusEXT = NULL;
99 PFNGLDELETEFRAMEBUFFERSEXTPROC GLEXT_glDeleteFramebuffersEXT = NULL;
100 PFNGLDELETERENDERBUFFERSEXTPROC GLEXT_glDeleteRenderbuffersEXT = NULL;
101
102 /* ARB_multitexture command function pointers */
103 PFNGLACTIVETEXTUREARBPROC GLEXT_glActiveTextureARB = NULL;
104 PFNGLCLIENTACTIVETEXTUREARBPROC GLEXT_glClientActiveTextureARB = NULL;
105 PFNGLMULTITEXCOORD2FARBPROC GLEXT_glMultiTexCoord2fARB = NULL;
106 PFNGLMULTITEXCOORD2FVARBPROC GLEXT_glMultiTexCoord2fvARB = NULL;
107
108 /* ARB_texture_compression */
109 PFNGLCOMPRESSEDTEXIMAGE2DARBPROC GLEXT_glCompressedTexImage2DARB = NULL;
110
111 PFNGLBLENDCOLOREXTPROC GLEXT_glBlendColorEXT = NULL;
112
113 /* VBO */
114 PFNGLGENBUFFERSARBPROC GLEXT_glGenBuffersARB = NULL;
115 PFNGLDELETEBUFFERSARBPROC GLEXT_glDeleteBuffersARB = NULL;
116 PFNGLBINDBUFFERARBPROC GLEXT_glBindBufferARB = NULL;
117 PFNGLBUFFERDATAARBPROC GLEXT_glBufferDataARB = NULL;
118
119 /* PBO */
120 PFNGLBUFFERSUBDATAARBPROC GLEXT_glBufferSubDataARB = NULL;
121 PFNGLGETBUFFERPARAMETERIVARBPROC GLEXT_glGetBufferParameterivARB = NULL;
122 PFNGLMAPBUFFERARBPROC GLEXT_glMapBufferARB = NULL;
123 PFNGLUNMAPBUFFERARBPROC GLEXT_glUnmapBufferARB = NULL;
124
125
gld_InitOpenGLVersion(void)126 void gld_InitOpenGLVersion(void)
127 {
128 int MajorVersion, MinorVersion;
129 gl_version = OPENGL_VERSION_1_0;
130 if (sscanf((const char*)glGetString(GL_VERSION), "%d.%d", &MajorVersion, &MinorVersion) == 2)
131 {
132 if (MajorVersion > 1)
133 {
134 gl_version = OPENGL_VERSION_2_0;
135 if (MinorVersion > 0) gl_version = OPENGL_VERSION_2_1;
136 }
137 else
138 {
139 gl_version = OPENGL_VERSION_1_0;
140 if (MinorVersion > 0) gl_version = OPENGL_VERSION_1_1;
141 if (MinorVersion > 1) gl_version = OPENGL_VERSION_1_2;
142 if (MinorVersion > 2) gl_version = OPENGL_VERSION_1_3;
143 if (MinorVersion > 3) gl_version = OPENGL_VERSION_1_4;
144 if (MinorVersion > 4) gl_version = OPENGL_VERSION_1_5;
145 }
146 }
147 }
148
gld_InitOpenGL(dboolean compatibility_mode)149 void gld_InitOpenGL(dboolean compatibility_mode)
150 {
151 GLenum texture;
152 const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
153
154 gl_compatibility_mode = compatibility_mode;
155
156 gld_InitOpenGLVersion();
157
158 gl_ext_texture_filter_anisotropic = gl_ext_texture_filter_anisotropic_default &&
159 isExtensionSupported("GL_EXT_texture_filter_anisotropic") != NULL;
160 if (gl_ext_texture_filter_anisotropic)
161 lprintf(LO_INFO, "using GL_EXT_texture_filter_anisotropic\n");
162
163 // Any textures sizes are allowed
164 gl_arb_texture_non_power_of_two = gl_arb_texture_non_power_of_two_default &&
165 isExtensionSupported("GL_ARB_texture_non_power_of_two") != NULL;
166 if (gl_arb_texture_non_power_of_two)
167 lprintf(LO_INFO, "using GL_ARB_texture_non_power_of_two\n");
168
169 // Paletted textures
170 if (isExtensionSupported("GL_EXT_paletted_texture") != NULL)
171 {
172 if (gl_use_paletted_texture)
173 {
174 gl_paletted_texture = true;
175 GLEXT_glColorTableEXT = SDL_GL_GetProcAddress("glColorTableEXT");
176 if (GLEXT_glColorTableEXT == NULL)
177 gl_paletted_texture = false;
178 else
179 lprintf(LO_INFO,"using GL_EXT_paletted_texture\n");
180 }
181 }
182 else if (isExtensionSupported("GL_EXT_shared_texture_palette") != NULL)
183 {
184 if (gl_use_shared_texture_palette)
185 {
186 gl_shared_texture_palette = true;
187 GLEXT_glColorTableEXT = SDL_GL_GetProcAddress("glColorTableEXT");
188 if (GLEXT_glColorTableEXT == NULL)
189 gl_shared_texture_palette = false;
190 else
191 lprintf(LO_INFO,"using GL_EXT_shared_texture_palette\n");
192 }
193 }
194
195 //
196 // ARB_multitexture command function pointers
197 //
198
199 gl_arb_multitexture = gl_arb_multitexture_default &&
200 isExtensionSupported("GL_ARB_multitexture") != NULL;
201 if (gl_arb_multitexture)
202 {
203 GLEXT_glActiveTextureARB = SDL_GL_GetProcAddress("glActiveTextureARB");
204 GLEXT_glClientActiveTextureARB = SDL_GL_GetProcAddress("glClientActiveTextureARB");
205 GLEXT_glMultiTexCoord2fARB = SDL_GL_GetProcAddress("glMultiTexCoord2fARB");
206 GLEXT_glMultiTexCoord2fvARB = SDL_GL_GetProcAddress("glMultiTexCoord2fvARB");
207
208 if (!GLEXT_glActiveTextureARB || !GLEXT_glClientActiveTextureARB ||
209 !GLEXT_glMultiTexCoord2fARB || !GLEXT_glMultiTexCoord2fvARB)
210 gl_arb_multitexture = false;
211 }
212 if (gl_arb_multitexture)
213 lprintf(LO_INFO,"using GL_ARB_multitexture\n");
214
215 //
216 // ARB_texture_compression
217 //
218
219 gl_arb_texture_compression = gl_arb_texture_compression_default &&
220 isExtensionSupported("GL_ARB_texture_compression") != NULL;
221 if (gl_arb_texture_compression)
222 {
223 GLEXT_glCompressedTexImage2DARB = SDL_GL_GetProcAddress("glCompressedTexImage2DARB");
224
225 if (!GLEXT_glCompressedTexImage2DARB)
226 gl_arb_texture_compression = false;
227 }
228 if (gl_arb_texture_compression)
229 lprintf(LO_INFO,"using GL_ARB_texture_compression\n");
230
231 //
232 // EXT_framebuffer_object
233 //
234 gl_ext_framebuffer_object = gl_ext_framebuffer_object_default &&
235 isExtensionSupported("GL_EXT_framebuffer_object") != NULL;
236 if (gl_ext_framebuffer_object)
237 {
238 GLEXT_glGenFramebuffersEXT = SDL_GL_GetProcAddress("glGenFramebuffersEXT");
239 GLEXT_glBindFramebufferEXT = SDL_GL_GetProcAddress("glBindFramebufferEXT");
240 GLEXT_glGenRenderbuffersEXT = SDL_GL_GetProcAddress("glGenRenderbuffersEXT");
241 GLEXT_glBindRenderbufferEXT = SDL_GL_GetProcAddress("glBindRenderbufferEXT");
242 GLEXT_glRenderbufferStorageEXT = SDL_GL_GetProcAddress("glRenderbufferStorageEXT");
243 GLEXT_glFramebufferRenderbufferEXT = SDL_GL_GetProcAddress("glFramebufferRenderbufferEXT");
244 GLEXT_glFramebufferTexture2DEXT = SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
245 GLEXT_glCheckFramebufferStatusEXT = SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
246 GLEXT_glDeleteFramebuffersEXT = SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
247 GLEXT_glDeleteRenderbuffersEXT = SDL_GL_GetProcAddress("glDeleteRenderbuffersEXT");
248
249 if (!GLEXT_glGenFramebuffersEXT || !GLEXT_glBindFramebufferEXT ||
250 !GLEXT_glGenRenderbuffersEXT || !GLEXT_glBindRenderbufferEXT ||
251 !GLEXT_glRenderbufferStorageEXT || !GLEXT_glFramebufferRenderbufferEXT ||
252 !GLEXT_glFramebufferTexture2DEXT || !GLEXT_glCheckFramebufferStatusEXT ||
253 !GLEXT_glDeleteFramebuffersEXT || !GLEXT_glDeleteRenderbuffersEXT)
254 gl_ext_framebuffer_object = false;
255 }
256 if (gl_ext_framebuffer_object)
257 lprintf(LO_INFO,"using GL_EXT_framebuffer_object\n");
258
259 gl_ext_packed_depth_stencil = gl_ext_packed_depth_stencil_default &&
260 isExtensionSupported("GL_EXT_packed_depth_stencil") != NULL;
261 if (gl_ext_packed_depth_stencil)
262 lprintf(LO_INFO,"using GL_EXT_packed_depth_stencil\n");
263
264 //
265 // Blending
266 //
267
268 gl_ext_blend_color = gl_ext_blend_color_default &&
269 isExtensionSupported("GL_EXT_blend_color") != NULL;
270 if (gl_ext_blend_color)
271 {
272 GLEXT_glBlendColorEXT = SDL_GL_GetProcAddress("glBlendColorEXT");
273
274 if (!GLEXT_glBlendColorEXT)
275 gl_ext_blend_color = false;
276 }
277 if (gl_ext_blend_color)
278 lprintf(LO_INFO,"using GL_EXT_blend_color\n");
279
280 // VBO
281 #ifdef USE_VBO
282 gl_ext_arb_vertex_buffer_object = gl_ext_arb_vertex_buffer_object_default &&
283 isExtensionSupported("GL_ARB_vertex_buffer_object") != NULL;
284 if (gl_ext_arb_vertex_buffer_object)
285 {
286 GLEXT_glGenBuffersARB = SDL_GL_GetProcAddress("glGenBuffersARB");
287 GLEXT_glDeleteBuffersARB = SDL_GL_GetProcAddress("glDeleteBuffersARB");
288 GLEXT_glBindBufferARB = SDL_GL_GetProcAddress("glBindBufferARB");
289 GLEXT_glBufferDataARB = SDL_GL_GetProcAddress("glBufferDataARB");
290
291 if (!GLEXT_glGenBuffersARB || !GLEXT_glDeleteBuffersARB ||
292 !GLEXT_glBindBufferARB || !GLEXT_glBufferDataARB)
293 gl_ext_arb_vertex_buffer_object = false;
294 }
295 if (gl_ext_arb_vertex_buffer_object)
296 lprintf(LO_INFO,"using GL_ARB_vertex_buffer_object\n");
297 #else
298 gl_ext_arb_vertex_buffer_object = false;
299 #endif
300
301 gl_arb_pixel_buffer_object = gl_arb_pixel_buffer_object_default &&
302 isExtensionSupported("GL_ARB_pixel_buffer_object") != NULL;
303 if (gl_arb_pixel_buffer_object)
304 {
305 GLEXT_glGenBuffersARB = SDL_GL_GetProcAddress("glGenBuffersARB");
306 GLEXT_glBindBufferARB = SDL_GL_GetProcAddress("glBindBufferARB");
307 GLEXT_glBufferDataARB = SDL_GL_GetProcAddress("glBufferDataARB");
308 GLEXT_glBufferSubDataARB = SDL_GL_GetProcAddress("glBufferSubDataARB");
309 GLEXT_glDeleteBuffersARB = SDL_GL_GetProcAddress("glDeleteBuffersARB");
310 GLEXT_glGetBufferParameterivARB = SDL_GL_GetProcAddress("glGetBufferParameterivARB");
311 GLEXT_glMapBufferARB = SDL_GL_GetProcAddress("glMapBufferARB");
312 GLEXT_glUnmapBufferARB = SDL_GL_GetProcAddress("glUnmapBufferARB");
313
314 if (!GLEXT_glGenBuffersARB || !GLEXT_glBindBufferARB ||
315 !GLEXT_glBufferDataARB || !GLEXT_glBufferSubDataARB ||
316 !GLEXT_glDeleteBuffersARB || !GLEXT_glGetBufferParameterivARB ||
317 !GLEXT_glMapBufferARB || !GLEXT_glUnmapBufferARB)
318 gl_arb_pixel_buffer_object = false;
319 }
320 if (gl_arb_pixel_buffer_object)
321 lprintf(LO_INFO,"using GL_ARB_pixel_buffer_object\n");
322
323 //
324 // Stencil support
325 //
326
327 gl_use_stencil = gl_use_stencil_default;
328
329 // GL_CLAMP_TO_EDGE
330 GLEXT_CLAMP_TO_EDGE = (gl_version >= OPENGL_VERSION_1_2 ? GL_CLAMP_TO_EDGE : GL_CLAMP);
331
332 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max_texture_size);
333 lprintf(LO_INFO,"GL_MAX_TEXTURE_SIZE=%i\n", gl_max_texture_size);
334
335 // Additional checks
336 if (gl_version < OPENGL_VERSION_1_3)
337 {
338 gl_ext_framebuffer_object = false;
339 gl_ext_blend_color = false;
340 }
341
342 if ((compatibility_mode) || (gl_version <= OPENGL_VERSION_1_1))
343 {
344 lprintf(LO_INFO, "gld_InitOpenGL: Compatibility mode is used.\n");
345 gl_arb_texture_non_power_of_two = false;
346 gl_arb_multitexture = false;
347 gl_arb_texture_compression = false;
348 gl_ext_framebuffer_object = false;
349 gl_ext_packed_depth_stencil = false;
350 gl_ext_blend_color = false;
351 gl_use_stencil = false;
352 gl_ext_arb_vertex_buffer_object = false;
353 gl_arb_pixel_buffer_object = false;
354 GLEXT_CLAMP_TO_EDGE = GL_CLAMP;
355 gl_version = OPENGL_VERSION_1_1;
356 }
357
358 //init states manager
359 gld_EnableMultisample(true);
360 gld_EnableMultisample(false);
361
362 for (texture = GL_TEXTURE0_ARB; texture <= GL_TEXTURE31_ARB; texture++)
363 {
364 gld_EnableTexture2D(texture, true);
365 gld_EnableTexture2D(texture, false);
366
367 gld_EnableClientCoordArray(texture, true);
368 gld_EnableClientCoordArray(texture, false);
369 }
370 }
371
gld_EnableTexture2D(GLenum texture,int enable)372 void gld_EnableTexture2D(GLenum texture, int enable)
373 {
374 int arb;
375
376 if (!gl_arb_multitexture && texture != GL_TEXTURE0_ARB)
377 return;
378
379 arb = texture - GL_TEXTURE0_ARB;
380
381 #ifdef RANGECHECK
382 if (arb < 0 || arb > 31)
383 I_Error("gld_EnableTexture2D: wronge ARB texture unit %d", arb);
384 #endif
385
386 if (enable)
387 {
388 if (!active_texture_enabled[arb])
389 {
390 if (arb != 0)
391 {
392 GLEXT_glActiveTextureARB(texture);
393 glEnable(GL_TEXTURE_2D);
394 GLEXT_glActiveTextureARB(GL_TEXTURE0_ARB);
395 }
396 else
397 {
398 glEnable(GL_TEXTURE_2D);
399 }
400 active_texture_enabled[arb] = enable;
401 }
402 }
403 else
404 {
405 if (active_texture_enabled[arb])
406 {
407 if (arb != 0)
408 {
409 GLEXT_glActiveTextureARB(texture);
410 glDisable(GL_TEXTURE_2D);
411 GLEXT_glActiveTextureARB(GL_TEXTURE0_ARB);
412 }
413 else
414 {
415 glDisable(GL_TEXTURE_2D);
416 }
417 active_texture_enabled[arb] = enable;
418 }
419 }
420 }
421
gld_EnableClientCoordArray(GLenum texture,int enable)422 void gld_EnableClientCoordArray(GLenum texture, int enable)
423 {
424 #ifdef USE_VERTEX_ARRAYS
425 int arb;
426
427 if (!gl_arb_multitexture)
428 return;
429
430 arb = texture - GL_TEXTURE0_ARB;
431
432 #ifdef RANGECHECK
433 if (arb < 0 || arb > 31)
434 I_Error("gld_EnableTexture2D: wronge ARB texture unit %d", arb);
435 #endif
436
437 if (enable)
438 {
439 if (!clieant_active_texture_enabled[arb])
440 {
441 GLEXT_glClientActiveTextureARB(texture);
442 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
443 GLEXT_glClientActiveTextureARB(GL_TEXTURE0_ARB);
444
445 clieant_active_texture_enabled[arb] = enable;
446 }
447 }
448 else
449 {
450 if (clieant_active_texture_enabled[arb])
451 {
452 GLEXT_glClientActiveTextureARB(texture);
453 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
454 GLEXT_glClientActiveTextureARB(GL_TEXTURE0_ARB);
455
456 clieant_active_texture_enabled[arb] = enable;
457 }
458 }
459 #endif
460 }
461
gld_EnableMultisample(int enable)462 void gld_EnableMultisample(int enable)
463 {
464 static int multisample_is_enabled = 0;
465 if (enable)
466 {
467 if (!multisample_is_enabled)
468 {
469 glEnable(GL_MULTISAMPLE_ARB);
470
471 multisample_is_enabled = enable;
472 }
473 }
474 else
475 {
476 if (multisample_is_enabled)
477 {
478 glDisable(GL_MULTISAMPLE_ARB);
479
480 multisample_is_enabled = enable;
481 }
482 }
483 }
484
SetTextureMode(tex_mode_e type)485 void SetTextureMode(tex_mode_e type)
486 {
487 if (gl_compatibility_mode)
488 {
489 type = TM_MODULATE;
490 }
491
492 if (type == TM_MASK)
493 {
494 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
495 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
496 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
497 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
498
499 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
500 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
501 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE0);
502 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
503 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
504 }
505 else if (type == TM_OPAQUE)
506 {
507 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
508 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
509 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
510 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
511 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
512 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
513
514 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
515 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
516 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
517 }
518 else if (type == TM_INVERT)
519 {
520 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
521 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
522 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
523 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
524 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);
525 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
526
527 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
528 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
529 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE0);
530 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
531 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
532 }
533 else if (type == TM_INVERTOPAQUE)
534 {
535 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
536 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
537 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
538 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
539 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);
540 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
541
542 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
543 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
544 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
545 }
546 else // if (type == TM_MODULATE)
547 {
548 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
549 }
550 }
551