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