mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
ioquake3 porting
This commit is contained in:
parent
2704b798e2
commit
ca3340b158
449 changed files with 104109 additions and 77701 deletions
523
code/renderergl2/tr_animation.c
Normal file
523
code/renderergl2/tr_animation.c
Normal file
|
@ -0,0 +1,523 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
/*
|
||||
|
||||
All bones should be an identity orientation to display the mesh exactly
|
||||
as it is specified.
|
||||
|
||||
For all other frames, the bones represent the transformation from the
|
||||
orientation of the bone in the base frame to the orientation in this
|
||||
frame.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// copied and adapted from tr_mesh.c
|
||||
|
||||
/*
|
||||
=============
|
||||
R_MDRCullModel
|
||||
=============
|
||||
*/
|
||||
|
||||
static int R_MDRCullModel( mdrHeader_t *header, trRefEntity_t *ent ) {
|
||||
vec3_t bounds[2];
|
||||
mdrFrame_t *oldFrame, *newFrame;
|
||||
int i, frameSize;
|
||||
|
||||
frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
// compute frame pointers
|
||||
newFrame = ( mdrFrame_t * ) ( ( byte * ) header + header->ofsFrames + frameSize * ent->e.frame);
|
||||
oldFrame = ( mdrFrame_t * ) ( ( byte * ) header + header->ofsFrames + frameSize * ent->e.oldframe);
|
||||
|
||||
// cull bounding sphere ONLY if this is not an upscaled entity
|
||||
if ( !ent->e.nonNormalizedAxes )
|
||||
{
|
||||
if ( ent->e.frame == ent->e.oldframe )
|
||||
{
|
||||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
// Ummm... yeah yeah I know we don't really have an md3 here.. but we pretend
|
||||
// we do. After all, the purpose of mdrs are not that different, are they?
|
||||
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
|
||||
case CULL_IN:
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sphereCull, sphereCullB;
|
||||
|
||||
sphereCull = R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius );
|
||||
if ( newFrame == oldFrame ) {
|
||||
sphereCullB = sphereCull;
|
||||
} else {
|
||||
sphereCullB = R_CullLocalPointAndRadius( oldFrame->localOrigin, oldFrame->radius );
|
||||
}
|
||||
|
||||
if ( sphereCull == sphereCullB )
|
||||
{
|
||||
if ( sphereCull == CULL_OUT )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
else if ( sphereCull == CULL_IN )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate a bounding box in the current coordinate system
|
||||
for (i = 0 ; i < 3 ; i++) {
|
||||
bounds[0][i] = oldFrame->bounds[0][i] < newFrame->bounds[0][i] ? oldFrame->bounds[0][i] : newFrame->bounds[0][i];
|
||||
bounds[1][i] = oldFrame->bounds[1][i] > newFrame->bounds[1][i] ? oldFrame->bounds[1][i] : newFrame->bounds[1][i];
|
||||
}
|
||||
|
||||
switch ( R_CullLocalBox( bounds ) )
|
||||
{
|
||||
case CULL_IN:
|
||||
tr.pc.c_box_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_box_cull_md3_clip++;
|
||||
return CULL_CLIP;
|
||||
case CULL_OUT:
|
||||
default:
|
||||
tr.pc.c_box_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_MDRComputeFogNum
|
||||
|
||||
=================
|
||||
*/
|
||||
|
||||
int R_MDRComputeFogNum( mdrHeader_t *header, trRefEntity_t *ent ) {
|
||||
int i, j;
|
||||
fog_t *fog;
|
||||
mdrFrame_t *mdrFrame;
|
||||
vec3_t localOrigin;
|
||||
int frameSize;
|
||||
|
||||
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
// FIXME: non-normalized axis issues
|
||||
mdrFrame = ( mdrFrame_t * ) ( ( byte * ) header + header->ofsFrames + frameSize * ent->e.frame);
|
||||
VectorAdd( ent->e.origin, mdrFrame->localOrigin, localOrigin );
|
||||
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
|
||||
fog = &tr.world->fogs[i];
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( localOrigin[j] - mdrFrame->radius >= fog->bounds[1][j] ) {
|
||||
break;
|
||||
}
|
||||
if ( localOrigin[j] + mdrFrame->radius <= fog->bounds[0][j] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == 3 ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_MDRAddAnimSurfaces
|
||||
==============
|
||||
*/
|
||||
|
||||
// much stuff in there is just copied from R_AddMd3Surfaces in tr_mesh.c
|
||||
|
||||
void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) {
|
||||
mdrHeader_t *header;
|
||||
mdrSurface_t *surface;
|
||||
mdrLOD_t *lod;
|
||||
shader_t *shader;
|
||||
skin_t *skin;
|
||||
int i, j;
|
||||
int lodnum = 0;
|
||||
int fogNum = 0;
|
||||
int cull;
|
||||
int cubemapIndex;
|
||||
qboolean personalModel;
|
||||
|
||||
header = (mdrHeader_t *) tr.currentModel->modelData;
|
||||
|
||||
personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !(tr.viewParms.isPortal
|
||||
|| (tr.viewParms.flags & (VPF_SHADOWMAP | VPF_DEPTHSHADOW)));
|
||||
|
||||
if ( ent->e.renderfx & RF_WRAP_FRAMES )
|
||||
{
|
||||
ent->e.frame %= header->numFrames;
|
||||
ent->e.oldframe %= header->numFrames;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate the frames so there is no chance of a crash.
|
||||
// This will write directly into the entity structure, so
|
||||
// when the surfaces are rendered, they don't need to be
|
||||
// range checked again.
|
||||
//
|
||||
if ((ent->e.frame >= header->numFrames)
|
||||
|| (ent->e.frame < 0)
|
||||
|| (ent->e.oldframe >= header->numFrames)
|
||||
|| (ent->e.oldframe < 0) )
|
||||
{
|
||||
ri.Printf( PRINT_DEVELOPER, "R_MDRAddAnimSurfaces: no such frame %d to %d for '%s'\n",
|
||||
ent->e.oldframe, ent->e.frame, tr.currentModel->name );
|
||||
ent->e.frame = 0;
|
||||
ent->e.oldframe = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// cull the entire model if merged bounding box of both frames
|
||||
// is outside the view frustum.
|
||||
//
|
||||
cull = R_MDRCullModel (header, ent);
|
||||
if ( cull == CULL_OUT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// figure out the current LOD of the model we're rendering, and set the lod pointer respectively.
|
||||
lodnum = R_ComputeLOD(ent);
|
||||
// check whether this model has as that many LODs at all. If not, try the closest thing we got.
|
||||
if(header->numLODs <= 0)
|
||||
return;
|
||||
if(header->numLODs <= lodnum)
|
||||
lodnum = header->numLODs - 1;
|
||||
|
||||
lod = (mdrLOD_t *)( (byte *)header + header->ofsLODs);
|
||||
for(i = 0; i < lodnum; i++)
|
||||
{
|
||||
lod = (mdrLOD_t *) ((byte *) lod + lod->ofsEnd);
|
||||
}
|
||||
|
||||
// set up lighting
|
||||
if ( !personalModel || r_shadows->integer > 1 )
|
||||
{
|
||||
R_SetupEntityLighting( &tr.refdef, ent );
|
||||
}
|
||||
|
||||
// fogNum?
|
||||
fogNum = R_MDRComputeFogNum( header, ent );
|
||||
|
||||
cubemapIndex = R_CubemapForPoint(ent->e.origin);
|
||||
|
||||
surface = (mdrSurface_t *)( (byte *)lod + lod->ofsSurfaces );
|
||||
|
||||
for ( i = 0 ; i < lod->numSurfaces ; i++ )
|
||||
{
|
||||
|
||||
if(ent->e.customShader)
|
||||
shader = R_GetShaderByHandle(ent->e.customShader);
|
||||
else if(ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins)
|
||||
{
|
||||
skin = R_GetSkinByHandle(ent->e.customSkin);
|
||||
shader = tr.defaultShader;
|
||||
|
||||
for(j = 0; j < skin->numSurfaces; j++)
|
||||
{
|
||||
if (!strcmp(skin->surfaces[j].name, surface->name))
|
||||
{
|
||||
shader = skin->surfaces[j].shader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(surface->shaderIndex > 0)
|
||||
shader = R_GetShaderByHandle( surface->shaderIndex );
|
||||
else
|
||||
shader = tr.defaultShader;
|
||||
|
||||
// we will add shadows even if the main object isn't visible in the view
|
||||
|
||||
// stencil shadows can't do personal models unless I polyhedron clip
|
||||
if ( !personalModel
|
||||
&& r_shadows->integer == 2
|
||||
&& fogNum == 0
|
||||
&& !(ent->e.renderfx & ( RF_NOSHADOW | RF_DEPTHHACK ) )
|
||||
&& shader->sort == SS_OPAQUE )
|
||||
{
|
||||
R_AddDrawSurf( (void *)surface, tr.shadowShader, 0, qfalse, qfalse, 0 );
|
||||
}
|
||||
|
||||
// projection shadows work fine with personal models
|
||||
if ( r_shadows->integer == 3
|
||||
&& fogNum == 0
|
||||
&& (ent->e.renderfx & RF_SHADOW_PLANE )
|
||||
&& shader->sort == SS_OPAQUE )
|
||||
{
|
||||
R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse, 0 );
|
||||
}
|
||||
|
||||
if (!personalModel)
|
||||
R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse, qfalse, cubemapIndex );
|
||||
|
||||
surface = (mdrSurface_t *)( (byte *)surface + surface->ofsEnd );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
RB_MDRSurfaceAnim
|
||||
==============
|
||||
*/
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface )
|
||||
{
|
||||
int i, j, k;
|
||||
float frontlerp, backlerp;
|
||||
int *triangles;
|
||||
int indexes;
|
||||
int baseIndex, baseVertex;
|
||||
int numVerts;
|
||||
mdrVertex_t *v;
|
||||
mdrHeader_t *header;
|
||||
mdrFrame_t *frame;
|
||||
mdrFrame_t *oldFrame;
|
||||
mdrBone_t bones[MDR_MAX_BONES], *bonePtr, *bone;
|
||||
|
||||
int frameSize;
|
||||
|
||||
// don't lerp if lerping off, or this is the only frame, or the last frame...
|
||||
//
|
||||
if (backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame)
|
||||
{
|
||||
backlerp = 0; // if backlerp is 0, lerping is off and frontlerp is never used
|
||||
frontlerp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
backlerp = backEnd.currentEntity->e.backlerp;
|
||||
frontlerp = 1.0f - backlerp;
|
||||
}
|
||||
|
||||
header = (mdrHeader_t *)((byte *)surface + surface->ofsHeader);
|
||||
|
||||
frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
|
||||
|
||||
frame = (mdrFrame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.frame * frameSize );
|
||||
oldFrame = (mdrFrame_t *)((byte *)header + header->ofsFrames +
|
||||
backEnd.currentEntity->e.oldframe * frameSize );
|
||||
|
||||
RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles * 3 );
|
||||
|
||||
triangles = (int *) ((byte *)surface + surface->ofsTriangles);
|
||||
indexes = surface->numTriangles * 3;
|
||||
baseIndex = tess.numIndexes;
|
||||
baseVertex = tess.numVertexes;
|
||||
|
||||
// Set up all triangles.
|
||||
for (j = 0 ; j < indexes ; j++)
|
||||
{
|
||||
tess.indexes[baseIndex + j] = baseVertex + triangles[j];
|
||||
}
|
||||
tess.numIndexes += indexes;
|
||||
|
||||
//
|
||||
// lerp all the needed bones
|
||||
//
|
||||
if ( !backlerp )
|
||||
{
|
||||
// no lerping needed
|
||||
bonePtr = frame->bones;
|
||||
}
|
||||
else
|
||||
{
|
||||
bonePtr = bones;
|
||||
|
||||
for ( i = 0 ; i < header->numBones*12 ; i++ )
|
||||
{
|
||||
((float *)bonePtr)[i] = frontlerp * ((float *)frame->bones)[i] + backlerp * ((float *)oldFrame->bones)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// deform the vertexes by the lerped bones
|
||||
//
|
||||
numVerts = surface->numVerts;
|
||||
v = (mdrVertex_t *) ((byte *)surface + surface->ofsVerts);
|
||||
for ( j = 0; j < numVerts; j++ )
|
||||
{
|
||||
vec3_t tempVert, tempNormal;
|
||||
mdrWeight_t *w;
|
||||
|
||||
VectorClear( tempVert );
|
||||
VectorClear( tempNormal );
|
||||
w = v->weights;
|
||||
for ( k = 0 ; k < v->numWeights ; k++, w++ )
|
||||
{
|
||||
bone = bonePtr + w->boneIndex;
|
||||
|
||||
tempVert[0] += w->boneWeight * ( DotProduct( bone->matrix[0], w->offset ) + bone->matrix[0][3] );
|
||||
tempVert[1] += w->boneWeight * ( DotProduct( bone->matrix[1], w->offset ) + bone->matrix[1][3] );
|
||||
tempVert[2] += w->boneWeight * ( DotProduct( bone->matrix[2], w->offset ) + bone->matrix[2][3] );
|
||||
|
||||
tempNormal[0] += w->boneWeight * DotProduct( bone->matrix[0], v->normal );
|
||||
tempNormal[1] += w->boneWeight * DotProduct( bone->matrix[1], v->normal );
|
||||
tempNormal[2] += w->boneWeight * DotProduct( bone->matrix[2], v->normal );
|
||||
}
|
||||
|
||||
tess.xyz[baseVertex + j][0] = tempVert[0];
|
||||
tess.xyz[baseVertex + j][1] = tempVert[1];
|
||||
tess.xyz[baseVertex + j][2] = tempVert[2];
|
||||
|
||||
R_VaoPackNormal(tess.normal[baseVertex + j], tempNormal);
|
||||
|
||||
tess.texCoords[baseVertex + j][0] = v->texCoords[0];
|
||||
tess.texCoords[baseVertex + j][1] = v->texCoords[1];
|
||||
|
||||
v = (mdrVertex_t *)&v->weights[v->numWeights];
|
||||
}
|
||||
|
||||
tess.numVertexes += surface->numVerts;
|
||||
}
|
||||
|
||||
|
||||
#define MC_MASK_X ((1<<(MC_BITS_X))-1)
|
||||
#define MC_MASK_Y ((1<<(MC_BITS_Y))-1)
|
||||
#define MC_MASK_Z ((1<<(MC_BITS_Z))-1)
|
||||
#define MC_MASK_VECT ((1<<(MC_BITS_VECT))-1)
|
||||
|
||||
#define MC_SCALE_VECT (1.0f/(float)((1<<(MC_BITS_VECT-1))-2))
|
||||
|
||||
#define MC_POS_X (0)
|
||||
#define MC_SHIFT_X (0)
|
||||
|
||||
#define MC_POS_Y ((((MC_BITS_X))/8))
|
||||
#define MC_SHIFT_Y ((((MC_BITS_X)%8)))
|
||||
|
||||
#define MC_POS_Z ((((MC_BITS_X+MC_BITS_Y))/8))
|
||||
#define MC_SHIFT_Z ((((MC_BITS_X+MC_BITS_Y)%8)))
|
||||
|
||||
#define MC_POS_V11 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z))/8))
|
||||
#define MC_SHIFT_V11 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z)%8)))
|
||||
|
||||
#define MC_POS_V12 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT))/8))
|
||||
#define MC_SHIFT_V12 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT)%8)))
|
||||
|
||||
#define MC_POS_V13 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*2))/8))
|
||||
#define MC_SHIFT_V13 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*2)%8)))
|
||||
|
||||
#define MC_POS_V21 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*3))/8))
|
||||
#define MC_SHIFT_V21 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*3)%8)))
|
||||
|
||||
#define MC_POS_V22 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*4))/8))
|
||||
#define MC_SHIFT_V22 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*4)%8)))
|
||||
|
||||
#define MC_POS_V23 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*5))/8))
|
||||
#define MC_SHIFT_V23 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*5)%8)))
|
||||
|
||||
#define MC_POS_V31 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*6))/8))
|
||||
#define MC_SHIFT_V31 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*6)%8)))
|
||||
|
||||
#define MC_POS_V32 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*7))/8))
|
||||
#define MC_SHIFT_V32 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*7)%8)))
|
||||
|
||||
#define MC_POS_V33 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*8))/8))
|
||||
#define MC_SHIFT_V33 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*8)%8)))
|
||||
|
||||
void MC_UnCompress(float mat[3][4],const unsigned char * comp)
|
||||
{
|
||||
int val;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[0];
|
||||
val-=1<<(MC_BITS_X-1);
|
||||
mat[0][3]=((float)(val))*MC_SCALE_X;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[1];
|
||||
val-=1<<(MC_BITS_Y-1);
|
||||
mat[1][3]=((float)(val))*MC_SCALE_Y;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[2];
|
||||
val-=1<<(MC_BITS_Z-1);
|
||||
mat[2][3]=((float)(val))*MC_SCALE_Z;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[3];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[0][0]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[4];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[0][1]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[5];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[0][2]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
|
||||
val=(int)((unsigned short *)(comp))[6];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[1][0]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[7];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[1][1]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[8];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[1][2]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
|
||||
val=(int)((unsigned short *)(comp))[9];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[2][0]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[10];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[2][1]=((float)(val))*MC_SCALE_VECT;
|
||||
|
||||
val=(int)((unsigned short *)(comp))[11];
|
||||
val-=1<<(MC_BITS_VECT-1);
|
||||
mat[2][2]=((float)(val))*MC_SCALE_VECT;
|
||||
}
|
|
@ -517,6 +517,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
|||
{
|
||||
// hack the depth range to prevent view model from poking into walls
|
||||
depthRange = qtrue;
|
||||
|
||||
if(backEnd.currentEntity->e.renderfx & RF_CROSSHAIR)
|
||||
isCrosshair = qtrue;
|
||||
}
|
||||
} else {
|
||||
backEnd.currentEntity = &tr.worldEntity;
|
||||
|
|
|
@ -270,10 +270,10 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
|
|||
tr.numLightmaps = numLightmaps;
|
||||
}
|
||||
|
||||
tr.lightmaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *) );
|
||||
tr.lightmaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
|
||||
|
||||
if (tr.worldDeluxeMapping)
|
||||
tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *) );
|
||||
tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
|
||||
|
||||
textureInternalFormat = GL_RGBA8;
|
||||
if (r_hdr->integer)
|
||||
|
@ -584,7 +584,7 @@ static void R_LoadVisibility( lump_t *l ) {
|
|||
} else {
|
||||
byte *dest;
|
||||
|
||||
dest = ri.Hunk_Alloc( len - 8 );
|
||||
dest = ri.Hunk_Alloc( len - 8, h_low );
|
||||
Com_Memcpy( dest, buf + 8, len - 8 );
|
||||
s_worldData.vis = dest;
|
||||
}
|
||||
|
@ -719,15 +719,15 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
|
|||
|
||||
numIndexes = LittleLong(ds->numIndexes);
|
||||
|
||||
//cv = ri.Hunk_Alloc(sizeof(*cv));
|
||||
//cv = ri.Hunk_Alloc(sizeof(*cv), h_low);
|
||||
cv = (void *)surf->data;
|
||||
cv->surfaceType = SF_FACE;
|
||||
|
||||
cv->numIndexes = numIndexes;
|
||||
cv->indexes = ri.Hunk_Alloc(numIndexes * sizeof(cv->indexes[0]));
|
||||
cv->indexes = ri.Hunk_Alloc(numIndexes * sizeof(cv->indexes[0]), h_low);
|
||||
|
||||
cv->numVerts = numVerts;
|
||||
cv->verts = ri.Hunk_Alloc(numVerts * sizeof(cv->verts[0]));
|
||||
cv->verts = ri.Hunk_Alloc(numVerts * sizeof(cv->verts[0]), h_low);
|
||||
|
||||
// copy vertexes
|
||||
surf->cullinfo.type = CULLINFO_PLANE | CULLINFO_BOX;
|
||||
|
@ -880,15 +880,15 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor
|
|||
numVerts = LittleLong(ds->numVerts);
|
||||
numIndexes = LittleLong(ds->numIndexes);
|
||||
|
||||
//cv = ri.Hunk_Alloc(sizeof(*cv));
|
||||
//cv = ri.Hunk_Alloc(sizeof(*cv), h_low);
|
||||
cv = (void *)surf->data;
|
||||
cv->surfaceType = SF_TRIANGLES;
|
||||
|
||||
cv->numIndexes = numIndexes;
|
||||
cv->indexes = ri.Hunk_Alloc(numIndexes * sizeof(cv->indexes[0]));
|
||||
cv->indexes = ri.Hunk_Alloc(numIndexes * sizeof(cv->indexes[0]), h_low);
|
||||
|
||||
cv->numVerts = numVerts;
|
||||
cv->verts = ri.Hunk_Alloc(numVerts * sizeof(cv->verts[0]));
|
||||
cv->verts = ri.Hunk_Alloc(numVerts * sizeof(cv->verts[0]), h_low);
|
||||
|
||||
surf->data = (surfaceType_t *) cv;
|
||||
|
||||
|
@ -960,7 +960,7 @@ static void ParseFlare( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, int
|
|||
surf->shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
//flare = ri.Hunk_Alloc( sizeof( *flare ) );
|
||||
//flare = ri.Hunk_Alloc( sizeof( *flare ), h_low );
|
||||
flare = (void *)surf->data;
|
||||
flare->surfaceType = SF_FLARE;
|
||||
|
||||
|
@ -1658,22 +1658,22 @@ void R_MovePatchSurfacesToHunk(void) {
|
|||
//
|
||||
|
||||
copyFrom = grid->widthLodError;
|
||||
grid->widthLodError = ri.Hunk_Alloc( grid->width * 4 );
|
||||
grid->widthLodError = ri.Hunk_Alloc( grid->width * 4, h_low );
|
||||
Com_Memcpy(grid->widthLodError, copyFrom, grid->width * 4);
|
||||
ri.Free(copyFrom);
|
||||
|
||||
copyFrom = grid->heightLodError;
|
||||
grid->heightLodError = ri.Hunk_Alloc(grid->height * 4);
|
||||
grid->heightLodError = ri.Hunk_Alloc(grid->height * 4, h_low);
|
||||
Com_Memcpy(grid->heightLodError, copyFrom, grid->height * 4);
|
||||
ri.Free(copyFrom);
|
||||
|
||||
copyFrom = grid->indexes;
|
||||
grid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t));
|
||||
grid->indexes = ri.Hunk_Alloc(grid->numIndexes * sizeof(glIndex_t), h_low);
|
||||
Com_Memcpy(grid->indexes, copyFrom, grid->numIndexes * sizeof(glIndex_t));
|
||||
ri.Free(copyFrom);
|
||||
|
||||
copyFrom = grid->verts;
|
||||
grid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t));
|
||||
grid->verts = ri.Hunk_Alloc(grid->numVerts * sizeof(srfVert_t), h_low);
|
||||
Com_Memcpy(grid->verts, copyFrom, grid->numVerts * sizeof(srfVert_t));
|
||||
ri.Free(copyFrom);
|
||||
}
|
||||
|
@ -1712,13 +1712,13 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) {
|
|||
if ( indexLump->filelen % sizeof(*indexes))
|
||||
ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
|
||||
|
||||
out = ri.Hunk_Alloc ( count * sizeof(*out) );
|
||||
out = ri.Hunk_Alloc ( count * sizeof(*out), h_low );
|
||||
|
||||
s_worldData.surfaces = out;
|
||||
s_worldData.numsurfaces = count;
|
||||
s_worldData.surfacesViewCount = ri.Hunk_Alloc ( count * sizeof(*s_worldData.surfacesViewCount) );
|
||||
s_worldData.surfacesDlightBits = ri.Hunk_Alloc ( count * sizeof(*s_worldData.surfacesDlightBits) );
|
||||
s_worldData.surfacesPshadowBits = ri.Hunk_Alloc ( count * sizeof(*s_worldData.surfacesPshadowBits) );
|
||||
s_worldData.surfacesViewCount = ri.Hunk_Alloc ( count * sizeof(*s_worldData.surfacesViewCount), h_low );
|
||||
s_worldData.surfacesDlightBits = ri.Hunk_Alloc ( count * sizeof(*s_worldData.surfacesDlightBits), h_low );
|
||||
s_worldData.surfacesPshadowBits = ri.Hunk_Alloc ( count * sizeof(*s_worldData.surfacesPshadowBits), h_low );
|
||||
|
||||
// load hdr vertex colors
|
||||
if (r_hdr->integer)
|
||||
|
@ -1748,16 +1748,16 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) {
|
|||
for ( i = 0 ; i < count ; i++, in++, out++ ) {
|
||||
switch ( LittleLong( in->surfaceType ) ) {
|
||||
case MST_PATCH:
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t));
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
|
||||
break;
|
||||
case MST_TRIANGLE_SOUP:
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t));
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
|
||||
break;
|
||||
case MST_PLANAR:
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t));
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
|
||||
break;
|
||||
case MST_FLARE:
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfFlare_t));
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfFlare_t), h_low);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1826,7 +1826,7 @@ static void R_LoadSubmodels( lump_t *l ) {
|
|||
count = l->filelen / sizeof(*in);
|
||||
|
||||
s_worldData.numBModels = count;
|
||||
s_worldData.bmodels = out = ri.Hunk_Alloc( count * sizeof(*out) );
|
||||
s_worldData.bmodels = out = ri.Hunk_Alloc( count * sizeof(*out), h_low );
|
||||
|
||||
for ( i=0 ; i<count ; i++, in++, out++ ) {
|
||||
model_t *model;
|
||||
|
@ -1896,7 +1896,7 @@ static void R_LoadNodesAndLeafs (lump_t *nodeLump, lump_t *leafLump) {
|
|||
numNodes = nodeLump->filelen / sizeof(dnode_t);
|
||||
numLeafs = leafLump->filelen / sizeof(dleaf_t);
|
||||
|
||||
out = ri.Hunk_Alloc ( (numNodes + numLeafs) * sizeof(*out));
|
||||
out = ri.Hunk_Alloc ( (numNodes + numLeafs) * sizeof(*out), h_low);
|
||||
|
||||
s_worldData.nodes = out;
|
||||
s_worldData.numnodes = numNodes + numLeafs;
|
||||
|
@ -1966,7 +1966,7 @@ static void R_LoadShaders( lump_t *l ) {
|
|||
if (l->filelen % sizeof(*in))
|
||||
ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
|
||||
count = l->filelen / sizeof(*in);
|
||||
out = ri.Hunk_Alloc ( count*sizeof(*out) );
|
||||
out = ri.Hunk_Alloc ( count*sizeof(*out), h_low );
|
||||
|
||||
s_worldData.shaders = out;
|
||||
s_worldData.numShaders = count;
|
||||
|
@ -1995,7 +1995,7 @@ static void R_LoadMarksurfaces (lump_t *l)
|
|||
if (l->filelen % sizeof(*in))
|
||||
ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
|
||||
count = l->filelen / sizeof(*in);
|
||||
out = ri.Hunk_Alloc ( count*sizeof(*out));
|
||||
out = ri.Hunk_Alloc ( count*sizeof(*out), h_low);
|
||||
|
||||
s_worldData.marksurfaces = out;
|
||||
s_worldData.nummarksurfaces = count;
|
||||
|
@ -2024,7 +2024,7 @@ static void R_LoadPlanes( lump_t *l ) {
|
|||
if (l->filelen % sizeof(*in))
|
||||
ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name);
|
||||
count = l->filelen / sizeof(*in);
|
||||
out = ri.Hunk_Alloc ( count*2*sizeof(*out));
|
||||
out = ri.Hunk_Alloc ( count*2*sizeof(*out), h_low);
|
||||
|
||||
s_worldData.planes = out;
|
||||
s_worldData.numplanes = count;
|
||||
|
@ -2071,7 +2071,7 @@ static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump ) {
|
|||
|
||||
// create fog strucutres for them
|
||||
s_worldData.numfogs = count + 1;
|
||||
s_worldData.fogs = ri.Hunk_Alloc ( s_worldData.numfogs*sizeof(*out));
|
||||
s_worldData.fogs = ri.Hunk_Alloc ( s_worldData.numfogs*sizeof(*out), h_low);
|
||||
out = s_worldData.fogs + 1;
|
||||
|
||||
if ( !count ) {
|
||||
|
@ -2195,7 +2195,7 @@ void R_LoadLightGrid( lump_t *l ) {
|
|||
return;
|
||||
}
|
||||
|
||||
w->lightGridData = ri.Hunk_Alloc( l->filelen );
|
||||
w->lightGridData = ri.Hunk_Alloc( l->filelen, h_low );
|
||||
Com_Memcpy( w->lightGridData, (void *)(fileBase + l->fileofs), l->filelen );
|
||||
|
||||
// deal with overbright bits
|
||||
|
@ -2223,7 +2223,7 @@ void R_LoadLightGrid( lump_t *l ) {
|
|||
if (size != sizeof(float) * 6 * numGridPoints)
|
||||
ri.Error(ERR_DROP, "Bad size for %s (%i, expected %i)!", filename, size, (int)(sizeof(float)) * 6 * numGridPoints);
|
||||
|
||||
w->lightGrid16 = ri.Hunk_Alloc(sizeof(w->lightGrid16) * 6 * numGridPoints);
|
||||
w->lightGrid16 = ri.Hunk_Alloc(sizeof(w->lightGrid16) * 6 * numGridPoints, h_low);
|
||||
|
||||
for (i = 0; i < numGridPoints ; i++)
|
||||
{
|
||||
|
@ -2249,7 +2249,7 @@ void R_LoadLightGrid( lump_t *l ) {
|
|||
else if (0)
|
||||
{
|
||||
// promote 8-bit lightgrid to 16-bit
|
||||
w->lightGrid16 = ri.Hunk_Alloc(sizeof(w->lightGrid16) * 6 * numGridPoints);
|
||||
w->lightGrid16 = ri.Hunk_Alloc(sizeof(w->lightGrid16) * 6 * numGridPoints, h_low);
|
||||
|
||||
for (i = 0; i < numGridPoints; i++)
|
||||
{
|
||||
|
@ -2286,7 +2286,7 @@ void R_LoadEntities( lump_t *l ) {
|
|||
p = (char *)(fileBase + l->fileofs);
|
||||
|
||||
// store for reference by the cgame
|
||||
w->entityString = ri.Hunk_Alloc( l->filelen + 1 );
|
||||
w->entityString = ri.Hunk_Alloc( l->filelen + 1, h_low );
|
||||
strcpy( w->entityString, p );
|
||||
w->entityParsePoint = w->entityString;
|
||||
|
||||
|
@ -2490,7 +2490,7 @@ void R_LoadEnvironmentJson(const char *baseName)
|
|||
}
|
||||
|
||||
tr.numCubemaps = JSON_ArrayGetIndex(cubemapArrayJson, bufferEnd, NULL, 0);
|
||||
tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps));
|
||||
tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps), h_low);
|
||||
memset(tr.cubemaps, 0, tr.numCubemaps * sizeof(*tr.cubemaps));
|
||||
|
||||
for (i = 0; i < tr.numCubemaps; i++)
|
||||
|
@ -2543,7 +2543,7 @@ void R_LoadCubemapEntities(char *cubemapEntityName)
|
|||
return;
|
||||
|
||||
tr.numCubemaps = numCubemaps;
|
||||
tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps));
|
||||
tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps), h_low);
|
||||
memset(tr.cubemaps, 0, tr.numCubemaps * sizeof(*tr.cubemaps));
|
||||
|
||||
numCubemaps = 0;
|
||||
|
@ -2755,7 +2755,7 @@ void RE_LoadWorldMap( const char *name ) {
|
|||
Q_strncpyz( s_worldData.baseName, COM_SkipPath( s_worldData.name ), sizeof( s_worldData.name ) );
|
||||
COM_StripExtension(s_worldData.baseName, s_worldData.baseName, sizeof(s_worldData.baseName));
|
||||
|
||||
startMarker = ri.Hunk_Alloc(0);
|
||||
startMarker = ri.Hunk_Alloc(0, h_low);
|
||||
c_gridVerts = 0;
|
||||
|
||||
header = (dheader_t *)buffer.b;
|
||||
|
@ -2998,7 +2998,7 @@ void RE_LoadWorldMap( const char *name ) {
|
|||
}
|
||||
}
|
||||
|
||||
s_worldData.dataSize = (byte *)ri.Hunk_Alloc(0) - startMarker;
|
||||
s_worldData.dataSize = (byte *)ri.Hunk_Alloc(0, h_low) - startMarker;
|
||||
|
||||
// only set tr.world now that we know the entire level has loaded properly
|
||||
tr.world = &s_worldData;
|
||||
|
|
|
@ -1,451 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_draw.c -- drawing
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
vec4_t r_colorWhite = { 1.0, 1.0, 1.0, 1.0 };
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_SetColor
|
||||
================
|
||||
*/
|
||||
void Draw_SetColor( const vec4_t rgba ) {
|
||||
#if 1
|
||||
if( !rgba ) {
|
||||
rgba = r_colorWhite;
|
||||
}
|
||||
|
||||
backEnd.color2D[ 0 ] = rgba[ 0 ] * tr.identityLight;
|
||||
backEnd.color2D[ 1 ] = rgba[ 1 ] * tr.identityLight;
|
||||
backEnd.color2D[ 2 ] = rgba[ 2 ] * tr.identityLight;
|
||||
backEnd.color2D[ 3 ] = rgba[ 3 ];
|
||||
qglColor4fv( backEnd.color2D );
|
||||
#else
|
||||
RE_SetColor( rgba );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_StretchPic
|
||||
================
|
||||
*/
|
||||
void Draw_StretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader ) {
|
||||
#if 1
|
||||
shader_t *shader;
|
||||
|
||||
R_SyncRenderThread();
|
||||
|
||||
if( hShader ) {
|
||||
shader = R_GetShaderByHandle( hShader );
|
||||
} else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
if( w <= 0 ) {
|
||||
w = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->width;
|
||||
h = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->height;
|
||||
}
|
||||
|
||||
// draw the pic
|
||||
RB_Color4f( backEnd.color2D[ 0 ], backEnd.color2D[ 1 ], backEnd.color2D[ 2 ], backEnd.color2D[ 3 ] );
|
||||
RB_BeginSurface( shader, 0, 0 );
|
||||
|
||||
RB_Texcoord2f( s1, t1 );
|
||||
RB_Vertex2f( x, y );
|
||||
|
||||
RB_Texcoord2f( s2, t1 );
|
||||
RB_Vertex2f( x + w, y );
|
||||
|
||||
RB_Texcoord2f( s1, t2 );
|
||||
RB_Vertex2f( x, y + h );
|
||||
|
||||
RB_Texcoord2f( s2, t2 );
|
||||
RB_Vertex2f( x + w, y + h );
|
||||
|
||||
RB_StreamEnd();
|
||||
#else
|
||||
RE_StretchPic( x, y, w, h, s1, t1, s2, t2, hShader );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_TilePic
|
||||
================
|
||||
*/
|
||||
void Draw_TilePic( float x, float y, float w, float h , qhandle_t hShader ) {
|
||||
shader_t *shader;
|
||||
float picw, pich;
|
||||
|
||||
R_SyncRenderThread();
|
||||
|
||||
if( hShader ) {
|
||||
shader = R_GetShaderByHandle( hShader );
|
||||
}
|
||||
else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
if( w <= 0 ) {
|
||||
w = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->width;
|
||||
h = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->height;
|
||||
}
|
||||
|
||||
picw = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->uploadWidth;
|
||||
pich = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->uploadHeight;
|
||||
|
||||
// draw the pic
|
||||
RB_Color4f( backEnd.color2D[ 0 ], backEnd.color2D[ 1 ], backEnd.color2D[ 2 ], backEnd.color2D[ 3 ] );
|
||||
|
||||
RB_StreamBegin( shader );
|
||||
|
||||
RB_Texcoord2f( x / picw, y / pich );
|
||||
RB_Vertex2f( x, y );
|
||||
|
||||
RB_Texcoord2f( ( x + w ) / picw, y / pich );
|
||||
RB_Vertex2f( x + w, y );
|
||||
|
||||
RB_Texcoord2f( x / picw, ( y + h ) / pich );
|
||||
RB_Vertex2f( x, y + h );
|
||||
|
||||
RB_Texcoord2f( ( x + w ) / picw, ( y + h ) / pich );
|
||||
RB_Vertex2f( x + w, y + h );
|
||||
|
||||
RB_StreamEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_TilePicOffset
|
||||
================
|
||||
*/
|
||||
void Draw_TilePicOffset( float x, float y, float w, float h, qhandle_t hShader, int offsetX, int offsetY ) {
|
||||
shader_t *shader;
|
||||
float picw, pich;
|
||||
|
||||
R_SyncRenderThread();
|
||||
|
||||
if( hShader ) {
|
||||
shader = R_GetShaderByHandle( hShader );
|
||||
} else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
if( w <= 0 ) {
|
||||
w = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->width;
|
||||
h = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->height;
|
||||
}
|
||||
|
||||
picw = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->uploadWidth;
|
||||
pich = shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->uploadHeight;
|
||||
|
||||
// draw the pic
|
||||
RB_Color4f( backEnd.color2D[ 0 ], backEnd.color2D[ 1 ], backEnd.color2D[ 2 ], backEnd.color2D[ 3 ] );
|
||||
|
||||
RB_StreamBegin( shader );
|
||||
|
||||
RB_Texcoord2f( x / picw, y / pich );
|
||||
RB_Vertex2f( x + offsetX, y + offsetY );
|
||||
|
||||
RB_Texcoord2f( ( x + w ) / picw, y / pich );
|
||||
RB_Vertex2f( x + offsetX + w, y + offsetY );
|
||||
|
||||
RB_Texcoord2f( x / picw, ( y + h ) / pich );
|
||||
RB_Vertex2f( x + offsetX, y + offsetY + h );
|
||||
|
||||
RB_Texcoord2f( ( x + w ) / picw, ( y + h ) / pich );
|
||||
RB_Vertex2f( x + offsetX + w, y + offsetY + h );
|
||||
|
||||
RB_StreamEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_TrianglePic
|
||||
================
|
||||
*/
|
||||
void Draw_TrianglePic( const vec2_t vPoints[ 3 ], const vec2_t vTexCoords[ 3 ], qhandle_t hShader ) {
|
||||
int i;
|
||||
shader_t *shader;
|
||||
|
||||
R_SyncRenderThread();
|
||||
|
||||
if( hShader ) {
|
||||
shader = R_GetShaderByHandle( hShader );
|
||||
} else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
// draw the pic
|
||||
RB_Color4f( backEnd.color2D[ 0 ], backEnd.color2D[ 1 ], backEnd.color2D[ 2 ], backEnd.color2D[ 3 ] );
|
||||
|
||||
RB_BeginSurface( shader, 0, 0 );
|
||||
|
||||
for( i = 0; i < 3; i++ ) {
|
||||
RB_Texcoord2f( vTexCoords[ i ][ 0 ], vTexCoords[ i ][ 1 ] );
|
||||
RB_Vertex2f( vPoints[ i ][ 0 ], vPoints[ i ][ 1 ] );
|
||||
}
|
||||
|
||||
RB_StreamEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
RE_DrawBackground_TexSubImage
|
||||
================
|
||||
*/
|
||||
void RE_DrawBackground_TexSubImage( int cols, int rows, int bgr, byte *data ) {
|
||||
GLenum format;
|
||||
int w, h;
|
||||
|
||||
w = glConfig.vidWidth;
|
||||
h = glConfig.vidHeight;
|
||||
|
||||
R_SyncRenderThread();
|
||||
qglFinish();
|
||||
|
||||
if( bgr ) {
|
||||
format = GL_BGR_EXT;
|
||||
} else {
|
||||
format = GL_RGB;
|
||||
}
|
||||
|
||||
GL_Bind( tr.scratchImage[ 0 ] );
|
||||
|
||||
if( cols == tr.scratchImage[ 0 ]->width && rows == tr.scratchImage[ 0 ]->height && format == tr.scratchImage[ 0 ]->internalFormat )
|
||||
{
|
||||
qglTexSubImage2D( 3553, 0, 0, 0, cols, rows, format, 5121, data );
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.scratchImage[ 0 ]->uploadWidth = cols;
|
||||
tr.scratchImage[ 0 ]->uploadHeight = rows;
|
||||
tr.scratchImage[ 0 ]->internalFormat = format;
|
||||
qglTexImage2D( GL_TEXTURE_2D, 0, 3, cols, rows, 0, format, 5121, data );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 9729.0 );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 9729.0 );
|
||||
}
|
||||
|
||||
qglDisable( GL_CULL_FACE );
|
||||
qglDisable( GL_DEPTH_TEST );
|
||||
qglEnable( GL_TEXTURE_2D );
|
||||
|
||||
qglBegin( GL_QUADS );
|
||||
|
||||
qglTexCoord2f( 0.5 / ( GLfloat )cols, ( ( GLfloat )rows - 0.5 ) / rows );
|
||||
qglVertex2f( 0, 0 );
|
||||
|
||||
qglTexCoord2f( ( ( GLfloat )cols - 0.5 ) / cols, ( ( GLfloat )rows - 0.5 ) / rows );
|
||||
qglVertex2f( w, 0 );
|
||||
|
||||
qglTexCoord2f( ( ( GLfloat )cols - 0.5 ) / cols, 0.5 / ( GLfloat )rows );
|
||||
qglVertex2f( w, h );
|
||||
|
||||
qglTexCoord2f( 0.5 / ( GLfloat )rows, 0.5 / ( GLfloat )rows );
|
||||
qglVertex2f( 0, h );
|
||||
|
||||
qglEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
RE_DrawBackground_DrawPixels
|
||||
================
|
||||
*/
|
||||
void RE_DrawBackground_DrawPixels( int cols, int rows, int bgr, byte *data ) {
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_StretchRaw
|
||||
|
||||
Stretches a raw 32 bit power of 2 bitmap image over the given screen rectangle.
|
||||
Used for cinematics.
|
||||
=============
|
||||
*/
|
||||
void RE_StretchRaw( int x, int y, int w, int h, int cols, int rows, int components, const byte *data ) {
|
||||
int i, j;
|
||||
int start, end;
|
||||
|
||||
if (!tr.registered) {
|
||||
return;
|
||||
}
|
||||
R_SyncRenderThread();
|
||||
|
||||
// we definately want to sync every frame for the cinematics
|
||||
qglFinish();
|
||||
|
||||
start = end = 0;
|
||||
if (r_speeds->integer) {
|
||||
start = ri.Milliseconds();
|
||||
}
|
||||
|
||||
// make sure rows and cols are powers of 2
|
||||
for (i = 0; (1 << i) < cols; i++) {
|
||||
}
|
||||
for (j = 0; (1 << j) < rows; j++) {
|
||||
}
|
||||
if ((1 << i) != cols || (1 << j) != rows) {
|
||||
ri.Error(ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows);
|
||||
}
|
||||
|
||||
GL_Bind(tr.scratchImage[0]);
|
||||
|
||||
// if the scratchImage isn't in the format we want, specify it as a new texture
|
||||
if (cols != tr.scratchImage[0]->width || rows != tr.scratchImage[0]->height) {
|
||||
tr.scratchImage[0]->width = tr.scratchImage[0]->uploadWidth = cols;
|
||||
tr.scratchImage[0]->height = tr.scratchImage[0]->uploadHeight = rows;
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
}
|
||||
else {
|
||||
// otherwise, just subimage upload it so that drivers can tell we are going to be changing
|
||||
// it and don't try and do a texture compression
|
||||
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
|
||||
if (r_speeds->integer) {
|
||||
end = ri.Milliseconds();
|
||||
ri.Printf(PRINT_ALL, "qglTexSubImage2D %i, %i: %i msec\n", cols, rows, end - start);
|
||||
}
|
||||
|
||||
RB_SetGL2D();
|
||||
|
||||
qglColor3f(tr.identityLight, tr.identityLight, tr.identityLight);
|
||||
|
||||
qglBegin(GL_QUADS);
|
||||
qglTexCoord2f(0.5f / cols, 0.5f / rows);
|
||||
qglVertex2f(x, y);
|
||||
qglTexCoord2f((cols - 0.5f) / cols, 0.5f / rows);
|
||||
qglVertex2f(x + w, y);
|
||||
qglTexCoord2f((cols - 0.5f) / cols, (rows - 0.5f) / rows);
|
||||
qglVertex2f(x + w, y + h);
|
||||
qglTexCoord2f(0.5f / cols, (rows - 0.5f) / rows);
|
||||
qglVertex2f(x, y + h);
|
||||
qglEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
AddBox
|
||||
================
|
||||
*/
|
||||
void AddBox( float x, float y, float w, float h ) {
|
||||
R_SyncRenderThread();
|
||||
|
||||
qglColor4fv( backEnd.color2D );
|
||||
qglDisable( GL_TEXTURE_2D );
|
||||
GL_State( 0x422 );
|
||||
|
||||
qglBegin( GL_QUADS );
|
||||
|
||||
qglVertex2f( x, y );
|
||||
qglVertex2f( x + w, y );
|
||||
qglVertex2f( x + w, y + h );
|
||||
qglVertex2f( x, y + h );
|
||||
|
||||
qglEnd();
|
||||
|
||||
qglEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
DrawBox
|
||||
================
|
||||
*/
|
||||
void DrawBox( float x, float y, float w, float h ) {
|
||||
R_SyncRenderThread();
|
||||
|
||||
qglColor4fv( backEnd.color2D );
|
||||
qglDisable( GL_TEXTURE_2D );
|
||||
GL_State( 0x465 );
|
||||
|
||||
qglBegin( GL_QUADS );
|
||||
|
||||
qglVertex2f( x, y );
|
||||
qglVertex2f( x + w, y );
|
||||
qglVertex2f( x + w, y + h );
|
||||
qglVertex2f( x, y + h );
|
||||
|
||||
qglEnd();
|
||||
|
||||
qglEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
DrawLineLoop
|
||||
================
|
||||
*/
|
||||
void DrawLineLoop( const vec2_t *points, int count, int stipple_factor, int stipple_mask ) {
|
||||
int i;
|
||||
|
||||
R_SyncRenderThread();
|
||||
|
||||
qglDisable( GL_TEXTURE_2D );
|
||||
|
||||
if( stipple_factor ) {
|
||||
qglEnable( GL_LINE_STIPPLE );
|
||||
qglLineStipple( stipple_factor, stipple_mask );
|
||||
}
|
||||
|
||||
qglBegin( GL_LINE_LOOP );
|
||||
|
||||
for( i = 0; i < count; i++ ) {
|
||||
qglVertex2i( points[ i ][ 0 ], points[ i ][ 1 ] );
|
||||
}
|
||||
|
||||
qglEnd();
|
||||
|
||||
qglEnable( GL_TEXTURE_2D );
|
||||
|
||||
if( stipple_factor ) {
|
||||
qglDisable( GL_LINE_STIPPLE );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Set2DWindow
|
||||
================
|
||||
*/
|
||||
void Set2DWindow( int x, int y, int w, int h, float left, float right, float bottom, float top, float n, float f ) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
RE_Scissor
|
||||
================
|
||||
*/
|
||||
void RE_Scissor( int x, int y, int width, int height ) {
|
||||
qglEnable( GL_SCISSOR_TEST );
|
||||
qglScissor( x, y, width, height );
|
||||
}
|
|
@ -156,6 +156,13 @@ void Mat4SimpleInverse( const mat4_t in, mat4_t out)
|
|||
out[ 3] = 0.0f; out[ 7] = 0.0f; out[11] = 0.0f; out[15] = 1.0f;
|
||||
}
|
||||
|
||||
void VectorLerp( vec3_t a, vec3_t b, float lerp, vec3_t c)
|
||||
{
|
||||
c[0] = a[0] * (1.0f - lerp) + b[0] * lerp;
|
||||
c[1] = a[1] * (1.0f - lerp) + b[1] * lerp;
|
||||
c[2] = a[2] * (1.0f - lerp) + b[2] * lerp;
|
||||
}
|
||||
|
||||
qboolean SpheresIntersect(vec3_t origin1, float radius1, vec3_t origin2, float radius2)
|
||||
{
|
||||
float radiusSum = radius1 + radius2;
|
||||
|
|
|
@ -46,6 +46,7 @@ void Mat4SimpleInverse( const mat4_t in, mat4_t out);
|
|||
|
||||
#define VectorCopy4(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
|
||||
#define VectorSet4(v,x,y,z,w) ((v)[0]=(x),(v)[1]=(y),(v)[2]=(z),(v)[3]=(w))
|
||||
#define DotProduct4(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3])
|
||||
#define VectorScale4(a,b,c) ((c)[0]=(a)[0]*(b),(c)[1]=(a)[1]*(b),(c)[2]=(a)[2]*(b),(c)[3]=(a)[3]*(b))
|
||||
|
||||
#define VectorCopy5(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3],(b)[4]=(a)[4])
|
||||
|
@ -55,6 +56,26 @@ void Mat4SimpleInverse( const mat4_t in, mat4_t out);
|
|||
#define ByteToFloat(a) ((float)(a) * 1.0f/255.0f)
|
||||
#define FloatToByte(a) (byte)((a) * 255.0f)
|
||||
|
||||
static ID_INLINE int VectorCompare4(const vec4_t v1, const vec4_t v2)
|
||||
{
|
||||
if(v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2] || v1[3] != v2[3])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ID_INLINE int VectorCompare5(const vec5_t v1, const vec5_t v2)
|
||||
{
|
||||
if(v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2] || v1[3] != v2[3] || v1[4] != v2[4])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void VectorLerp( vec3_t a, vec3_t b, float lerp, vec3_t c);
|
||||
|
||||
|
||||
qboolean SpheresIntersect(vec3_t origin1, float radius1, vec3_t origin2, float radius2);
|
||||
void BoundingSphereOfSpheres(vec3_t origin1, float radius1, vec3_t origin2, float radius2, vec3_t origin3, float *radius3);
|
||||
|
|
|
@ -101,7 +101,7 @@ FBO_t *FBO_Create(const char *name, int width, int height)
|
|||
ri.Error(ERR_DROP, "FBO_Create: MAX_FBOS hit");
|
||||
}
|
||||
|
||||
fbo = tr.fbos[tr.numFBOs] = ri.Hunk_Alloc(sizeof(*fbo));
|
||||
fbo = tr.fbos[tr.numFBOs] = ri.Hunk_Alloc(sizeof(*fbo), h_low);
|
||||
Q_strncpyz(fbo->name, name, sizeof(fbo->name));
|
||||
fbo->index = tr.numFBOs++;
|
||||
fbo->width = width;
|
||||
|
@ -273,10 +273,8 @@ void FBO_Init(void)
|
|||
if (multisample < 2 || !glRefConfig.framebufferBlit)
|
||||
multisample = 0;
|
||||
|
||||
if (multisample != r_ext_framebuffer_multisample->integer) {
|
||||
char buf[10];
|
||||
ri.Cvar_Set("r_ext_framebuffer_multisample", itoa(multisample, buf, 10));
|
||||
}
|
||||
if (multisample != r_ext_framebuffer_multisample->integer)
|
||||
ri.Cvar_SetValue("r_ext_framebuffer_multisample", (float)multisample);
|
||||
|
||||
// only create a render FBO if we need to resolve MSAA or do HDR
|
||||
// otherwise just render straight to the screen (tr.renderFbo = NULL)
|
||||
|
|
|
@ -2121,7 +2121,7 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe
|
|||
ri.Error( ERR_DROP, "R_CreateImage: MAX_DRAWIMAGES hit");
|
||||
}
|
||||
|
||||
image = tr.images[tr.numImages] = ri.Hunk_Alloc( sizeof( image_t ) );
|
||||
image = tr.images[tr.numImages] = ri.Hunk_Alloc( sizeof( image_t ), h_low );
|
||||
qglGenTextures(1, &image->texnum);
|
||||
tr.numImages++;
|
||||
|
||||
|
@ -3098,7 +3098,7 @@ qhandle_t RE_RegisterSkin( const char *name ) {
|
|||
return 0;
|
||||
}
|
||||
tr.numSkins++;
|
||||
skin = ri.Hunk_Alloc( sizeof( skin_t ) );
|
||||
skin = ri.Hunk_Alloc( sizeof( skin_t ), h_low );
|
||||
tr.skins[hSkin] = skin;
|
||||
Q_strncpyz( skin->name, name, sizeof( skin->name ) );
|
||||
skin->numSurfaces = 0;
|
||||
|
@ -3108,7 +3108,7 @@ qhandle_t RE_RegisterSkin( const char *name ) {
|
|||
// If not a .skin file, load as a single shader
|
||||
if ( strcmp( name + strlen( name ) - 5, ".skin" ) ) {
|
||||
skin->numSurfaces = 1;
|
||||
skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ) );
|
||||
skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low );
|
||||
skin->surfaces[0].shader = R_FindShader( name, LIGHTMAP_NONE, qtrue );
|
||||
return hSkin;
|
||||
}
|
||||
|
@ -3166,7 +3166,7 @@ qhandle_t RE_RegisterSkin( const char *name ) {
|
|||
}
|
||||
|
||||
// copy surfaces to skin
|
||||
skin->surfaces = ri.Hunk_Alloc( skin->numSurfaces * sizeof( skinSurface_t ) );
|
||||
skin->surfaces = ri.Hunk_Alloc( skin->numSurfaces * sizeof( skinSurface_t ), h_low );
|
||||
memcpy( skin->surfaces, parseSurfaces, skin->numSurfaces * sizeof( skinSurface_t ) );
|
||||
|
||||
return hSkin;
|
||||
|
@ -3184,10 +3184,10 @@ void R_InitSkins( void ) {
|
|||
tr.numSkins = 1;
|
||||
|
||||
// make the default skin have all default shaders
|
||||
skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ) );
|
||||
skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low );
|
||||
Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name ) );
|
||||
skin->numSurfaces = 1;
|
||||
skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ) );
|
||||
skin->surfaces = ri.Hunk_Alloc( sizeof( skinSurface_t ), h_low );
|
||||
skin->surfaces[0].shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ float displayAspect = 0.0f;
|
|||
qboolean haveClampToEdge = qfalse;
|
||||
|
||||
glstate_t glState;
|
||||
int r_sequencenumber;
|
||||
|
||||
static void GfxInfo_f( void );
|
||||
static void GfxMemInfo_f( void );
|
||||
|
@ -237,46 +236,6 @@ int max_polys;
|
|||
cvar_t *r_maxpolyverts;
|
||||
int max_polyverts;
|
||||
|
||||
cvar_t* r_staticlod;
|
||||
cvar_t* r_lodscale;
|
||||
cvar_t* r_lodcap;
|
||||
cvar_t* r_lodviewmodelcap;
|
||||
|
||||
cvar_t* r_uselod;
|
||||
cvar_t* lod_LOD;
|
||||
cvar_t* lod_minLOD;
|
||||
cvar_t* lod_maxLOD;
|
||||
cvar_t* lod_LOD_slider;
|
||||
cvar_t* lod_curve_0_val;
|
||||
cvar_t* lod_curve_1_val;
|
||||
cvar_t* lod_curve_2_val;
|
||||
cvar_t* lod_curve_3_val;
|
||||
cvar_t* lod_curve_4_val;
|
||||
cvar_t* lod_edit_0;
|
||||
cvar_t* lod_edit_1;
|
||||
cvar_t* lod_edit_2;
|
||||
cvar_t* lod_edit_3;
|
||||
cvar_t* lod_edit_4;
|
||||
cvar_t* lod_curve_0_slider;
|
||||
cvar_t* lod_curve_1_slider;
|
||||
cvar_t* lod_curve_2_slider;
|
||||
cvar_t* lod_curve_3_slider;
|
||||
cvar_t* lod_curve_4_slider;
|
||||
cvar_t* lod_pitch_val;
|
||||
cvar_t* lod_zee_val;
|
||||
cvar_t* lod_mesh;
|
||||
cvar_t* lod_meshname;
|
||||
cvar_t* lod_tikiname;
|
||||
cvar_t* lod_metric;
|
||||
cvar_t* lod_tris;
|
||||
cvar_t* lod_position;
|
||||
cvar_t* lod_save;
|
||||
cvar_t* lod_tool;
|
||||
|
||||
cvar_t* r_numdebuglines;
|
||||
|
||||
cvar_t* r_showSkeleton;
|
||||
|
||||
/*
|
||||
** InitOpenGL
|
||||
**
|
||||
|
@ -909,6 +868,87 @@ void R_ExportCubemaps_f(void)
|
|||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
==================
|
||||
RB_TakeVideoFrameCmd
|
||||
==================
|
||||
*/
|
||||
const void *RB_TakeVideoFrameCmd( const void *data )
|
||||
{
|
||||
const videoFrameCommand_t *cmd;
|
||||
byte *cBuf;
|
||||
size_t memcount, linelen;
|
||||
int padwidth, avipadwidth, padlen, avipadlen;
|
||||
GLint packAlign;
|
||||
|
||||
// finish any 2D drawing if needed
|
||||
if(tess.numIndexes)
|
||||
RB_EndSurface();
|
||||
|
||||
cmd = (const videoFrameCommand_t *)data;
|
||||
|
||||
qglGetIntegerv(GL_PACK_ALIGNMENT, &packAlign);
|
||||
|
||||
linelen = cmd->width * 3;
|
||||
|
||||
// Alignment stuff for glReadPixels
|
||||
padwidth = PAD(linelen, packAlign);
|
||||
padlen = padwidth - linelen;
|
||||
// AVI line padding
|
||||
avipadwidth = PAD(linelen, AVI_LINE_PADDING);
|
||||
avipadlen = avipadwidth - linelen;
|
||||
|
||||
cBuf = PADP(cmd->captureBuffer, packAlign);
|
||||
|
||||
qglReadPixels(0, 0, cmd->width, cmd->height, GL_RGB,
|
||||
GL_UNSIGNED_BYTE, cBuf);
|
||||
|
||||
memcount = padwidth * cmd->height;
|
||||
|
||||
// gamma correct
|
||||
if(glConfig.deviceSupportsGamma)
|
||||
R_GammaCorrect(cBuf, memcount);
|
||||
|
||||
if(cmd->motionJpeg)
|
||||
{
|
||||
memcount = RE_SaveJPGToBuffer(cmd->encodeBuffer, linelen * cmd->height,
|
||||
r_aviMotionJpegQuality->integer,
|
||||
cmd->width, cmd->height, cBuf, padlen);
|
||||
ri.CL_WriteAVIVideoFrame(cmd->encodeBuffer, memcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte *lineend, *memend;
|
||||
byte *srcptr, *destptr;
|
||||
|
||||
srcptr = cBuf;
|
||||
destptr = cmd->encodeBuffer;
|
||||
memend = srcptr + memcount;
|
||||
|
||||
// swap R and B and remove line paddings
|
||||
while(srcptr < memend)
|
||||
{
|
||||
lineend = srcptr + linelen;
|
||||
while(srcptr < lineend)
|
||||
{
|
||||
*destptr++ = srcptr[2];
|
||||
*destptr++ = srcptr[1];
|
||||
*destptr++ = srcptr[0];
|
||||
srcptr += 3;
|
||||
}
|
||||
|
||||
Com_Memset(destptr, '\0', avipadlen);
|
||||
destptr += avipadlen;
|
||||
|
||||
srcptr += padlen;
|
||||
}
|
||||
|
||||
ri.CL_WriteAVIVideoFrame(cmd->encodeBuffer, avipadwidth * cmd->height);
|
||||
}
|
||||
|
||||
return (const void *)(cmd + 1);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
|
@ -986,11 +1026,6 @@ void R_PrintLongString(const char *string) {
|
|||
}
|
||||
}
|
||||
|
||||
const char* RE_GetGraphicsInfo() {
|
||||
// FIXME: unimplemented
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
GfxInfo_f
|
||||
|
@ -1074,16 +1109,6 @@ void GfxInfo_f( void )
|
|||
}
|
||||
}
|
||||
|
||||
qboolean R_SetMode(int mode) {
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void R_SetFullscreen(qboolean fullscreen, glconfig_t* config) {
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
GfxMemInfo_f
|
||||
|
@ -1170,12 +1195,14 @@ void R_Register( void )
|
|||
r_picmip = ri.Cvar_Get ("r_picmip", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_roundImagesDown = ri.Cvar_Get ("r_roundImagesDown", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_colorMipLevels = ri.Cvar_Get ("r_colorMipLevels", "0", CVAR_LATCH );
|
||||
ri.Cvar_CheckRange( r_picmip, 0, 16, qtrue );
|
||||
r_detailTextures = ri.Cvar_Get( "r_detailtextures", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_texturebits = ri.Cvar_Get( "r_texturebits", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_colorbits = ri.Cvar_Get( "r_colorbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_stencilbits = ri.Cvar_Get( "r_stencilbits", "8", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_depthbits = ri.Cvar_Get( "r_depthbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_ext_multisample = ri.Cvar_Get( "r_ext_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
ri.Cvar_CheckRange( r_ext_multisample, 0, 4, qtrue );
|
||||
r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_mode = ri.Cvar_Get( "r_mode", "-2", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
@ -1190,6 +1217,7 @@ void R_Register( void )
|
|||
r_subdivisions = ri.Cvar_Get ("r_subdivisions", "4", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_stereoEnabled = ri.Cvar_Get( "r_stereoEnabled", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_greyscale = ri.Cvar_Get("r_greyscale", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
ri.Cvar_CheckRange(r_greyscale, 0, 1, qfalse);
|
||||
|
||||
r_externalGLSL = ri.Cvar_Get( "r_externalGLSL", "0", CVAR_LATCH );
|
||||
|
||||
|
@ -1256,6 +1284,7 @@ void R_Register( void )
|
|||
// temporary latched variables that can only change over a restart
|
||||
//
|
||||
r_displayRefresh = ri.Cvar_Get( "r_displayRefresh", "0", CVAR_LATCH );
|
||||
ri.Cvar_CheckRange( r_displayRefresh, 0, 200, qtrue );
|
||||
r_fullbright = ri.Cvar_Get ("r_fullbright", "0", CVAR_LATCH|CVAR_CHEAT );
|
||||
r_mapOverBrightBits = ri.Cvar_Get ("r_mapOverBrightBits", "2", CVAR_LATCH );
|
||||
r_intensity = ri.Cvar_Get ("r_intensity", "1", CVAR_LATCH );
|
||||
|
@ -1268,6 +1297,7 @@ void R_Register( void )
|
|||
r_lodbias = ri.Cvar_Get( "r_lodbias", "0", CVAR_ARCHIVE );
|
||||
r_flares = ri.Cvar_Get ("r_flares", "0", CVAR_ARCHIVE );
|
||||
r_znear = ri.Cvar_Get( "r_znear", "4", CVAR_CHEAT );
|
||||
ri.Cvar_CheckRange( r_znear, 0.001f, 200, qfalse );
|
||||
r_zproj = ri.Cvar_Get( "r_zproj", "64", CVAR_ARCHIVE );
|
||||
r_stereoSeparation = ri.Cvar_Get( "r_stereoSeparation", "64", CVAR_ARCHIVE );
|
||||
r_ignoreGLErrors = ri.Cvar_Get( "r_ignoreGLErrors", "1", CVAR_ARCHIVE );
|
||||
|
@ -1446,7 +1476,7 @@ void R_Init( void ) {
|
|||
if (max_polyverts < MAX_POLYVERTS)
|
||||
max_polyverts = MAX_POLYVERTS;
|
||||
|
||||
ptr = ri.Hunk_Alloc( sizeof( *backEndData ) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts);
|
||||
ptr = ri.Hunk_Alloc( sizeof( *backEndData ) + sizeof(srfPoly_t) * max_polys + sizeof(polyVert_t) * max_polyverts, h_low);
|
||||
backEndData = (backEndData_t *) ptr;
|
||||
backEndData->polys = (srfPoly_t *) ((char *) ptr + sizeof( *backEndData ));
|
||||
backEndData->polyVerts = (polyVert_t *) ((char *) ptr + sizeof( *backEndData ) + sizeof(srfPoly_t) * max_polys);
|
||||
|
@ -1549,9 +1579,6 @@ void RE_EndRegistration( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
void RE_SetRenderTime(int t) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
|
@ -1579,77 +1606,43 @@ refexport_t *GetRefAPI ( int apiVersion, refimport_t *rimp ) {
|
|||
|
||||
// the RE_ functions are Renderer Entry points
|
||||
|
||||
re.Shutdown = RE_Shutdown;
|
||||
re.Shutdown = RE_Shutdown;
|
||||
|
||||
re.FreeModels = RE_FreeModels;
|
||||
re.BeginRegistration = RE_BeginRegistration;
|
||||
re.EndRegistration = RE_EndRegistration;
|
||||
re.RegisterModel = RE_RegisterModel;
|
||||
re.SpawnEffectModel = RE_SpawnEffectModel;
|
||||
re.RegisterServerModel = RE_RegisterServerModel;
|
||||
re.UnregisterServerModel = RE_UnregisterServerModel;
|
||||
re.RegisterShader = RE_RegisterShader;
|
||||
re.RegisterShaderNoMip = RE_RegisterShaderNoMip;
|
||||
re.LoadWorld = RE_LoadWorldMap;
|
||||
re.PrintBSPFileSizes = RE_PrintBSPFileSizes;
|
||||
re.MapVersion = RE_MapVersion;
|
||||
re.LoadFont = R_LoadFont;
|
||||
re.SetWorldVisData = RE_SetWorldVisData;
|
||||
re.BeginRegistration = RE_BeginRegistration;
|
||||
re.RegisterModel = RE_RegisterModel;
|
||||
re.RegisterSkin = RE_RegisterSkin;
|
||||
re.RegisterShader = RE_RegisterShader;
|
||||
re.RegisterShaderNoMip = RE_RegisterShaderNoMip;
|
||||
re.LoadWorld = RE_LoadWorldMap;
|
||||
re.SetWorldVisData = RE_SetWorldVisData;
|
||||
re.EndRegistration = RE_EndRegistration;
|
||||
|
||||
re.BeginFrame = RE_BeginFrame;
|
||||
re.EndFrame = RE_EndFrame;
|
||||
re.BeginFrame = RE_BeginFrame;
|
||||
re.EndFrame = RE_EndFrame;
|
||||
|
||||
re.MarkFragments = R_MarkFragments;
|
||||
re.MarkFragmentsForInlineModel = R_MarkFragmentsForInlineModel;
|
||||
re.GetInlineModelBounds = R_GetInlineModelBounds;
|
||||
re.GetLightingForDecal = R_GetLightingForDecal;
|
||||
re.GetLightingForSmoke = R_GetLightingForSmoke;
|
||||
re.R_GatherLightSources = R_GatherLightSources;
|
||||
re.ModelBounds = R_ModelBounds;
|
||||
re.ModelRadius = R_ModelRadius;
|
||||
re.MarkFragments = R_MarkFragments;
|
||||
re.LerpTag = R_LerpTag;
|
||||
re.ModelBounds = R_ModelBounds;
|
||||
|
||||
re.ClearScene = RE_ClearScene;
|
||||
re.AddRefEntityToScene = RE_AddRefEntityToScene;
|
||||
re.AddRefSpriteToScene = RE_AddRefSpriteToScene;
|
||||
re.AddPolyToScene = RE_AddPolyToScene;
|
||||
re.AddTerrainMarkToScene = RE_AddTerrainMarkToScene;
|
||||
re.AddLightToScene = RE_AddLightToScene;
|
||||
re.RenderScene = RE_RenderScene;
|
||||
re.GetRenderEntity = RE_GetRenderEntity;
|
||||
re.ClearScene = RE_ClearScene;
|
||||
re.AddRefEntityToScene = RE_AddRefEntityToScene;
|
||||
re.AddPolyToScene = RE_AddPolyToScene;
|
||||
re.LightForPoint = R_LightForPoint;
|
||||
re.AddLightToScene = RE_AddLightToScene;
|
||||
re.AddAdditiveLightToScene = RE_AddAdditiveLightToScene;
|
||||
re.RenderScene = RE_RenderScene;
|
||||
|
||||
re.SavePerformanceCounters = R_SavePerformanceCounters;
|
||||
re.SetColor = RE_SetColor;
|
||||
re.DrawStretchPic = RE_StretchPic;
|
||||
re.DrawStretchRaw = RE_StretchRaw;
|
||||
re.UploadCinematic = RE_UploadCinematic;
|
||||
|
||||
re.R_Model_GetHandle = R_Model_GetHandle;
|
||||
re.SetColor = Draw_SetColor;
|
||||
re.DrawStretchPic = Draw_StretchPic;
|
||||
re.DrawStretchRaw = RE_StretchRaw;
|
||||
re.DebugLine = R_DebugLine;
|
||||
re.DrawTilePic = Draw_TilePic;
|
||||
re.DrawTilePicOffset = Draw_TilePicOffset;
|
||||
re.DrawTrianglePic = Draw_TrianglePic;
|
||||
re.DrawBox = DrawBox;
|
||||
re.AddBox = AddBox;
|
||||
re.Set2DWindow = Set2DWindow;
|
||||
re.Scissor = RE_Scissor;
|
||||
re.DrawLineLoop = DrawLineLoop;
|
||||
re.DrawString = R_DrawString;
|
||||
re.GetFontHeight = R_GetFontHeight;
|
||||
re.GetFontStringWidth = R_GetFontStringWidth;
|
||||
re.SwipeBegin = RE_SwipeBegin;
|
||||
re.SwipeEnd = RE_SwipeEnd;
|
||||
re.SetRenderTime = RE_SetRenderTime;
|
||||
re.Noise = R_NoiseGet4f;
|
||||
re.RegisterFont = RE_RegisterFont;
|
||||
re.RemapShader = R_RemapShader;
|
||||
re.GetEntityToken = R_GetEntityToken;
|
||||
re.inPVS = R_inPVS;
|
||||
|
||||
re.SetMode = R_SetMode;
|
||||
re.SetFullscreen = R_SetFullscreen;
|
||||
|
||||
re.GetShaderHeight = RE_GetShaderHeight;
|
||||
re.GetShaderWidth = RE_GetShaderWidth;
|
||||
re.GetGraphicsInfo = RE_GetGraphicsInfo;
|
||||
re.ForceUpdatePose = RE_ForceUpdatePose;
|
||||
re.TIKI_Orientation = RE_TIKI_Orientation;
|
||||
re.TIKI_IsOnGround = RE_TIKI_IsOnGround;
|
||||
re.SetFrameNumber = RE_SetFrameNumber;
|
||||
re.TakeVideoFrame = RE_TakeVideoFrame;
|
||||
|
||||
return &re;
|
||||
}
|
||||
|
|
|
@ -425,9 +425,9 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
|
|||
}
|
||||
|
||||
// save out the byte packet version
|
||||
((byte *)&ent->ambientLightInt)[0] = ftol(ent->ambientLight[0]);
|
||||
((byte *)&ent->ambientLightInt)[1] = ftol(ent->ambientLight[1]);
|
||||
((byte *)&ent->ambientLightInt)[2] = ftol(ent->ambientLight[2]);
|
||||
((byte *)&ent->ambientLightInt)[0] = ri.ftol(ent->ambientLight[0]);
|
||||
((byte *)&ent->ambientLightInt)[1] = ri.ftol(ent->ambientLight[1]);
|
||||
((byte *)&ent->ambientLightInt)[2] = ri.ftol(ent->ambientLight[2]);
|
||||
((byte *)&ent->ambientLightInt)[3] = 0xff;
|
||||
|
||||
// transform the direction to local space
|
||||
|
|
|
@ -20,7 +20,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef TR_LOCAL_H
|
||||
#define TR_LOCAL_H
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qfiles.h"
|
||||
|
@ -66,101 +68,6 @@ typedef unsigned int glIndex_t;
|
|||
#define MAX_DRAWN_PSHADOWS 16 // do not increase past 32, because bit flags are used on surfaces
|
||||
#define PSHADOW_MAP_SIZE 512
|
||||
|
||||
typedef struct skelSurfaceGame_s skelSurfaceGame_t;
|
||||
typedef struct staticSurface_s staticSurface_t;
|
||||
|
||||
// any changes in surfaceType must be mirrored in rb_surfaceTable[]
|
||||
typedef enum {
|
||||
SF_BAD,
|
||||
SF_SKIP, // ignore
|
||||
SF_FACE,
|
||||
SF_GRID,
|
||||
SF_POLY,
|
||||
SF_MARK_FRAG,
|
||||
SF_FLARE,
|
||||
SF_ENTITY, // beams, rails, lightning, etc that can be determined by entity
|
||||
SF_DISPLAY_LIST,
|
||||
SF_TIKI_SKEL,
|
||||
SF_TIKI_STATIC,
|
||||
SF_SWIPE,
|
||||
SF_SPRITE,
|
||||
SF_TERRAIN_PATCH,
|
||||
SF_TRIANGLES,
|
||||
SF_MDV,
|
||||
SF_MDR,
|
||||
SF_IQM,
|
||||
SF_VAO_MDVMESH,
|
||||
SF_VAO_IQM,
|
||||
|
||||
SF_NUM_SURFACE_TYPES,
|
||||
SF_MAX = 0x7fffffff // ensures that sizeof( surfaceType_t ) == sizeof( int )
|
||||
} surfaceType_t;
|
||||
|
||||
typedef struct {
|
||||
struct mnode_s* cntNode;
|
||||
qboolean inUse;
|
||||
struct msurface_s* skySurfs[32];
|
||||
int numSurfs;
|
||||
vec3_t offset;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
} portalsky_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t transformed;
|
||||
int index;
|
||||
} sphere_dlight_t;
|
||||
|
||||
typedef enum {
|
||||
LIGHT_POINT,
|
||||
LIGHT_DIRECTIONAL,
|
||||
LIGHT_SPOT,
|
||||
LIGHT_SPOT_FAST
|
||||
} lighttype_t;
|
||||
|
||||
typedef struct reallightinfo_s {
|
||||
vec3_t color;
|
||||
lighttype_t eType;
|
||||
float fIntensity;
|
||||
float fDist;
|
||||
float fSpotSlope;
|
||||
float fSpotConst;
|
||||
float fSpotScale;
|
||||
vec3_t vOrigin;
|
||||
vec3_t vDirection;
|
||||
} reallightinfo_t;
|
||||
|
||||
typedef float cube_entry_t[3][4];
|
||||
|
||||
typedef struct {
|
||||
vec3_t origin;
|
||||
vec3_t worldOrigin;
|
||||
vec3_t traceOrigin;
|
||||
float radius;
|
||||
struct mnode_s* leaves[8];
|
||||
void(*TessFunction) ();
|
||||
union ambient {
|
||||
unsigned char level[4];
|
||||
int value;
|
||||
};
|
||||
int numRealLights;
|
||||
reallightinfo_t light[32];
|
||||
int bUsesCubeMap;
|
||||
float cubemap[24][3][4];
|
||||
} sphereor_t;
|
||||
|
||||
typedef struct spherel_s {
|
||||
vec3_t origin;
|
||||
vec3_t color;
|
||||
float intensity;
|
||||
struct mnode_s* leaf;
|
||||
int needs_trace;
|
||||
int spot_light;
|
||||
float spot_radiusbydistance;
|
||||
vec3_t spot_dir;
|
||||
int reference_count;
|
||||
} spherel_t;
|
||||
|
||||
typedef struct cubemap_s {
|
||||
char name[MAX_QPATH];
|
||||
vec3_t origin;
|
||||
|
@ -195,17 +102,6 @@ typedef struct {
|
|||
vec3_t directedLight;
|
||||
} trRefEntity_t;
|
||||
|
||||
typedef struct refSprite_s {
|
||||
surfaceType_t surftype;
|
||||
int hModel;
|
||||
int shaderNum;
|
||||
float origin[3];
|
||||
float scale;
|
||||
float axis[3][3];
|
||||
unsigned char shaderRGBA[4];
|
||||
int renderfx;
|
||||
float shaderTime;
|
||||
} refSprite_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t origin; // in world coordinates
|
||||
|
@ -870,18 +766,7 @@ typedef struct {
|
|||
float sunAmbCol[4];
|
||||
|
||||
float autoExposureMinMax[2];
|
||||
float toneMinAvgMaxLinear[3];
|
||||
|
||||
int numSpriteSurfs;
|
||||
struct drawSurf_s* spriteSurfs;
|
||||
int numStaticModels;
|
||||
struct cStaticModelUnpacked_s* staticModels;
|
||||
int numStaticModelData;
|
||||
unsigned char* staticModelData;
|
||||
qboolean sky_portal;
|
||||
float sky_alpha;
|
||||
vec3_t sky_origin;
|
||||
vec3_t sky_axis[3];
|
||||
float toneMinAvgMaxLinear[3];
|
||||
} trRefdef_t;
|
||||
|
||||
|
||||
|
@ -964,6 +849,25 @@ SURFACES
|
|||
*/
|
||||
typedef byte color4ub_t[4];
|
||||
|
||||
// any changes in surfaceType must be mirrored in rb_surfaceTable[]
|
||||
typedef enum {
|
||||
SF_BAD,
|
||||
SF_SKIP, // ignore
|
||||
SF_FACE,
|
||||
SF_GRID,
|
||||
SF_TRIANGLES,
|
||||
SF_POLY,
|
||||
SF_MDV,
|
||||
SF_MDR,
|
||||
SF_IQM,
|
||||
SF_FLARE,
|
||||
SF_ENTITY, // beams, rails, lightning, etc that can be determined by entity
|
||||
SF_VAO_MDVMESH,
|
||||
SF_VAO_IQM,
|
||||
|
||||
SF_NUM_SURFACE_TYPES,
|
||||
SF_MAX = 0x7fffffff // ensures that sizeof( surfaceType_t ) == sizeof( int )
|
||||
} surfaceType_t;
|
||||
|
||||
typedef struct drawSurf_s {
|
||||
unsigned int sort; // bit combination for fast compares
|
||||
|
@ -986,12 +890,6 @@ typedef struct srfPoly_s {
|
|||
polyVert_t *verts;
|
||||
} srfPoly_t;
|
||||
|
||||
typedef struct srfMarkFragment_s {
|
||||
surfaceType_t surfaceType;
|
||||
int iIndex;
|
||||
int numVerts;
|
||||
polyVert_t* verts;
|
||||
} srfMarkFragment_t;
|
||||
|
||||
typedef struct srfFlare_s {
|
||||
surfaceType_t surfaceType;
|
||||
|
@ -1146,115 +1044,6 @@ typedef struct srfVaoMdvMesh_s
|
|||
vao_t *vao;
|
||||
} srfVaoMdvMesh_t;
|
||||
|
||||
typedef union varnodeUnpacked_u {
|
||||
float fVariance;
|
||||
byte flags;
|
||||
} varnodeUnpacked_t;
|
||||
|
||||
typedef unsigned short terraInt;
|
||||
|
||||
typedef struct terrainVert_s {
|
||||
vec3_t xyz;
|
||||
vec2_t texCoords[2];
|
||||
float fVariance;
|
||||
float fHgtAvg;
|
||||
float fHgtAdd;
|
||||
unsigned int uiDistRecalc;
|
||||
terraInt nRef;
|
||||
terraInt iVertArray;
|
||||
byte* pHgt;
|
||||
terraInt iNext;
|
||||
terraInt iPrev;
|
||||
} terrainVert_t;
|
||||
|
||||
typedef struct terraTri_s {
|
||||
unsigned short iPt[3];
|
||||
terraInt nSplit;
|
||||
unsigned int uiDistRecalc;
|
||||
struct cTerraPatchUnpacked_s* patch;
|
||||
varnodeUnpacked_t* varnode;
|
||||
terraInt index;
|
||||
byte lod;
|
||||
byte byConstChecks;
|
||||
terraInt iLeft;
|
||||
terraInt iRight;
|
||||
terraInt iBase;
|
||||
terraInt iLeftChild;
|
||||
terraInt iRightChild;
|
||||
terraInt iParent;
|
||||
terraInt iPrev;
|
||||
terraInt iNext;
|
||||
} terraTri_t;
|
||||
|
||||
typedef struct srfTerrain_s {
|
||||
surfaceType_t surfaceType;
|
||||
terraInt iVertHead;
|
||||
terraInt iTriHead;
|
||||
terraInt iTriTail;
|
||||
terraInt iMergeHead;
|
||||
int nVerts;
|
||||
int nTris;
|
||||
int lmapSize;
|
||||
int dlightBits[2];
|
||||
float lmapStep;
|
||||
int dlightMap[2];
|
||||
byte* lmData;
|
||||
float lmapX;
|
||||
float lmapY;
|
||||
} srfTerrain_t;
|
||||
|
||||
typedef struct cTerraPatchUnpacked_s {
|
||||
srfTerrain_t drawinfo;
|
||||
int viewCount;
|
||||
int visCountCheck;
|
||||
int visCountDraw;
|
||||
int frameCount;
|
||||
unsigned int uiDistRecalc;
|
||||
float s;
|
||||
float t;
|
||||
float texCoord[2][2][2];
|
||||
float x0;
|
||||
float y0;
|
||||
float z0;
|
||||
float zmax;
|
||||
shader_t* shader;
|
||||
short int iNorth;
|
||||
short int iEast;
|
||||
short int iSouth;
|
||||
short int iWest;
|
||||
struct cTerraPatchUnpacked_s* pNextActive;
|
||||
varnodeUnpacked_t varTree[2][63];
|
||||
unsigned char heightmap[81];
|
||||
byte flags;
|
||||
byte byDirty;
|
||||
} cTerraPatchUnpacked_t;
|
||||
|
||||
typedef struct srfStaticModel_s {
|
||||
surfaceType_t surfaceType;
|
||||
struct cStaticModelUnpacked_s* parent;
|
||||
} srfStaticModel_t;
|
||||
|
||||
typedef struct cStaticModelUnpacked_s {
|
||||
qboolean useSpecialLighting;
|
||||
qboolean bLightGridCalculated;
|
||||
qboolean bRendered;
|
||||
char model[128];
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t axis[3];
|
||||
float scale;
|
||||
int firstVertexData;
|
||||
int numVertexData;
|
||||
int visCount;
|
||||
dtiki_t* tiki;
|
||||
sphere_dlight_t dlights[32];
|
||||
int numdlights;
|
||||
float radius;
|
||||
float cull_radius;
|
||||
int iGridLighting;
|
||||
float lodpercentage[2];
|
||||
} cStaticModelUnpacked_t;
|
||||
|
||||
extern void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])(void *);
|
||||
|
||||
/*
|
||||
|
@ -1351,15 +1140,6 @@ typedef struct {
|
|||
int numSurfaces;
|
||||
} bmodel_t;
|
||||
|
||||
typedef struct {
|
||||
float width;
|
||||
float height;
|
||||
float origin_x;
|
||||
float origin_y;
|
||||
float scale;
|
||||
shader_t* shader;
|
||||
} sprite_t;
|
||||
|
||||
typedef struct {
|
||||
char name[MAX_QPATH]; // ie: maps/tim_dm2.bsp
|
||||
char baseName[MAX_QPATH]; // ie: tim_dm2
|
||||
|
@ -1400,21 +1180,6 @@ typedef struct {
|
|||
byte *lightGridData;
|
||||
uint16_t *lightGrid16;
|
||||
|
||||
int numTerraPatches;
|
||||
cTerraPatchUnpacked_t* terraPatches;
|
||||
cTerraPatchUnpacked_t* activeTerraPatches;
|
||||
|
||||
int numVisTerraPatches;
|
||||
cTerraPatchUnpacked_t** visTerraPatches;
|
||||
|
||||
int numStaticModelData;
|
||||
byte* staticModelData;
|
||||
|
||||
int numStaticModels;
|
||||
cStaticModelUnpacked_t* staticModels;
|
||||
|
||||
int numVisStaticModels;
|
||||
cStaticModelUnpacked_t** visStaticModels;
|
||||
|
||||
int numClusters;
|
||||
int clusterBytes;
|
||||
|
@ -1501,10 +1266,11 @@ typedef struct mdvModel_s
|
|||
//======================================================================
|
||||
|
||||
typedef enum {
|
||||
MOD_BAD,
|
||||
MOD_BRUSH,
|
||||
MOD_TIKI,
|
||||
MOD_SPRITE
|
||||
MOD_BAD,
|
||||
MOD_BRUSH,
|
||||
MOD_MESH,
|
||||
MOD_MDR,
|
||||
MOD_IQM
|
||||
} modtype_t;
|
||||
|
||||
typedef struct model_s {
|
||||
|
@ -1517,14 +1283,7 @@ typedef struct model_s {
|
|||
mdvModel_t *mdv[MD3_MAX_LODS]; // only if type == MOD_MESH
|
||||
void *modelData; // only if type == (MOD_MDR | MOD_IQM)
|
||||
|
||||
int numLods;
|
||||
|
||||
qboolean serveronly;
|
||||
union {
|
||||
bmodel_t* bmodel;
|
||||
dtiki_t* tiki;
|
||||
sprite_t* sprite;
|
||||
} d;
|
||||
int numLods;
|
||||
} model_t;
|
||||
|
||||
|
||||
|
@ -1534,6 +1293,7 @@ void R_ModelInit (void);
|
|||
model_t *R_GetModelByHandle( qhandle_t hModel );
|
||||
int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame,
|
||||
float frac, const char *tagName );
|
||||
void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs );
|
||||
|
||||
void R_Modellist_f (void);
|
||||
|
||||
|
@ -1703,14 +1463,7 @@ typedef struct {
|
|||
backEndCounters_t pc;
|
||||
qboolean isHyperspace;
|
||||
trRefEntity_t *currentEntity;
|
||||
qboolean skyRenderedThisView; // flag for drawing sun
|
||||
sphereor_t spheres[128];
|
||||
unsigned char numSpheresUsed;
|
||||
sphereor_t* currentSphere;
|
||||
sphereor_t spareSphere;
|
||||
sphereor_t hudSphere;
|
||||
cStaticModelUnpacked_t* currentStaticModel;
|
||||
int dsStreamVert;
|
||||
qboolean skyRenderedThisView; // flag for drawing sun
|
||||
|
||||
qboolean projection2D; // if qtrue, drawstretchpic doesn't need to change modes
|
||||
byte color2D[4];
|
||||
|
@ -1820,8 +1573,7 @@ typedef struct {
|
|||
trRefEntity_t *currentEntity;
|
||||
trRefEntity_t worldEntity; // point currentEntity at this when rendering world
|
||||
int currentEntityNum;
|
||||
int shiftedEntityNum; // currentEntityNum << QSORT_REFENTITYNUM_SHIFT
|
||||
int shiftedIsStatic;
|
||||
int shiftedEntityNum; // currentEntityNum << QSORT_REFENTITYNUM_SHIFT
|
||||
model_t *currentModel;
|
||||
|
||||
//
|
||||
|
@ -1850,10 +1602,7 @@ typedef struct {
|
|||
|
||||
float identityLight; // 1.0 / ( 1 << overbrightBits )
|
||||
int identityLightByte; // identityLight * 255
|
||||
int overbrightBits; // r_overbrightBits->integer, but set to 0 if no hw gamma
|
||||
int overbrightShift;
|
||||
float overbrightMult;
|
||||
int needsLightScale;
|
||||
int overbrightBits; // r_overbrightBits->integer, but set to 0 if no hw gamma
|
||||
|
||||
orientationr_t or; // for current entity
|
||||
|
||||
|
@ -1907,22 +1656,9 @@ typedef struct {
|
|||
float triangleTable[FUNCTABLE_SIZE];
|
||||
float sawToothTable[FUNCTABLE_SIZE];
|
||||
float inverseSawToothTable[FUNCTABLE_SIZE];
|
||||
float fogTable[FOG_TABLE_SIZE];
|
||||
|
||||
spherel_t sSunLight;
|
||||
spherel_t sLights[1532];
|
||||
int numSLights;
|
||||
int rendererhandle;
|
||||
qboolean shadersParsed;
|
||||
int frame_skel_index;
|
||||
int skel_index[1024];
|
||||
fontheader_t* pFontDebugStrings;
|
||||
float fogTable[FOG_TABLE_SIZE];
|
||||
} trGlobals_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern backEndState_t backEnd;
|
||||
extern trGlobals_t tr;
|
||||
extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init
|
||||
|
@ -2088,46 +1824,7 @@ extern cvar_t *r_simpleMipMaps;
|
|||
extern cvar_t *r_showImages;
|
||||
extern cvar_t *r_debugSort;
|
||||
|
||||
extern cvar_t* r_printShaders;
|
||||
extern cvar_t* r_staticlod;
|
||||
extern cvar_t* r_lodscale;
|
||||
extern cvar_t* r_lodcap;
|
||||
extern cvar_t* r_lodviewmodelcap;
|
||||
|
||||
extern cvar_t* r_uselod;
|
||||
extern cvar_t* lod_LOD;
|
||||
extern cvar_t* lod_minLOD;
|
||||
extern cvar_t* lod_maxLOD;
|
||||
extern cvar_t* lod_LOD_slider;
|
||||
extern cvar_t* lod_curve_0_val;
|
||||
extern cvar_t* lod_curve_1_val;
|
||||
extern cvar_t* lod_curve_2_val;
|
||||
extern cvar_t* lod_curve_3_val;
|
||||
extern cvar_t* lod_curve_4_val;
|
||||
extern cvar_t* lod_edit_0;
|
||||
extern cvar_t* lod_edit_1;
|
||||
extern cvar_t* lod_edit_2;
|
||||
extern cvar_t* lod_edit_3;
|
||||
extern cvar_t* lod_edit_4;
|
||||
extern cvar_t* lod_curve_0_slider;
|
||||
extern cvar_t* lod_curve_1_slider;
|
||||
extern cvar_t* lod_curve_2_slider;
|
||||
extern cvar_t* lod_curve_3_slider;
|
||||
extern cvar_t* lod_curve_4_slider;
|
||||
extern cvar_t* lod_pitch_val;
|
||||
extern cvar_t* lod_zee_val;
|
||||
extern cvar_t* lod_mesh;
|
||||
extern cvar_t* lod_meshname;
|
||||
extern cvar_t* lod_tikiname;
|
||||
extern cvar_t* lod_metric;
|
||||
extern cvar_t* lod_tris;
|
||||
extern cvar_t* lod_position;
|
||||
extern cvar_t* lod_save;
|
||||
extern cvar_t* lod_tool;
|
||||
|
||||
extern cvar_t* r_numdebuglines;
|
||||
|
||||
extern cvar_t* r_showSkeleton;
|
||||
extern cvar_t *r_printShaders;
|
||||
|
||||
extern cvar_t *r_marksOnTriangleMeshes;
|
||||
|
||||
|
@ -2161,8 +1858,6 @@ static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
|
|||
|
||||
void R_SwapBuffers( int );
|
||||
|
||||
void R_DebugCircle(const vec3_t org, float radius, float r, float g, float b, float alpha, qboolean horizontal);
|
||||
void R_DebugLine(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha);
|
||||
void R_RenderView( viewParms_t *parms );
|
||||
void R_RenderDlightCubemaps(const refdef_t *fd);
|
||||
void R_RenderPshadowMaps(const refdef_t *fd);
|
||||
|
@ -2201,7 +1896,6 @@ int R_CullLocalPointAndRadius( const vec3_t origin, float radius );
|
|||
|
||||
void R_SetupProjection(viewParms_t *dest, float zProj, float zFar, qboolean computeFrustum);
|
||||
void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, orientationr_t *or );
|
||||
void R_RotateForStaticModel(cStaticModelUnpacked_t* SM, const viewParms_t* viewParms, orientationr_t* or );
|
||||
|
||||
/*
|
||||
** GL wrapper/helper functions
|
||||
|
@ -2253,24 +1947,12 @@ void GL_Cull( int cullType );
|
|||
|
||||
#define GLS_DEFAULT GLS_DEPTHMASK_TRUE
|
||||
|
||||
void Draw_SetColor(const vec4_t rgba);
|
||||
void Draw_StretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader);
|
||||
void Draw_TilePic(float x, float y, float w, float h, qhandle_t hShader);
|
||||
void Draw_TilePicOffset(float x, float y, float w, float h, qhandle_t hShader, int offsetX, int offsetY);
|
||||
void Draw_TrianglePic(const vec2_t vPoints[3], const vec2_t vTexCoords[3], qhandle_t hShader);
|
||||
void DrawBox(float x, float y, float w, float h);
|
||||
void AddBox(float x, float y, float w, float h);
|
||||
void Set2DWindow(int x, int y, int w, int h, float left, float right, float bottom, float top, float n, float f);
|
||||
void RE_Scissor(int x, int y, int width, int height);
|
||||
void DrawLineLoop(const vec2_t* points, int count, int stipple_factor, int stipple_mask);
|
||||
void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty);
|
||||
void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty);
|
||||
|
||||
void RE_BeginFrame( stereoFrame_t stereoFrame );
|
||||
void RE_BeginRegistration( glconfig_t *glconfig );
|
||||
void RE_LoadWorldMap(const char* mapname);
|
||||
void RE_PrintBSPFileSizes(void);
|
||||
int RE_MapVersion(void);
|
||||
void RE_LoadWorldMap( const char *mapname );
|
||||
void RE_SetWorldVisData( const byte *vis );
|
||||
qhandle_t RE_RegisterModel( const char *name );
|
||||
qhandle_t RE_RegisterSkin( const char *name );
|
||||
|
@ -2408,8 +2090,7 @@ WORLD MAP
|
|||
============================================================
|
||||
*/
|
||||
|
||||
void R_AddBrushModelSurfaces(trRefEntity_t* e);
|
||||
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs);
|
||||
void R_AddBrushModelSurfaces( trRefEntity_t *e );
|
||||
void R_AddWorldSurfaces( void );
|
||||
qboolean R_inPVS( const vec3_t p1, const vec3_t p2 );
|
||||
|
||||
|
@ -2437,13 +2118,10 @@ LIGHTS
|
|||
*/
|
||||
|
||||
void R_DlightBmodel( bmodel_t *bmodel );
|
||||
void R_GetLightingForDecal(vec3_t vLight, vec3_t vFacing, vec3_t vOrigin);
|
||||
void R_GetLightingForSmoke(vec3_t vLight, vec3_t vOrigin);
|
||||
void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent );
|
||||
void R_TransformDlights( int count, dlight_t *dl, orientationr_t *or );
|
||||
int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir );
|
||||
int R_LightDirForPoint(vec3_t point, vec3_t lightDir, vec3_t normal, world_t* world);
|
||||
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights);
|
||||
int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *world );
|
||||
int R_CubemapForPoint( vec3_t point );
|
||||
|
||||
|
||||
|
@ -2499,9 +2177,6 @@ MARKERS, POLYGON PROJECTION ON WORLD POLYGONS
|
|||
int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projection,
|
||||
int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer );
|
||||
|
||||
void R_MarkFragmentsForInlineModel(clipHandle_t bmodel, const vec3_t angles, const vec3_t origin, int numPoints,
|
||||
const vec3_t* points, const vec3_t projection, int maxPoints, vec3_t pointBuffer,
|
||||
int maxFragments, markFragment_t* fragmentBuffer, float radiusSquared);
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
@ -2575,10 +2250,7 @@ SCENE GENERATION
|
|||
void R_InitNextFrame( void );
|
||||
|
||||
void RE_ClearScene( void );
|
||||
void RE_AddRefEntityToScene(const refEntity_t* ent);
|
||||
void RE_AddRefSpriteToScene(const refEntity_t* ent);
|
||||
void RE_AddTerrainMarkToScene(int iTerrainIndex, qhandle_t hShader, int numVerts, const polyVert_t* verts, int renderfx);
|
||||
refEntity_t* RE_GetRenderEntity(int entityNumber);
|
||||
void RE_AddRefEntityToScene( const refEntity_t *ent );
|
||||
void RE_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num );
|
||||
void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b );
|
||||
void RE_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b );
|
||||
|
@ -2613,76 +2285,15 @@ ANIMATED MODELS
|
|||
=============================================================
|
||||
*/
|
||||
|
||||
void R_MakeAnimModel(model_t* model);
|
||||
void R_AddAnimSurfaces(trRefEntity_t* ent);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SPRITE
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
sprite_t* SPR_RegisterSprite(const char* name);
|
||||
void RB_DrawSprite(const refSprite_t* spr);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
TIKI
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void RE_FreeModels(void);
|
||||
qhandle_t RE_SpawnEffectModel(const char* szModel, vec3_t vPos, vec3_t* axis);
|
||||
qhandle_t RE_RegisterServerModel(const char* name);
|
||||
void RE_UnregisterServerModel(qhandle_t hModel);
|
||||
orientation_t RE_TIKI_Orientation(refEntity_t* model, int tagnum);
|
||||
qboolean RE_TIKI_IsOnGround(refEntity_t* model, int tagnum, float threshold);
|
||||
float R_ModelRadius(qhandle_t handle);
|
||||
void R_ModelBounds(qhandle_t handle, vec3_t mins, vec3_t maxs);
|
||||
dtiki_t* R_Model_GetHandle(qhandle_t handle);
|
||||
|
||||
float R_GetRadius(refEntity_t* model);
|
||||
void R_GetFrame(refEntity_t* model, struct skelAnimFrame_s* newFrame);
|
||||
void RE_ForceUpdatePose(refEntity_t* model);
|
||||
void RE_SetFrameNumber(int frameNumber);
|
||||
void R_UpdatePoseInternal(refEntity_t* model);
|
||||
void RB_SkelMesh(skelSurfaceGame_t* sf);
|
||||
void RB_StaticMesh(staticSurface_t* staticSurf);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
FONT
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
fontheader_t* R_LoadFont(const char* name);
|
||||
void R_DrawString(const fontheader_t* font, const char* text, float x, float y, int maxlen, qboolean bVirtualScreen);
|
||||
float R_GetFontHeight(const fontheader_t* font);
|
||||
float R_GetFontStringWidth(const fontheader_t* font, const char* s);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SWIPE
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void RB_DrawSwipeSurface(surfaceType_t* pswipe);
|
||||
void RE_SwipeBegin(float thistime, float life, qhandle_t shader);
|
||||
void RE_SwipeEnd();
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
UTIL
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
int RE_GetShaderHeight(qhandle_t hShader);
|
||||
int RE_GetShaderWidth(qhandle_t hShader);
|
||||
void R_MDRAddAnimSurfaces( trRefEntity_t *ent );
|
||||
void RB_MDRSurfaceAnim( mdrSurface_t *surface );
|
||||
qboolean R_LoadIQM (model_t *mod, void *buffer, int filesize, const char *name );
|
||||
void R_AddIQMSurfaces( trRefEntity_t *ent );
|
||||
void RB_IQMSurfaceAnim( surfaceType_t *surface );
|
||||
void RB_IQMSurfaceAnimVao( srfVaoIQModel_t *surface );
|
||||
int R_IQMLerpTag( orientation_t *tag, iqmData_t *data,
|
||||
int startFrame, int endFrame,
|
||||
float frac, const char *tagName );
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
@ -2717,10 +2328,6 @@ RENDERER BACK END FUNCTIONS
|
|||
|
||||
void RB_ExecuteRenderCommands( const void *data );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
|
@ -2857,10 +2464,7 @@ typedef struct {
|
|||
dlight_t dlights[MAX_DLIGHTS];
|
||||
trRefEntity_t entities[MAX_REFENTITIES];
|
||||
srfPoly_t *polys;//[MAX_POLYS];
|
||||
polyVert_t* polyVerts;//[MAX_POLYVERTS];
|
||||
refSprite_t sprites[2048];
|
||||
cStaticModelUnpacked_t* staticModels;
|
||||
byte* staticModelData;
|
||||
polyVert_t *polyVerts;//[MAX_POLYVERTS];
|
||||
pshadow_t pshadows[MAX_CALC_PSHADOWS];
|
||||
renderCommandList_t commands;
|
||||
} backEndData_t;
|
||||
|
@ -2872,8 +2476,7 @@ extern backEndData_t *backEndData; // the second one may not be allocated
|
|||
|
||||
|
||||
void *R_GetCommandBuffer( int bytes );
|
||||
void RB_ExecuteRenderCommands(const void* data);
|
||||
void R_SavePerformanceCounters(void);
|
||||
void RB_ExecuteRenderCommands( const void *data );
|
||||
|
||||
void R_IssuePendingRenderCommands( void );
|
||||
|
||||
|
@ -2884,6 +2487,7 @@ void R_AddPostProcessCmd (void);
|
|||
void RE_SetColor( const float *rgba );
|
||||
void RE_StretchPic ( float x, float y, float w, float h,
|
||||
float s1, float t1, float s2, float t2, qhandle_t hShader );
|
||||
void RE_BeginFrame( stereoFrame_t stereoFrame );
|
||||
void RE_EndFrame( int *frontEndMsec, int *backEndMsec );
|
||||
void RE_SaveJPG(char * filename, int quality, int image_width, int image_height,
|
||||
unsigned char *image_buffer, int padding);
|
||||
|
@ -2892,3 +2496,5 @@ size_t RE_SaveJPGToBuffer(byte *buffer, size_t bufSize, int quality,
|
|||
void RE_TakeVideoFrame( int width, int height,
|
||||
byte *captureBuffer, byte *encodeBuffer, qboolean motionJpeg );
|
||||
|
||||
|
||||
#endif //TR_LOCAL_H
|
||||
|
|
|
@ -1094,7 +1094,24 @@ qboolean R_GetPortalOrientations( drawSurf_t *drawSurf, int entityNum,
|
|||
VectorSubtract( vec3_origin, camera->axis[1], camera->axis[1] );
|
||||
|
||||
// optionally rotate
|
||||
if ( e->e.skinNum ) {
|
||||
if ( e->e.oldframe ) {
|
||||
// if a speed is specified
|
||||
if ( e->e.frame ) {
|
||||
// continuous rotate
|
||||
d = (tr.refdef.time/1000.0f) * e->e.frame;
|
||||
VectorCopy( camera->axis[1], transformed );
|
||||
RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
|
||||
CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
|
||||
} else {
|
||||
// bobbing rotate, with skinNum being the rotation offset
|
||||
d = sin( tr.refdef.time * 0.003f );
|
||||
d = e->e.skinNum + d * 4;
|
||||
VectorCopy( camera->axis[1], transformed );
|
||||
RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
|
||||
CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
|
||||
}
|
||||
}
|
||||
else if ( e->e.skinNum ) {
|
||||
d = e->e.skinNum;
|
||||
VectorCopy( camera->axis[1], transformed );
|
||||
RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
|
||||
|
@ -1353,6 +1370,10 @@ int R_SpriteFogNum( trRefEntity_t *ent ) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ( ent->e.renderfx & RF_CROSSHAIR ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
|
||||
fog = &tr.world->fogs[i];
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
|
@ -1556,6 +1577,9 @@ static void R_AddEntitySurface (int entityNum)
|
|||
break; // don't draw anything
|
||||
case RT_SPRITE:
|
||||
case RT_BEAM:
|
||||
case RT_LIGHTNING:
|
||||
case RT_RAIL_CORE:
|
||||
case RT_RAIL_RINGS:
|
||||
// self blood sprites, talk balloons, etc should not be drawn in the primary
|
||||
// view. We can't just do this check for all entities, because md3
|
||||
// entities may still want to cast shadows from them
|
||||
|
@ -1575,6 +1599,15 @@ static void R_AddEntitySurface (int entityNum)
|
|||
R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0, 0, 0 /*cubeMap*/ );
|
||||
} else {
|
||||
switch ( tr.currentModel->type ) {
|
||||
case MOD_MESH:
|
||||
R_AddMD3Surfaces( ent );
|
||||
break;
|
||||
case MOD_MDR:
|
||||
R_MDRAddAnimSurfaces( ent );
|
||||
break;
|
||||
case MOD_IQM:
|
||||
R_AddIQMSurfaces( ent );
|
||||
break;
|
||||
case MOD_BRUSH:
|
||||
R_AddBrushModelSurfaces( ent );
|
||||
break;
|
||||
|
@ -1834,7 +1867,7 @@ void R_RenderPshadowMaps(const refdef_t *fd)
|
|||
{
|
||||
trRefEntity_t *ent = &tr.refdef.entities[i];
|
||||
|
||||
if((ent->e.renderfx & (RF_FIRST_PERSON)))
|
||||
if((ent->e.renderfx & (RF_FIRST_PERSON | RF_NOSHADOW)))
|
||||
continue;
|
||||
|
||||
//if((ent->e.renderfx & RF_THIRD_PERSON))
|
||||
|
@ -1859,6 +1892,37 @@ void R_RenderPshadowMaps(const refdef_t *fd)
|
|||
|
||||
switch (model->type)
|
||||
{
|
||||
case MOD_MESH:
|
||||
{
|
||||
mdvFrame_t *frame = &model->mdv[0]->frames[ent->e.frame];
|
||||
|
||||
radius = frame->radius * scale;
|
||||
}
|
||||
break;
|
||||
|
||||
case MOD_MDR:
|
||||
{
|
||||
// FIXME: never actually tested this
|
||||
mdrHeader_t *header = model->modelData;
|
||||
int frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );
|
||||
mdrFrame_t *frame = ( mdrFrame_t * ) ( ( byte * ) header + header->ofsFrames + frameSize * ent->e.frame);
|
||||
|
||||
radius = frame->radius;
|
||||
}
|
||||
break;
|
||||
case MOD_IQM:
|
||||
{
|
||||
// FIXME: never actually tested this
|
||||
iqmData_t *data = model->modelData;
|
||||
vec3_t diag;
|
||||
float *framebounds;
|
||||
|
||||
framebounds = data->bounds + 6*ent->e.frame;
|
||||
VectorSubtract( framebounds+3, framebounds, diag );
|
||||
radius = 0.5f * VectorLength( diag );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
417
code/renderergl2/tr_mesh.c
Normal file
417
code/renderergl2/tr_mesh.c
Normal file
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_mesh.c: triangle model functions
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
static float ProjectRadius( float r, vec3_t location )
|
||||
{
|
||||
float pr;
|
||||
float dist;
|
||||
float c;
|
||||
vec3_t p;
|
||||
float projected[4];
|
||||
|
||||
c = DotProduct( tr.viewParms.or.axis[0], tr.viewParms.or.origin );
|
||||
dist = DotProduct( tr.viewParms.or.axis[0], location ) - c;
|
||||
|
||||
if ( dist <= 0 )
|
||||
return 0;
|
||||
|
||||
p[0] = 0;
|
||||
p[1] = fabs( r );
|
||||
p[2] = -dist;
|
||||
|
||||
projected[0] = p[0] * tr.viewParms.projectionMatrix[0] +
|
||||
p[1] * tr.viewParms.projectionMatrix[4] +
|
||||
p[2] * tr.viewParms.projectionMatrix[8] +
|
||||
tr.viewParms.projectionMatrix[12];
|
||||
|
||||
projected[1] = p[0] * tr.viewParms.projectionMatrix[1] +
|
||||
p[1] * tr.viewParms.projectionMatrix[5] +
|
||||
p[2] * tr.viewParms.projectionMatrix[9] +
|
||||
tr.viewParms.projectionMatrix[13];
|
||||
|
||||
projected[2] = p[0] * tr.viewParms.projectionMatrix[2] +
|
||||
p[1] * tr.viewParms.projectionMatrix[6] +
|
||||
p[2] * tr.viewParms.projectionMatrix[10] +
|
||||
tr.viewParms.projectionMatrix[14];
|
||||
|
||||
projected[3] = p[0] * tr.viewParms.projectionMatrix[3] +
|
||||
p[1] * tr.viewParms.projectionMatrix[7] +
|
||||
p[2] * tr.viewParms.projectionMatrix[11] +
|
||||
tr.viewParms.projectionMatrix[15];
|
||||
|
||||
|
||||
pr = projected[1] / projected[3];
|
||||
|
||||
if ( pr > 1.0f )
|
||||
pr = 1.0f;
|
||||
|
||||
return pr;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_CullModel
|
||||
=============
|
||||
*/
|
||||
static int R_CullModel( mdvModel_t *model, trRefEntity_t *ent ) {
|
||||
vec3_t bounds[2];
|
||||
mdvFrame_t *oldFrame, *newFrame;
|
||||
int i;
|
||||
|
||||
// compute frame pointers
|
||||
newFrame = model->frames + ent->e.frame;
|
||||
oldFrame = model->frames + ent->e.oldframe;
|
||||
|
||||
// cull bounding sphere ONLY if this is not an upscaled entity
|
||||
if ( !ent->e.nonNormalizedAxes )
|
||||
{
|
||||
if ( ent->e.frame == ent->e.oldframe )
|
||||
{
|
||||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
|
||||
case CULL_IN:
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sphereCull, sphereCullB;
|
||||
|
||||
sphereCull = R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius );
|
||||
if ( newFrame == oldFrame ) {
|
||||
sphereCullB = sphereCull;
|
||||
} else {
|
||||
sphereCullB = R_CullLocalPointAndRadius( oldFrame->localOrigin, oldFrame->radius );
|
||||
}
|
||||
|
||||
if ( sphereCull == sphereCullB )
|
||||
{
|
||||
if ( sphereCull == CULL_OUT )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
else if ( sphereCull == CULL_IN )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate a bounding box in the current coordinate system
|
||||
for (i = 0 ; i < 3 ; i++) {
|
||||
bounds[0][i] = oldFrame->bounds[0][i] < newFrame->bounds[0][i] ? oldFrame->bounds[0][i] : newFrame->bounds[0][i];
|
||||
bounds[1][i] = oldFrame->bounds[1][i] > newFrame->bounds[1][i] ? oldFrame->bounds[1][i] : newFrame->bounds[1][i];
|
||||
}
|
||||
|
||||
switch ( R_CullLocalBox( bounds ) )
|
||||
{
|
||||
case CULL_IN:
|
||||
tr.pc.c_box_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_box_cull_md3_clip++;
|
||||
return CULL_CLIP;
|
||||
case CULL_OUT:
|
||||
default:
|
||||
tr.pc.c_box_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_ComputeLOD
|
||||
|
||||
=================
|
||||
*/
|
||||
int R_ComputeLOD( trRefEntity_t *ent ) {
|
||||
float radius;
|
||||
float flod, lodscale;
|
||||
float projectedRadius;
|
||||
mdvFrame_t *frame;
|
||||
mdrHeader_t *mdr;
|
||||
mdrFrame_t *mdrframe;
|
||||
int lod;
|
||||
|
||||
if ( tr.currentModel->numLods < 2 )
|
||||
{
|
||||
// model has only 1 LOD level, skip computations and bias
|
||||
lod = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// multiple LODs exist, so compute projected bounding sphere
|
||||
// and use that as a criteria for selecting LOD
|
||||
|
||||
if(tr.currentModel->type == MOD_MDR)
|
||||
{
|
||||
int frameSize;
|
||||
mdr = (mdrHeader_t *) tr.currentModel->modelData;
|
||||
frameSize = (size_t) (&((mdrFrame_t *)0)->bones[mdr->numBones]);
|
||||
|
||||
mdrframe = (mdrFrame_t *) ((byte *) mdr + mdr->ofsFrames + frameSize * ent->e.frame);
|
||||
|
||||
radius = RadiusFromBounds(mdrframe->bounds[0], mdrframe->bounds[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//frame = ( md3Frame_t * ) ( ( ( unsigned char * ) tr.currentModel->md3[0] ) + tr.currentModel->md3[0]->ofsFrames );
|
||||
frame = tr.currentModel->mdv[0]->frames;
|
||||
|
||||
frame += ent->e.frame;
|
||||
|
||||
radius = RadiusFromBounds( frame->bounds[0], frame->bounds[1] );
|
||||
}
|
||||
|
||||
if ( ( projectedRadius = ProjectRadius( radius, ent->e.origin ) ) != 0 )
|
||||
{
|
||||
lodscale = r_lodscale->value;
|
||||
if (lodscale > 20) lodscale = 20;
|
||||
flod = 1.0f - projectedRadius * lodscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
// object intersects near view plane, e.g. view weapon
|
||||
flod = 0;
|
||||
}
|
||||
|
||||
flod *= tr.currentModel->numLods;
|
||||
lod = ri.ftol(flod);
|
||||
|
||||
if ( lod < 0 )
|
||||
{
|
||||
lod = 0;
|
||||
}
|
||||
else if ( lod >= tr.currentModel->numLods )
|
||||
{
|
||||
lod = tr.currentModel->numLods - 1;
|
||||
}
|
||||
}
|
||||
|
||||
lod += r_lodbias->integer;
|
||||
|
||||
if ( lod >= tr.currentModel->numLods )
|
||||
lod = tr.currentModel->numLods - 1;
|
||||
if ( lod < 0 )
|
||||
lod = 0;
|
||||
|
||||
return lod;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_ComputeFogNum
|
||||
|
||||
=================
|
||||
*/
|
||||
int R_ComputeFogNum( mdvModel_t *model, trRefEntity_t *ent ) {
|
||||
int i, j;
|
||||
fog_t *fog;
|
||||
mdvFrame_t *mdvFrame;
|
||||
vec3_t localOrigin;
|
||||
|
||||
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: non-normalized axis issues
|
||||
mdvFrame = model->frames + ent->e.frame;
|
||||
VectorAdd( ent->e.origin, mdvFrame->localOrigin, localOrigin );
|
||||
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
|
||||
fog = &tr.world->fogs[i];
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( localOrigin[j] - mdvFrame->radius >= fog->bounds[1][j] ) {
|
||||
break;
|
||||
}
|
||||
if ( localOrigin[j] + mdvFrame->radius <= fog->bounds[0][j] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == 3 ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_AddMD3Surfaces
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_AddMD3Surfaces( trRefEntity_t *ent ) {
|
||||
int i;
|
||||
mdvModel_t *model = NULL;
|
||||
mdvSurface_t *surface = NULL;
|
||||
shader_t *shader = NULL;
|
||||
int cull;
|
||||
int lod;
|
||||
int fogNum;
|
||||
int cubemapIndex;
|
||||
qboolean personalModel;
|
||||
|
||||
// don't add third_person objects if not in a portal
|
||||
personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !(tr.viewParms.isPortal
|
||||
|| (tr.viewParms.flags & (VPF_SHADOWMAP | VPF_DEPTHSHADOW)));
|
||||
|
||||
if ( ent->e.renderfx & RF_WRAP_FRAMES ) {
|
||||
ent->e.frame %= tr.currentModel->mdv[0]->numFrames;
|
||||
ent->e.oldframe %= tr.currentModel->mdv[0]->numFrames;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate the frames so there is no chance of a crash.
|
||||
// This will write directly into the entity structure, so
|
||||
// when the surfaces are rendered, they don't need to be
|
||||
// range checked again.
|
||||
//
|
||||
if ( (ent->e.frame >= tr.currentModel->mdv[0]->numFrames)
|
||||
|| (ent->e.frame < 0)
|
||||
|| (ent->e.oldframe >= tr.currentModel->mdv[0]->numFrames)
|
||||
|| (ent->e.oldframe < 0) ) {
|
||||
ri.Printf( PRINT_DEVELOPER, "R_AddMD3Surfaces: no such frame %d to %d for '%s'\n",
|
||||
ent->e.oldframe, ent->e.frame,
|
||||
tr.currentModel->name );
|
||||
ent->e.frame = 0;
|
||||
ent->e.oldframe = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// compute LOD
|
||||
//
|
||||
lod = R_ComputeLOD( ent );
|
||||
|
||||
model = tr.currentModel->mdv[lod];
|
||||
|
||||
//
|
||||
// cull the entire model if merged bounding box of both frames
|
||||
// is outside the view frustum.
|
||||
//
|
||||
cull = R_CullModel ( model, ent );
|
||||
if ( cull == CULL_OUT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// set up lighting now that we know we aren't culled
|
||||
//
|
||||
if ( !personalModel || r_shadows->integer > 1 ) {
|
||||
R_SetupEntityLighting( &tr.refdef, ent );
|
||||
}
|
||||
|
||||
//
|
||||
// see if we are in a fog volume
|
||||
//
|
||||
fogNum = R_ComputeFogNum( model, ent );
|
||||
|
||||
cubemapIndex = R_CubemapForPoint(ent->e.origin);
|
||||
|
||||
//
|
||||
// draw all surfaces
|
||||
//
|
||||
surface = model->surfaces;
|
||||
for ( i = 0 ; i < model->numSurfaces ; i++ ) {
|
||||
|
||||
if ( ent->e.customShader ) {
|
||||
shader = R_GetShaderByHandle( ent->e.customShader );
|
||||
} else if ( ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins ) {
|
||||
skin_t *skin;
|
||||
int j;
|
||||
|
||||
skin = R_GetSkinByHandle( ent->e.customSkin );
|
||||
|
||||
// match the surface name to something in the skin file
|
||||
shader = tr.defaultShader;
|
||||
for ( j = 0 ; j < skin->numSurfaces ; j++ ) {
|
||||
// the names have both been lowercased
|
||||
if ( !strcmp( skin->surfaces[j].name, surface->name ) ) {
|
||||
shader = skin->surfaces[j].shader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shader == tr.defaultShader) {
|
||||
ri.Printf( PRINT_DEVELOPER, "WARNING: no shader for surface %s in skin %s\n", surface->name, skin->name);
|
||||
}
|
||||
else if (shader->defaultShader) {
|
||||
ri.Printf( PRINT_DEVELOPER, "WARNING: shader %s in skin %s not found\n", shader->name, skin->name);
|
||||
}
|
||||
} else if ( surface->numShaderIndexes <= 0 ) {
|
||||
shader = tr.defaultShader;
|
||||
} else {
|
||||
shader = tr.shaders[ surface->shaderIndexes[ ent->e.skinNum % surface->numShaderIndexes ] ];
|
||||
}
|
||||
|
||||
// we will add shadows even if the main object isn't visible in the view
|
||||
|
||||
// stencil shadows can't do personal models unless I polyhedron clip
|
||||
if ( !personalModel
|
||||
&& r_shadows->integer == 2
|
||||
&& fogNum == 0
|
||||
&& !(ent->e.renderfx & ( RF_NOSHADOW | RF_DEPTHHACK ) )
|
||||
&& shader->sort == SS_OPAQUE ) {
|
||||
R_AddDrawSurf( (void *)&model->vaoSurfaces[i], tr.shadowShader, 0, qfalse, qfalse, 0 );
|
||||
}
|
||||
|
||||
// projection shadows work fine with personal models
|
||||
if ( r_shadows->integer == 3
|
||||
&& fogNum == 0
|
||||
&& (ent->e.renderfx & RF_SHADOW_PLANE )
|
||||
&& shader->sort == SS_OPAQUE ) {
|
||||
R_AddDrawSurf( (void *)&model->vaoSurfaces[i], tr.projectionShadowShader, 0, qfalse, qfalse, 0 );
|
||||
}
|
||||
|
||||
// don't add third_person objects if not viewing through a portal
|
||||
if ( !personalModel ) {
|
||||
R_AddDrawSurf((void *)&model->vaoSurfaces[i], shader, fogNum, qfalse, qfalse, cubemapIndex );
|
||||
}
|
||||
|
||||
surface++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
1418
code/renderergl2/tr_model.c
Normal file
1418
code/renderergl2/tr_model.c
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1758
code/renderergl2/tr_model_iqm.c
Normal file
1758
code/renderergl2/tr_model_iqm.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -286,6 +286,8 @@ void RE_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, flo
|
|||
|
||||
void RE_BeginScene(const refdef_t *fd)
|
||||
{
|
||||
Com_Memcpy( tr.refdef.text, fd->text, sizeof( tr.refdef.text ) );
|
||||
|
||||
tr.refdef.x = fd->x;
|
||||
tr.refdef.y = fd->y;
|
||||
tr.refdef.width = fd->width;
|
||||
|
|
|
@ -64,6 +64,13 @@ R_BindAnimatedImageToTMU
|
|||
static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
|
||||
int64_t index;
|
||||
|
||||
if ( bundle->isVideoMap ) {
|
||||
ri.CIN_RunCinematic(bundle->videoMapHandle);
|
||||
ri.CIN_UploadCinematic(bundle->videoMapHandle);
|
||||
GL_BindToTMU(tr.scratchImage[bundle->videoMapHandle], tmu);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( bundle->numImageAnimations <= 1 ) {
|
||||
GL_BindToTMU( bundle->image[0], tmu);
|
||||
return;
|
||||
|
|
|
@ -788,6 +788,22 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
|||
totalImages, MAX_IMAGE_ANIMATIONS, shader.name );
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( token, "videoMap" ) )
|
||||
{
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
if ( !token[0] )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: missing parameter for 'videoMap' keyword in shader '%s'\n", shader.name );
|
||||
return qfalse;
|
||||
}
|
||||
stage->bundle[0].videoMapHandle = ri.CIN_PlayCinematic( token, 0, 0, 256, 256, (CIN_loop | CIN_silent | CIN_shader));
|
||||
if (stage->bundle[0].videoMapHandle != -1) {
|
||||
stage->bundle[0].isVideoMap = qtrue;
|
||||
stage->bundle[0].image[0] = tr.scratchImage[stage->bundle[0].videoMapHandle];
|
||||
} else {
|
||||
ri.Printf( PRINT_WARNING, "WARNING: could not load '%s' for 'videoMap' keyword in shader '%s'\n", token, shader.name );
|
||||
}
|
||||
}
|
||||
//
|
||||
// alphafunc <func>
|
||||
//
|
||||
|
@ -2744,7 +2760,7 @@ static shader_t *GeneratePermanentShader( void ) {
|
|||
return tr.defaultShader;
|
||||
}
|
||||
|
||||
newShader = ri.Hunk_Alloc( sizeof( shader_t ) );
|
||||
newShader = ri.Hunk_Alloc( sizeof( shader_t ), h_low );
|
||||
|
||||
*newShader = shader;
|
||||
|
||||
|
@ -2766,12 +2782,12 @@ static shader_t *GeneratePermanentShader( void ) {
|
|||
if ( !stages[i].active ) {
|
||||
break;
|
||||
}
|
||||
newShader->stages[i] = ri.Hunk_Alloc( sizeof( stages[i] ) );
|
||||
newShader->stages[i] = ri.Hunk_Alloc( sizeof( stages[i] ), h_low );
|
||||
*newShader->stages[i] = stages[i];
|
||||
|
||||
for ( b = 0 ; b < NUM_TEXTURE_BUNDLES ; b++ ) {
|
||||
size = newShader->stages[i]->bundle[b].numTexMods * sizeof( texModInfo_t );
|
||||
newShader->stages[i]->bundle[b].texMods = ri.Hunk_Alloc( size );
|
||||
newShader->stages[i]->bundle[b].texMods = ri.Hunk_Alloc( size, h_low );
|
||||
Com_Memcpy( newShader->stages[i]->bundle[b].texMods, stages[i].bundle[b].texMods, size );
|
||||
}
|
||||
}
|
||||
|
@ -3654,7 +3670,7 @@ static void ScanAndLoadShaderFiles( void )
|
|||
|
||||
long sum = 0, summand;
|
||||
// scan for shader files
|
||||
shaderFiles = ri.FS_ListFiles( "scripts", ".shader", qfalse, &numShaderFiles );
|
||||
shaderFiles = ri.FS_ListFiles( "scripts", ".shader", &numShaderFiles );
|
||||
|
||||
if ( !shaderFiles || !numShaderFiles )
|
||||
{
|
||||
|
@ -3736,7 +3752,7 @@ static void ScanAndLoadShaderFiles( void )
|
|||
}
|
||||
|
||||
// build single large buffer
|
||||
s_shaderText = ri.Hunk_Alloc( sum + numShaderFiles*2 );
|
||||
s_shaderText = ri.Hunk_Alloc( sum + numShaderFiles*2, h_low );
|
||||
s_shaderText[ 0 ] = '\0';
|
||||
textEnd = s_shaderText;
|
||||
|
||||
|
@ -3776,7 +3792,7 @@ static void ScanAndLoadShaderFiles( void )
|
|||
|
||||
size += MAX_SHADERTEXT_HASH;
|
||||
|
||||
hashMem = ri.Hunk_Alloc( size * sizeof(char *) );
|
||||
hashMem = ri.Hunk_Alloc( size * sizeof(char *), h_low );
|
||||
|
||||
for (i = 0; i < MAX_SHADERTEXT_HASH; i++) {
|
||||
shaderTextHashTable[i] = (char **) hashMem;
|
||||
|
|
|
@ -284,3 +284,50 @@ void RB_ShadowFinish( void ) {
|
|||
qglDisable( GL_STENCIL_TEST );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
RB_ProjectionShadowDeform
|
||||
|
||||
=================
|
||||
*/
|
||||
void RB_ProjectionShadowDeform( void ) {
|
||||
float *xyz;
|
||||
int i;
|
||||
float h;
|
||||
vec3_t ground;
|
||||
vec3_t light;
|
||||
float groundDist;
|
||||
float d;
|
||||
vec3_t lightDir;
|
||||
|
||||
xyz = ( float * ) tess.xyz;
|
||||
|
||||
ground[0] = backEnd.or.axis[0][2];
|
||||
ground[1] = backEnd.or.axis[1][2];
|
||||
ground[2] = backEnd.or.axis[2][2];
|
||||
|
||||
groundDist = backEnd.or.origin[2] - backEnd.currentEntity->e.shadowPlane;
|
||||
|
||||
VectorCopy( backEnd.currentEntity->modelLightDir, lightDir );
|
||||
d = DotProduct( lightDir, ground );
|
||||
// don't let the shadows get too long or go negative
|
||||
if ( d < 0.5 ) {
|
||||
VectorMA( lightDir, (0.5 - d), ground, lightDir );
|
||||
d = DotProduct( lightDir, ground );
|
||||
}
|
||||
d = 1.0 / d;
|
||||
|
||||
light[0] = lightDir[0] * d;
|
||||
light[1] = lightDir[1] * d;
|
||||
light[2] = lightDir[2] * d;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4 ) {
|
||||
h = DotProduct( xyz, ground ) + groundDist;
|
||||
|
||||
xyz[0] -= light[0] * h;
|
||||
xyz[1] -= light[1] * h;
|
||||
xyz[2] -= light[2] * h;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -643,10 +643,10 @@ static void FillCloudBox( const shader_t *shader, int stage )
|
|||
continue;
|
||||
}
|
||||
|
||||
sky_mins_subd[0] = ftol(sky_mins[0][i] * HALF_SKY_SUBDIVISIONS);
|
||||
sky_mins_subd[1] = ftol(sky_mins[1][i] * HALF_SKY_SUBDIVISIONS);
|
||||
sky_maxs_subd[0] = ftol(sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS);
|
||||
sky_maxs_subd[1] = ftol(sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS);
|
||||
sky_mins_subd[0] = ri.ftol(sky_mins[0][i] * HALF_SKY_SUBDIVISIONS);
|
||||
sky_mins_subd[1] = ri.ftol(sky_mins[1][i] * HALF_SKY_SUBDIVISIONS);
|
||||
sky_maxs_subd[0] = ri.ftol(sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS);
|
||||
sky_maxs_subd[1] = ri.ftol(sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS);
|
||||
|
||||
if ( sky_mins_subd[0] < -HALF_SKY_SUBDIVISIONS )
|
||||
sky_mins_subd[0] = -HALF_SKY_SUBDIVISIONS;
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_sphere_shade.cpp -- sphere shade
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
|
@ -1,468 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_staticmodels.cpp -- static model rendering
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tiki.h"
|
||||
|
||||
#define MAX_STATIC_MODELS_SURFS 8192
|
||||
|
||||
int g_nStaticSurfaces;
|
||||
staticSurface_t g_staticSurfaces[ MAX_STATIC_MODELS_SURFS ];
|
||||
qboolean g_bInfostaticmodels;
|
||||
|
||||
/*
|
||||
==============
|
||||
R_InitStaticModels
|
||||
==============
|
||||
*/
|
||||
void R_InitStaticModels( void ) {
|
||||
cStaticModelUnpacked_t *pSM;
|
||||
char szTemp[ 1024 ];
|
||||
bool exists;
|
||||
skelBoneCache_t bones[ 128 ];
|
||||
float radius;
|
||||
int i, j, k, l;
|
||||
|
||||
g_bInfostaticmodels = qfalse;
|
||||
|
||||
if( tr.overbrightShift )
|
||||
{
|
||||
for( i = 0; i < tr.world->numStaticModelData; i++ )
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
r = ( int )( ( float )tr.world->staticModelData[ i * 4 ] * tr.overbrightMult );
|
||||
g = ( int )( ( float )tr.world->staticModelData[ i * 4 + 1 ] * tr.overbrightMult );
|
||||
b = ( int )( ( float )tr.world->staticModelData[ i * 4 + 2 ] * tr.overbrightMult );
|
||||
|
||||
if( ( r | g | b ) & 0xFFFFFF00 )
|
||||
{
|
||||
float t;
|
||||
unsigned long long rgb;
|
||||
|
||||
rgb = ( g + ( ~( ( unsigned long long )( r - g ) >> 32 ) & ( r - g ) ) - b );
|
||||
|
||||
t = 255.0 / ( float )( b + ( ~( rgb & 0x00000000FFFFFFFF ) & rgb ) );
|
||||
|
||||
r = ( int )( ( float )r * t );
|
||||
g = ( int )( ( float )g * t );
|
||||
b = ( int )( ( float )b * t );
|
||||
}
|
||||
|
||||
tr.world->staticModelData[ i * 4 ] = r;
|
||||
tr.world->staticModelData[ i * 4 + 1 ] = g;
|
||||
tr.world->staticModelData[ i * 4 + 2 ] = b;
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < tr.world->numStaticModels; i++ )
|
||||
{
|
||||
vec3_t mins, maxs;
|
||||
|
||||
pSM = &tr.world->staticModels[ i ];
|
||||
|
||||
pSM->bRendered = qfalse;
|
||||
AngleVectorsLeft( pSM->angles, pSM->axis[ 0 ], pSM->axis[ 1 ], pSM->axis[ 2 ] );
|
||||
|
||||
if( !strnicmp( pSM->model, "models", 6 ) ) {
|
||||
strcpy( szTemp, pSM->model );
|
||||
} else {
|
||||
sprintf( szTemp, "models/%s", pSM->model );
|
||||
}
|
||||
|
||||
FS_CanonicalFilename( szTemp );
|
||||
exists = TIKI_FindTiki( szTemp ) != NULL;
|
||||
pSM->tiki = TIKI_RegisterTiki( szTemp );
|
||||
|
||||
if( !pSM->tiki ) {
|
||||
ri.Printf( PRINT_WARNING, "^~^~^: Warning: Cannot Load Static Model %s\n", szTemp );
|
||||
continue;
|
||||
}
|
||||
|
||||
pSM->radius = TIKI_GlobalRadius( pSM->tiki );
|
||||
|
||||
//
|
||||
// register shaders
|
||||
//
|
||||
for( j = 0; j < pSM->tiki->num_surfaces; j++ )
|
||||
{
|
||||
dtikisurface_t *surf = &pSM->tiki->surfaces[ j ];
|
||||
|
||||
for( k = 0; k < surf->numskins; k++ )
|
||||
{
|
||||
if( surf->shader[ k ][ 0 ] ) {
|
||||
shader_t *sh = R_FindShader( surf->shader[ k ], -1, ( surf->flags & TIKI_SURF_SKIN1 ) );
|
||||
surf->hShader[ k ] = sh->index;
|
||||
} else {
|
||||
surf->hShader[ k ] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prepare the skeleton frame for the static model
|
||||
TIKI_GetSkelAnimFrame( pSM->tiki, bones, &radius, &mins, &maxs );
|
||||
pSM->cull_radius = radius * pSM->tiki->load_scale * pSM->scale;
|
||||
|
||||
// Suggestion:
|
||||
// It would be cool to have animated static model in the future
|
||||
|
||||
if( !exists )
|
||||
{
|
||||
for( j = 0; j < pSM->tiki->numMeshes; j++ )
|
||||
{
|
||||
skelHeaderGame_t *skelmodel = TIKI_GetSkel( pSM->tiki->mesh[ j ] );
|
||||
skelSurfaceGame_t *surf;
|
||||
|
||||
if( !skelmodel ) {
|
||||
ri.Printf( PRINT_WARNING, "^~^~^: Warning: Missing mesh in Static Model %s\n", skelmodel->name );
|
||||
continue;
|
||||
}
|
||||
|
||||
surf = skelmodel->pSurfaces;
|
||||
|
||||
for( k = 0; k < skelmodel->numSurfaces; k++, surf = surf->pNext )
|
||||
{
|
||||
byte *buf;
|
||||
byte *p;
|
||||
skelWeight_t *weight;
|
||||
skeletorVertex_t *vert;
|
||||
|
||||
if( surf->pStaticXyz ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// allocate static vectors
|
||||
p = buf = ( byte * )ri.TIKI_Alloc( ( sizeof( vec4_t ) + sizeof( vec4_t ) + sizeof( vec2_t ) * 2 ) * surf->numVerts );
|
||||
surf->pStaticXyz = ( vec4_t * )p;
|
||||
p += sizeof( vec4_t ) * surf->numVerts;
|
||||
surf->pStaticNormal = ( vec4_t * )p;
|
||||
p += sizeof( vec4_t ) * surf->numVerts;
|
||||
surf->pStaticTexCoords = ( vec2_t ( * )[ 2 ] )p;
|
||||
|
||||
vert = surf->pVerts;
|
||||
|
||||
for( l = 0; l < surf->numVerts; l++ )
|
||||
{
|
||||
int channel;
|
||||
skelBoneCache_t *bone;
|
||||
|
||||
weight = ( skelWeight_t * )( ( byte * )vert + sizeof( skeletorVertex_t ) );
|
||||
|
||||
if( j > 0 ) {
|
||||
channel = pSM->tiki->m_boneList.GetLocalFromGlobal( skelmodel->pBones[ weight->boneIndex ].channel );
|
||||
} else {
|
||||
channel = weight->boneIndex;
|
||||
}
|
||||
|
||||
bone = &bones[ channel ];
|
||||
|
||||
surf->pStaticXyz[ l ][ 0 ] = ( ( weight->offset[ 0 ] * bone->matrix[ 0 ][ 0 ]
|
||||
+ weight->offset[ 1 ] * bone->matrix[ 1 ][ 0 ]
|
||||
+ weight->offset[ 2 ] * bone->matrix[ 2 ][ 0 ] )
|
||||
+ bone->offset[ 0 ] ) * weight->boneWeight;
|
||||
surf->pStaticXyz[ l ][ 1 ] = ( ( weight->offset[ 0 ] * bone->matrix[ 0 ][ 1 ]
|
||||
+ weight->offset[ 1 ] * bone->matrix[ 1 ][ 1 ]
|
||||
+ weight->offset[ 2 ] * bone->matrix[ 2 ][ 1 ] )
|
||||
+ bone->offset[ 1 ] ) * weight->boneWeight;
|
||||
surf->pStaticXyz[ l ][ 2 ] = ( ( weight->offset[ 0 ] * bone->matrix[ 0 ][ 2 ]
|
||||
+ weight->offset[ 1 ] * bone->matrix[ 1 ][ 2 ]
|
||||
+ weight->offset[ 2 ] * bone->matrix[ 2 ][ 2 ] )
|
||||
+ bone->offset[ 2 ] ) * weight->boneWeight;
|
||||
|
||||
surf->pStaticNormal[ l ][ 0 ] = vert->normal[ 0 ] * bone->matrix[ 0 ][ 0 ]
|
||||
+ vert->normal[ 1 ] * bone->matrix[ 1 ][ 0 ]
|
||||
+ vert->normal[ 2 ] * bone->matrix[ 2 ][ 0 ];
|
||||
surf->pStaticNormal[ l ][ 1 ] = vert->normal[ 0 ] * bone->matrix[ 0 ][ 1 ]
|
||||
+ vert->normal[ 1 ] * bone->matrix[ 1 ][ 1 ]
|
||||
+ vert->normal[ 2 ] * bone->matrix[ 2 ][ 1 ];
|
||||
surf->pStaticNormal[ l ][ 2 ] = vert->normal[ 0 ] * bone->matrix[ 0 ][ 2 ]
|
||||
+ vert->normal[ 1 ] * bone->matrix[ 1 ][ 2 ]
|
||||
+ vert->normal[ 2 ] * bone->matrix[ 2 ][ 2 ];
|
||||
|
||||
surf->pStaticTexCoords[ l ][ 0 ][ 0 ] = vert->texCoords[ 0 ];
|
||||
surf->pStaticTexCoords[ l ][ 0 ][ 1 ] = vert->texCoords[ 1 ];
|
||||
surf->pStaticTexCoords[ l ][ 1 ][ 0 ] = vert->texCoords[ 0 ];
|
||||
surf->pStaticTexCoords[ l ][ 1 ][ 1 ] = vert->texCoords[ 1 ];
|
||||
|
||||
vert = ( skeletorVertex_t * )( ( byte * )vert + sizeof( skeletorVertex_t ) + sizeof( skeletorMorph_t ) * vert->numMorphs + sizeof( skelWeight_t ) * vert->numWeights );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr.refdef.numStaticModels = tr.world->numStaticModels;
|
||||
tr.refdef.staticModels = tr.world->staticModels;
|
||||
tr.refdef.numStaticModelData = tr.world->numStaticModelData;
|
||||
tr.refdef.staticModelData = tr.world->staticModelData;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_CullStaticModel
|
||||
==============
|
||||
*/
|
||||
static int R_CullStaticModel( dtiki_t *tiki, float fScale, const vec3_t vLocalOrg ) {
|
||||
vec3_t bounds[ 2 ];
|
||||
int i;
|
||||
int cull;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
bounds[ 0 ][ i ] = vLocalOrg[ i ] + tiki->a->mins[ i ] * fScale;
|
||||
bounds[ 1 ][ i ] = vLocalOrg[ i ] + tiki->a->maxs[ i ] * fScale;
|
||||
}
|
||||
|
||||
cull = R_CullLocalBox( bounds );
|
||||
|
||||
// FIXME: r_showcull
|
||||
|
||||
switch( cull )
|
||||
{
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_box_cull_md3_clip++;
|
||||
break;
|
||||
case CULL_IN:
|
||||
tr.pc.c_box_cull_md3_in++;
|
||||
break;
|
||||
case CULL_OUT:
|
||||
tr.pc.c_box_cull_md3_out++;
|
||||
break;
|
||||
}
|
||||
|
||||
return cull;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_AddStaticModelSurfaces
|
||||
==============
|
||||
*/
|
||||
void R_AddStaticModelSurfaces( void ) {
|
||||
cStaticModelUnpacked_t *SM;
|
||||
int i, j;
|
||||
int ofsStaticData;
|
||||
int iRadiusCull;
|
||||
dtiki_t *tiki;
|
||||
float tiki_scale;
|
||||
vec3_t tiki_localorigin;
|
||||
vec3_t tiki_worldorigin;
|
||||
|
||||
if( !tr.world->numStaticModels ) {
|
||||
return;
|
||||
}
|
||||
|
||||
tr.shiftedIsStatic = 1;
|
||||
|
||||
for( i = 0; i < tr.world->numStaticModels; i++ )
|
||||
{
|
||||
SM = &tr.world->staticModels[ i ];
|
||||
|
||||
//if( SM->visCount != tr.visCounts[ tr.visIndex ] ) {
|
||||
// continue;
|
||||
//}
|
||||
|
||||
tiki = SM->tiki;
|
||||
|
||||
if( !tiki ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tr.currentEntityNum = i;
|
||||
tr.shiftedEntityNum = i << QSORT_REFENTITYNUM_SHIFT;
|
||||
|
||||
R_RotateForStaticModel( SM, &tr.viewParms, &tr.or );
|
||||
|
||||
ofsStaticData = 0;
|
||||
|
||||
// get the world position
|
||||
tiki_scale = tiki->load_scale * SM->scale;
|
||||
VectorScale( tiki->load_origin, tiki_scale, tiki_localorigin );
|
||||
R_LocalPointToWorld( tiki_localorigin, tiki_worldorigin );
|
||||
|
||||
iRadiusCull = R_CullPointAndRadius( tiki_worldorigin, SM->cull_radius );
|
||||
|
||||
// FIXME: r_showcull
|
||||
|
||||
if( iRadiusCull != 2 && ( iRadiusCull != 1 || R_CullStaticModel( SM->tiki, tiki_scale, tiki_localorigin ) ) )
|
||||
{
|
||||
dtikisurface_t *dsurf;
|
||||
|
||||
// FIXME: Calc LOD
|
||||
if( tr.viewParms.isPortal )
|
||||
{
|
||||
//R_CalcLod( tiki_worldorigin, SM->cull_radius / SM->scale );
|
||||
SM->lodpercentage[ 1 ] = SM->cull_radius / SM->scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
//R_CalcLod( tiki_worldorigin, SM->cull_radius / SM->scale );
|
||||
SM->lodpercentage[ 0 ] = SM->cull_radius / SM->scale;
|
||||
}
|
||||
|
||||
//
|
||||
// draw all meshes
|
||||
//
|
||||
dsurf = tiki->surfaces;
|
||||
for( int mesh = 0; mesh < tiki->numMeshes; mesh++ )
|
||||
{
|
||||
skelHeaderGame_t *skelmodel = TIKI_GetSkel( tiki->mesh[ mesh ] );
|
||||
skelSurfaceGame_t *surface;
|
||||
shader_t *shader;
|
||||
|
||||
if( !skelmodel ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// draw all surfaces
|
||||
//
|
||||
surface = skelmodel->pSurfaces;
|
||||
for( j = 0; j < skelmodel->numSurfaces; j++, surface = surface->pNext, dsurf++ )
|
||||
{
|
||||
if( g_nStaticSurfaces >= MAX_STATIC_MODELS_SURFS )
|
||||
{
|
||||
ri.Printf( PRINT_DEVELOPER, "^~^~^ ERROR: MAX_STATIC_MODELS_SURFS exceeded - surface of '%s' skipped\n", tiki->a->name );
|
||||
continue;
|
||||
}
|
||||
|
||||
g_staticSurfaces[ g_nStaticSurfaces ].ident = SF_TIKI_STATIC;
|
||||
g_staticSurfaces[ g_nStaticSurfaces ].ofsStaticData = ofsStaticData;
|
||||
g_staticSurfaces[ g_nStaticSurfaces ].surface = surface;
|
||||
g_staticSurfaces[ g_nStaticSurfaces ].meshNum = mesh;
|
||||
|
||||
shader = tr.shaders[ dsurf->hShader[ 0 ] ];
|
||||
|
||||
SM->bRendered = qtrue;
|
||||
R_AddDrawSurf( ( surfaceType_t * )&g_staticSurfaces[ g_nStaticSurfaces ], shader, 0, 0, 0, 0 );
|
||||
|
||||
g_nStaticSurfaces++;
|
||||
ofsStaticData += surface->numVerts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr.shiftedIsStatic = 0;
|
||||
}
|
||||
/*
|
||||
=============
|
||||
RB_StaticMesh
|
||||
=============
|
||||
*/
|
||||
void RB_StaticMesh( staticSurface_t *staticSurf ) {
|
||||
int i, j;
|
||||
dtiki_t *tiki;
|
||||
skelSurfaceGame_t *surf;
|
||||
int meshNum;
|
||||
skelHeaderGame_t *skelmodel;
|
||||
int render_count;
|
||||
skelIndex_t *collapse_map;
|
||||
skelIndex_t *triangles;
|
||||
int indexes;
|
||||
int baseIndex, baseVertex;
|
||||
short collapse[ 1000 ];
|
||||
|
||||
tiki = backEnd.currentStaticModel->tiki;
|
||||
surf = staticSurf->surface;
|
||||
|
||||
assert(surf->pStaticXyz);
|
||||
|
||||
meshNum = staticSurf->meshNum;
|
||||
skelmodel = TIKI_GetSkel(tiki->mesh[meshNum]);
|
||||
|
||||
// FIXME: LOD
|
||||
render_count = surf->numVerts;
|
||||
|
||||
if (tess.numVertexes + render_count >= TIKI_MAX_VERTEXES ||
|
||||
tess.numIndexes + surf->numTriangles >= TIKI_MAX_TRIANGLES * 3) {
|
||||
RB_CHECKOVERFLOW(render_count, surf->numTriangles);
|
||||
}
|
||||
|
||||
collapse_map = surf->pCollapse;
|
||||
triangles = surf->pTriangles;
|
||||
indexes = surf->numTriangles * 3;
|
||||
baseIndex = tess.numIndexes;
|
||||
baseVertex = tess.numVertexes;
|
||||
tess.numVertexes += render_count;
|
||||
|
||||
if (render_count == surf->numVerts)
|
||||
{
|
||||
for (j = 0; j < indexes; j++) {
|
||||
tess.indexes[baseIndex + j] = baseVertex + triangles[j];
|
||||
}
|
||||
tess.numIndexes += indexes;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < render_count; i++) {
|
||||
collapse[i] = i;
|
||||
}
|
||||
for (i = 0; i < surf->numVerts; i++) {
|
||||
collapse[i] = collapse[collapse_map[i]];
|
||||
}
|
||||
|
||||
for (j = 0; j < indexes; j += 3)
|
||||
{
|
||||
if (collapse[triangles[j]] == collapse[triangles[j + 1]] ||
|
||||
collapse[triangles[j + 1]] == collapse[triangles[j + 2]] ||
|
||||
collapse[triangles[j + 2]] == collapse[triangles[j]])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
tess.indexes[baseIndex + j] = baseVertex + collapse[triangles[j]];
|
||||
tess.indexes[baseIndex + j + 1] = baseVertex + collapse[triangles[j + 1]];
|
||||
tess.indexes[baseIndex + j + 2] = baseVertex + collapse[triangles[j + 2]];
|
||||
}
|
||||
tess.numIndexes += j;
|
||||
}
|
||||
|
||||
for (j = 0; j < render_count; j++) {
|
||||
Vector4Copy(surf->pStaticXyz[j], tess.xyz[baseVertex + j]);
|
||||
Vector4Copy(surf->pStaticNormal[j], tess.normal[baseVertex + j]);
|
||||
tess.texCoords[baseVertex + j][0] = surf->pStaticTexCoords[j][0][0];
|
||||
tess.texCoords[baseVertex + j][1] = surf->pStaticTexCoords[j][0][1];
|
||||
}
|
||||
|
||||
if (backEndData->staticModels) {
|
||||
color4ub_t* in = (color4ub_t*)&backEndData->staticModelData[backEnd.currentStaticModel->firstVertexData + staticSurf->ofsStaticData];
|
||||
|
||||
for (i = 0; i < render_count; i++, in++)
|
||||
{
|
||||
tess.color[baseVertex + i][0] = (*in)[0] * 257;
|
||||
tess.color[baseVertex + i][0] = (*in)[1] * 257;
|
||||
tess.color[baseVertex + i][0] = (*in)[2] * 257;
|
||||
tess.color[baseVertex + i][0] = 65535;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < render_count; i++) {
|
||||
tess.color[baseVertex + i][0] = 65535;
|
||||
tess.color[baseVertex + i][1] = 65535;
|
||||
tess.color[baseVertex + i][2] = 65535;
|
||||
tess.color[baseVertex + i][3] = 65535;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -447,9 +447,6 @@ static qboolean RB_SurfaceVaoCached(int numVerts, srfVert_t *verts, int numIndex
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
void RB_SurfaceMarkFragment(srfMarkFragment_t* p) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
|
@ -555,6 +552,337 @@ static void RB_SurfaceBeam( void )
|
|||
tess.firstIndex = 0;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
|
||||
static void DoRailCore( const vec3_t start, const vec3_t end, const vec3_t up, float len, float spanWidth )
|
||||
{
|
||||
float spanWidth2;
|
||||
int vbase;
|
||||
float t = len / 256.0f;
|
||||
|
||||
RB_CheckVao(tess.vao);
|
||||
|
||||
RB_CHECKOVERFLOW( 4, 6 );
|
||||
|
||||
vbase = tess.numVertexes;
|
||||
|
||||
spanWidth2 = -spanWidth;
|
||||
|
||||
// FIXME: use quad stamp?
|
||||
VectorMA( start, spanWidth, up, tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0] = 0;
|
||||
tess.texCoords[tess.numVertexes][1] = 0;
|
||||
tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25f * 257.0f;
|
||||
tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25f * 257.0f;
|
||||
tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25f * 257.0f;
|
||||
tess.numVertexes++;
|
||||
|
||||
VectorMA( start, spanWidth2, up, tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0] = 0;
|
||||
tess.texCoords[tess.numVertexes][1] = 1;
|
||||
tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
|
||||
tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
|
||||
tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
|
||||
tess.numVertexes++;
|
||||
|
||||
VectorMA( end, spanWidth, up, tess.xyz[tess.numVertexes] );
|
||||
|
||||
tess.texCoords[tess.numVertexes][0] = t;
|
||||
tess.texCoords[tess.numVertexes][1] = 0;
|
||||
tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
|
||||
tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
|
||||
tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
|
||||
tess.numVertexes++;
|
||||
|
||||
VectorMA( end, spanWidth2, up, tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0] = t;
|
||||
tess.texCoords[tess.numVertexes][1] = 1;
|
||||
tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
|
||||
tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
|
||||
tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
|
||||
tess.numVertexes++;
|
||||
|
||||
tess.indexes[tess.numIndexes++] = vbase;
|
||||
tess.indexes[tess.numIndexes++] = vbase + 1;
|
||||
tess.indexes[tess.numIndexes++] = vbase + 2;
|
||||
|
||||
tess.indexes[tess.numIndexes++] = vbase + 2;
|
||||
tess.indexes[tess.numIndexes++] = vbase + 1;
|
||||
tess.indexes[tess.numIndexes++] = vbase + 3;
|
||||
}
|
||||
|
||||
static void DoRailDiscs( int numSegs, const vec3_t start, const vec3_t dir, const vec3_t right, const vec3_t up )
|
||||
{
|
||||
int i;
|
||||
vec3_t pos[4];
|
||||
vec3_t v;
|
||||
int spanWidth = r_railWidth->integer;
|
||||
float c, s;
|
||||
float scale;
|
||||
|
||||
if ( numSegs > 1 )
|
||||
numSegs--;
|
||||
if ( !numSegs )
|
||||
return;
|
||||
|
||||
scale = 0.25;
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
c = cos( DEG2RAD( 45 + i * 90 ) );
|
||||
s = sin( DEG2RAD( 45 + i * 90 ) );
|
||||
v[0] = ( right[0] * c + up[0] * s ) * scale * spanWidth;
|
||||
v[1] = ( right[1] * c + up[1] * s ) * scale * spanWidth;
|
||||
v[2] = ( right[2] * c + up[2] * s ) * scale * spanWidth;
|
||||
VectorAdd( start, v, pos[i] );
|
||||
|
||||
if ( numSegs > 1 )
|
||||
{
|
||||
// offset by 1 segment if we're doing a long distance shot
|
||||
VectorAdd( pos[i], dir, pos[i] );
|
||||
}
|
||||
}
|
||||
|
||||
RB_CheckVao(tess.vao);
|
||||
|
||||
for ( i = 0; i < numSegs; i++ )
|
||||
{
|
||||
int j;
|
||||
|
||||
RB_CHECKOVERFLOW( 4, 6 );
|
||||
|
||||
for ( j = 0; j < 4; j++ )
|
||||
{
|
||||
VectorCopy( pos[j], tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0] = (j < 2);
|
||||
tess.texCoords[tess.numVertexes][1] = (j && j != 3);
|
||||
tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
|
||||
tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
|
||||
tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
|
||||
tess.numVertexes++;
|
||||
|
||||
VectorAdd( pos[j], dir, pos[j] );
|
||||
}
|
||||
|
||||
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 0;
|
||||
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 1;
|
||||
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 3;
|
||||
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 3;
|
||||
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 1;
|
||||
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_SurfaceRailRinges
|
||||
*/
|
||||
static void RB_SurfaceRailRings( void ) {
|
||||
refEntity_t *e;
|
||||
int numSegs;
|
||||
int len;
|
||||
vec3_t vec;
|
||||
vec3_t right, up;
|
||||
vec3_t start, end;
|
||||
|
||||
e = &backEnd.currentEntity->e;
|
||||
|
||||
VectorCopy( e->oldorigin, start );
|
||||
VectorCopy( e->origin, end );
|
||||
|
||||
// compute variables
|
||||
VectorSubtract( end, start, vec );
|
||||
len = VectorNormalize( vec );
|
||||
MakeNormalVectors( vec, right, up );
|
||||
numSegs = ( len ) / r_railSegmentLength->value;
|
||||
if ( numSegs <= 0 ) {
|
||||
numSegs = 1;
|
||||
}
|
||||
|
||||
VectorScale( vec, r_railSegmentLength->value, vec );
|
||||
|
||||
DoRailDiscs( numSegs, start, vec, right, up );
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_SurfaceRailCore
|
||||
*/
|
||||
static void RB_SurfaceRailCore( void ) {
|
||||
refEntity_t *e;
|
||||
int len;
|
||||
vec3_t right;
|
||||
vec3_t vec;
|
||||
vec3_t start, end;
|
||||
vec3_t v1, v2;
|
||||
|
||||
e = &backEnd.currentEntity->e;
|
||||
|
||||
VectorCopy( e->oldorigin, start );
|
||||
VectorCopy( e->origin, end );
|
||||
|
||||
VectorSubtract( end, start, vec );
|
||||
len = VectorNormalize( vec );
|
||||
|
||||
// compute side vector
|
||||
VectorSubtract( start, backEnd.viewParms.or.origin, v1 );
|
||||
VectorNormalize( v1 );
|
||||
VectorSubtract( end, backEnd.viewParms.or.origin, v2 );
|
||||
VectorNormalize( v2 );
|
||||
CrossProduct( v1, v2, right );
|
||||
VectorNormalize( right );
|
||||
|
||||
DoRailCore( start, end, right, len, r_railCoreWidth->integer );
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_SurfaceLightningBolt
|
||||
*/
|
||||
static void RB_SurfaceLightningBolt( void ) {
|
||||
refEntity_t *e;
|
||||
int len;
|
||||
vec3_t right;
|
||||
vec3_t vec;
|
||||
vec3_t start, end;
|
||||
vec3_t v1, v2;
|
||||
int i;
|
||||
|
||||
e = &backEnd.currentEntity->e;
|
||||
|
||||
VectorCopy( e->oldorigin, end );
|
||||
VectorCopy( e->origin, start );
|
||||
|
||||
// compute variables
|
||||
VectorSubtract( end, start, vec );
|
||||
len = VectorNormalize( vec );
|
||||
|
||||
// compute side vector
|
||||
VectorSubtract( start, backEnd.viewParms.or.origin, v1 );
|
||||
VectorNormalize( v1 );
|
||||
VectorSubtract( end, backEnd.viewParms.or.origin, v2 );
|
||||
VectorNormalize( v2 );
|
||||
CrossProduct( v1, v2, right );
|
||||
VectorNormalize( right );
|
||||
|
||||
for ( i = 0 ; i < 4 ; i++ ) {
|
||||
vec3_t temp;
|
||||
|
||||
DoRailCore( start, end, right, len, 8 );
|
||||
RotatePointAroundVector( temp, vec, right, 45 );
|
||||
VectorCopy( temp, right );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void LerpMeshVertexes(mdvSurface_t *surf, float backlerp)
|
||||
{
|
||||
float *outXyz;
|
||||
int16_t *outNormal, *outTangent;
|
||||
mdvVertex_t *newVerts;
|
||||
int vertNum;
|
||||
|
||||
newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts;
|
||||
|
||||
outXyz = tess.xyz[tess.numVertexes];
|
||||
outNormal = tess.normal[tess.numVertexes];
|
||||
outTangent = tess.tangent[tess.numVertexes];
|
||||
|
||||
if (backlerp == 0)
|
||||
{
|
||||
//
|
||||
// just copy the vertexes
|
||||
//
|
||||
|
||||
for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
|
||||
{
|
||||
VectorCopy(newVerts->xyz, outXyz);
|
||||
VectorCopy4(newVerts->normal, outNormal);
|
||||
VectorCopy4(newVerts->tangent, outTangent);
|
||||
|
||||
newVerts++;
|
||||
outXyz += 4;
|
||||
outNormal += 4;
|
||||
outTangent += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// interpolate and copy the vertex and normal
|
||||
//
|
||||
|
||||
mdvVertex_t *oldVerts;
|
||||
|
||||
oldVerts = surf->verts + backEnd.currentEntity->e.oldframe * surf->numVerts;
|
||||
|
||||
for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++)
|
||||
{
|
||||
VectorLerp(newVerts->xyz, oldVerts->xyz, backlerp, outXyz);
|
||||
|
||||
outNormal[0] = (int16_t)(newVerts->normal[0] * (1.0f - backlerp) + oldVerts->normal[0] * backlerp);
|
||||
outNormal[1] = (int16_t)(newVerts->normal[1] * (1.0f - backlerp) + oldVerts->normal[1] * backlerp);
|
||||
outNormal[2] = (int16_t)(newVerts->normal[2] * (1.0f - backlerp) + oldVerts->normal[2] * backlerp);
|
||||
outNormal[3] = 0;
|
||||
|
||||
outTangent[0] = (int16_t)(newVerts->tangent[0] * (1.0f - backlerp) + oldVerts->tangent[0] * backlerp);
|
||||
outTangent[1] = (int16_t)(newVerts->tangent[1] * (1.0f - backlerp) + oldVerts->tangent[1] * backlerp);
|
||||
outTangent[2] = (int16_t)(newVerts->tangent[2] * (1.0f - backlerp) + oldVerts->tangent[2] * backlerp);
|
||||
outTangent[3] = newVerts->tangent[3];
|
||||
|
||||
newVerts++;
|
||||
oldVerts++;
|
||||
outXyz += 4;
|
||||
outNormal += 4;
|
||||
outTangent += 4;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RB_SurfaceMesh
|
||||
=============
|
||||
*/
|
||||
static void RB_SurfaceMesh(mdvSurface_t *surface) {
|
||||
int j;
|
||||
float backlerp;
|
||||
mdvSt_t *texCoords;
|
||||
int Bob, Doug;
|
||||
int numVerts;
|
||||
|
||||
if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
|
||||
backlerp = 0;
|
||||
} else {
|
||||
backlerp = backEnd.currentEntity->e.backlerp;
|
||||
}
|
||||
|
||||
RB_CheckVao(tess.vao);
|
||||
|
||||
RB_CHECKOVERFLOW( surface->numVerts, surface->numIndexes );
|
||||
|
||||
LerpMeshVertexes (surface, backlerp);
|
||||
|
||||
Bob = tess.numIndexes;
|
||||
Doug = tess.numVertexes;
|
||||
for (j = 0 ; j < surface->numIndexes ; j++) {
|
||||
tess.indexes[Bob + j] = Doug + surface->indexes[j];
|
||||
}
|
||||
tess.numIndexes += surface->numIndexes;
|
||||
|
||||
texCoords = surface->st;
|
||||
|
||||
numVerts = surface->numVerts;
|
||||
for ( j = 0; j < numVerts; j++ ) {
|
||||
tess.texCoords[Doug + j][0] = texCoords[j].st[0];
|
||||
tess.texCoords[Doug + j][1] = texCoords[j].st[1];
|
||||
// FIXME: fill in lightmapST for completeness?
|
||||
}
|
||||
|
||||
tess.numVertexes += surface->numVerts;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
RB_SurfaceFace
|
||||
|
@ -853,6 +1181,15 @@ static void RB_SurfaceEntity( surfaceType_t *surfType ) {
|
|||
case RT_BEAM:
|
||||
RB_SurfaceBeam();
|
||||
break;
|
||||
case RT_RAIL_CORE:
|
||||
RB_SurfaceRailCore();
|
||||
break;
|
||||
case RT_RAIL_RINGS:
|
||||
RB_SurfaceRailRings();
|
||||
break;
|
||||
case RT_LIGHTNING:
|
||||
RB_SurfaceLightningBolt();
|
||||
break;
|
||||
default:
|
||||
RB_SurfaceAxis();
|
||||
break;
|
||||
|
@ -902,7 +1239,7 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
|
|||
|
||||
refEnt = &backEnd.currentEntity->e;
|
||||
|
||||
glState.vertexAttribsInterpolation = (refEnt->wasframe == refEnt->frameInfo[0].index) ? 0.0f : refEnt->actionWeight;
|
||||
glState.vertexAttribsInterpolation = (refEnt->oldframe == refEnt->frame) ? 0.0f : refEnt->backlerp;
|
||||
|
||||
if (surface->mdvModel->numFrames > 1)
|
||||
{
|
||||
|
@ -916,7 +1253,7 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
|
|||
qglBindBuffer(GL_ARRAY_BUFFER, surface->vao->vertexesVBO);
|
||||
}
|
||||
|
||||
frameOffset = refEnt->wasframe * surface->vao->frameSize;
|
||||
frameOffset = refEnt->frame * surface->vao->frameSize;
|
||||
|
||||
attribIndex = ATTR_INDEX_POSITION;
|
||||
vAtb = &surface->vao->attribs[attribIndex];
|
||||
|
@ -930,7 +1267,7 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
|
|||
vAtb = &surface->vao->attribs[attribIndex];
|
||||
qglVertexAttribPointer(attribIndex, vAtb->count, vAtb->type, vAtb->normalized, vAtb->stride, BUFFER_OFFSET(vAtb->offset + frameOffset));
|
||||
|
||||
frameOffset = refEnt->wasframe * surface->vao->frameSize;
|
||||
frameOffset = refEnt->oldframe * surface->vao->frameSize;
|
||||
|
||||
attribIndex = ATTR_INDEX_POSITION2;
|
||||
vAtb = &surface->vao->attribs[attribIndex];
|
||||
|
@ -962,29 +1299,19 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface)
|
|||
static void RB_SurfaceSkip( void *surf ) {
|
||||
}
|
||||
|
||||
void RB_DrawTerrainTris(srfTerrain_t* p) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])(void*) = {
|
||||
(void(*)(void*))RB_SurfaceBad, // SF_BAD,
|
||||
(void(*)(void*))RB_SurfaceSkip, // SF_SKIP,
|
||||
(void(*)(void*))RB_SurfaceFace, // SF_FACE,
|
||||
(void(*)(void*))RB_SurfaceGrid, // SF_GRID,
|
||||
(void(*)(void*))RB_SurfacePolychain, // SF_POLY,
|
||||
(void(*)(void*))RB_SurfaceMarkFragment, // SF_MARK_FRAG
|
||||
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE
|
||||
(void(*)(void*))RB_SurfaceEntity, // SF_ENTITY
|
||||
(void(*)(void*))NULL, // SF_DISPLAY_LIST
|
||||
(void(*)(void*))RB_SkelMesh, // SF_TIKI_SKEL
|
||||
(void(*)(void*))RB_StaticMesh, // SF_TIKI_STATIC
|
||||
(void(*)(void*))RB_DrawSwipeSurface, // SF_SWIPE
|
||||
(void(*)(void*))RB_DrawSprite, // SF_SPRITE
|
||||
(void(*)(void*))RB_DrawTerrainTris, // SF_TERRAIN_PATCH
|
||||
(void(*)(void*))RB_SurfaceTriangles, // SF_TRIANGLES,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
|
||||
(void(*)(void*))RB_SurfaceBad, // SF_BAD,
|
||||
(void(*)(void*))RB_SurfaceSkip, // SF_SKIP,
|
||||
(void(*)(void*))RB_SurfaceFace, // SF_FACE,
|
||||
(void(*)(void*))RB_SurfaceGrid, // SF_GRID,
|
||||
(void(*)(void*))RB_SurfaceTriangles, // SF_TRIANGLES,
|
||||
(void(*)(void*))RB_SurfacePolychain, // SF_POLY,
|
||||
(void(*)(void*))RB_SurfaceMesh, // SF_MDV,
|
||||
(void(*)(void*))RB_MDRSurfaceAnim, // SF_MDR,
|
||||
(void(*)(void*))RB_IQMSurfaceAnim, // SF_IQM,
|
||||
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE,
|
||||
(void(*)(void*))RB_SurfaceEntity, // SF_ENTITY
|
||||
(void(*)(void*))RB_SurfaceVaoMdvMesh, // SF_VAO_MDVMESH
|
||||
(void(*)(void*))RB_IQMSurfaceAnimVao, // SF_VAO_IQM
|
||||
};
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_swipe.cpp -- swipe rendering
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
void RB_DrawSwipeSurface(surfaceType_t* pswipe) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RE_SwipeBegin(float thistime, float life, qhandle_t shader)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RE_SwipePoint(vec3_t point1, vec3_t point2, float time)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RE_SwipeEnd()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
|
@ -1,259 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_util.c -- renderer utility
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
static vec4_t cntColor;
|
||||
static float cntSt[ 2 ];
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamBegin
|
||||
===============
|
||||
*/
|
||||
void RB_StreamBegin( shader_t *shader ) {
|
||||
RB_BeginSurface( shader, 0, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamEnd
|
||||
===============
|
||||
*/
|
||||
void RB_StreamEnd( void ) {
|
||||
int i;
|
||||
|
||||
if( tess.numVertexes <= 2 ) {
|
||||
RB_EndSurface();
|
||||
return;
|
||||
}
|
||||
|
||||
tess.indexes[ 0 ] = 0;
|
||||
tess.indexes[ 1 ] = 1;
|
||||
tess.indexes[ 2 ] = 2;
|
||||
|
||||
for( i = 0; i < tess.numVertexes - 2; i++ ) {
|
||||
tess.indexes[ i * 3 + 0 ] = ( i & 1 ) + i;
|
||||
tess.indexes[ i * 3 + 1 ] = i - ( ( i & 1 ) - 1 );
|
||||
tess.indexes[ i * 3 + 2 ] = i + 2;
|
||||
tess.numIndexes += 3;
|
||||
}
|
||||
|
||||
RB_EndSurface();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamBeginDrawSurf
|
||||
===============
|
||||
*/
|
||||
void RB_StreamBeginDrawSurf( void ) {
|
||||
backEnd.dsStreamVert = tess.numVertexes;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamEndDrawSurf
|
||||
===============
|
||||
*/
|
||||
void RB_StreamEndDrawSurf( void ) {
|
||||
int numverts;
|
||||
int i;
|
||||
|
||||
if( tess.numVertexes - backEnd.dsStreamVert <= 2 ) {
|
||||
tess.numVertexes = backEnd.dsStreamVert;
|
||||
return;
|
||||
}
|
||||
|
||||
numverts = tess.numVertexes - backEnd.dsStreamVert - 2;
|
||||
for( i = 0; i < numverts; i++ ) {
|
||||
tess.indexes[ i + tess.numIndexes ] = ( i & 1 ) + i + backEnd.dsStreamVert;
|
||||
tess.indexes[ i + tess.numIndexes + 1 ] = i + backEnd.dsStreamVert - ( ( i & 1 ) - 1 );
|
||||
tess.indexes[ i + tess.numIndexes + 2 ] = i + backEnd.dsStreamVert + 2;
|
||||
tess.numIndexes += 3;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
addTriangle
|
||||
===============
|
||||
*/
|
||||
static void addTriangle( void ) {
|
||||
tess.texCoords[ tess.numVertexes ][ 0 ] = cntSt[ 0 ];
|
||||
tess.texCoords[ tess.numVertexes ][ 1 ] = cntSt[ 1 ];
|
||||
tess.color[ tess.numVertexes ][ 0 ] = cntColor[ 0 ];
|
||||
tess.color[ tess.numVertexes ][ 1 ] = cntColor[ 1 ];
|
||||
tess.color[ tess.numVertexes ][ 2 ] = cntColor[ 2 ];
|
||||
tess.color[ tess.numVertexes ][ 3 ] = cntColor[ 3 ];
|
||||
tess.numVertexes++;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex3fv
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex3fv( vec3_t v ) {
|
||||
VectorCopy( v, tess.xyz[ tess.numVertexes ] );
|
||||
addTriangle();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex3f
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex3f( vec_t x, vec_t y, vec_t z ) {
|
||||
tess.xyz[ tess.numVertexes ][ 0 ] = x;
|
||||
tess.xyz[ tess.numVertexes ][ 1 ] = y;
|
||||
tess.xyz[ tess.numVertexes ][ 2 ] = z;
|
||||
addTriangle();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex2f
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex2f( vec_t x, vec_t y ) {
|
||||
RB_Vertex3f( x, y, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color4f
|
||||
===============
|
||||
*/
|
||||
void RB_Color4f( vec_t r, vec_t g, vec_t b, vec_t a ) {
|
||||
cntColor[ 0 ] = r;
|
||||
cntColor[ 1 ] = g;
|
||||
cntColor[ 2 ] = b;
|
||||
cntColor[ 3 ] = a;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color3f
|
||||
===============
|
||||
*/
|
||||
void RB_Color3f( vec_t r, vec_t g, vec_t b ) {
|
||||
RB_Color4f( r, g, b, 1.0 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color3fv
|
||||
===============
|
||||
*/
|
||||
void RB_Color3fv( vec3_t col ) {
|
||||
RB_Color3f( col[ 0 ], col[ 1 ], col[ 2 ] );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color4bv
|
||||
===============
|
||||
*/
|
||||
void RB_Color4bv( unsigned char *colors ) {
|
||||
cntColor[ 0 ] = colors[ 0 ] * 255.0;
|
||||
cntColor[ 1 ] = colors[ 1 ] * 255.0;
|
||||
cntColor[ 2 ] = colors[ 2 ] * 255.0;
|
||||
cntColor[ 3 ] = colors[ 3 ] * 255.0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Texcoord2f
|
||||
===============
|
||||
*/
|
||||
void RB_Texcoord2f( float s, float t ) {
|
||||
cntSt[ 0 ] = s;
|
||||
cntSt[ 1 ] = t;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Texcoord2fv
|
||||
===============
|
||||
*/
|
||||
void RB_Texcoord2fv( vec2_t st ) {
|
||||
cntSt[ 0 ] = st[ 0 ];
|
||||
cntSt[ 1 ] = st[ 1 ];
|
||||
}
|
||||
|
||||
static int Numbers[ 12 ][ 8 ];
|
||||
static float Lines[ 13 ][ 4 ];
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DrawDebugNumber
|
||||
===============
|
||||
*/
|
||||
void R_DrawDebugNumber( const vec3_t org, float number, float scale, float r, float g, float b, int precision ) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DebugRotatedBBox
|
||||
===============
|
||||
*/
|
||||
void R_DebugRotatedBBox( const vec3_t org, vec3_t ang, vec3_t mins, vec3_t maxs, float r, float g, float b, float alpha ) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_GetShaderWidth
|
||||
===============
|
||||
*/
|
||||
int RE_GetShaderWidth( qhandle_t hShader ) {
|
||||
shader_t *shader;
|
||||
|
||||
if( hShader ) {
|
||||
shader = R_GetShaderByHandle( hShader );
|
||||
} else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
return shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->uploadWidth;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_GetShaderHeight
|
||||
===============
|
||||
*/
|
||||
int RE_GetShaderHeight( qhandle_t hShader ) {
|
||||
shader_t *shader;
|
||||
|
||||
if( hShader ) {
|
||||
shader = R_GetShaderByHandle( hShader );
|
||||
}
|
||||
else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
return shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->uploadHeight;
|
||||
}
|
|
@ -130,7 +130,7 @@ vao_t *R_CreateVao(const char *name, byte *vertexes, int vertexesSize, byte *ind
|
|||
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
vao = tr.vaos[tr.numVaos] = ri.Hunk_Alloc(sizeof(*vao));
|
||||
vao = tr.vaos[tr.numVaos] = ri.Hunk_Alloc(sizeof(*vao), h_low);
|
||||
tr.numVaos++;
|
||||
|
||||
memset(vao, 0, sizeof(*vao));
|
||||
|
@ -198,7 +198,7 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int num
|
|||
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
vao = tr.vaos[tr.numVaos] = ri.Hunk_Alloc(sizeof(*vao));
|
||||
vao = tr.vaos[tr.numVaos] = ri.Hunk_Alloc(sizeof(*vao), h_low);
|
||||
tr.numVaos++;
|
||||
|
||||
memset(vao, 0, sizeof(*vao));
|
||||
|
|
|
@ -393,10 +393,6 @@ void R_AddBrushModelSurfaces ( trRefEntity_t *ent ) {
|
|||
=============================================================
|
||||
*/
|
||||
|
||||
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -632,6 +628,25 @@ static const byte *R_ClusterPVS (int cluster) {
|
|||
return tr.world->vis + cluster * tr.world->clusterBytes;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_inPVS
|
||||
=================
|
||||
*/
|
||||
qboolean R_inPVS( const vec3_t p1, const vec3_t p2 ) {
|
||||
mnode_t *leaf;
|
||||
byte *vis;
|
||||
|
||||
leaf = R_PointInLeaf( p1 );
|
||||
vis = ri.CM_ClusterPVS( leaf->cluster ); // why not R_ClusterPVS ??
|
||||
leaf = R_PointInLeaf( p2 );
|
||||
|
||||
if ( !(vis[leaf->cluster>>3] & (1<<(leaf->cluster&7))) ) {
|
||||
return qfalse;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_MarkLeaves
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue