UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
r_sphere.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 1997-2001 Id Software, Inc.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24 */
25 
26 #include "r_local.h"
27 #include "r_sphere.h"
28 #include "r_error.h"
29 #include "r_geoscape.h"
30 
32 
36 
37 static inline float rhoSpiral (const int index, const float deltaRho, const float thetaAngle)
38 {
39  const float rhoAngle = (index == 0) ? 0.0f : (float) ((index - 1) * deltaRho + thetaAngle * deltaRho / (2.0f * M_PI));
40  return rhoAngle > M_PI ? M_PI : rhoAngle;
41 }
42 
51 void R_SphereGenerate (sphere_t* sphere, const int tris, const float radius)
52 {
53  const float drho = M_PI / tris;
54  /* must multiply pi by 2, rather than do integer division of tris by two,
55  * otherwise it goes wrong when tris is an odd number */
56  const float dtheta = 2.0f * M_PI / tris;
58  int vertspos = 0;
59  int texespos = 0;
60 
61  sphere->glslProgram = nullptr;
62 
63  sphere->verts = Mem_PoolAllocTypeN(float, (tris + 1) * (tris + 2) * 6, vid_genericPool);
64  sphere->texes = Mem_PoolAllocTypeN(float, (tris + 1) * (tris + 2) * 4, vid_genericPool);
65  sphere->normals = Mem_PoolAllocTypeN(float, (tris + 1) * (tris + 2) * 6, vid_genericPool);
66 
67  /* must be i <= tris, as one loop is wasted, because of the spiral */
68  for (int i = 0; i <= tris; i++) { /* loop through rho, from pole to pole */
69  /* must be j <= tris, so it meets up again */
70  for (int j = 0; j <= tris ; j++) { /* loop through theta, around equator */
71  const float theta = j * dtheta;
72  const float stheta = (float) (-sin(theta));
73  const float ctheta = (float) (cos(theta));
74 
75  /* second term in rho adds a spiral */
76  const float rho = rhoSpiral(i, drho, theta);
77  const float rhodrho = rhoSpiral(i + 1, drho, theta); /* rho plus drho, minding boundary conditions */
78  const float srho = (float) (sin(rho));
79  const float crho = (float) (cos(rho));
80  const float srhodrho = (float) (sin(rhodrho));
81  const float crhodrho = (float) (cos(rhodrho));
82 
83  const float st = 1 - rho / M_PI;
84  const float stdt = 1 - rhodrho / M_PI;
85 
86  const float s = theta / (4.0f * M_PI);
87 
88  Vector2Set((&sphere->texes[texespos]), s, stdt);
89  texespos += 2;
90 
91  VectorSet((&sphere->verts[vertspos]),
92  stheta * srhodrho * radius,
93  ctheta * srhodrho * radius,
94  crhodrho * radius);
95  VectorNormalize2((&sphere->verts[vertspos]), (&sphere->normals[vertspos]));
96  vertspos += 3;
97 
98  Vector2Set((&sphere->texes[texespos]), s, st);
99  texespos += 2;
100 
101  VectorSet((&sphere->verts[vertspos]),
102  stheta * srho * radius,
103  ctheta * srho * radius,
104  crho * radius);
105  VectorNormalize2((&sphere->verts[vertspos]), (&sphere->normals[vertspos]));
106  vertspos += 3;
107  }
108  }
109  sphere->num_tris = (tris + 1) * (tris + 2) * 2;
110 }
111 
119 void R_SphereInit (void)
120 {
121  r_sphereDetails = Cvar_Get("r_sphereDetails", "1.0", CVAR_ARCHIVE, "Factor to increase or decrease the sphere tris");
122  if (r_sphereDetails->integer <= 0)
123  Cvar_SetValue("r_sphereDetails", 1.0);
124 
125  R_SphereGenerate(&r_globeEarth, 60 * r_sphereDetails->value, EARTH_RADIUS);
126  R_SphereGenerate(&r_globeEarthAtmosphere, 60 * r_sphereDetails->value, EARTH_RADIUS * 1.03);
127  /* the earth has more details than the moon */
128  R_SphereGenerate(&r_globeMoon, 20 * r_sphereDetails->value, MOON_RADIUS);
129 }
130 
131 static inline void R_SphereActivateTextureUnit (gltexunit_t* texunit, void* texCoordBuffer)
132 {
133  R_SelectTexture(texunit);
134  R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texCoordBuffer);
135  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
136 }
137 
138 static inline void R_SphereDeactivateTextureUnit (gltexunit_t* texunit)
139 {
140  R_SelectTexture(texunit);
141  R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
142  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
143 }
144 
145 static void R_SphereRenderTris (const sphere_t* sphere)
146 {
147  glEnable(GL_CULL_FACE);
148  glEnable(GL_NORMALIZE);
149 
150  glDrawArrays(GL_TRIANGLE_STRIP, 0, sphere->num_tris);
151 
152  refdef.batchCount++;
153 
154  glDisable(GL_NORMALIZE);
155  glDisable(GL_CULL_FACE);
156 }
157 
162 static inline bool R_SphereCheckGLSL (const sphere_t* sphere)
163 {
164  return sphere->glslProgram && qglUseProgram && r_programs->integer;
165 }
166 
170 static void R_SphereShade (const sphere_t* sphere)
171 {
172  if (sphere->overlay)
173  R_BindTexture(sphere->overlay->texnum);
174  else
175  R_BindTexture(sphere->texture->texnum);
176 
177  if (sphere->overlayAlphaMask) {
180  R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, sphere->texes);
182  }
183 
184  R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, sphere->verts);
185  R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, sphere->texes);
186  R_BindArray(GL_NORMAL_ARRAY, GL_FLOAT, sphere->normals);
187 
188  glEnableClientState(GL_NORMAL_ARRAY);
189 
190  R_SphereRenderTris(sphere);
191 
192  glDisableClientState(GL_NORMAL_ARRAY);
193 
194  if (sphere->overlayAlphaMask)
196 }
197 
201 static void R_SphereShadeGLSL (const sphere_t* sphere)
202 {
203  if (Vector4NotEmpty(sphere->nightLightPos))
204  glLightfv(GL_LIGHT1, GL_POSITION, sphere->nightLightPos);
205 
206  /* configure openGL to use our shader program */
207  R_EnableLighting(sphere->glslProgram, true);
208 
209  R_BindTexture(sphere->texture->texnum);
210  if (sphere->blendTexture)
212  if (sphere->normalMap)
214 
215  if (sphere->blendScale >= 0)
216  R_ProgramParameter1f("BLENDSCALE", sphere->blendScale);
217  if (sphere->glowScale >= 0)
218  R_ProgramParameter1f("GLOWSCALE", sphere->glowScale);
219 
220  /* set up pointers */
223 
225  R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, sphere->verts);
226  R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, sphere->texes);
227  R_BindArray(GL_NORMAL_ARRAY, GL_FLOAT, sphere->normals);
228 
229  R_SphereRenderTris(sphere);
230 
233 
234  /* deactivate the shader program */
235  R_EnableLighting(nullptr, false);
237 }
238 
247 void R_SphereRender (const sphere_t* sphere, const vec3_t pos, const vec3_t rotate, const float scale, const vec4_t lightPos)
248 {
249  /* go to a new matrix */
250  glPushMatrix();
251 
252  glMatrixMode(GL_MODELVIEW);
253  glTranslatef(pos[0], pos[1], pos[2]);
254 
255  /* flatten the sphere */
256  glScalef(scale * viddef.rx, scale * viddef.ry, scale);
257  R_CheckError();
258 
259  /* rotate the globe as given in ccs.angles */
260  glRotatef(rotate[YAW], 1, 0, 0);
261  glRotatef(rotate[ROLL], 0, 1, 0);
262  glRotatef(rotate[PITCH], 0, 0, 1);
263 
264  if (lightPos && VectorNotEmpty(lightPos))
265  glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
266 
267  R_CheckError();
268 
269  if (!sphere->overlay && R_SphereCheckGLSL(sphere))
270  R_SphereShadeGLSL(sphere); /* render globe with bump mapping, specularity, etc. */
271  else
272  R_SphereShade(sphere); /* otherwise, use basic OpenGL rendering */
273 
274  /* cleanup common to both GLSL and normal rendering */
275  R_CheckError();
276 
277  /* restore the previous matrix */
278  glPopMatrix();
279 
280  refdef.aliasCount += sphere->num_tris * sphere->num_tris;
281 
282  R_BindDefaultArray(GL_VERTEX_ARRAY);
283  R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
284  R_BindDefaultArray(GL_NORMAL_ARRAY);
285 }
#define Vector4NotEmpty(a)
Definition: vector.h:76
void R_EnableTexture(gltexunit_t *texunit, bool enable)
Definition: r_state.cpp:303
float * normals
Definition: r_sphere.h:31
#define VectorSet(v, x, y, z)
Definition: vector.h:59
static void R_SphereActivateTextureUnit(gltexunit_t *texunit, void *texCoordBuffer)
Definition: r_sphere.cpp:131
int num_tris
Definition: r_sphere.h:37
#define ROLL
Definition: mathlib.h:56
static const vec3_t scale
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
Definition: cvar.h:71
void R_BindLightmapTexture(GLuint texnum)
Definition: r_state.cpp:90
static void R_SphereShadeGLSL(const sphere_t *sphere)
render sphere using GLSL (bump mapping, specularity, and season-blending)
Definition: r_sphere.cpp:201
cvar_t * r_programs
Definition: r_main.cpp:97
image_t * blendTexture
Definition: r_sphere.h:33
static cvar_t * r_sphereDetails
Definition: r_sphere.cpp:31
float rx
Definition: cl_video.h:71
float value
Definition: cvar.h:80
memPool_t * vid_genericPool
Definition: cl_main.cpp:87
viddef_t viddef
Definition: cl_video.cpp:34
local graphics definitions
static bool R_SphereCheckGLSL(const sphere_t *sphere)
Definition: r_sphere.cpp:162
vec_t VectorNormalize2(const vec3_t v, vec3_t out)
Calculated the normal vector for a given vec3_t.
Definition: mathlib.cpp:237
int integer
Definition: cvar.h:81
float * verts
Definition: r_sphere.h:30
#define texunit_lightmap
Definition: r_state.h:69
void R_SphereInit(void)
Creates the spheres we need for rendering the 3d globe.
Definition: r_sphere.cpp:119
#define CVAR_ARCHIVE
Definition: cvar.h:40
#define YAW
Definition: mathlib.h:55
static float rhoSpiral(const int index, const float deltaRho, const float thetaAngle)
Definition: r_sphere.cpp:37
sphere_t r_globeEarthAtmosphere
Definition: r_sphere.cpp:35
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
Definition: cvar.cpp:342
rendererData_t refdef
Definition: r_main.cpp:45
#define texunit_1
Definition: r_state.h:62
#define Vector2Set(v, x, y)
Definition: vector.h:61
#define M_PI
Definition: mathlib.h:34
image_t * texture
Definition: r_sphere.h:32
texunits maintain multitexture state
Definition: r_state.h:48
#define PITCH
Definition: mathlib.h:54
void R_BindDefaultArray(GLenum target)
Binds the appropriate shared vertex array to the specified target.
Definition: r_state.cpp:182
#define VectorNotEmpty(a)
Definition: vector.h:72
sphere_t r_globeEarth
Definition: r_sphere.cpp:33
QGL_EXTERN GLuint index
Definition: r_gl.h:110
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
#define Mem_PoolAllocTypeN(type, n, pool)
Definition: mem.h:42
float blendScale
Definition: r_sphere.h:41
#define texunit_2
Definition: r_state.h:63
#define texunit_diffuse
Definition: r_state.h:68
void R_SphereRender(const sphere_t *sphere, const vec3_t pos, const vec3_t rotate, const float scale, const vec4_t lightPos)
Draw the sphere.
Definition: r_sphere.cpp:247
image_t * overlay
Definition: r_sphere.h:34
QGL_EXTERN GLint i
Definition: r_gl.h:113
float glowScale
Definition: r_sphere.h:42
void R_SphereGenerate(sphere_t *sphere, const int tris, const float radius)
Initialize the globe chain arrays.
Definition: r_sphere.cpp:51
#define EARTH_RADIUS
Definition: r_geoscape.h:34
static void R_SphereDeactivateTextureUnit(gltexunit_t *texunit)
Definition: r_sphere.cpp:138
Error checking function.
vec_t vec3_t[3]
Definition: ufotypes.h:39
bool R_EnableLighting(r_program_t *program, bool enable)
Enables hardware-accelerated lighting with the specified program. This should be called after any tex...
Definition: r_state.cpp:350
vec4_t nightLightPos
Definition: r_sphere.h:43
#define R_CheckError()
Definition: r_error.h:30
float ry
Definition: cl_video.h:72
image_t * overlayAlphaMask
Definition: r_sphere.h:35
#define MOON_RADIUS
Definition: r_geoscape.h:35
Functions to generate and render spheres.
static void R_SphereRenderTris(const sphere_t *sphere)
Definition: r_sphere.cpp:145
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition: cvar.cpp:671
void R_ProgramParameter1f(const char *name, GLfloat value)
Definition: r_program.cpp:121
image_t * normalMap
Definition: r_sphere.h:36
static void R_SphereShade(const sphere_t *sphere)
render sphere using standard OpenGL lighting
Definition: r_sphere.cpp:170
float * texes
Definition: r_sphere.h:29
void R_BindTextureForTexUnit(GLuint texnum, gltexunit_t *texunit)
Definition: r_state.cpp:77
#define R_BindTexture(tn)
Definition: r_state.h:184
r_program_t * glslProgram
Definition: r_sphere.h:40
sphere_t r_globeMoon
Definition: r_sphere.cpp:34
bool R_SelectTexture(gltexunit_t *texunit)
Returns false if the texunit is not supported.
Definition: r_state.cpp:40
void R_BindArray(GLenum target, GLenum type, const void *array)
Definition: r_state.cpp:148
GLuint texnum
Definition: r_image.h:66
vec_t vec4_t[4]
Definition: ufotypes.h:40