Quake II RTX doxygen
1.0 dev
surf.c
Go to the documentation of this file.
1
/*
2
Copyright (C) 1997-2001 Id Software, Inc.
3
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License along
15
with this program; if not, write to the Free Software Foundation, Inc.,
16
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
*/
18
// r_surf.c: surface-related refresh code
19
20
#include "
sw.h
"
21
22
drawsurf_t
r_drawsurf
;
23
24
static
int
sourcetstep
;
25
static
void
*
prowdestbase
;
26
static
byte
*
pbasesource
;
27
static
int
surfrowbytes
;
28
static
unsigned
*
r_lightptr
;
29
static
int
r_stepback
;
30
static
int
r_lightwidth
;
31
static
int
r_numhblocks
,
r_numvblocks
;
32
static
byte
*
r_source
, *
r_sourcemax
;
33
34
static
void
R_DrawSurfaceBlock8_mip0
(
void
);
35
static
void
R_DrawSurfaceBlock8_mip1
(
void
);
36
static
void
R_DrawSurfaceBlock8_mip2
(
void
);
37
static
void
R_DrawSurfaceBlock8_mip3
(
void
);
38
39
static
void
(*
surfmiptable
[4])(
void
) = {
40
R_DrawSurfaceBlock8_mip0
,
41
R_DrawSurfaceBlock8_mip1
,
42
R_DrawSurfaceBlock8_mip2
,
43
R_DrawSurfaceBlock8_mip3
44
};
45
46
static
int
sc_size
;
47
static
surfcache_t
*
sc_rover
, *
sc_base
;
48
49
/*
50
===============
51
R_TextureAnimation
52
53
Returns the proper texture for a given time and base texture
54
===============
55
*/
56
static
image_t
*
R_TextureAnimation
(mtexinfo_t *tex)
57
{
58
int
c
;
59
60
if
(!tex->next)
61
return
tex->image;
62
63
c
=
currententity
->frame % tex->numframes;
64
while
(
c
) {
65
tex = tex->next;
66
c
--;
67
}
68
69
return
tex->image;
70
}
71
72
/*
73
===============
74
R_DrawSurface
75
===============
76
*/
77
static
void
R_DrawSurface
(
void
)
78
{
79
byte
*basetptr;
80
int
smax, tmax, twidth;
81
int
u;
82
int
soffset, toffset;
83
int
horzblockstep;
84
byte
*pcolumndest;
85
void
(*pblockdrawer)(
void
);
86
image_t
*mt;
87
int
blocksize;
88
int
blockdivshift;
89
90
surfrowbytes
=
r_drawsurf
.
rowbytes
;
91
92
mt =
r_drawsurf
.
image
;
93
94
r_source
= mt->pixels[
r_drawsurf
.
surfmip
];
95
96
twidth = (mt->upload_width >>
r_drawsurf
.
surfmip
) *
TEX_BYTES
;
97
98
blocksize = 16 >>
r_drawsurf
.
surfmip
;
99
blockdivshift = 4 -
r_drawsurf
.
surfmip
;
100
101
r_lightwidth
= S_MAX(
r_drawsurf
.
surf
) *
LIGHTMAP_BYTES
;
102
103
r_numhblocks
=
r_drawsurf
.
surfwidth
>> blockdivshift;
104
r_numvblocks
=
r_drawsurf
.
surfheight
>> blockdivshift;
105
106
pblockdrawer =
surfmiptable
[
r_drawsurf
.
surfmip
];
107
// TODO: only needs to be set when there is a display settings change
108
horzblockstep = blocksize *
TEX_BYTES
;
109
110
smax = mt->upload_width >>
r_drawsurf
.
surfmip
;
111
tmax = mt->upload_height >>
r_drawsurf
.
surfmip
;
112
sourcetstep
= twidth;
113
r_stepback
= tmax * twidth;
114
115
r_sourcemax
=
r_source
+ tmax * smax *
TEX_BYTES
;
116
117
soffset =
r_drawsurf
.
surf
->texturemins[0];
118
toffset =
r_drawsurf
.
surf
->texturemins[1];
119
120
// << 16 components are to guarantee positive values for %
121
soffset = ((soffset >>
r_drawsurf
.
surfmip
) + (smax << 16)) % smax;
122
toffset = ((toffset >>
r_drawsurf
.
surfmip
) + (tmax << 16)) % tmax;
123
124
basetptr = &
r_source
[toffset * twidth];
125
126
pcolumndest =
r_drawsurf
.
surfdat
;
127
128
for
(u = 0; u <
r_numhblocks
; u++) {
129
r_lightptr
= (
unsigned
*)
blocklights
+ u *
LIGHTMAP_BYTES
;
130
131
prowdestbase
= pcolumndest;
132
133
pbasesource
= basetptr + soffset *
TEX_BYTES
;
134
135
(*pblockdrawer)();
136
137
soffset += blocksize;
138
if
(soffset >= smax)
139
soffset = 0;
140
141
pcolumndest += horzblockstep;
142
}
143
}
144
145
//=============================================================================
146
147
#define BLOCK_FUNC R_DrawSurfaceBlock8_mip0
148
#define BLOCK_SHIFT 4
149
#include "
block.h
"
150
151
#define BLOCK_FUNC R_DrawSurfaceBlock8_mip1
152
#define BLOCK_SHIFT 3
153
#include "
block.h
"
154
155
#define BLOCK_FUNC R_DrawSurfaceBlock8_mip2
156
#define BLOCK_SHIFT 2
157
#include "
block.h
"
158
159
#define BLOCK_FUNC R_DrawSurfaceBlock8_mip3
160
#define BLOCK_SHIFT 1
161
#include "
block.h
"
162
163
//============================================================================
164
165
166
/*
167
================
168
R_InitCaches
169
170
================
171
*/
172
void
R_InitCaches
(
void
)
173
{
174
int
size;
175
int
pix;
176
177
// calculate size to allocate
178
if
(
sw_surfcacheoverride
->integer) {
179
size =
Cvar_ClampInteger
(
sw_surfcacheoverride
,
180
SURFCACHE_SIZE_AT_320X240
,
181
SURFCACHE_SIZE_AT_320X240
* 25);
182
}
else
{
183
size =
SURFCACHE_SIZE_AT_320X240
;
184
185
pix =
vid
.
width
*
vid
.
height
;
186
if
(pix > 64000)
187
size += (pix - 64000) * 3;
188
}
189
190
size *=
TEX_BYTES
;
191
192
// round up to page size
193
size = (size + 8191) & ~8191;
194
195
Com_DPrintf(
"%ik surface cache\n"
, size / 1024);
196
197
sc_size
= size;
198
sc_base
= (
surfcache_t
*)R_Malloc(size);
199
sc_rover
=
sc_base
;
200
201
sc_base
->
next
= NULL;
202
sc_base
->
owner
= NULL;
203
sc_base
->
size
=
sc_size
;
204
}
205
206
void
R_FreeCaches
(
void
)
207
{
208
if
(
sc_base
) {
209
Z_Free
(
sc_base
);
210
sc_base
= NULL;
211
}
212
213
sc_size
= 0;
214
sc_rover
= NULL;
215
}
216
217
/*
218
==================
219
D_FlushCaches
220
==================
221
*/
222
void
D_FlushCaches
(
void
)
223
{
224
surfcache_t
*
c
;
225
226
if
(!
sc_base
)
227
return
;
228
229
for
(
c
=
sc_base
;
c
;
c
=
c
->next) {
230
if
(
c
->owner) {
231
*
c
->owner = NULL;
232
}
233
}
234
235
sc_rover
=
sc_base
;
236
sc_base
->
next
= NULL;
237
sc_base
->
owner
= NULL;
238
sc_base
->
size
=
sc_size
;
239
}
240
241
/*
242
=================
243
D_SCAlloc
244
=================
245
*/
246
static
surfcache_t
*
D_SCAlloc
(
int
width
,
int
size)
247
{
248
surfcache_t
*
new
;
249
250
if
((
width
< 0) || (
width
> 256))
251
Com_Error
(ERR_FATAL,
"D_SCAlloc: bad cache width %d\n"
,
width
);
252
253
if
((size <= 0) || (size > 0x10000 *
TEX_BYTES
))
254
Com_Error
(ERR_FATAL,
"D_SCAlloc: bad cache size %d\n"
, size);
255
256
size +=
sizeof
(
surfcache_t
) - 4;
257
size = (size + 3) & ~3;
258
if
(size >
sc_size
)
259
Com_Error
(ERR_FATAL,
"D_SCAlloc: %i > cache size of %i"
, size,
sc_size
);
260
261
// if there is not size bytes after the rover, reset to the start
262
if
(!
sc_rover
|| (
byte
*)
sc_rover
- (
byte
*)
sc_base
>
sc_size
- size) {
263
sc_rover
=
sc_base
;
264
}
265
266
// colect and free surfcache_t blocks until the rover block is large enough
267
new
=
sc_rover
;
268
if
(
sc_rover
->
owner
)
269
*
sc_rover
->
owner
= NULL;
270
271
while
(new->size < size) {
272
// free another
273
sc_rover
=
sc_rover
->
next
;
274
if
(!
sc_rover
)
275
Com_Error
(ERR_FATAL,
"D_SCAlloc: hit the end of memory"
);
276
if
(
sc_rover
->
owner
)
277
*
sc_rover
->
owner
= NULL;
278
279
new
->
size
+=
sc_rover
->
size
;
280
new
->next =
sc_rover
->
next
;
281
}
282
283
// create a fragment out of any leftovers
284
if
(new->size - size > 256) {
285
sc_rover
= (
surfcache_t
*)((
byte
*)
new
+ size);
286
sc_rover
->
size
=
new
->size - size;
287
sc_rover
->
next
=
new
->
next
;
288
sc_rover
->
width
= 0;
289
sc_rover
->
owner
= NULL;
290
new
->
next
=
sc_rover
;
291
new
->
size
= size;
292
}
else
293
sc_rover
=
new
->
next
;
294
295
new
->
width
=
width
;
296
// DEBUG
297
if
(
width
> 0)
298
new
->height = (size -
sizeof
(*new) +
sizeof
(
new
->data)) /
width
;
299
300
new
->owner = NULL;
// should be set properly after return
301
302
return
new
;
303
}
304
305
306
/*
307
=================
308
D_SCDump
309
=================
310
*/
311
void
D_SCDump_f
(
void
)
312
{
313
surfcache_t
*test;
314
315
for
(test =
sc_base
; test; test = test->
next
) {
316
if
(test ==
sc_rover
)
317
Com_Printf(
"ROVER:\n"
);
318
Com_Printf(
"%p : %i bytes %i width\n"
, test, test->
size
,
319
test->
width
);
320
}
321
}
322
323
//=============================================================================
324
325
/*
326
================
327
D_CacheSurface
328
================
329
*/
330
surfcache_t
*
D_CacheSurface
(mface_t *surface,
int
miplevel
)
331
{
332
surfcache_t
*cache;
333
float
surfscale;
334
335
//
336
// if the surface is animating or flashing, flush the cache
337
//
338
r_drawsurf
.
image
=
R_TextureAnimation
(surface->texinfo);
339
r_drawsurf
.
lightadj
[0] =
r_newrefdef
.lightstyles[surface->styles[0]].white *
sw_modulate
->value * 256;
340
r_drawsurf
.
lightadj
[1] =
r_newrefdef
.lightstyles[surface->styles[1]].white *
sw_modulate
->value * 256;
341
r_drawsurf
.
lightadj
[2] =
r_newrefdef
.lightstyles[surface->styles[2]].white *
sw_modulate
->value * 256;
342
r_drawsurf
.
lightadj
[3] =
r_newrefdef
.lightstyles[surface->styles[3]].white *
sw_modulate
->value * 256;
343
344
//
345
// see if the cache holds apropriate data
346
//
347
cache = surface->cachespots[
miplevel
];
348
349
if
(cache && !cache->
dlight
&& surface->dlightframe !=
r_framecount
350
&& cache->
image
==
r_drawsurf
.
image
351
&& cache->
lightadj
[0] ==
r_drawsurf
.
lightadj
[0]
352
&& cache->
lightadj
[1] ==
r_drawsurf
.
lightadj
[1]
353
&& cache->
lightadj
[2] ==
r_drawsurf
.
lightadj
[2]
354
&& cache->
lightadj
[3] ==
r_drawsurf
.
lightadj
[3])
355
return
cache;
356
357
//
358
// determine shape of surface
359
//
360
surfscale = 1.0 / (1 <<
miplevel
);
361
r_drawsurf
.
surfmip
=
miplevel
;
362
r_drawsurf
.
surfwidth
= surface->extents[0] >>
miplevel
;
363
r_drawsurf
.
rowbytes
=
r_drawsurf
.
surfwidth
*
TEX_BYTES
;
364
r_drawsurf
.
surfheight
= surface->extents[1] >>
miplevel
;
365
366
//
367
// allocate memory if needed
368
//
369
if
(!cache) {
// if a texture just animated, don't reallocate it
370
cache =
D_SCAlloc
(
r_drawsurf
.
surfwidth
,
371
r_drawsurf
.
surfwidth
*
r_drawsurf
.
surfheight
*
TEX_BYTES
);
372
surface->cachespots[
miplevel
] = cache;
373
cache->
owner
= &surface->cachespots[
miplevel
];
374
cache->
mipscale
= surfscale;
375
}
376
377
if
(surface->dlightframe ==
r_framecount
)
378
cache->
dlight
= 1;
379
else
380
cache->
dlight
= 0;
381
382
r_drawsurf
.
surfdat
= (
pixel_t
*)cache->
data
;
383
384
cache->
image
=
r_drawsurf
.
image
;
385
cache->
lightadj
[0] =
r_drawsurf
.
lightadj
[0];
386
cache->
lightadj
[1] =
r_drawsurf
.
lightadj
[1];
387
cache->
lightadj
[2] =
r_drawsurf
.
lightadj
[2];
388
cache->
lightadj
[3] =
r_drawsurf
.
lightadj
[3];
389
390
//
391
// draw and light the surface texture
392
//
393
r_drawsurf
.
surf
= surface;
394
395
c_surf
++;
396
397
// calculate the lightings
398
R_BuildLightMap
();
399
400
// rasterize the surface into the cache
401
R_DrawSurface
();
402
403
return
cache;
404
}
405
406
sc_base
static surfcache_t * sc_base
Definition:
surf.c:47
drawsurf_s
Definition:
sw.h:176
block.h
surfcache_s::size
int size
Definition:
sw.h:212
r_numvblocks
static int r_numvblocks
Definition:
surf.c:31
drawsurf_s::surfheight
int surfheight
Definition:
sw.h:184
pbasesource
static byte * pbasesource
Definition:
surf.c:26
r_newrefdef
refdef_t r_newrefdef
Definition:
main.c:28
r_lightwidth
static int r_lightwidth
Definition:
surf.c:30
miplevel
static int miplevel
Definition:
edge.c:61
R_DrawSurfaceBlock8_mip2
static void R_DrawSurfaceBlock8_mip2(void)
surfcache_s
Definition:
sw.h:207
image_t
struct image_s image_t
Definition:
material.h:27
sc_size
static int sc_size
Definition:
surf.c:46
R_DrawSurfaceBlock8_mip1
static void R_DrawSurfaceBlock8_mip1(void)
R_TextureAnimation
static image_t * R_TextureAnimation(mtexinfo_t *tex)
Definition:
surf.c:56
TEX_BYTES
#define TEX_BYTES
Definition:
sw.h:50
surfmiptable
static void(* surfmiptable[4])(void)
Definition:
surf.c:39
viddef_t::width
int width
Definition:
sw.h:127
D_SCDump_f
void D_SCDump_f(void)
Definition:
surf.c:311
surfcache_s::lightadj
int lightadj[MAX_LIGHTMAPS]
Definition:
sw.h:210
sw_surfcacheoverride
cvar_t * sw_surfcacheoverride
Definition:
main.c:84
r_framecount
int r_framecount
Definition:
main.c:64
r_lightptr
static unsigned * r_lightptr
Definition:
surf.c:28
viddef_t::height
int height
Definition:
sw.h:128
prowdestbase
static void * prowdestbase
Definition:
surf.c:25
c_surf
int c_surf
Definition:
main.c:42
surfcache_s::image
image_t * image
Definition:
sw.h:216
R_DrawSurfaceBlock8_mip3
static void R_DrawSurfaceBlock8_mip3(void)
r_sourcemax
static byte * r_sourcemax
Definition:
surf.c:32
blocklights
static float blocklights[MAX_BLOCKLIGHTS *3]
Definition:
surf.c:112
surfcache_t
struct surfcache_s surfcache_t
width
static int width
Definition:
physical_sky.c:38
currententity
entity_t * currententity
Definition:
bsp.c:26
drawsurf_s::surf
mface_t * surf
Definition:
sw.h:179
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition:
g_main.c:258
R_BuildLightMap
void R_BuildLightMap(void)
Definition:
light.c:290
pixel_t
unsigned char pixel_t
Definition:
sw.h:121
drawsurf_s::lightadj
fixed8_t lightadj[MAX_LIGHTMAPS]
Definition:
sw.h:180
sw.h
drawsurf_s::rowbytes
int rowbytes
Definition:
sw.h:178
surfcache_s::mipscale
float mipscale
Definition:
sw.h:215
Z_Free
void Z_Free(void *ptr)
Definition:
zone.c:147
R_InitCaches
void R_InitCaches(void)
Definition:
surf.c:172
drawsurf_s::image
image_t * image
Definition:
sw.h:181
surfcache_s::owner
struct surfcache_s ** owner
Definition:
sw.h:209
void
void(APIENTRY *qwglDrawBuffer)(GLenum mode)
r_source
static byte * r_source
Definition:
surf.c:32
sc_rover
static surfcache_t * sc_rover
Definition:
surf.c:47
r_numhblocks
static int r_numhblocks
Definition:
surf.c:31
drawsurf_s::surfmip
int surfmip
Definition:
sw.h:182
D_SCAlloc
static surfcache_t * D_SCAlloc(int width, int size)
Definition:
surf.c:246
c
statCounters_t c
Definition:
main.c:30
sw_modulate
cvar_t * sw_modulate
Definition:
main.c:87
LIGHTMAP_BYTES
#define LIGHTMAP_BYTES
Definition:
sw.h:203
D_FlushCaches
void D_FlushCaches(void)
Definition:
surf.c:222
Cvar_ClampInteger
int Cvar_ClampInteger(cvar_t *var, int min, int max)
Definition:
cvar.c:549
r_drawsurf
drawsurf_t r_drawsurf
Definition:
surf.c:22
drawsurf_s::surfwidth
int surfwidth
Definition:
sw.h:183
surfcache_s::data
byte data[4]
Definition:
sw.h:217
r_stepback
static int r_stepback
Definition:
surf.c:29
sourcetstep
static int sourcetstep
Definition:
surf.c:24
drawsurf_s::surfdat
byte * surfdat
Definition:
sw.h:177
R_DrawSurface
static void R_DrawSurface(void)
Definition:
surf.c:77
D_CacheSurface
surfcache_t * D_CacheSurface(mface_t *surface, int miplevel)
Definition:
surf.c:330
surfcache_s::dlight
int dlight
Definition:
sw.h:211
R_FreeCaches
void R_FreeCaches(void)
Definition:
surf.c:206
surfcache_s::width
unsigned width
Definition:
sw.h:213
vid
viddef_t vid
Definition:
main.c:22
surfcache_s::next
struct surfcache_s * next
Definition:
sw.h:208
surfrowbytes
static int surfrowbytes
Definition:
surf.c:27
R_DrawSurfaceBlock8_mip0
static void R_DrawSurfaceBlock8_mip0(void)
SURFCACHE_SIZE_AT_320X240
#define SURFCACHE_SIZE_AT_320X240
Definition:
sw.h:94
src
refresh
sw
surf.c
Generated by
1.8.17