1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
4 // This file is part of Scorched3D.
6 // Scorched3D 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 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D 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.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <image/Image.h>
22 #include <GLEXT/GLState.h>
23 #include <common/Vector.h>
24 #include <sky/Hemisphere.h>
25 #include <common/Defines.h>
29 void Hemisphere::draw(float radius
, float radius2
,
30 int heightSlices
, int rotationSlices
,
31 int startHeightSlice
, int startRotationSlice
,
32 int endHeightSlice
, int endRotationSlice
,
33 bool inverse
, unsigned int flags
)
35 glBegin(GL_QUAD_STRIP
);
36 const float maxTexCoord
= 1.0f
;
37 for (int j
=startHeightSlice
; j
<endHeightSlice
; j
++)
39 float theta1
= j
* HALFPI
/ float(heightSlices
);
40 float theta2
= (j
+ 1) * HALFPI
/ float(heightSlices
);
42 for (int i
=startRotationSlice
;i
<=endRotationSlice
;i
++)
44 float theta3
= i
* TWOPI
/ float(rotationSlices
);
45 float c
= theta3
/ TWOPI
* maxTexCoord
;
48 e1
[0] = float(cos(theta1
) * cos(theta3
));
49 e1
[2] = float(sin(theta1
));
50 e1
[1] = float(cos(theta1
) * sin(theta3
));
51 p1
[0] = radius
* e1
[0];
52 p1
[2] = radius2
* e1
[2];
53 p1
[1] = radius
* e1
[1];
56 e2
[0] = float(cos(theta2
) * cos(theta3
));
57 e2
[2] = float(sin(theta2
));
58 e2
[1] = float(cos(theta2
) * sin(theta3
));
59 p2
[0] = radius
* e2
[0];
60 p2
[2] = radius2
* e2
[2];
61 p2
[1] = radius
* e2
[1];
65 if (flags
& eWidthTexture
) glTexCoord2f((p1
[0] + radius
) / (2 * radius
),
66 (p1
[1] + radius
) / (2 * radius
));
67 else glTexCoord2f(c
, float(j
) / float(heightSlices
));
69 if (flags
& eWidthTexture
) glTexCoord2f((p2
[0] + radius
) / (2 * radius
),
70 (p2
[1] + radius
) / (2 * radius
));
71 else glTexCoord2f(c
, float(j
+1) / float(heightSlices
));
76 if (flags
& eWidthTexture
) glTexCoord2f((p2
[0] + radius
) / (2 * radius
),
77 (p2
[1] + radius
) / (2 * radius
));
78 else glTexCoord2f(c
, float(j
+1) / float(heightSlices
));
80 if (flags
& eWidthTexture
) glTexCoord2f((p1
[0] + radius
) / (2 * radius
),
81 (p1
[1] + radius
) / (2 * radius
));
82 else glTexCoord2f(c
, float(j
) / float(heightSlices
));
87 glBegin(GL_QUAD_STRIP
);
92 void Hemisphere::drawColored(float radius
, float radius2
,
93 int heightSlices
, int rotationSlices
,
94 int startHeightSlice
, int startRotationSlice
,
95 int endHeightSlice
, int endRotationSlice
,
96 bool inverse
, Image
&colors
, Vector
&sunDir
, int daytime
,
99 GLubyte
*bits
= colors
.getBits();
101 glBegin(GL_QUAD_STRIP
);
102 const float maxTexCoord
= 1.0f
;
103 for (int j
=startHeightSlice
; j
<endHeightSlice
; j
++)
105 float theta1
= j
* HALFPI
/ float(heightSlices
);
106 if (j
<0) theta1
*= 0.75f
;
107 float theta2
= (j
+ 1) * HALFPI
/ float(heightSlices
);
109 int colorJ
= MAX(j
- 1, 0);
110 int colorIndexA
= int(float(colorJ
) / float(heightSlices
) * 15.0f
);
111 int colorIndexB
= int(float(j
) / float(heightSlices
) * 15.0f
);
112 int bitmapIndexA
= daytime
* 3 + (16 * 3) * colorIndexA
;
113 int bitmapIndexB
= daytime
* 3 + (16 * 3) * colorIndexB
;
115 DIALOG_ASSERT(bitmapIndexA
>= 0);
116 DIALOG_ASSERT(bitmapIndexB
+ 2 <
117 colors
.getWidth() * colors
.getHeight() * colors
.getComponents());
119 for (int i
=startRotationSlice
;i
<=endRotationSlice
;i
++)
121 float theta3
= i
* TWOPI
/ float(rotationSlices
);
122 float c
= theta3
/ TWOPI
* maxTexCoord
;
125 e1
[0] = float(cos(theta1
) * cos(theta3
));
126 e1
[2] = float(sin(theta1
));
127 e1
[1] = float(cos(theta1
) * sin(theta3
));
128 p1
[0] = radius
* e1
[0];
129 p1
[2] = radius2
* e1
[2];
130 p1
[1] = radius
* e1
[1];
136 dotP
= e1
.Normalize().dotP(sunDir
);
137 dotP
= (dotP
+ 1.0f
) / 4.0f
;
140 c1
[0] = MIN(float(bits
[bitmapIndexA
]) / 255.0f
+ dotP
, 1.0f
);
141 c1
[1] = MIN(float(bits
[bitmapIndexA
+ 1]) / 255.0f
+ dotP
, 1.0f
);
142 c1
[2] = MIN(float(bits
[bitmapIndexA
+ 2]) / 255.0f
+ dotP
, 1.0f
);
146 e2
[0] = float(cos(theta2
) * cos(theta3
));
147 e2
[2] = float(sin(theta2
));
148 e2
[1] = float(cos(theta2
) * sin(theta3
));
149 p2
[0] = radius
* e2
[0];
150 p2
[2] = radius2
* e2
[2];
151 p2
[1] = radius
* e2
[1];
157 dotP
= e2
.Normalize().dotP(sunDir
);
158 dotP
= (dotP
+ 1.0f
) / 4.0f
;
161 c2
[0] = MIN(float(bits
[bitmapIndexB
]) / 255.0f
+ dotP
, 1.0f
);
162 c2
[1] = MIN(float(bits
[bitmapIndexB
+ 1]) / 255.0f
+ dotP
, 1.0f
);
163 c2
[2] = MIN(float(bits
[bitmapIndexB
+ 2]) / 255.0f
+ dotP
, 1.0f
);
182 glBegin(GL_QUAD_STRIP
);