UFO: Alien Invasion
Loading...
Searching...
No Matches
patches.cpp
Go to the documentation of this file.
1
4
5/*
6Copyright (C) 1997-2001 Id Software, Inc.
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17See the GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23*/
24
25#include "lighting.h"
26#include "bsp.h"
27#include "../../shared/images.h"
28
31
32/*
33===================================================================
34TEXTURE LIGHT VALUES
35===================================================================
36*/
37
42{
43 int j, texels = 0;
44 char path[MAX_QPATH];
45 int color[3];
46 SDL_Surface* surf;
47
48 /* always set index 0 even if no textures */
49 VectorSet(texture_reflectivity[0], 0.5, 0.5, 0.5);
50
51 VectorSet(color, 0, 0, 0);
52
53 for (int i = 0; i < curTile->numtexinfo; i++) {
54 /* see if an earlier texinfo already got the value */
55 for (j = 0; j < i; j++) {
56 if (Q_streq(curTile->texinfo[i].texture, curTile->texinfo[j].texture)) {
58 break;
59 }
60 }
61 if (j != i) /* earlier texinfo found, continue */
62 continue;
63
64 /* load the image file */
65 Com_sprintf(path, sizeof(path), "textures/%s", curTile->texinfo[i].texture);
66 if (!(surf = Img_LoadImage(path))) {
67 Verb_Printf(VERB_NORMAL, "Couldn't load %s\n", path);
68 VectorSet(texture_reflectivity[i], 0.5, 0.5, 0.5);
69 continue;
70 }
71
72 /* calculate average color */
73 texels = surf->w * surf->h;
74 color[0] = color[1] = color[2] = 0;
75
76 for(j = 0; j < texels; j++){
77 const byte* pos = (byte*)surf->pixels + j * 4;
78 color[0] += *pos++; /* r */
79 color[1] += *pos++; /* g */
80 color[2] += *pos++; /* b */
81 }
82
83 Verb_Printf(VERB_EXTRA, "Loaded %s (%dx%d)\n", curTile->texinfo[i].texture, surf->w, surf->h);
84
85 SDL_FreeSurface(surf);
86
87 for(j = 0; j < 3; j++){
88 const float r = color[j] / texels / 255.0;
89 texture_reflectivity[i][j] = r;
90 }
91 }
92}
93
94
96{
97 winding_t* w = AllocWinding(f->numedges);
98 w->numpoints = f->numedges;
99
100 for (int i = 0; i < f->numedges; i++) {
101 const int se = curTile->surfedges[f->firstedge + i];
102 int v;
103 if (se < 0)
104 v = curTile->edges[-se].v[1];
105 else
106 v = curTile->edges[se].v[0];
107
108 dBspVertex_t* dv = &curTile->vertexes[v];
109 VectorCopy(dv->point, w->p[i]);
110 }
111
113
114 return w;
115}
116
117static inline bool HasLight (const dBspSurface_t* f)
118{
119 const dBspTexinfo_t* tex;
120
121 tex = &curTile->texinfo[f->texinfo];
122 return (tex->surfaceFlags & SURF_LIGHT) && tex->value;
123}
124
130static inline void EmissiveLight (patch_t* patch)
131{
132 const dBspTexinfo_t* tex = &curTile->texinfo[patch->face->texinfo];
133 const vec_t* ref = texture_reflectivity[patch->face->texinfo];
134
135 VectorScale(ref, tex->value, patch->light);
136}
137
145static void BuildPatch (int fn, winding_t* w)
146{
147 patch_t* patch;
148 dBspPlane_t* plane;
149
150 patch = Mem_AllocType(patch_t);
151
152 face_patches[fn] = patch;
153
154 patch->face = &curTile->faces[fn];
155 patch->winding = w;
156
157 /* resolve the normal */
158 plane = &curTile->planes[patch->face->planenum];
159
160 if (patch->face->side)
161 VectorNegate(plane->normal, patch->normal);
162 else
163 VectorCopy(plane->normal, patch->normal);
164
165 WindingCenter(w, patch->origin);
166
167 /* nudge the origin out along the normal */
168 VectorMA(patch->origin, 2.0, patch->normal, patch->origin);
169
170 patch->area = WindingArea(w);
171
172 if (patch->area < 1.0) /* clamp area */
173 patch->area = 1.0;
174
175 EmissiveLight(patch); /* surface light */
176}
177
178static entity_t* EntityForModel (int modnum)
179{
180 char name[16];
181
182 Com_sprintf(name, sizeof(name), "*%i", modnum);
183 /* search the entities for one using modnum */
184 for (int i = 0; i < num_entities; i++) {
185 const char* s = ValueForKey(&entities[i], "model");
186 if (Q_streq(s, name))
187 return &entities[i];
188 }
189
190 /* return the world */
191 return &entities[0];
192}
193
198void BuildPatches (void)
199{
201
202 for (int i = 0; i < curTile->nummodels; i++) {
203 const dBspModel_t* mod = &curTile->models[i];
204 const entity_t* ent = EntityForModel(i);
206 /* bmodels with origin brushes (like func_door) need to be offset into their
207 * in-use position */
208 GetVectorForKey(ent, "origin", origin);
209
210 for (int j = 0; j < mod->numfaces; j++) {
211 const int facenum = mod->firstface + j;
212 dBspSurface_t* f = &curTile->faces[facenum];
213
214 /* store the origin in case of moving bmodels (e.g. func_door) */
215 VectorCopy(origin, face_offset[facenum]);
216
217 if (!HasLight(f)) /* no light */
218 continue;
219
221
222 for (int k = 0; k < w->numpoints; k++)
223 VectorAdd(w->p[k], origin, w->p[k]);
224
225 BuildPatch(facenum, w);
226 }
227 }
228}
229
230/*
231=======================================================================
232SUBDIVIDE
233=======================================================================
234*/
235
236#define PATCH_SUBDIVIDE 64
237
238static void FinishSubdividePatch (patch_t* patch, patch_t* newp)
239{
240 VectorCopy(patch->normal, newp->normal);
241
242 VectorCopy(patch->light, newp->light);
243
244 patch->area = WindingArea(patch->winding);
245
246 if (patch->area < 1.0)
247 patch->area = 1.0;
248
249 newp->area = WindingArea(newp->winding);
250
251 if (newp->area < 1.0)
252 newp->area = 1.0;
253
254 WindingCenter(patch->winding, patch->origin);
255 /* nudge the patch origin out along the normal */
256 VectorMA(patch->origin, 2.0, patch->normal, patch->origin);
257
258 WindingCenter(newp->winding, newp->origin);
259 /* nudge the patch origin out along the normal */
260 VectorMA(newp->origin, 2.0, newp->normal, newp->origin);
261}
262
266static void SubdividePatch(patch_t* patch)
267{
268 winding_t* w, *o1, *o2;
269 vec3_t mins, maxs;
270 vec3_t split;
271 vec_t dist;
272 int i;
273 patch_t* newp;
274
275 w = patch->winding;
276 WindingBounds(w, mins, maxs);
277
278 VectorClear(split);
279
280 for (i = 0; i < 3; i++) {
281 if (floor((mins[i] + 1) / PATCH_SUBDIVIDE) < floor((maxs[i] - 1) / PATCH_SUBDIVIDE)) {
282 split[i] = 1.0;
283 break;
284 }
285 }
286 /* no splitting needed */
287 if (i == 3)
288 return;
289
290 /* split the winding */
291 dist = PATCH_SUBDIVIDE * (1 + floor((mins[i] + 1) / PATCH_SUBDIVIDE));
292 ClipWindingEpsilon(w, split, dist, ON_EPSILON, &o1, &o2);
293
294 /* create a new patch */
295 newp = Mem_AllocType(patch_t);
296
297 newp->next = patch->next;
298 patch->next = newp;
299
300 patch->winding = o1;
301 newp->winding = o2;
302
303 FinishSubdividePatch(patch, newp);
304
305 SubdividePatch(patch);
306 SubdividePatch(newp);
307}
308
313{
314 for (int i = 0; i < MAX_MAP_FACES; i++) {
315 patch_t* p = face_patches[i];
316
317 if (p) /* break it up */
319 }
320}
321
325void FreePatches (void)
326{
327 for (int i = 0; i < MAX_MAP_FACES; i++) {
328 patch_t* p = face_patches[i];
329 while (p) {
330 patch_t* pnext = p->next;
331 Mem_Free(p);
332 p = pnext;
333 }
334 }
335}
void GetVectorForKey(const entity_t *ent, const char *key, vec3_t vec)
Converts the value of a entity parameter into a vec3_t.
Definition bspfile.cpp:592
int num_entities
Definition bspfile.cpp:394
entity_t entities[MAX_MAP_ENTITIES]
Definition bspfile.cpp:395
const char * ValueForKey(const entity_t *ent, const char *key)
Definition bspfile.cpp:558
#define ON_EPSILON
Definition defines.h:374
#define SURF_LIGHT
Definition defines.h:254
#define MAX_MAP_TEXINFO
Definition defines.h:138
#define MAX_MAP_FACES
Definition defines.h:144
#define MAX_QPATH
Definition filesys.h:40
SDL_Surface * Img_LoadImage(char const *name)
Loads the specified image from the game filesystem into an SDL_Surface.
Definition images.cpp:488
Image loading and saving functions.
voidpf uLong int origin
Definition ioapi.h:45
vec3_t face_offset[MAX_MAP_FACES]
Definition lightmap.cpp:34
patch_t * face_patches[MAX_MAP_FACES]
Definition patches.cpp:30
void VectorMA(const vec3_t veca, const float scale, const vec3_t vecb, vec3_t outVector)
Sets vector_out (vc) to vevtor1 (va) + scale * vector2 (vb).
Definition mathlib.cpp:261
#define Mem_Free(ptr)
Definition mem.h:35
#define Mem_AllocType(type)
Definition mem.h:39
void SubdividePatches(void)
Iterate all of the head face patches, subdividing them as necessary.
Definition patches.cpp:312
static entity_t * EntityForModel(int modnum)
Definition patches.cpp:178
void CalcTextureReflectivity(void)
Calculates the texture color that is used for light emitting surfaces.
Definition patches.cpp:41
static vec3_t texture_reflectivity[MAX_MAP_TEXINFO]
Definition patches.cpp:29
void FreePatches(void)
After light sources have been created, patches may be freed.
Definition patches.cpp:325
static void FinishSubdividePatch(patch_t *patch, patch_t *newp)
Definition patches.cpp:238
static void SubdividePatch(patch_t *patch)
Chops the patch by a global grid.
Definition patches.cpp:266
static void BuildPatch(int fn, winding_t *w)
Build a patch for a surface that emits light.
Definition patches.cpp:145
static winding_t * WindingFromFace(const dBspSurface_t *f)
Definition patches.cpp:95
static void EmissiveLight(patch_t *patch)
Check for light emitted by texture.
Definition patches.cpp:130
static bool HasLight(const dBspSurface_t *f)
Definition patches.cpp:117
#define PATCH_SUBDIVIDE
Definition patches.cpp:236
void BuildPatches(void)
Create surface fragments for light-emitting surfaces so that light sources may be computed along them...
Definition patches.cpp:198
winding_t * AllocWinding(int points)
Allocate a new winding (polygon).
Definition polylib.cpp:38
void RemoveColinearPoints(winding_t *w)
Definition polylib.cpp:55
void WindingCenter(const winding_t *w, vec3_t center)
Definition polylib.cpp:106
void WindingBounds(const winding_t *w, vec3_t mins, vec3_t maxs)
Definition polylib.cpp:97
vec_t WindingArea(const winding_t *w)
Definition polylib.cpp:81
void ClipWindingEpsilon(const winding_t *in, const vec3_t normal, const vec_t dist, const vec_t epsilon, winding_t **front, winding_t **back)
Definition polylib.cpp:204
QGL_EXTERN int GLboolean GLfloat * v
Definition r_gl.h:120
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
#define Q_streq(a, b)
Definition shared.h:136
#define OBJZERO(obj)
Definition shared.h:178
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
int firstface
Definition typedefs.h:358
vec3_t normal
Definition typedefs.h:373
short texinfo
Definition typedefs.h:409
uint16_t planenum
Definition typedefs.h:404
uint32_t surfaceFlags
Definition typedefs.h:390
uint32_t value
Definition typedefs.h:391
float point[3]
Definition typedefs.h:362
winding_t * winding
Definition lighting.h:35
struct patch_s * next
Definition lighting.h:43
vec3_t light
Definition lighting.h:41
vec3_t normal
Definition lighting.h:38
dBspSurface_t * face
Definition lighting.h:34
vec3_t origin
Definition lighting.h:37
float area
Definition lighting.h:40
for storing the vertices of the side of a brush or other polygon
Definition polylib.h:30
int numpoints
Definition polylib.h:31
vec3_t p[4]
Definition polylib.h:32
dMapTile_t * curTile
Definition bsp.cpp:32
void Verb_Printf(const verbosityLevel_t importance, const char *format,...) __attribute__((format(__printf__
@ VERB_NORMAL
Definition shared.h:45
@ VERB_EXTRA
Definition shared.h:46
float vec_t
Definition ufotypes.h:37
vec_t vec3_t[3]
Definition ufotypes.h:39
#define VectorClear(a)
Definition vector.h:55
#define VectorNegate(src, dest)
Definition vector.h:58
#define VectorCopy(src, dest)
Definition vector.h:51
#define VectorAdd(a, b, dest)
Definition vector.h:47
#define VectorSet(v, x, y, z)
Definition vector.h:59
#define VectorScale(in, scale, out)
Definition vector.h:79