2 //**************************************************************************
6 //**************************************************************************
8 // HEADER FILES ------------------------------------------------------------
11 #define WIN32_LEAN_AND_MEAN
22 // MACROS ------------------------------------------------------------------
24 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
26 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
28 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
30 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
32 extern float texw, texh;
34 extern float vx, vy, vz;
36 extern boolean special200; // Should sky2 be used?
37 extern int Sky1Texture, Sky2Texture;
38 extern fixed_t Sky1ColumnOffset, Sky2ColumnOffset;
39 extern boolean DoubleSky;
40 extern byte topLineRGB[3];
43 // PUBLIC DATA DEFINITIONS -------------------------------------------------
46 fadeout_t fadeOut[2]; // For both skies.
48 // PRIVATE DATA DEFINITIONS ------------------------------------------------
50 // CODE --------------------------------------------------------------------
52 // The texture offset to be applied to the texture coordinates in SkyVertex().
53 static float maxSideAngle = (float) PI/3;
55 static int rows, columns;
56 static float scale = 32; // Fogging affects, thus close-by.
58 static fadeout_t *currentFO;
60 // Calculate the vertex and texture coordinates.
61 static void SkyVertex(int r, int c)
63 // The direction must be clockwise.
64 float topAngle = c/(float)columns * 2*PI;
65 float sideAngle = maxSideAngle * (rows-r)/(float)rows;
66 float height = sin(sideAngle);
67 float realRadius = scale*cos(sideAngle);
68 float x = vx + realRadius*cos(topAngle),
69 z = vz + realRadius*sin(topAngle),
70 y = vy + ((!yflip)? scale*height : -scale*height);
72 // And the texture coordinates.
73 if(!yflip) // Flipped Y is for the lower hemisphere.
74 glTexCoord2f(4*c/(float)columns + texoff/texw, r/(float)rows*200.0/256.0);
76 glTexCoord2f(4*c/(float)columns + texoff/texw, (rows-r)/(float)rows*200.0/256.0);
80 if(r==0) glColor4f(1,1,1,0); else glColor3f(1,1,1);
84 if(r==0) glColor3f(0,0,0); else glColor3f(1,1,1);
86 // And finally the vertex.
90 static void CapSideVertex(int r, int c)
92 // The direction must be clockwise.
93 float topAngle = c/(float)columns * 2*PI;
94 float sideAngle = maxSideAngle * (rows-r)/(float)rows;
95 float height = sin(sideAngle);
96 float realRadius = scale*cos(sideAngle);
98 glVertex3f(vx + realRadius*cos(topAngle),
99 vy + ((!yflip)? scale*height : -scale*height),
100 vz + realRadius*sin(topAngle));
103 // Hemi is Upper or Lower. Zero is not acceptable.
104 // The current texture is used. SKYHEMI_NO_TOPCAP can be used.
105 void OGL_RenderSkyHemisphere(int hemi)
109 if(hemi & SKYHEMI_LOWER) yflip = true; else yflip = false;
111 // The top row (row 0) is the one that's faded out.
112 // There must be at least 4 columns. The preferable number
113 // is 4n, where n is 1, 2, 3... There should be at least
114 // two rows because the first one is always faded.
116 columns = 4*skyDetail; // 4n
117 if(hemi & SKYHEMI_JUST_CAP)
119 //glBindTexture(GL_TEXTURE_2D, 0);
120 glDisable( GL_TEXTURE_2D );
122 // Use the appropriate color.
124 glColor3fv(currentFO->rgb);
127 glBegin(GL_TRIANGLE_FAN);
128 for(c=0; c<columns; c++) CapSideVertex(0, c);
131 // If we are doing a colored fadeout...
134 // We must fill the background for the top row since it'll
135 // be partially translucent.
136 glBegin(GL_TRIANGLE_STRIP);
138 for(c=0; c<columns; c++)
140 CapSideVertex(1, c); // One step down.
141 CapSideVertex(0, c+1); // And one step right.
147 glEnable( GL_TEXTURE_2D );
151 // The total number of triangles per hemisphere can be calculated
152 // as follows: rows * columns * 2 + 2 (for the top cap).
153 for(r=0; r<rows; r++)
155 glBegin(GL_TRIANGLE_STRIP);
156 // Add the start vertex.
158 for(c=0; c<columns; c++)
160 SkyVertex(r+1, c); // One step down.
161 SkyVertex(r, c+1); // And one step right.
163 // Add the end vertex for this row. This vertex is also
164 // the start vertex for the next row.
168 for(c=0; c<columns; c++)
179 void OGL_HandleColoredFadeOut(int skynum)
183 currentFO = fadeOut + skynum-1;
184 // We have to remember the top line average RGB.
187 currentFO->set = 1; // Now it is.
188 for(i=0; i<3; i++) currentFO->rgb[i] = topLineRGB[i]/255.0;
189 // Determine if it should be used.
190 for(currentFO->use=false, i=0; i<3; i++)
191 if(currentFO->rgb[i] > .3)
193 // Colored fadeout is needed.
194 currentFO->use = true;
200 static void OGL_DrawSkyhemi(int whichHemi)
207 skyname = OGL_PrepareSky(Sky2Texture, false);
208 OGL_HandleColoredFadeOut(2);
209 // First the top cap.
210 OGL_RenderSkyHemisphere(whichHemi | SKYHEMI_JUST_CAP);
212 glBindTexture(GL_TEXTURE_2D, skyname);
213 texoff = FIX2FLT(Sky2ColumnOffset);
214 OGL_RenderSkyHemisphere(whichHemi);
216 // Then the masked sky1.
217 glBindTexture(GL_TEXTURE_2D, OGL_PrepareSky(Sky1Texture, true));
218 texoff = FIX2FLT(Sky1ColumnOffset);
220 else // Single-layer sky.
222 if(special200) // Use sky2?
224 skyname = OGL_PrepareSky(Sky2Texture, false);
225 texoff = FIX2FLT(Sky2ColumnOffset);
226 OGL_HandleColoredFadeOut(2);
228 else // Sky1, then. This is the normal case.
230 skyname = OGL_PrepareSky(Sky1Texture, false);
231 texoff = FIX2FLT(Sky1ColumnOffset);
232 OGL_HandleColoredFadeOut((Sky1Texture==P_GetMapSky1Texture(gamemap))?1:2);
234 // First the top cap.
235 OGL_RenderSkyHemisphere(whichHemi | SKYHEMI_JUST_CAP);
236 glBindTexture(GL_TEXTURE_2D, skyname);
238 // Render the front sky (sky1).
239 OGL_RenderSkyHemisphere(whichHemi);
242 void R_RenderSkyHemispheres(int hemis)
244 // IS there a sky to be rendered?
247 // We don't want anything written in the depth buffer, not yet.
248 glDepthMask(GL_FALSE);
249 glPushAttrib(GL_ENABLE_BIT);
250 // Disable culling, all triangles face the viewer.
251 glDisable(GL_CULL_FACE);
253 // Draw the possibly visible hemispheres.
254 if(hemis & SKYHEMI_UPPER) OGL_DrawSkyhemi(SKYHEMI_UPPER);
255 if(hemis & SKYHEMI_LOWER) OGL_DrawSkyhemi(SKYHEMI_LOWER);
256 // Enable the disabled things.
258 glDepthMask(GL_TRUE);