00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "r_local.h"
00027 #include "r_lightmap.h"
00028 #include "r_material.h"
00029 #include "r_light.h"
00030 #include "r_draw.h"
00031
00032
00033
00034
00035
00036
00037
00038 #define BACKFACE_EPSILON 0.01
00039
00040
00047 static qboolean R_CullBox (const vec3_t mins, const vec3_t maxs)
00048 {
00049 int i;
00050
00051 if (r_nocull->integer)
00052 return qfalse;
00053
00054 for (i = lengthof(r_locals.frustum) - 1; i >= 0; i--)
00055 if (TR_BoxOnPlaneSide(mins, maxs, &r_locals.frustum[i]) == PSIDE_BACK)
00056 return qtrue;
00057 return qfalse;
00058 }
00059
00060
00068 qboolean R_CullSphere (const vec3_t centre, const float radius, const unsigned int clipflags)
00069 {
00070 unsigned int i;
00071 unsigned int bit;
00072 const cBspPlane_t *p;
00073
00074 if (r_nocull->integer)
00075 return qfalse;
00076
00077 for (i = lengthof(r_locals.frustum), bit = 1, p = r_locals.frustum; i > 0; i--, bit <<= 1, p++) {
00078 if (!(clipflags & bit))
00079 continue;
00080 if (DotProduct(centre, p->normal) - p->dist <= -radius)
00081 return qtrue;
00082 }
00083
00084 return qfalse;
00085 }
00086
00093 qboolean R_CullBspModel (const entity_t *e)
00094 {
00095 vec3_t mins, maxs, entOrigin;
00096
00097
00098 if (!e->model->bsp.nummodelsurfaces)
00099 return qtrue;
00100
00101 VectorCopy(*R_EntityGetOrigin(e), entOrigin);
00102 if (e->isOriginBrushModel) {
00103 int i;
00104 for (i = 0; i < 3; i++) {
00105 mins[i] = entOrigin[i] - e->model->radius;
00106 maxs[i] = entOrigin[i] + e->model->radius;
00107 }
00108 } else {
00109 VectorAdd(entOrigin, e->model->mins, mins);
00110 VectorAdd(entOrigin, e->model->maxs, maxs);
00111 }
00112
00113 return R_CullBox(mins, maxs);
00114 }
00115
00121 static void R_DrawBspModelSurfaces (const entity_t *e, const vec3_t modelorg)
00122 {
00123 int i;
00124 mBspSurface_t *surf;
00125
00126
00127
00128 const int f = r_locals.frame;
00129 r_locals.frame = -1;
00130
00131 surf = &e->model->bsp.surfaces[e->model->bsp.firstmodelsurface];
00132
00133 for (i = 0; i < e->model->bsp.nummodelsurfaces; i++, surf++) {
00135 #if 0
00136 float dot;
00137
00138 if (AXIAL(surf->plane))
00139 dot = modelorg[surf->plane->type] - surf->plane->dist;
00140 else
00141 dot = DotProduct(modelorg, surf->plane->normal) - surf->plane->dist;
00142
00143 if (((surf->flags & MSURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
00144 (!(surf->flags & MSURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
00145 #endif
00146
00147 surf->frame = r_locals.frame;
00148 }
00149
00150 R_DrawOpaqueSurfaces(e->model->bsp.opaque_surfaces);
00151
00152 R_DrawOpaqueWarpSurfaces(e->model->bsp.opaque_warp_surfaces);
00153
00154 R_DrawAlphaTestSurfaces(e->model->bsp.alpha_test_surfaces);
00155
00156 R_EnableBlend(qtrue);
00157
00158 R_DrawMaterialSurfaces(e->model->bsp.material_surfaces);
00159
00160 R_DrawFlareSurfaces(e->model->bsp.flare_surfaces);
00161
00162 R_EnableFog(qfalse);
00163
00164 R_DrawBlendSurfaces(e->model->bsp.blend_surfaces);
00165
00166 R_DrawBlendWarpSurfaces(e->model->bsp.blend_warp_surfaces);
00167
00168 R_EnableFog(qtrue);
00169
00170 R_EnableBlend(qfalse);
00171
00172
00173 r_locals.frame = f;
00174 }
00175
00181 void R_DrawBrushModel (const entity_t * e)
00182 {
00183
00184 vec3_t modelorg, entOrigin;
00185
00186 VectorCopy(*R_EntityGetOrigin(e), entOrigin);
00187
00188
00189 VectorSubtract(refdef.viewOrigin, entOrigin, modelorg);
00190 if (VectorNotEmpty(e->angles)) {
00191 vec3_t rotationMatrix[3];
00192 VectorCreateRotationMatrix(e->angles, rotationMatrix);
00193 VectorRotatePoint(modelorg, rotationMatrix);
00194 }
00195
00196 R_ShiftLights(entOrigin);
00197
00198 glPushMatrix();
00199
00200 glTranslatef(entOrigin[0], entOrigin[1], entOrigin[2]);
00201 glRotatef(e->angles[YAW], 0, 0, 1);
00202 glRotatef(e->angles[PITCH], 0, 1, 0);
00203 glRotatef(e->angles[ROLL], 1, 0, 0);
00204
00205 R_DrawBspModelSurfaces(e, modelorg);
00206
00207
00208 if (r_showbox->integer)
00209 R_DrawBoundingBox(e->model->mins, e->model->maxs);
00210
00211 glPopMatrix();
00212
00213 R_ShiftLights(vec3_origin);
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00227 void R_DrawBspNormals (int tile)
00228 {
00229 int i, j, k;
00230 const mBspSurface_t *surf;
00231 const mBspModel_t *bsp;
00232 const vec4_t color = {1.0, 0.0, 0.0, 1.0};
00233
00234 if (!r_shownormals->integer)
00235 return;
00236
00237 R_EnableTexture(&texunit_diffuse, qfalse);
00238
00239 R_ResetArrayState();
00240
00241 R_Color(color);
00242
00243 k = 0;
00244 bsp = &r_mapTiles[tile]->bsp;
00245 surf = bsp->surfaces;
00246 for (i = 0; i < bsp->numsurfaces; i++, surf++) {
00247 if (surf->frame != r_locals.frame)
00248 continue;
00249
00250 if (surf->texinfo->flags & SURF_WARP)
00251 continue;
00252
00253 if (r_shownormals->integer > 1 && !(surf->texinfo->flags & SURF_PHONG))
00254 continue;
00255
00256
00257 if (k > MAX_GL_ARRAY_LENGTH - 512) {
00258 glDrawArrays(GL_LINES, 0, k / 3);
00259 k = 0;
00260 }
00261
00262 for (j = 0; j < surf->numedges; j++) {
00263 vec3_t end;
00264 const GLfloat *vertex = &bsp->verts[(surf->index + j) * 3];
00265 const GLfloat *normal = &bsp->normals[(surf->index + j) * 3];
00266
00267 VectorMA(vertex, 12.0, normal, end);
00268
00269 memcpy(&r_state.vertex_array_3d[k], vertex, sizeof(vec3_t));
00270 memcpy(&r_state.vertex_array_3d[k + 3], end, sizeof(vec3_t));
00271 k += sizeof(vec3_t) / sizeof(vec_t) * 2;
00272 if (k > MAX_GL_ARRAY_LENGTH)
00273 Com_Error(ERR_DROP, "R_DrawBspNormals: Overflow in array buffer");
00274 }
00275 }
00276
00277 glDrawArrays(GL_LINES, 0, k / 3);
00278
00279 R_EnableTexture(&texunit_diffuse, qtrue);
00280
00281 R_Color(NULL);
00282 }
00283
00292 static void R_RecursiveWorldNode (const mBspNode_t * node, int tile)
00293 {
00294 int i, side, sidebit;
00295 mBspSurface_t *surf;
00296 float dot;
00297
00298 if (node->contents == CONTENTS_SOLID)
00299 return;
00300
00301 if (R_CullBox(node->minmaxs, node->minmaxs + 3))
00302 return;
00303
00304
00305 if (node->contents > CONTENTS_NODE)
00306 return;
00307
00308
00309 assert(node->plane);
00310
00311
00312
00313 if (r_isometric->integer) {
00314 dot = -DotProduct(r_locals.forward, node->plane->normal);
00315 } else if (!AXIAL(node->plane)) {
00316 dot = DotProduct(refdef.viewOrigin, node->plane->normal) - node->plane->dist;
00317 } else {
00318 dot = refdef.viewOrigin[node->plane->type] - node->plane->dist;
00319 }
00320
00321 if (dot >= 0) {
00322 side = 0;
00323 sidebit = 0;
00324 } else {
00325 side = 1;
00326 sidebit = MSURF_PLANEBACK;
00327 }
00328
00329
00330 R_RecursiveWorldNode(node->children[side], tile);
00331
00332 surf = r_mapTiles[tile]->bsp.surfaces + node->firstsurface;
00333 for (i = 0; i < node->numsurfaces; i++, surf++) {
00334
00335 if ((surf->flags & MSURF_PLANEBACK) == sidebit)
00336 surf->frame = r_locals.frame;
00337 }
00338
00339
00340 R_RecursiveWorldNode(node->children[!side], tile);
00341 }
00342
00350 static void R_RecurseWorld (const mBspNode_t * node, int tile)
00351 {
00352
00353 if (node->contents == CONTENTS_PATHFINDING_NODE) {
00354 R_RecurseWorld(node->children[0], tile);
00355 R_RecurseWorld(node->children[1], tile);
00356 } else {
00357 R_RecursiveWorldNode(node, tile);
00358 }
00359 }
00360
00361
00366 void R_GetLevelSurfaceLists (void)
00367 {
00368 int i, tile, mask;
00369
00370 r_locals.frame++;
00371
00372
00373 if (r_locals.frame > 0xffff)
00374 r_locals.frame = 0;
00375
00376 if (!r_drawworld->integer)
00377 return;
00378
00379 mask = 1 << refdef.worldlevel;
00380
00381 for (tile = 0; tile < r_numMapTiles; tile++) {
00382
00383 for (i = 0; i <= LEVEL_LASTVISIBLE; i++) {
00384
00385 if (i && !(i & mask))
00386 continue;
00387
00388 if (!r_mapTiles[tile]->bsp.submodels[i].numfaces)
00389 continue;
00390
00391 R_RecurseWorld(r_mapTiles[tile]->bsp.nodes + r_mapTiles[tile]->bsp.submodels[i].headnode, tile);
00392 }
00393 }
00394 }