1 /*
2
3 Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
4 and the "Aleph One" developers.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 This license is contained in the file "COPYING",
17 which is included with this source code; it is available online at
18 http://www.gnu.org/licenses/gpl.html
19
20 OpenGL Renderer,
21 by Loren Petrich,
22 May 30, 2000
23
24 This contains code for doing fader stuff.
25 */
26
27 #include "cseries.h"
28 #include "fades.h"
29 #include "Random.h"
30 #include "render.h"
31 #include "OGL_Render.h"
32 #include "OGL_Setup.h"
33 #include "OGL_Faders.h"
34
35 #ifdef HAVE_OPENGL
36
37 // The randomizer for the flat-static color
38 static GM_Random FlatStaticRandom;
39
40 // Alternative: partially-transparent instead of the logic-op effect
41 static bool UseFlatStatic;
42 static uint16 FlatStaticColor[4];
43
44
45 #ifdef HAVE_OPENGL
46 #include "OGL_Headers.h"
47 #endif
48
49 // Fader stuff
OGL_FaderActive()50 bool OGL_FaderActive()
51 {
52 if (!OGL_IsActive()) return false;
53
54 OGL_ConfigureData& ConfigureData = Get_OGL_ConfigureData();
55 return TEST_FLAG(ConfigureData.Flags,OGL_Flag_Fader);
56 }
57
58 static OGL_Fader FaderQueue[NUMBER_OF_FADER_QUEUE_ENTRIES];
59
GetOGL_FaderQueueEntry(int Index)60 OGL_Fader *GetOGL_FaderQueueEntry(int Index)
61 {
62 assert(Index >= 0 && Index < NUMBER_OF_FADER_QUEUE_ENTRIES);
63
64 return FaderQueue + Index;
65 }
66
67
68 // Multiply a color by its alpha channel;
69 // make the results separate so as not to destroy the original values
MultAlpha(GLfloat * InColor,GLfloat * OutColor)70 inline void MultAlpha(GLfloat *InColor, GLfloat *OutColor)
71 {
72 for (int c=0; c<3; c++)
73 OutColor[c] = InColor[c]*InColor[3];
74 OutColor[3] = InColor[3];
75 }
76
77
78 // Take the complement of a color;
79 // make the results separate so as not to destroy the original values
ComplementColor(GLfloat * InColor,GLfloat * OutColor)80 inline void ComplementColor(GLfloat *InColor, GLfloat *OutColor)
81 {
82 for (int c=0; c<3; c++)
83 OutColor[c] = 1-InColor[c];
84 OutColor[3] = InColor[3];
85 }
86
87
OGL_DoFades(float Left,float Top,float Right,float Bottom)88 bool OGL_DoFades(float Left, float Top, float Right, float Bottom)
89 {
90 if (!OGL_FaderActive()) return false;
91
92 // Set up the vertices
93 GLfloat Vertices[4][2];
94 Vertices[0][0] = Left;
95 Vertices[0][1] = Top;
96 Vertices[1][0] = Right;
97 Vertices[1][1] = Top;
98 Vertices[2][0] = Right;
99 Vertices[2][1] = Bottom;
100 Vertices[3][0] = Left;
101 Vertices[3][1] = Bottom;
102 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
103 glVertexPointer(2,GL_FLOAT,0,Vertices[0]);
104
105 // Do real blending
106 glDisable(GL_ALPHA_TEST);
107 glEnable(GL_BLEND);
108 glDisable(GL_TEXTURE_2D);
109
110 // Modified color:
111 GLfloat BlendColor[4];
112
113 for (int f=0; f<NUMBER_OF_FADER_QUEUE_ENTRIES; f++)
114 {
115 OGL_Fader& Fader = FaderQueue[f];
116
117 switch(Fader.Type)
118 {
119 case NONE:
120 break;
121
122 case _tint_fader_type:
123 // The simplest kind: fade to the fader color.
124 glColor4fv(Fader.Color);
125 glDrawArrays(GL_POLYGON,0,4);
126 break;
127
128 case _randomize_fader_type:
129 UseFlatStatic = TEST_FLAG(Get_OGL_ConfigureData().Flags,OGL_Flag_FlatStatic);
130 if (UseFlatStatic)
131 {
132 for (int c=0; c<3; c++)
133 FlatStaticColor[c] = FlatStaticRandom.KISS() + FlatStaticRandom.LFIB4();
134 FlatStaticColor[3] = PIN(int(65535*Fader.Color[3]+0.5),0,65535);
135 glDisable(GL_ALPHA_TEST);
136 glEnable(GL_BLEND);
137 glColor4usv(FlatStaticColor);
138 glDrawArrays(GL_POLYGON,0,4);
139 }
140 else
141 {
142 // Do random flipping of the lower bits of color values;
143 // the stronger the opacity (alpha), the more bits to flip.
144 glDisable(GL_BLEND);
145 MultAlpha(Fader.Color,BlendColor);
146 glColor3fv(BlendColor);
147 glEnable(GL_COLOR_LOGIC_OP);
148 glLogicOp(GL_XOR);
149 glDrawArrays(GL_POLYGON,0,4);
150 // Revert to defaults
151 glDisable(GL_COLOR_LOGIC_OP);
152 glEnable(GL_BLEND);
153 }
154 break;
155
156 case _negate_fader_type:
157 // This is only a partial approximation of the negation effect
158 // Neither glBlendColorEXT nor glBlendEquationEXT is currently supported
159 // in ATI Rage 128 AppleGL, which makes my life more difficult :-P
160 MultAlpha(Fader.Color,BlendColor);
161 glColor4fv(BlendColor);
162 glBlendFunc(GL_ONE_MINUS_DST_COLOR,GL_ONE_MINUS_SRC_ALPHA);
163 glDrawArrays(GL_POLYGON,0,4);
164 // Revert to defaults
165 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
166 break;
167
168 case _dodge_fader_type:
169 ComplementColor(Fader.Color,BlendColor);
170 MultAlpha(BlendColor,BlendColor);
171 glColor4fv(BlendColor);
172 glBlendFunc(GL_DST_COLOR,GL_ONE_MINUS_SRC_ALPHA);
173 glDrawArrays(GL_POLYGON,0,4);
174 glBlendFunc(GL_DST_COLOR,GL_ONE);
175 glDrawArrays(GL_POLYGON,0,4);
176 // Revert to defaults
177 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
178 break;
179
180 case _burn_fader_type:
181 // Attempted to get that reversed-color effect at maximum intensity,
182 // with it being only near maximum intensity
183 // (MultAlpha + GL_SRC_ALPHA means opacity^2).
184 MultAlpha(Fader.Color,BlendColor);
185 glColor4fv(BlendColor);
186 glBlendFunc(GL_DST_COLOR,GL_ONE);
187 glDrawArrays(GL_POLYGON,0,4);
188 ComplementColor(Fader.Color,BlendColor);
189 MultAlpha(BlendColor,BlendColor);
190 glColor4fv(BlendColor);
191 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
192 glDrawArrays(GL_POLYGON,0,4);
193 // Revert to defaults
194 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
195 break;
196
197 case _soft_tint_fader_type:
198 // Fade to the color multiplied by the fader color,
199 // as if the scene was illuminated by light with that fader color.
200 MultAlpha(Fader.Color,BlendColor);
201 glColor4fv(BlendColor);
202 glBlendFunc(GL_DST_COLOR,GL_ONE_MINUS_SRC_ALPHA);
203 glDrawArrays(GL_POLYGON,0,4);
204 // Revert to defaults
205 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
206 break;
207 }
208 }
209 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
210
211 return true;
212 }
213
214 #endif // def HAVE_OPENGL
215