cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"};
cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
+cvar_t r_draw2d = {0, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"};
cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
static int r_qwskincache_size;
/// vertex coordinates for a quad that covers the screen exactly
+extern const float r_screenvertex3f[12];
const float r_screenvertex3f[12] =
{
0, 0, 0,
vec_t s, t, intensity;
#define NORMSIZE 64
unsigned char *data;
- data = Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
+ data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
for (side = 0;side < 6;side++)
{
for (y = 0;y < NORMSIZE;y++)
}
size = image_width;
r_refdef.fog_height_tablesize = size;
- r_refdef.fog_height_table1d = Mem_Alloc(r_main_mempool, size * 4);
- r_refdef.fog_height_table2d = Mem_Alloc(r_main_mempool, size * size * 4);
+ r_refdef.fog_height_table1d = (unsigned char *)Mem_Alloc(r_main_mempool, size * 4);
+ r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
memcpy(r_refdef.fog_height_table1d, inpixels, size * 4);
Mem_Free(inpixels);
// LordHavoc: now the magic - what is that table2d for? it is a cooked
}
memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
}
- break;
#endif
+ break;
case RENDERPATH_GL13:
case RENDERPATH_GL11:
break;
Image_StripImageExtension(name, basename, sizeof(basename));
// check for DDS texture file first
- if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor)))
+ if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor, miplevel)))
{
- basepixels = loadimagepixelsbgra(name, complain, true, r_texture_convertsRGB_skin.integer, &miplevel);
+ basepixels = loadimagepixelsbgra(name, complain, true, r_texture_convertsRGB_skin.integer != 0, &miplevel);
if (basepixels == NULL)
return NULL;
}
skinframe->hasalpha = ddshasalpha;
VectorCopy(ddsavgcolor, skinframe->avgcolor);
if (r_loadfog && skinframe->hasalpha)
- skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL);
+ skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL, miplevel);
//Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
}
else
if (r_loaddds)
{
+ mymiplevel = savemiplevel;
if (r_loadnormalmap)
- skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL);
- skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL);
+ skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL, mymiplevel);
+ skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
if (r_loadgloss)
- skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL);
+ skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
}
// _norm is the name used by tenebrae and has been adopted as standard
// _luma is supported only for tenebrae compatibility
// _glow is the preferred name
mymiplevel = savemiplevel;
- if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer, &mymiplevel))))
+ if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel))))
{
skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow)
}
mymiplevel = savemiplevel;
- if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer, &mymiplevel)))
+ if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
{
skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
}
mymiplevel = savemiplevel;
- if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer, &mymiplevel)))
+ if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
{
skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants)
}
mymiplevel = savemiplevel;
- if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer, &mymiplevel)))
+ if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
{
skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt)
}
mymiplevel = savemiplevel;
- if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer, &mymiplevel)))
+ if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
{
skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect)
Con_Printf("loading quake skin \"%s\"\n", name);
// we actually don't upload anything until the first use, because mdl skins frequently go unused, and are almost never used in both modes (colormapped and non-colormapped)
- skinframe->qpixels = Mem_Alloc(r_main_mempool, width*height);
+ skinframe->qpixels = (unsigned char *)Mem_Alloc(r_main_mempool, width*height);
memcpy(skinframe->qpixels, skindata, width*height);
skinframe->qwidth = width;
skinframe->qheight = height;
// generate an image name based on the base and and suffix
dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix);
// load it
- if ((image_buffer = loadimagepixelsbgra(name, false, false, r_texture_convertsRGB_cubemap.integer, NULL)))
+ if ((image_buffer = loadimagepixelsbgra(name, false, false, r_texture_convertsRGB_cubemap.integer != 0, NULL)))
{
// an image loaded, make sure width and height are equal
if (image_width == image_height && (!cubemappixels || image_width == cubemapsize))
if (developer_loading.integer)
Con_Printf("loading cubemap \"%s\"\n", basename);
- cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR, -1, NULL);
+ cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
Mem_Free(cubemappixels);
}
else
r_refdef.viewcache.maxentities = numentities;
if (r_refdef.viewcache.entityvisible)
Mem_Free(r_refdef.viewcache.entityvisible);
- r_refdef.viewcache.entityvisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.maxentities);
+ r_refdef.viewcache.entityvisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.maxentities);
}
if (r_refdef.viewcache.world_numclusters != numclusters)
{
r_refdef.viewcache.world_numclusterbytes = numclusterbytes;
if (r_refdef.viewcache.world_pvsbits)
Mem_Free(r_refdef.viewcache.world_pvsbits);
- r_refdef.viewcache.world_pvsbits = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numclusterbytes);
+ r_refdef.viewcache.world_pvsbits = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numclusterbytes);
}
if (r_refdef.viewcache.world_numleafs != numleafs)
{
r_refdef.viewcache.world_numleafs = numleafs;
if (r_refdef.viewcache.world_leafvisible)
Mem_Free(r_refdef.viewcache.world_leafvisible);
- r_refdef.viewcache.world_leafvisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numleafs);
+ r_refdef.viewcache.world_leafvisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numleafs);
}
if (r_refdef.viewcache.world_numsurfaces != numsurfaces)
{
r_refdef.viewcache.world_numsurfaces = numsurfaces;
if (r_refdef.viewcache.world_surfacevisible)
Mem_Free(r_refdef.viewcache.world_surfacevisible);
- r_refdef.viewcache.world_surfacevisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numsurfaces);
+ r_refdef.viewcache.world_surfacevisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numsurfaces);
}
}
Cvar_RegisterVariable(&r_showdisabledepthtest);
Cvar_RegisterVariable(&r_drawportals);
Cvar_RegisterVariable(&r_drawentities);
+ Cvar_RegisterVariable(&r_draw2d);
Cvar_RegisterVariable(&r_drawworld);
Cvar_RegisterVariable(&r_cullentities_trace);
Cvar_RegisterVariable(&r_cullentities_trace_samples);
Cvar_RegisterVariable(&r_framedatasize);
if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
Cvar_SetValue("r_fullbrights", 0);
- R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
+ R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap, NULL, NULL);
Cvar_RegisterVariable(&r_track_sprites);
Cvar_RegisterVariable(&r_track_sprites_flags);
{
int i;
if (!ent->animcache_vertexmesh && ent->animcache_normal3f)
- ent->animcache_vertexmesh = R_FrameData_Alloc(sizeof(r_vertexmesh_t)*numvertices);
+ ent->animcache_vertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(sizeof(r_vertexmesh_t)*numvertices);
if (!ent->animcache_vertexposition)
- ent->animcache_vertexposition = R_FrameData_Alloc(sizeof(r_vertexposition_t)*numvertices);
+ ent->animcache_vertexposition = (r_vertexposition_t *)R_FrameData_Alloc(sizeof(r_vertexposition_t)*numvertices);
if (ent->animcache_vertexposition)
{
for (i = 0;i < numvertices;i++)
{
numvertices = model->surfmesh.num_vertices;
if (wantnormals)
- ent->animcache_normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
if (wanttangents)
{
- ent->animcache_svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
- ent->animcache_tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
}
if (!r_framedata_failed)
{
return false;
// get some memory for this entity and generate mesh data
numvertices = model->surfmesh.num_vertices;
- ent->animcache_vertex3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_vertex3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
if (wantnormals)
- ent->animcache_normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
if (wanttangents)
{
- ent->animcache_svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
- ent->animcache_tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
}
if (!r_framedata_failed)
{
r_waterstate.numwaterplanes = 0;
}
-void R_Water_AddWaterPlane(msurface_t *surface)
+void R_Water_AddWaterPlane(msurface_t *surface, int entno)
{
int triangleindex, planeindex;
const int *e;
r_refdef.view.cullface_front = GL_FRONT;
r_refdef.view.cullface_back = GL_BACK;
// also reverse the view matrix
- Matrix4x4_ConcatScale3(&r_refdef.view.matrix, 1, -1, 1);
+ Matrix4x4_ConcatScale3(&r_refdef.view.matrix, 1, 1, -1); // this serves to invert texcoords in the result, as the copied texture is mapped the wrong way round
R_RenderView_UpdateViewVectors();
if(p->camera_entity)
r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, visorigin, 2, r_refdef.viewcache.world_pvsbits, (r_refdef.viewcache.world_numclusters+7)>>3, false);
r_qwskincache_size = cl.maxclients;
if (r_qwskincache)
Mem_Free(r_qwskincache);
- r_qwskincache = Mem_Alloc(r_main_mempool, sizeof(*r_qwskincache) * r_qwskincache_size);
+ r_qwskincache = (r_qwskincache_t *)Mem_Alloc(r_main_mempool, sizeof(*r_qwskincache) * r_qwskincache_size);
}
if (strcmp(r_qwskincache[i].name, cl.scores[i].qw_skin))
R_LoadQWSkin(&r_qwskincache[i], cl.scores[i].qw_skin);
// may require regenerating vertexmesh or vertexposition arrays...
needsupdate = 0;
+ // check if any dynamic vertex processing must occur
+ dynamicvertex = false;
+
if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_ARRAY_VERTEXCOLOR)) && texturesurfacelist[0]->lightmapinfo)
needsupdate |= BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_NOGAPS;
for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform;deformindex++, deform++)
case Q3DEFORM_NONE:
break;
case Q3DEFORM_AUTOSPRITE:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_AUTOSPRITE2:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_NORMAL:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_WAVE:
if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
break; // if wavefunc is a nop, ignore this transform
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_BULGE:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_MOVE:
if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
break; // if wavefunc is a nop, ignore this transform
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX;
break;
case Q3TCGEN_TEXTURE:
break;
case Q3TCGEN_LIGHTMAP:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_LIGHTMAP | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP;
break;
case Q3TCGEN_VECTOR:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
break;
case Q3TCGEN_ENVIRONMENT:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
break;
}
if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
{
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
}
- // check if any dynamic vertex processing must occur
- dynamicvertex = false;
-
if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
{
dynamicvertex = true;
qboolean useshortelements;
decalsystem->maxdecals = max(16, decalsystem->maxdecals * 2);
useshortelements = decalsystem->maxdecals * 3 <= 65536;
- decalsystem->decals = Mem_Alloc(cls.levelmempool, decalsystem->maxdecals * (sizeof(tridecal_t) + sizeof(float[3][3]) + sizeof(float[3][2]) + sizeof(float[3][4]) + sizeof(int[3]) + (useshortelements ? sizeof(unsigned short[3]) : 0)));
+ decalsystem->decals = (tridecal_t *)Mem_Alloc(cls.levelmempool, decalsystem->maxdecals * (sizeof(tridecal_t) + sizeof(float[3][3]) + sizeof(float[3][2]) + sizeof(float[3][4]) + sizeof(int[3]) + (useshortelements ? sizeof(unsigned short[3]) : 0)));
decalsystem->color4f = (float *)(decalsystem->decals + decalsystem->maxdecals);
decalsystem->texcoord2f = (float *)(decalsystem->color4f + decalsystem->maxdecals*12);
decalsystem->vertex3f = (float *)(decalsystem->texcoord2f + decalsystem->maxdecals*6);
extern cvar_t cl_decals_bias;
extern cvar_t cl_decals_models;
extern cvar_t cl_decals_newsystem_intensitymultiplier;
+// baseparms, parms, temps
+static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, int decalsequence, qboolean dynamic, float (*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex)
+{
+ int cornerindex;
+ int index;
+ float v[9][3];
+ const float *vertex3f;
+ int numpoints;
+ float points[2][9][3];
+ float temp[3];
+ float tc[9][2];
+ float f;
+ float c[9][4];
+ const int *e;
+
+ e = rsurface.modelelement3i + 3*triangleindex;
+
+ vertex3f = rsurface.modelvertex3f;
+
+ for (cornerindex = 0;cornerindex < 3;cornerindex++)
+ {
+ index = 3*e[cornerindex];
+ VectorCopy(vertex3f + index, v[cornerindex]);
+ }
+ // cull backfaces
+ //TriangleNormal(v[0], v[1], v[2], normal);
+ //if (DotProduct(normal, localnormal) < 0.0f)
+ // continue;
+ // clip by each of the box planes formed from the projection matrix
+ // if anything survives, we emit the decal
+ numpoints = PolygonF_Clip(3 , v[0] , planes[0][0], planes[0][1], planes[0][2], planes[0][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
+ if (numpoints < 3)
+ return;
+ numpoints = PolygonF_Clip(numpoints, points[1][0], planes[1][0], planes[1][1], planes[1][2], planes[1][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[0][0]);
+ if (numpoints < 3)
+ return;
+ numpoints = PolygonF_Clip(numpoints, points[0][0], planes[2][0], planes[2][1], planes[2][2], planes[2][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
+ if (numpoints < 3)
+ return;
+ numpoints = PolygonF_Clip(numpoints, points[1][0], planes[3][0], planes[3][1], planes[3][2], planes[3][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[0][0]);
+ if (numpoints < 3)
+ return;
+ numpoints = PolygonF_Clip(numpoints, points[0][0], planes[4][0], planes[4][1], planes[4][2], planes[4][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
+ if (numpoints < 3)
+ return;
+ numpoints = PolygonF_Clip(numpoints, points[1][0], planes[5][0], planes[5][1], planes[5][2], planes[5][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), v[0]);
+ if (numpoints < 3)
+ return;
+ // some part of the triangle survived, so we have to accept it...
+ if (dynamic)
+ {
+ // dynamic always uses the original triangle
+ numpoints = 3;
+ for (cornerindex = 0;cornerindex < 3;cornerindex++)
+ {
+ index = 3*e[cornerindex];
+ VectorCopy(vertex3f + index, v[cornerindex]);
+ }
+ }
+ for (cornerindex = 0;cornerindex < numpoints;cornerindex++)
+ {
+ // convert vertex positions to texcoords
+ Matrix4x4_Transform(projection, v[cornerindex], temp);
+ tc[cornerindex][0] = (temp[1]+1.0f)*0.5f * (s2-s1) + s1;
+ tc[cornerindex][1] = (temp[2]+1.0f)*0.5f * (t2-t1) + t1;
+ // calculate distance fade from the projection origin
+ f = a * (1.0f-fabs(temp[0])) * cl_decals_newsystem_intensitymultiplier.value;
+ f = bound(0.0f, f, 1.0f);
+ c[cornerindex][0] = r * f;
+ c[cornerindex][1] = g * f;
+ c[cornerindex][2] = b * f;
+ c[cornerindex][3] = 1.0f;
+ //VectorMA(v[cornerindex], cl_decals_bias.value, localnormal, v[cornerindex]);
+ }
+ if (dynamic)
+ R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[1], v[2], tc[0], tc[1], tc[2], c[0], c[1], c[2], triangleindex, surfaceindex, decalsequence);
+ else
+ for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
+ R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1, surfaceindex, decalsequence);
+}
static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, int decalsequence)
{
matrix4x4_t projection;
decalsystem_t *decalsystem;
qboolean dynamic;
dp_model_t *model;
- const float *vertex3f;
const msurface_t *surface;
const msurface_t *surfaces;
const int *surfacelist;
int surfacelistindex;
int surfaceindex;
int triangleindex;
- int cornerindex;
- int index;
- int numpoints;
- const int *e;
float localorigin[3];
float localnormal[3];
float localmins[3];
float localmaxs[3];
float localsize;
- float v[9][3];
- float tc[9][2];
- float c[9][4];
//float normal[3];
float planes[6][4];
- float f;
- float points[2][9][3];
float angles[3];
- float temp[3];
+ bih_t *bih;
+ int bih_triangles_count;
+ int bih_triangles[256];
+ int bih_surfaces[256];
decalsystem = &ent->decalsystem;
model = ent->model;
#endif
dynamic = model->surfmesh.isanimated;
- vertex3f = rsurface.modelvertex3f;
numsurfacelist = model->nummodelsurfaces;
surfacelist = model->sortedmodelsurfaces;
surfaces = model->data_surfaces;
- for (surfacelistindex = 0;surfacelistindex < numsurfacelist;surfacelistindex++)
+
+ bih = NULL;
+ bih_triangles_count = -1;
+ if(!dynamic)
{
- surfaceindex = surfacelist[surfacelistindex];
- surface = surfaces + surfaceindex;
- // check cull box first because it rejects more than any other check
- if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
- continue;
- // skip transparent surfaces
- texture = surface->texture;
- if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
- continue;
- if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
- continue;
- numtriangles = surface->num_triangles;
- for (triangleindex = 0, e = rsurface.modelelement3i + 3*surface->num_firsttriangle;triangleindex < numtriangles;triangleindex++, e += 3)
+ if(model->render_bih.numleafs)
+ bih = &model->render_bih;
+ else if(model->collision_bih.numleafs)
+ bih = &model->collision_bih;
+ }
+ if(bih)
+ bih_triangles_count = BIH_GetTriangleListForBox(bih, sizeof(bih_triangles) / sizeof(*bih_triangles), bih_triangles, bih_surfaces, localmins, localmaxs);
+ if(bih_triangles_count == 0)
+ return;
+ if(bih_triangles_count > (int) (sizeof(bih_triangles) / sizeof(*bih_triangles))) // hit too many, likely bad anyway
+ return;
+ if(bih_triangles_count > 0)
+ {
+ for (triangleindex = 0; triangleindex < bih_triangles_count; ++triangleindex)
{
- for (cornerindex = 0;cornerindex < 3;cornerindex++)
- {
- index = 3*e[cornerindex];
- VectorCopy(vertex3f + index, v[cornerindex]);
- }
- // cull backfaces
- //TriangleNormal(v[0], v[1], v[2], normal);
- //if (DotProduct(normal, localnormal) < 0.0f)
- // continue;
- // clip by each of the box planes formed from the projection matrix
- // if anything survives, we emit the decal
- numpoints = PolygonF_Clip(3 , v[0] , planes[0][0], planes[0][1], planes[0][2], planes[0][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
- if (numpoints < 3)
- continue;
- numpoints = PolygonF_Clip(numpoints, points[1][0], planes[1][0], planes[1][1], planes[1][2], planes[1][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[0][0]);
- if (numpoints < 3)
+ surfaceindex = bih_surfaces[triangleindex];
+ surface = surfaces + surfaceindex;
+ texture = surface->texture;
+ if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
continue;
- numpoints = PolygonF_Clip(numpoints, points[0][0], planes[2][0], planes[2][1], planes[2][2], planes[2][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
- if (numpoints < 3)
+ if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
continue;
- numpoints = PolygonF_Clip(numpoints, points[1][0], planes[3][0], planes[3][1], planes[3][2], planes[3][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[0][0]);
- if (numpoints < 3)
+ R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, bih_triangles[triangleindex], surfaceindex);
+ }
+ }
+ else
+ {
+ for (surfacelistindex = 0;surfacelistindex < numsurfacelist;surfacelistindex++)
+ {
+ surfaceindex = surfacelist[surfacelistindex];
+ surface = surfaces + surfaceindex;
+ // check cull box first because it rejects more than any other check
+ if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
continue;
- numpoints = PolygonF_Clip(numpoints, points[0][0], planes[4][0], planes[4][1], planes[4][2], planes[4][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
- if (numpoints < 3)
+ // skip transparent surfaces
+ texture = surface->texture;
+ if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
continue;
- numpoints = PolygonF_Clip(numpoints, points[1][0], planes[5][0], planes[5][1], planes[5][2], planes[5][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), v[0]);
- if (numpoints < 3)
+ if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
continue;
- // some part of the triangle survived, so we have to accept it...
- if (dynamic)
- {
- // dynamic always uses the original triangle
- numpoints = 3;
- for (cornerindex = 0;cornerindex < 3;cornerindex++)
- {
- index = 3*e[cornerindex];
- VectorCopy(vertex3f + index, v[cornerindex]);
- }
- }
- for (cornerindex = 0;cornerindex < numpoints;cornerindex++)
- {
- // convert vertex positions to texcoords
- Matrix4x4_Transform(&projection, v[cornerindex], temp);
- tc[cornerindex][0] = (temp[1]+1.0f)*0.5f * (s2-s1) + s1;
- tc[cornerindex][1] = (temp[2]+1.0f)*0.5f * (t2-t1) + t1;
- // calculate distance fade from the projection origin
- f = a * (1.0f-fabs(temp[0])) * cl_decals_newsystem_intensitymultiplier.value;
- f = bound(0.0f, f, 1.0f);
- c[cornerindex][0] = r * f;
- c[cornerindex][1] = g * f;
- c[cornerindex][2] = b * f;
- c[cornerindex][3] = 1.0f;
- //VectorMA(v[cornerindex], cl_decals_bias.value, localnormal, v[cornerindex]);
- }
- if (dynamic)
- R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[1], v[2], tc[0], tc[1], tc[2], c[0], c[1], c[2], triangleindex+surface->num_firsttriangle, surfaceindex, decalsequence);
- else
- for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
- R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1, surfaceindex, decalsequence);
+ numtriangles = surface->num_triangles;
+ for (triangleindex = 0; triangleindex < numtriangles; triangleindex++)
+ R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, triangleindex + surface->num_firsttriangle, surfaceindex);
}
}
}