mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
Merge branch 'master' into sdl2
This commit is contained in:
commit
779ebfacfd
32 changed files with 996 additions and 1795 deletions
|
@ -2429,6 +2429,9 @@ void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) {
|
|||
server->game[0] = '\0';
|
||||
server->gameType = 0;
|
||||
server->netType = 0;
|
||||
server->punkbuster = 0;
|
||||
server->g_humanplayers = 0;
|
||||
server->g_needpass = 0;
|
||||
}
|
||||
|
||||
#define MAX_SERVERSPERPACKET 256
|
||||
|
@ -2937,13 +2940,13 @@ void CL_Frame ( int msec ) {
|
|||
if ( CL_VideoRecording( ) && cl_aviFrameRate->integer && msec) {
|
||||
// save the current screen
|
||||
if ( clc.state == CA_ACTIVE || cl_forceavidemo->integer) {
|
||||
float fps = MIN(cl_aviFrameRate->value * com_timescale->value, 1000.0f);
|
||||
float frameDuration = MAX(1000.0f / fps, 1.0f) + clc.aviVideoFrameRemainder;
|
||||
|
||||
CL_TakeVideoFrame( );
|
||||
|
||||
// fixed time for next frame'
|
||||
msec = (int)ceil( (1000.0f / cl_aviFrameRate->value) * com_timescale->value );
|
||||
if (msec == 0) {
|
||||
msec = 1;
|
||||
}
|
||||
msec = (int)frameDuration;
|
||||
clc.aviVideoFrameRemainder = frameDuration - msec;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3836,21 +3839,8 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
|
|||
|
||||
// add this to the list
|
||||
cls.numlocalservers = i+1;
|
||||
cls.localServers[i].adr = from;
|
||||
cls.localServers[i].clients = 0;
|
||||
cls.localServers[i].hostName[0] = '\0';
|
||||
cls.localServers[i].mapName[0] = '\0';
|
||||
cls.localServers[i].maxClients = 0;
|
||||
cls.localServers[i].maxPing = 0;
|
||||
cls.localServers[i].minPing = 0;
|
||||
cls.localServers[i].ping = -1;
|
||||
cls.localServers[i].game[0] = '\0';
|
||||
cls.localServers[i].gameType = 0;
|
||||
cls.localServers[i].netType = from.type;
|
||||
cls.localServers[i].punkbuster = 0;
|
||||
cls.localServers[i].g_humanplayers = 0;
|
||||
cls.localServers[i].g_needpass = 0;
|
||||
|
||||
CL_InitServerInfo( &cls.localServers[i], &from );
|
||||
|
||||
Q_strncpyz( info, MSG_ReadString( msg ), MAX_INFO_STRING );
|
||||
if (strlen(info)) {
|
||||
if (info[strlen(info)-1] != '\n') {
|
||||
|
|
|
@ -233,6 +233,9 @@ typedef struct {
|
|||
int timeDemoMaxDuration; // maximum frame duration
|
||||
unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations
|
||||
|
||||
float aviVideoFrameRemainder;
|
||||
float aviSoundFrameRemainder;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
qboolean voipEnabled;
|
||||
qboolean speexInitialized;
|
||||
|
|
|
@ -271,6 +271,11 @@ static sfx_t *S_FindName( const char *name ) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (name[0] == '*') {
|
||||
Com_Printf( S_COLOR_YELLOW "WARNING: Tried to load player sound directly: %s\n", name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash = S_HashSFXName(name);
|
||||
|
||||
sfx = sfxHash[hash];
|
||||
|
@ -1237,7 +1242,13 @@ void S_GetSoundtime(void)
|
|||
|
||||
if( CL_VideoRecording( ) )
|
||||
{
|
||||
s_soundtime += (int)ceil( dma.speed / cl_aviFrameRate->value );
|
||||
float fps = MIN(cl_aviFrameRate->value, 1000.0f);
|
||||
float frameDuration = MAX(dma.speed / fps, 1.0f) + clc.aviSoundFrameRemainder;
|
||||
|
||||
int msec = (int)frameDuration;
|
||||
s_soundtime += msec;
|
||||
clc.aviSoundFrameRemainder = frameDuration - msec;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -208,11 +208,6 @@ qboolean S_LoadSound( sfx_t *sfx )
|
|||
snd_info_t info;
|
||||
// int size;
|
||||
|
||||
// player specific sounds are never directly loaded
|
||||
if ( sfx->soundName[0] == '*') {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// load it in
|
||||
data = S_CodecLoad(sfx->soundName, &info);
|
||||
if(!data)
|
||||
|
|
|
@ -208,6 +208,11 @@ static sfxHandle_t S_AL_BufferFind(const char *filename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ( filename[0] == '*' ) {
|
||||
Com_Printf( S_COLOR_YELLOW "WARNING: Tried to load player sound directly: %s\n", filename );
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < numSfx; i++)
|
||||
{
|
||||
if(!Q_stricmp(knownSfx[i].filename, filename))
|
||||
|
@ -325,10 +330,6 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
if(curSfx->filename[0] == '\0')
|
||||
return;
|
||||
|
||||
// Player SFX
|
||||
if(curSfx->filename[0] == '*')
|
||||
return;
|
||||
|
||||
// Already done?
|
||||
if((curSfx->inMemory) || (curSfx->isDefault) || (!cache && curSfx->isDefaultChecked))
|
||||
return;
|
||||
|
|
|
@ -874,16 +874,6 @@ void GL_SetDefaultState( void )
|
|||
qglEnable( GL_SCISSOR_TEST );
|
||||
qglDisable( GL_CULL_FACE );
|
||||
qglDisable( GL_BLEND );
|
||||
|
||||
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
qglClearDepth( 1.0 );
|
||||
|
||||
qglDrawBuffer( GL_FRONT );
|
||||
qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
|
||||
|
||||
qglDrawBuffer( GL_BACK );
|
||||
qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -41,10 +41,6 @@ typedef unsigned int glIndex_t;
|
|||
#define SHADERNUM_BITS 14
|
||||
#define MAX_SHADERS (1<<SHADERNUM_BITS)
|
||||
|
||||
//#define MAX_SHADER_STATES 2048
|
||||
#define MAX_STATES_PER_SHADER 32
|
||||
#define MAX_STATE_NAME 32
|
||||
|
||||
|
||||
|
||||
typedef struct dlight_s {
|
||||
|
@ -266,7 +262,6 @@ typedef struct {
|
|||
|
||||
int videoMapHandle;
|
||||
qboolean isLightmap;
|
||||
qboolean vertexLightmap;
|
||||
qboolean isVideoMap;
|
||||
} textureBundle_t;
|
||||
|
||||
|
@ -370,27 +365,11 @@ typedef struct shader_s {
|
|||
float clampTime; // time this shader is clamped to
|
||||
float timeOffset; // current time offset for this shader
|
||||
|
||||
int numStates; // if non-zero this is a state shader
|
||||
struct shader_s *currentShader; // current state if this is a state shader
|
||||
struct shader_s *parentShader; // current state if this is a state shader
|
||||
int currentState; // current state index for cycle purposes
|
||||
long expireTime; // time in milliseconds this expires
|
||||
|
||||
struct shader_s *remappedShader; // current shader this one is remapped too
|
||||
|
||||
int shaderStates[MAX_STATES_PER_SHADER]; // index to valid shader states
|
||||
|
||||
struct shader_s *next;
|
||||
} shader_t;
|
||||
|
||||
typedef struct shaderState_s {
|
||||
char shaderName[MAX_QPATH]; // name of shader this state belongs to
|
||||
char name[MAX_STATE_NAME]; // name of this state
|
||||
char stateShader[MAX_QPATH]; // shader this name invokes
|
||||
int cycleTime; // time this cycle lasts, <= 0 is forever
|
||||
shader_t *shader;
|
||||
} shaderState_t;
|
||||
|
||||
|
||||
// trRefdef_t holds everything that comes in refdef_t,
|
||||
// as well as the locally generated scene information
|
||||
|
@ -610,6 +589,7 @@ typedef struct {
|
|||
int num_frames;
|
||||
int num_surfaces;
|
||||
int num_joints;
|
||||
int num_poses;
|
||||
struct srfIQModel_s *surfaces;
|
||||
|
||||
float *positions;
|
||||
|
@ -617,10 +597,18 @@ typedef struct {
|
|||
float *normals;
|
||||
float *tangents;
|
||||
byte *blendIndexes;
|
||||
byte *blendWeights;
|
||||
union {
|
||||
float *f;
|
||||
byte *b;
|
||||
} blendWeights;
|
||||
byte *colors;
|
||||
int *triangles;
|
||||
|
||||
// depending upon the exporter, blend indices and weights might be int/float
|
||||
// as opposed to the recommended byte/byte, for example Noesis exports
|
||||
// int/float whereas the official IQM tool exports byte/byte
|
||||
byte blendWeightsType; // IQM_UBYTE or IQM_FLOAT
|
||||
|
||||
int *jointParents;
|
||||
float *jointMats;
|
||||
float *poseMats;
|
||||
|
|
|
@ -25,6 +25,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
// 3x4 identity matrix
|
||||
static float identityMatrix[12] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0
|
||||
};
|
||||
|
||||
static qboolean IQM_CheckRange( iqmHeader_t *header, int offset,
|
||||
int count,int size ) {
|
||||
// return true if the range specified by offset, count and size
|
||||
|
@ -143,6 +150,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
iqmData_t *iqmData;
|
||||
srfIQModel_t *surface;
|
||||
char meshName[MAX_QPATH];
|
||||
byte blendIndexesType, blendWeightsType;
|
||||
|
||||
if( filesize < sizeof(iqmHeader_t) ) {
|
||||
return qfalse;
|
||||
|
@ -198,6 +206,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
blendIndexesType = blendWeightsType = IQM_UBYTE;
|
||||
|
||||
// check and swap vertex arrays
|
||||
if( IQM_CheckRange( header, header->ofs_vertexarrays,
|
||||
header->num_vertexarrays,
|
||||
|
@ -264,11 +274,20 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
}
|
||||
break;
|
||||
case IQM_BLENDINDEXES:
|
||||
if( (vertexarray->format != IQM_INT &&
|
||||
vertexarray->format != IQM_UBYTE) ||
|
||||
vertexarray->size != 4 ) {
|
||||
return qfalse;
|
||||
}
|
||||
blendIndexesType = vertexarray->format;
|
||||
break;
|
||||
case IQM_BLENDWEIGHTS:
|
||||
if( vertexarray->format != IQM_UBYTE ||
|
||||
if( (vertexarray->format != IQM_FLOAT &&
|
||||
vertexarray->format != IQM_UBYTE) ||
|
||||
vertexarray->size != 4 ) {
|
||||
return qfalse;
|
||||
}
|
||||
blendWeightsType = vertexarray->format;
|
||||
break;
|
||||
case IQM_COLOR:
|
||||
if( vertexarray->format != IQM_UBYTE ||
|
||||
|
@ -343,7 +362,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
}
|
||||
}
|
||||
|
||||
if( header->num_poses != header->num_joints ) {
|
||||
if( header->num_poses != header->num_joints && header->num_poses != 0 ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadIQM: %s has %d poses and %d joints, must have the same number or 0 poses\n",
|
||||
mod_name, header->num_poses, header->num_joints );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -379,7 +400,10 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
joint_names += strlen( (char *)header + header->ofs_text +
|
||||
joint->name ) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( header->num_poses )
|
||||
{
|
||||
// check and swap poses
|
||||
if( IQM_CheckRange( header, header->ofs_poses,
|
||||
header->num_poses, sizeof(iqmPose_t) ) ) {
|
||||
|
@ -438,7 +462,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
size = sizeof(iqmData_t);
|
||||
size += header->num_meshes * sizeof( srfIQModel_t );
|
||||
size += header->num_joints * 12 * sizeof( float ); // joint mats
|
||||
size += header->num_joints * header->num_frames * 12 * sizeof( float ); // pose mats
|
||||
size += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats
|
||||
if(header->ofs_bounds)
|
||||
size += header->num_frames * 6 * sizeof(float); // model bounds
|
||||
size += header->num_vertexes * 3 * sizeof(float); // positions
|
||||
|
@ -446,12 +470,18 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
size += header->num_vertexes * 3 * sizeof(float); // normals
|
||||
size += header->num_vertexes * 4 * sizeof(float); // tangents
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // blendIndexes
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // blendWeights
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // colors
|
||||
size += header->num_joints * sizeof(int); // parents
|
||||
size += header->num_triangles * 3 * sizeof(int); // triangles
|
||||
size += joint_names; // joint names
|
||||
|
||||
// blendWeights
|
||||
if (blendWeightsType == IQM_FLOAT) {
|
||||
size += header->num_vertexes * 4 * sizeof(float);
|
||||
} else {
|
||||
size += header->num_vertexes * 4 * sizeof(byte);
|
||||
}
|
||||
|
||||
mod->type = MOD_IQM;
|
||||
iqmData = (iqmData_t *)ri.Hunk_Alloc( size, h_low );
|
||||
mod->modelData = iqmData;
|
||||
|
@ -462,28 +492,40 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
iqmData->num_frames = header->num_frames;
|
||||
iqmData->num_surfaces = header->num_meshes;
|
||||
iqmData->num_joints = header->num_joints;
|
||||
iqmData->num_poses = header->num_poses;
|
||||
iqmData->blendWeightsType = blendWeightsType;
|
||||
iqmData->surfaces = (srfIQModel_t *)(iqmData + 1);
|
||||
iqmData->jointMats = (float *) (iqmData->surfaces + iqmData->num_surfaces);
|
||||
iqmData->poseMats = iqmData->jointMats + 12 * header->num_joints;
|
||||
if(header->ofs_bounds)
|
||||
{
|
||||
iqmData->bounds = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
|
||||
iqmData->bounds = iqmData->poseMats + 12 * header->num_poses * header->num_frames;
|
||||
iqmData->positions = iqmData->bounds + 6 * header->num_frames;
|
||||
}
|
||||
else
|
||||
iqmData->positions = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
|
||||
iqmData->positions = iqmData->poseMats + 12 * header->num_poses * header->num_frames;
|
||||
iqmData->texcoords = iqmData->positions + 3 * header->num_vertexes;
|
||||
iqmData->normals = iqmData->texcoords + 2 * header->num_vertexes;
|
||||
iqmData->tangents = iqmData->normals + 3 * header->num_vertexes;
|
||||
iqmData->blendIndexes = (byte *)(iqmData->tangents + 4 * header->num_vertexes);
|
||||
iqmData->blendWeights = iqmData->blendIndexes + 4 * header->num_vertexes;
|
||||
iqmData->colors = iqmData->blendWeights + 4 * header->num_vertexes;
|
||||
|
||||
if(blendWeightsType == IQM_FLOAT) {
|
||||
iqmData->blendWeights.f = (float *)(iqmData->blendIndexes + 4 * header->num_vertexes);
|
||||
iqmData->colors = (byte *)(iqmData->blendWeights.f + 4 * header->num_vertexes);
|
||||
} else {
|
||||
iqmData->blendWeights.b = iqmData->blendIndexes + 4 * header->num_vertexes;
|
||||
iqmData->colors = iqmData->blendWeights.b + 4 * header->num_vertexes;
|
||||
}
|
||||
|
||||
iqmData->jointParents = (int *)(iqmData->colors + 4 * header->num_vertexes);
|
||||
iqmData->triangles = iqmData->jointParents + header->num_joints;
|
||||
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
|
||||
|
||||
if ( header->num_joints == 0 )
|
||||
iqmData->jointMats = iqmData->poseMats = NULL;
|
||||
iqmData->jointMats = NULL;
|
||||
|
||||
if ( header->num_poses == 0 )
|
||||
iqmData->poseMats = NULL;
|
||||
|
||||
// calculate joint matrices and their inverses
|
||||
// joint inverses are needed only until the pose matrices are calculated
|
||||
|
@ -620,14 +662,27 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
n * sizeof(float) );
|
||||
break;
|
||||
case IQM_BLENDINDEXES:
|
||||
Com_Memcpy( iqmData->blendIndexes,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
if( blendIndexesType == IQM_INT ) {
|
||||
int *data = (int*)((byte*)header + vertexarray->offset);
|
||||
for ( j = 0; j < n; j++ ) {
|
||||
iqmData->blendIndexes[j] = (byte)data[j];
|
||||
}
|
||||
} else {
|
||||
Com_Memcpy( iqmData->blendIndexes,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
}
|
||||
break;
|
||||
case IQM_BLENDWEIGHTS:
|
||||
Com_Memcpy( iqmData->blendWeights,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
if( blendWeightsType == IQM_FLOAT ) {
|
||||
Com_Memcpy( iqmData->blendWeights.f,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(float) );
|
||||
} else {
|
||||
Com_Memcpy( iqmData->blendWeights.b,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
}
|
||||
break;
|
||||
case IQM_COLOR:
|
||||
Com_Memcpy( iqmData->colors,
|
||||
|
@ -892,9 +947,21 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
|||
int *joint = data->jointParents;
|
||||
int i;
|
||||
|
||||
if ( oldframe == frame ) {
|
||||
mat1 = data->poseMats + 12 * data->num_joints * frame;
|
||||
if ( data->num_poses == 0 ) {
|
||||
for( i = 0; i < data->num_joints; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
Matrix34Multiply( mat + 12 * *joint,
|
||||
identityMatrix, mat + 12*i );
|
||||
} else {
|
||||
Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( oldframe == frame ) {
|
||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
Matrix34Multiply( mat + 12 * *joint,
|
||||
mat1 + 12*i, mat + 12*i );
|
||||
|
@ -903,10 +970,10 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
mat1 = data->poseMats + 12 * data->num_joints * frame;
|
||||
mat2 = data->poseMats + 12 * data->num_joints * oldframe;
|
||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
||||
mat2 = data->poseMats + 12 * data->num_poses * oldframe;
|
||||
|
||||
for( i = 0; i < data->num_joints; i++, joint++ ) {
|
||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
float tmpMat[12];
|
||||
InterpolateMatrix( mat1 + 12*i, mat2 + 12*i,
|
||||
|
@ -974,7 +1041,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
outColor = &tess.vertexColors[tess.numVertexes];
|
||||
|
||||
// compute interpolated joint matrices
|
||||
if ( data->num_joints > 0 ) {
|
||||
if ( data->num_poses > 0 ) {
|
||||
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
|
||||
}
|
||||
|
||||
|
@ -985,28 +1052,31 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
float vtxMat[12];
|
||||
float nrmMat[9];
|
||||
int vtx = i + surf->first_vertex;
|
||||
float blendWeights[4];
|
||||
int numWeights;
|
||||
|
||||
if ( data->num_joints == 0 || data->blendWeights[4*vtx] <= 0 ) {
|
||||
for ( numWeights = 0; numWeights < 4; numWeights++ ) {
|
||||
if ( data->blendWeightsType == IQM_FLOAT )
|
||||
blendWeights[numWeights] = data->blendWeights.f[4*vtx + numWeights];
|
||||
else
|
||||
blendWeights[numWeights] = (float)data->blendWeights.b[4*vtx + numWeights] / 255.0f;
|
||||
|
||||
if ( blendWeights[numWeights] <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( data->num_poses == 0 || numWeights == 0 ) {
|
||||
// no blend joint, use identity matrix.
|
||||
for( j = 0; j < 3; j++ ) {
|
||||
for( k = 0; k < 4; k++ )
|
||||
vtxMat[4*j+k] = ( k == j ) ? 1 : 0;
|
||||
}
|
||||
Com_Memcpy( vtxMat, identityMatrix, 12 * sizeof (float) );
|
||||
} else {
|
||||
// compute the vertex matrix by blending the up to
|
||||
// four blend weights
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] = data->blendWeights[4*vtx]
|
||||
* jointMats[12*data->blendIndexes[4*vtx] + k];
|
||||
for( j = 1; j < 4; j++ ) {
|
||||
if( data->blendWeights[4*vtx + j] <= 0 )
|
||||
break;
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] += data->blendWeights[4*vtx + j]
|
||||
* jointMats[12*data->blendIndexes[4*vtx + j] + k];
|
||||
Com_Memset( vtxMat, 0, 12 * sizeof (float) );
|
||||
for( j = 0; j < numWeights; j++ ) {
|
||||
for( k = 0; k < 12; k++ ) {
|
||||
vtxMat[k] += blendWeights[j] * jointMats[12*data->blendIndexes[4*vtx + j] + k];
|
||||
}
|
||||
}
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] *= 1.0f / 255.0f;
|
||||
}
|
||||
|
||||
// compute the normal matrix as transpose of the adjoint
|
||||
|
|
|
@ -1145,12 +1145,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
//
|
||||
// set state
|
||||
//
|
||||
if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer )
|
||||
{
|
||||
GL_Bind( tr.whiteImage );
|
||||
}
|
||||
else
|
||||
R_BindAnimatedImage( &pStage->bundle[0] );
|
||||
R_BindAnimatedImage( &pStage->bundle[0] );
|
||||
|
||||
GL_State( pStage->stateBits );
|
||||
|
||||
|
@ -1160,7 +1155,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
R_DrawElements( input->numIndexes, input->indexes );
|
||||
}
|
||||
// allow skipping out to show just lightmaps during development
|
||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) )
|
||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -85,15 +85,12 @@ float CalcFog(vec4 position)
|
|||
float s = dot(position, u_FogDistance) * 8.0;
|
||||
float t = dot(position, u_FogDepth);
|
||||
|
||||
if (t < 1.0)
|
||||
{
|
||||
t = step(step(0.0, -u_FogEyeT), t);
|
||||
}
|
||||
else
|
||||
{
|
||||
t /= t - min(u_FogEyeT, 0.0);
|
||||
}
|
||||
|
||||
float eyeOutside = step(0.0, -u_FogEyeT);
|
||||
float fogged = step(eyeOutside, t);
|
||||
|
||||
t = max(t, 1e-6);
|
||||
t *= fogged / (t - u_FogEyeT * eyeOutside);
|
||||
|
||||
return s * t;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ uniform vec4 u_DiffuseTexMatrix;
|
|||
uniform vec4 u_DiffuseTexOffTurb;
|
||||
|
||||
#if defined(USE_TCGEN) || defined(USE_RGBAGEN)
|
||||
uniform vec3 u_ViewOrigin;
|
||||
uniform vec3 u_LocalViewOrigin;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCGEN)
|
||||
|
@ -48,7 +48,7 @@ uniform int u_ColorGen;
|
|||
uniform int u_AlphaGen;
|
||||
uniform vec3 u_AmbientLight;
|
||||
uniform vec3 u_DirectedLight;
|
||||
uniform vec4 u_LightOrigin;
|
||||
uniform vec3 u_ModelLightDir;
|
||||
uniform float u_PortalRange;
|
||||
#endif
|
||||
|
||||
|
@ -93,7 +93,7 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
|
|||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
|
||||
{
|
||||
func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
|
||||
func = 1.0 - abs(4.0 * fract(value + 0.25) - 2.0);
|
||||
}
|
||||
else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
|
||||
{
|
||||
|
@ -123,7 +123,7 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3
|
|||
}
|
||||
else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
|
||||
{
|
||||
vec3 viewer = normalize(u_ViewOrigin - position);
|
||||
vec3 viewer = normalize(u_LocalViewOrigin - position);
|
||||
tex = -reflect(viewer, normal).yz * vec2(0.5, -0.5) + 0.5;
|
||||
}
|
||||
else if (TCGen == TCGEN_VECTOR)
|
||||
|
@ -158,30 +158,25 @@ vec4 CalcColor(vec3 position, vec3 normal)
|
|||
|
||||
if (u_ColorGen == CGEN_LIGHTING_DIFFUSE)
|
||||
{
|
||||
float incoming = clamp(dot(normal, u_LightOrigin.xyz), 0.0, 1.0);
|
||||
float incoming = clamp(dot(normal, u_ModelLightDir), 0.0, 1.0);
|
||||
|
||||
color.rgb = clamp(u_DirectedLight * incoming + u_AmbientLight, 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 toView = u_ViewOrigin - position;
|
||||
vec3 viewer = normalize(u_ViewOrigin - position);
|
||||
vec3 viewer = u_LocalViewOrigin - position;
|
||||
|
||||
if (u_AlphaGen == AGEN_LIGHTING_SPECULAR)
|
||||
{
|
||||
vec3 lightDir = normalize(vec3(-960.0, -1980.0, 96.0) - position.xyz);
|
||||
vec3 halfangle = normalize(lightDir + viewer);
|
||||
vec3 lightDir = normalize(vec3(-960.0, 1980.0, 96.0) - position.xyz);
|
||||
vec3 reflected = -reflect(lightDir, normal);
|
||||
|
||||
color.a = pow(max(dot(normal, halfangle), 0.0), 8.0);
|
||||
color.a = clamp(dot(reflected, normalize(viewer)), 0.0, 1.0);
|
||||
color.a *= color.a;
|
||||
color.a *= color.a;
|
||||
}
|
||||
else if (u_AlphaGen == AGEN_PORTAL)
|
||||
{
|
||||
float alpha = length(toView) / u_PortalRange;
|
||||
|
||||
color.a = clamp(alpha, 0.0, 1.0);
|
||||
}
|
||||
else if (u_AlphaGen == AGEN_FRESNEL)
|
||||
{
|
||||
color.a = 0.10 + 0.90 * pow(1.0 - dot(normal, viewer), 5);
|
||||
color.a = clamp(length(viewer) / u_PortalRange, 0.0, 1.0);
|
||||
}
|
||||
|
||||
return color;
|
||||
|
@ -194,14 +189,11 @@ float CalcFog(vec4 position)
|
|||
float s = dot(position, u_FogDistance) * 8.0;
|
||||
float t = dot(position, u_FogDepth);
|
||||
|
||||
if (t < 1.0)
|
||||
{
|
||||
t = step(step(0.0, -u_FogEyeT), t);
|
||||
}
|
||||
else
|
||||
{
|
||||
t /= t - min(u_FogEyeT, 0.0);
|
||||
}
|
||||
float eyeOutside = step(0.0, -u_FogEyeT);
|
||||
float fogged = step(eyeOutside, t);
|
||||
|
||||
t = max(t, 1e-6);
|
||||
t *= fogged / (t - u_FogEyeT * eyeOutside);
|
||||
|
||||
return s * t;
|
||||
}
|
||||
|
|
|
@ -24,45 +24,40 @@ uniform sampler2D u_ShadowMap;
|
|||
uniform samplerCube u_CubeMap;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VECTOR)
|
||||
#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
|
||||
uniform vec3 u_DirectedLight;
|
||||
uniform vec3 u_AmbientLight;
|
||||
uniform float u_LightRadius;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
uniform vec3 u_PrimaryLightColor;
|
||||
uniform vec3 u_PrimaryLightAmbient;
|
||||
uniform float u_PrimaryLightRadius;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT)
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
uniform vec2 u_MaterialInfo;
|
||||
#endif
|
||||
|
||||
varying vec2 var_DiffuseTex;
|
||||
#if defined(USE_LIGHTMAP)
|
||||
varying vec2 var_LightTex;
|
||||
#endif
|
||||
varying vec4 var_TexCoords;
|
||||
|
||||
varying vec4 var_Color;
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
varying vec3 var_ViewDir;
|
||||
varying vec3 var_Normal;
|
||||
varying vec3 var_Tangent;
|
||||
varying vec3 var_Bitangent;
|
||||
varying vec4 var_Normal;
|
||||
varying vec4 var_Tangent;
|
||||
varying vec4 var_Bitangent;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
varying vec3 var_lightColor;
|
||||
varying vec3 var_LightColor;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
|
||||
varying vec4 var_LightDir;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
varying vec3 var_PrimaryLightDir;
|
||||
varying vec4 var_PrimaryLightDir;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -181,17 +176,21 @@ float CalcBlinn(float NH, float shininess)
|
|||
#endif
|
||||
}
|
||||
|
||||
float CalcGGX(float NH, float shininess)
|
||||
float CalcGGX(float NH, float gloss)
|
||||
{
|
||||
// from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes.pdf
|
||||
float m_sq = 2.0 / shininess;
|
||||
float d = ((NH * NH) * (m_sq - 1.0) + 1.0);
|
||||
return m_sq / (d * d);
|
||||
// from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||
float a_sq = exp2(gloss * -13.0 + 1.0);
|
||||
float d = ((NH * NH) * (a_sq - 1.0) + 1.0);
|
||||
return a_sq / (d * d);
|
||||
}
|
||||
|
||||
float CalcFresnel(float EH)
|
||||
{
|
||||
#if 1
|
||||
// From http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
|
||||
// not accurate, but fast
|
||||
return exp2(-10.0 * EH);
|
||||
#elif 0
|
||||
// From http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/
|
||||
return exp2((-5.55473 * EH - 6.98316) * EH);
|
||||
#elif 0
|
||||
|
@ -201,42 +200,48 @@ float CalcFresnel(float EH)
|
|||
|
||||
return blend;
|
||||
#else
|
||||
return pow(1.0 - NH, 5.0);
|
||||
return pow(1.0 - EH, 5.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
float CalcVisibility(float NH, float NL, float NE, float EH, float shininess)
|
||||
float CalcVisibility(float NH, float NL, float NE, float EH, float gloss)
|
||||
{
|
||||
#if 0
|
||||
float geo = 2.0 * NH * min(NE, NL);
|
||||
geo /= max(EH, geo);
|
||||
|
||||
return geo;
|
||||
#else
|
||||
// Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes.pdf
|
||||
// NL, NE in numerator factored out from cook-torrance
|
||||
#if 1
|
||||
// From http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
|
||||
float k = min(1.0, gloss + 0.545);
|
||||
return 1.0 / (k * EH * EH + (1.0 - k));
|
||||
#elif 0
|
||||
float roughness = exp2(gloss * -6.5);
|
||||
|
||||
#if defined(USE_GGX)
|
||||
float roughness = sqrt(2.0 / (shininess + 2.0));
|
||||
float k = (roughness + 1.0);
|
||||
// From http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||
float k = roughness + 1.0;
|
||||
k *= k * 0.125;
|
||||
#else
|
||||
float k = 2.0 / sqrt(3.1415926535 * (shininess + 2.0));
|
||||
float k = roughness;
|
||||
#endif
|
||||
// Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||
// NL, NE in numerator factored out from cook-torrance
|
||||
float k2 = 1.0 - k;
|
||||
|
||||
float invGeo1 = NL * k2 + k;
|
||||
float invGeo2 = NE * k2 + k;
|
||||
|
||||
return 1.0 / (invGeo1 * invGeo2);
|
||||
#endif
|
||||
#else
|
||||
float geo = 2.0 * NH * min(NE, NL);
|
||||
geo /= max(EH, geo);
|
||||
|
||||
return geo;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float shininess)
|
||||
vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float gloss, float shininess)
|
||||
{
|
||||
float blinn = CalcBlinn(NH, shininess);
|
||||
vec3 fSpecular = mix(specular, vec3(1.0), CalcFresnel(EH));
|
||||
float vis = CalcVisibility(NH, NL, NE, EH, shininess);
|
||||
float vis = CalcVisibility(NH, NL, NE, EH, gloss);
|
||||
|
||||
#if defined(USE_BLINN)
|
||||
// Normalized Blinn-Phong
|
||||
|
@ -261,60 +266,66 @@ vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float s
|
|||
return vec3(0.0);
|
||||
}
|
||||
|
||||
|
||||
float CalcLightAttenuation(vec3 dir, float sqrRadius)
|
||||
{
|
||||
// point light at >0 radius, directional otherwise
|
||||
float point = float(sqrRadius > 0.0);
|
||||
|
||||
// inverse square light
|
||||
float attenuation = sqrRadius / dot(dir, dir);
|
||||
|
||||
// zero light at radius, approximating q3 style
|
||||
// also don't attenuate directional light
|
||||
attenuation = (0.5 * attenuation - 1.5) * point + 1.0;
|
||||
|
||||
// clamp attenuation
|
||||
#if defined(NO_LIGHT_CLAMP)
|
||||
attenuation = max(attenuation, 0.0);
|
||||
#else
|
||||
attenuation = clamp(attenuation, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
return attenuation;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 L, N, E, H;
|
||||
float NL, NH, NE, EH;
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
mat3 tangentToWorld = mat3(var_Tangent, var_Bitangent, var_Normal);
|
||||
mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz);
|
||||
#endif
|
||||
|
||||
#if defined(USE_DELUXEMAP)
|
||||
L = (2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0));
|
||||
L = (2.0 * texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(1.0));
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
L = L * tangentToWorld;
|
||||
L = L * tangentToWorld;
|
||||
#endif
|
||||
#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
L = var_LightDir.xyz;
|
||||
#endif
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
E = normalize(var_ViewDir);
|
||||
E = normalize(vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w));
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHTMAP)
|
||||
vec4 lightSample = texture2D(u_LightMap, var_LightTex).rgba;
|
||||
vec4 lightSample = texture2D(u_LightMap, var_TexCoords.zw).rgba;
|
||||
#if defined(RGBM_LIGHTMAP)
|
||||
lightSample.rgb *= 32.0 * lightSample.a;
|
||||
#endif
|
||||
vec3 lightColor = lightSample.rgb;
|
||||
#elif defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
|
||||
// inverse square light
|
||||
float attenuation = u_LightRadius * u_LightRadius / dot(L, L);
|
||||
|
||||
// zero light at radius, approximating q3 style
|
||||
attenuation = 0.5 * attenuation - 0.5;
|
||||
//attenuation = 0.0697168 * attenuation;
|
||||
//attenuation *= step(0.294117, attenuation);
|
||||
|
||||
// clamp attenuation
|
||||
#if defined(NO_LIGHT_CLAMP)
|
||||
attenuation *= step(0.0, attenuation);
|
||||
#else
|
||||
attenuation = clamp(attenuation, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
// don't attenuate directional light
|
||||
attenuation = (attenuation - 1.0) * var_LightDir.w + 1.0;
|
||||
|
||||
vec3 lightColor = u_DirectedLight * attenuation;
|
||||
vec3 lightColor = u_DirectedLight * CalcLightAttenuation(L, var_LightDir.w);
|
||||
vec3 ambientColor = u_AmbientLight;
|
||||
#elif defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
vec3 lightColor = var_lightColor;
|
||||
vec3 lightColor = var_LightColor;
|
||||
#endif
|
||||
|
||||
vec2 texCoords = var_DiffuseTex;
|
||||
|
||||
vec2 texCoords = var_TexCoords.xy;
|
||||
|
||||
#if defined(USE_PARALLAXMAP)
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
|
@ -329,13 +340,12 @@ void main()
|
|||
#endif
|
||||
|
||||
vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
|
||||
#if defined(USE_GAMMA2_TEXTURES)
|
||||
diffuse.rgb *= diffuse.rgb;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
|
||||
#if defined(USE_LINEAR_LIGHT)
|
||||
diffuse.rgb *= diffuse.rgb;
|
||||
#endif
|
||||
|
||||
#if defined(USE_NORMALMAP)
|
||||
#if defined(SWIZZLE_NORMALMAP)
|
||||
N.xy = 2.0 * texture2D(u_NormalMap, texCoords).ag - vec2(1.0);
|
||||
|
@ -349,7 +359,7 @@ void main()
|
|||
#elif defined(USE_TANGENT_SPACE_LIGHT)
|
||||
N = vec3(0.0, 0.0, 1.0);
|
||||
#else
|
||||
N = normalize(var_Normal);
|
||||
N = normalize(var_Normal.xyz);
|
||||
#endif
|
||||
|
||||
L = normalize(L);
|
||||
|
@ -362,7 +372,7 @@ void main()
|
|||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
shadowValue *= step(0.0, var_PrimaryLightDir.z);
|
||||
#else
|
||||
shadowValue *= step(0.0, dot(var_Normal, var_PrimaryLightDir));
|
||||
shadowValue *= step(0.0, dot(var_Normal.xyz, var_PrimaryLightDir.xyz));
|
||||
#endif
|
||||
|
||||
#if defined(SHADOWMAP_MODULATE)
|
||||
|
@ -371,7 +381,7 @@ void main()
|
|||
|
||||
#if 0
|
||||
// Only shadow when the world light is parallel to the primary light
|
||||
shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir), 0.0, 1.0);
|
||||
shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir.xyz), 0.0, 1.0);
|
||||
#endif
|
||||
lightColor = mix(shadowColor, lightColor, shadowValue);
|
||||
#endif
|
||||
|
@ -383,7 +393,7 @@ void main()
|
|||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
float surfNL = L.z;
|
||||
#else
|
||||
float surfNL = clamp(dot(var_Normal, L), 0.0, 1.0);
|
||||
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
// Scale the incoming light to compensate for the baked-in light angle
|
||||
|
@ -402,9 +412,9 @@ void main()
|
|||
|
||||
#if defined(USE_SPECULARMAP)
|
||||
vec4 specular = texture2D(u_SpecularMap, texCoords);
|
||||
#if defined(USE_LINEAR_LIGHT)
|
||||
#if defined(USE_GAMMA2_TEXTURES)
|
||||
specular.rgb *= specular.rgb;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
vec4 specular = vec4(1.0);
|
||||
#endif
|
||||
|
@ -413,7 +423,6 @@ void main()
|
|||
|
||||
float gloss = specular.a;
|
||||
float shininess = exp2(gloss * 13.0);
|
||||
float localOcclusion = clamp((diffuse.r + diffuse.g + diffuse.b) * 16.0f, 0.0, 1.0);
|
||||
|
||||
#if defined(SPECULAR_IS_METALLIC)
|
||||
// diffuse is actually base color, and red of specular is metallicness
|
||||
|
@ -430,10 +439,12 @@ void main()
|
|||
reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess);
|
||||
|
||||
#if defined(r_deluxeSpecular) || defined(USE_LIGHT_VECTOR)
|
||||
float adjGloss = gloss;
|
||||
float adjShininess = shininess;
|
||||
|
||||
#if !defined(USE_LIGHT_VECTOR)
|
||||
adjShininess = exp2(gloss * r_deluxeSpecular * 13.0);
|
||||
adjGloss *= r_deluxeSpecular;
|
||||
adjShininess = exp2(adjGloss * 13.0);
|
||||
#endif
|
||||
|
||||
H = normalize(L + E);
|
||||
|
@ -442,9 +453,9 @@ void main()
|
|||
NH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
#if !defined(USE_LIGHT_VECTOR)
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjShininess) * r_deluxeSpecular * localOcclusion;
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess) * r_deluxeSpecular;
|
||||
#else
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjShininess) * localOcclusion;
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -461,24 +472,20 @@ void main()
|
|||
|
||||
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb;
|
||||
|
||||
#if defined(USE_LINEAR_LIGHT)
|
||||
cubeLightColor *= cubeLightColor;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHTMAP)
|
||||
cubeLightColor *= lightSample.rgb;
|
||||
#elif defined (USE_LIGHT_VERTEX)
|
||||
cubeLightColor *= var_lightColor;
|
||||
cubeLightColor *= var_LightColor;
|
||||
#else
|
||||
cubeLightColor *= lightColor * NL + ambientColor;
|
||||
#endif
|
||||
|
||||
//gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb;
|
||||
gl_FragColor.rgb += cubeLightColor * reflectance * localOcclusion;
|
||||
gl_FragColor.rgb += cubeLightColor * reflectance;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT)
|
||||
L = normalize(var_PrimaryLightDir);
|
||||
L = var_PrimaryLightDir.xyz; //normalize(var_PrimaryLightDir.xyz);
|
||||
NL = clamp(dot(N, L), 0.0, 1.0);
|
||||
|
||||
H = normalize(L + E);
|
||||
|
@ -486,17 +493,15 @@ void main()
|
|||
NH = clamp(dot(N, H), 0.0, 1.0);
|
||||
|
||||
reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess);
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, shininess);
|
||||
reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, gloss, shininess);
|
||||
|
||||
lightColor = u_PrimaryLightColor; // * CalcLightAttenuation(L, u_PrimaryLightDir.w);
|
||||
|
||||
#if defined(USE_SHADOWMAP)
|
||||
reflectance *= shadowValue;
|
||||
lightColor *= shadowValue;
|
||||
#endif
|
||||
|
||||
gl_FragColor.rgb += u_PrimaryLightColor * reflectance * NL;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LINEAR_LIGHT)
|
||||
gl_FragColor.rgb = sqrt(gl_FragColor.rgb);
|
||||
gl_FragColor.rgb += lightColor * reflectance * NL;
|
||||
#endif
|
||||
|
||||
gl_FragColor.a = diffuse.a;
|
||||
|
|
|
@ -22,6 +22,7 @@ attribute vec3 attr_LightDirection;
|
|||
|
||||
#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
||||
uniform vec3 u_ViewOrigin;
|
||||
uniform vec3 u_LocalViewOrigin;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCGEN)
|
||||
|
@ -49,37 +50,30 @@ uniform float u_VertexLerp;
|
|||
|
||||
#if defined(USE_LIGHT_VECTOR)
|
||||
uniform vec4 u_LightOrigin;
|
||||
#if defined(USE_FAST_LIGHT)
|
||||
uniform vec3 u_DirectedLight;
|
||||
uniform vec3 u_AmbientLight;
|
||||
uniform float u_LightRadius;
|
||||
uniform vec3 u_DirectedLight;
|
||||
#if defined(USE_FAST_LIGHT)
|
||||
uniform vec3 u_AmbientLight;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
uniform vec4 u_PrimaryLightOrigin;
|
||||
uniform float u_PrimaryLightRadius;
|
||||
#endif
|
||||
|
||||
varying vec2 var_DiffuseTex;
|
||||
|
||||
#if defined(USE_LIGHTMAP)
|
||||
varying vec2 var_LightTex;
|
||||
#endif
|
||||
|
||||
#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
|
||||
varying vec3 var_ViewDir;
|
||||
#endif
|
||||
varying vec4 var_TexCoords;
|
||||
|
||||
varying vec4 var_Color;
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
varying vec3 var_Normal;
|
||||
varying vec3 var_Tangent;
|
||||
varying vec3 var_Bitangent;
|
||||
varying vec4 var_Normal;
|
||||
varying vec4 var_Tangent;
|
||||
varying vec4 var_Bitangent;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
varying vec3 var_lightColor;
|
||||
varying vec3 var_LightColor;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
|
||||
|
@ -87,7 +81,7 @@ varying vec4 var_LightDir;
|
|||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
varying vec3 var_PrimaryLightDir;
|
||||
varying vec4 var_PrimaryLightDir;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TCGEN)
|
||||
|
@ -101,7 +95,7 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3
|
|||
}
|
||||
else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
|
||||
{
|
||||
vec3 viewer = normalize(u_ViewOrigin - position);
|
||||
vec3 viewer = normalize(u_LocalViewOrigin - position);
|
||||
tex = -reflect(viewer, normal).yz * vec2(0.5, -0.5) + 0.5;
|
||||
}
|
||||
else if (TCGen == TCGEN_VECTOR)
|
||||
|
@ -120,7 +114,7 @@ vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
|
|||
float phase = offTurb.w;
|
||||
vec2 st2 = vec2(dot(st, texMatrix.xz), dot(st, texMatrix.yw)) + offTurb.xy;
|
||||
|
||||
vec3 offsetPos = position * 0.0009765625;
|
||||
vec3 offsetPos = position / 1024.0;
|
||||
offsetPos.x += offsetPos.z;
|
||||
|
||||
vec2 texOffset = sin((offsetPos.xy + vec2(phase)) * 2.0 * M_PI);
|
||||
|
@ -130,6 +124,29 @@ vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
|
|||
#endif
|
||||
|
||||
|
||||
float CalcLightAttenuation(vec3 dir, float sqrRadius)
|
||||
{
|
||||
// point light at >0 radius, directional otherwise
|
||||
float point = float(sqrRadius > 0.0);
|
||||
|
||||
// inverse square light
|
||||
float attenuation = sqrRadius / dot(dir, dir);
|
||||
|
||||
// zero light at radius, approximating q3 style
|
||||
// also don't attenuate directional light
|
||||
attenuation = (0.5 * attenuation - 1.5) * point + 1.0;
|
||||
|
||||
// clamp attenuation
|
||||
#if defined(NO_LIGHT_CLAMP)
|
||||
attenuation = max(attenuation, 0.0);
|
||||
#else
|
||||
attenuation = clamp(attenuation, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
return attenuation;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(USE_VERTEX_ANIMATION)
|
||||
|
@ -151,9 +168,9 @@ void main()
|
|||
#endif
|
||||
|
||||
#if defined(USE_TCMOD)
|
||||
var_DiffuseTex = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
|
||||
var_TexCoords.xy = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
|
||||
#else
|
||||
var_DiffuseTex = texCoords;
|
||||
var_TexCoords.xy = texCoords;
|
||||
#endif
|
||||
|
||||
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
|
||||
|
@ -167,84 +184,67 @@ void main()
|
|||
|
||||
#if defined(USE_LIGHT_VECTOR)
|
||||
vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w);
|
||||
#elif defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
|
||||
#elif defined(USE_LIGHT) && !defined(USE_DELUXEMAP)
|
||||
vec3 L = attr_LightDirection;
|
||||
#if defined(USE_MODELMATRIX)
|
||||
L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
|
||||
L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHTMAP)
|
||||
var_LightTex = attr_TexCoord1.st;
|
||||
var_TexCoords.zw = attr_TexCoord1.st;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
var_lightColor = u_VertColor.rgb * attr_Color.rgb;
|
||||
var_Color.rgb = vec3(1.0);
|
||||
var_Color.a = u_VertColor.a * attr_Color.a + u_BaseColor.a;
|
||||
#else
|
||||
var_Color = u_VertColor * attr_Color + u_BaseColor;
|
||||
#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
|
||||
var_LightColor = var_Color.rgb;
|
||||
var_Color.rgb = vec3(1.0);
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)
|
||||
// inverse square light
|
||||
float attenuation = u_LightRadius * u_LightRadius / dot(L, L);
|
||||
|
||||
// zero light at radius, approximating q3 style
|
||||
attenuation = 0.5 * attenuation - 0.5;
|
||||
//attenuation = 0.0697168 * attenuation;
|
||||
//attenuation *= step(0.294117, attenuation);
|
||||
|
||||
// clamp attenuation
|
||||
#if defined(NO_LIGHT_CLAMP)
|
||||
attenuation *= step(0.0, attenuation);
|
||||
#else
|
||||
attenuation = clamp(attenuation, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
// don't attenuate directional light
|
||||
attenuation = (attenuation - 1.0) * u_LightOrigin.w + 1.0;
|
||||
|
||||
float attenuation = CalcLightAttenuation(L, u_LightRadius * u_LightRadius);
|
||||
float NL = clamp(dot(normal, normalize(L)), 0.0, 1.0);
|
||||
|
||||
var_Color.rgb *= u_DirectedLight * attenuation * NL + u_AmbientLight;
|
||||
#endif
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
var_Normal = normal;
|
||||
var_Tangent = tangent;
|
||||
var_Bitangent = bitangent;
|
||||
#endif
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
var_PrimaryLightDir = (u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w));
|
||||
var_PrimaryLightDir.xyz = u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w);
|
||||
var_PrimaryLightDir.w = u_PrimaryLightRadius * u_PrimaryLightRadius;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
|
||||
#if defined(USE_LIGHT_VECTOR)
|
||||
var_LightDir = vec4(L, u_LightOrigin.w);
|
||||
var_LightDir = vec4(L, u_LightRadius * u_LightRadius);
|
||||
#else
|
||||
var_LightDir = vec4(L, 0.0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
|
||||
var_ViewDir = (u_ViewOrigin - position);
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
vec3 viewDir = u_ViewOrigin - position;
|
||||
#endif
|
||||
|
||||
#if defined(USE_TANGENT_SPACE_LIGHT)
|
||||
mat3 tangentToWorld = mat3(tangent, bitangent, normal);
|
||||
|
||||
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
||||
var_PrimaryLightDir = var_PrimaryLightDir * tangentToWorld;
|
||||
var_PrimaryLightDir.xyz = var_PrimaryLightDir.xyz * tangentToWorld;
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
|
||||
var_LightDir.xyz = var_LightDir.xyz * tangentToWorld;
|
||||
#endif
|
||||
|
||||
#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
|
||||
var_ViewDir = var_ViewDir * tangentToWorld;
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
viewDir = viewDir * tangentToWorld;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP)
|
||||
// store view direction in tangent space to save on varyings
|
||||
var_Normal = vec4(normal, viewDir.x);
|
||||
var_Tangent = vec4(tangent, viewDir.y);
|
||||
var_Bitangent = vec4(bitangent, viewDir.z);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
|
|||
|
||||
if (r_hdr->integer)
|
||||
{
|
||||
if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel)
|
||||
if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer)
|
||||
textureInternalFormat = GL_RGBA16F_ARB;
|
||||
else
|
||||
textureInternalFormat = GL_RGBA8;
|
||||
|
@ -410,7 +410,7 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
|
|||
|
||||
VectorScale(color, lightScale, color);
|
||||
|
||||
if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel)
|
||||
if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer)
|
||||
ColorToRGBA16F(color, (unsigned short *)(&image[j*8]));
|
||||
else
|
||||
ColorToRGBM(color, &image[j*4]);
|
||||
|
@ -652,7 +652,7 @@ ParseFace
|
|||
*/
|
||||
static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf, int *indexes ) {
|
||||
int i, j;
|
||||
srfSurfaceFace_t *cv;
|
||||
srfBspSurface_t *cv;
|
||||
srfTriangle_t *tri;
|
||||
int numVerts, numTriangles, badTriangles;
|
||||
int realLightmapNum;
|
||||
|
@ -767,12 +767,12 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
|
|||
|
||||
// take the plane information from the lightmap vector
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
cv->plane.normal[i] = LittleFloat( ds->lightmapVecs[2][i] );
|
||||
cv->cullPlane.normal[i] = LittleFloat( ds->lightmapVecs[2][i] );
|
||||
}
|
||||
cv->plane.dist = DotProduct( cv->verts[0].xyz, cv->plane.normal );
|
||||
SetPlaneSignbits( &cv->plane );
|
||||
cv->plane.type = PlaneTypeForNormal( cv->plane.normal );
|
||||
surf->cullinfo.plane = cv->plane;
|
||||
cv->cullPlane.dist = DotProduct( cv->verts[0].xyz, cv->cullPlane.normal );
|
||||
SetPlaneSignbits( &cv->cullPlane );
|
||||
cv->cullPlane.type = PlaneTypeForNormal( cv->cullPlane.normal );
|
||||
surf->cullinfo.plane = cv->cullPlane;
|
||||
|
||||
surf->data = (surfaceType_t *)cv;
|
||||
|
||||
|
@ -800,7 +800,7 @@ ParseMesh
|
|||
===============
|
||||
*/
|
||||
static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf ) {
|
||||
srfGridMesh_t *grid;
|
||||
srfBspSurface_t *grid;
|
||||
int i, j;
|
||||
int width, height, numPoints;
|
||||
srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE];
|
||||
|
@ -903,7 +903,7 @@ ParseTriSurf
|
|||
===============
|
||||
*/
|
||||
static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf, int *indexes ) {
|
||||
srfTriangles_t *cv;
|
||||
srfBspSurface_t *cv;
|
||||
srfTriangle_t *tri;
|
||||
int i, j;
|
||||
int numVerts, numTriangles, badTriangles;
|
||||
|
@ -1065,7 +1065,7 @@ R_MergedWidthPoints
|
|||
returns true if there are grid points merged on a width edge
|
||||
=================
|
||||
*/
|
||||
int R_MergedWidthPoints(srfGridMesh_t *grid, int offset) {
|
||||
int R_MergedWidthPoints(srfBspSurface_t *grid, int offset) {
|
||||
int i, j;
|
||||
|
||||
for (i = 1; i < grid->width-1; i++) {
|
||||
|
@ -1086,7 +1086,7 @@ R_MergedHeightPoints
|
|||
returns true if there are grid points merged on a height edge
|
||||
=================
|
||||
*/
|
||||
int R_MergedHeightPoints(srfGridMesh_t *grid, int offset) {
|
||||
int R_MergedHeightPoints(srfBspSurface_t *grid, int offset) {
|
||||
int i, j;
|
||||
|
||||
for (i = 1; i < grid->height-1; i++) {
|
||||
|
@ -1109,13 +1109,13 @@ NOTE: never sync LoD through grid edges with merged points!
|
|||
FIXME: write generalized version that also avoids cracks between a patch and one that meets half way?
|
||||
=================
|
||||
*/
|
||||
void R_FixSharedVertexLodError_r( int start, srfGridMesh_t *grid1 ) {
|
||||
void R_FixSharedVertexLodError_r( int start, srfBspSurface_t *grid1 ) {
|
||||
int j, k, l, m, n, offset1, offset2, touch;
|
||||
srfGridMesh_t *grid2;
|
||||
srfBspSurface_t *grid2;
|
||||
|
||||
for ( j = start; j < s_worldData.numsurfaces; j++ ) {
|
||||
//
|
||||
grid2 = (srfGridMesh_t *) s_worldData.surfaces[j].data;
|
||||
grid2 = (srfBspSurface_t *) s_worldData.surfaces[j].data;
|
||||
// if this surface is not a grid
|
||||
if ( grid2->surfaceType != SF_GRID ) continue;
|
||||
// if the LOD errors are already fixed for this patch
|
||||
|
@ -1223,11 +1223,11 @@ If this is not the case this function will still do its job but won't fix the hi
|
|||
*/
|
||||
void R_FixSharedVertexLodError( void ) {
|
||||
int i;
|
||||
srfGridMesh_t *grid1;
|
||||
srfBspSurface_t *grid1;
|
||||
|
||||
for ( i = 0; i < s_worldData.numsurfaces; i++ ) {
|
||||
//
|
||||
grid1 = (srfGridMesh_t *) s_worldData.surfaces[i].data;
|
||||
grid1 = (srfBspSurface_t *) s_worldData.surfaces[i].data;
|
||||
// if this surface is not a grid
|
||||
if ( grid1->surfaceType != SF_GRID )
|
||||
continue;
|
||||
|
@ -1249,11 +1249,11 @@ R_StitchPatches
|
|||
*/
|
||||
int R_StitchPatches( int grid1num, int grid2num ) {
|
||||
float *v1, *v2;
|
||||
srfGridMesh_t *grid1, *grid2;
|
||||
srfBspSurface_t *grid1, *grid2;
|
||||
int k, l, m, n, offset1, offset2, row, column;
|
||||
|
||||
grid1 = (srfGridMesh_t *) s_worldData.surfaces[grid1num].data;
|
||||
grid2 = (srfGridMesh_t *) s_worldData.surfaces[grid2num].data;
|
||||
grid1 = (srfBspSurface_t *) s_worldData.surfaces[grid1num].data;
|
||||
grid2 = (srfBspSurface_t *) s_worldData.surfaces[grid2num].data;
|
||||
for (n = 0; n < 2; n++) {
|
||||
//
|
||||
if (n) offset1 = (grid1->height-1) * grid1->width;
|
||||
|
@ -1664,13 +1664,13 @@ might still appear at that side.
|
|||
*/
|
||||
int R_TryStitchingPatch( int grid1num ) {
|
||||
int j, numstitches;
|
||||
srfGridMesh_t *grid1, *grid2;
|
||||
srfBspSurface_t *grid1, *grid2;
|
||||
|
||||
numstitches = 0;
|
||||
grid1 = (srfGridMesh_t *) s_worldData.surfaces[grid1num].data;
|
||||
grid1 = (srfBspSurface_t *) s_worldData.surfaces[grid1num].data;
|
||||
for ( j = 0; j < s_worldData.numsurfaces; j++ ) {
|
||||
//
|
||||
grid2 = (srfGridMesh_t *) s_worldData.surfaces[j].data;
|
||||
grid2 = (srfBspSurface_t *) s_worldData.surfaces[j].data;
|
||||
// if this surface is not a grid
|
||||
if ( grid2->surfaceType != SF_GRID ) continue;
|
||||
// grids in the same LOD group should have the exact same lod radius
|
||||
|
@ -1695,7 +1695,7 @@ R_StitchAllPatches
|
|||
*/
|
||||
void R_StitchAllPatches( void ) {
|
||||
int i, stitched, numstitches;
|
||||
srfGridMesh_t *grid1;
|
||||
srfBspSurface_t *grid1;
|
||||
|
||||
numstitches = 0;
|
||||
do
|
||||
|
@ -1703,7 +1703,7 @@ void R_StitchAllPatches( void ) {
|
|||
stitched = qfalse;
|
||||
for ( i = 0; i < s_worldData.numsurfaces; i++ ) {
|
||||
//
|
||||
grid1 = (srfGridMesh_t *) s_worldData.surfaces[i].data;
|
||||
grid1 = (srfBspSurface_t *) s_worldData.surfaces[i].data;
|
||||
// if this surface is not a grid
|
||||
if ( grid1->surfaceType != SF_GRID )
|
||||
continue;
|
||||
|
@ -1728,11 +1728,11 @@ R_MovePatchSurfacesToHunk
|
|||
*/
|
||||
void R_MovePatchSurfacesToHunk(void) {
|
||||
int i, size;
|
||||
srfGridMesh_t *grid, *hunkgrid;
|
||||
srfBspSurface_t *grid, *hunkgrid;
|
||||
|
||||
for ( i = 0; i < s_worldData.numsurfaces; i++ ) {
|
||||
//
|
||||
grid = (srfGridMesh_t *) s_worldData.surfaces[i].data;
|
||||
grid = (srfBspSurface_t *) s_worldData.surfaces[i].data;
|
||||
// if this surface is not a grid
|
||||
if ( grid->surfaceType != SF_GRID )
|
||||
continue;
|
||||
|
@ -1831,10 +1831,10 @@ static void CopyVert(const srfVert_t * in, srfVert_t * out)
|
|||
|
||||
/*
|
||||
===============
|
||||
R_CreateWorldVBO
|
||||
R_CreateWorldVBOs
|
||||
===============
|
||||
*/
|
||||
static void R_CreateWorldVBO(void)
|
||||
static void R_CreateWorldVBOs(void)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
|
@ -1844,73 +1844,32 @@ static void R_CreateWorldVBO(void)
|
|||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
|
||||
int numSurfaces;
|
||||
msurface_t *surface;
|
||||
int numSortedSurfaces, numSurfaces;
|
||||
msurface_t *surface, **firstSurf, **lastSurf, **currSurf;
|
||||
msurface_t **surfacesSorted;
|
||||
|
||||
VBO_t *vbo;
|
||||
IBO_t *ibo;
|
||||
|
||||
int startTime, endTime;
|
||||
|
||||
startTime = ri.Milliseconds();
|
||||
|
||||
numVerts = 0;
|
||||
numTriangles = 0;
|
||||
numSurfaces = 0;
|
||||
for(k = 0, surface = &s_worldData.surfaces[0]; k < s_worldData.numsurfaces /* s_worldData.numWorldSurfaces */; k++, surface++)
|
||||
// count surfaces
|
||||
numSortedSurfaces = 0;
|
||||
for(surface = &s_worldData.surfaces[0]; surface < &s_worldData.surfaces[s_worldData.numsurfaces]; surface++)
|
||||
{
|
||||
if(*surface->data == SF_FACE)
|
||||
if(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES)
|
||||
{
|
||||
srfSurfaceFace_t *face = (srfSurfaceFace_t *) surface->data;
|
||||
|
||||
if(face->numVerts)
|
||||
numVerts += face->numVerts;
|
||||
|
||||
if(face->numTriangles)
|
||||
numTriangles += face->numTriangles;
|
||||
|
||||
numSurfaces++;
|
||||
}
|
||||
else if(*surface->data == SF_GRID)
|
||||
{
|
||||
srfGridMesh_t *grid = (srfGridMesh_t *) surface->data;
|
||||
|
||||
if(grid->numVerts)
|
||||
numVerts += grid->numVerts;
|
||||
|
||||
if(grid->numTriangles)
|
||||
numTriangles += grid->numTriangles;
|
||||
|
||||
numSurfaces++;
|
||||
}
|
||||
else if(*surface->data == SF_TRIANGLES)
|
||||
{
|
||||
srfTriangles_t *tri = (srfTriangles_t *) surface->data;
|
||||
|
||||
if(tri->numVerts)
|
||||
numVerts += tri->numVerts;
|
||||
|
||||
if(tri->numTriangles)
|
||||
numTriangles += tri->numTriangles;
|
||||
|
||||
numSurfaces++;
|
||||
numSortedSurfaces++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!numVerts || !numTriangles)
|
||||
return;
|
||||
|
||||
ri.Printf(PRINT_ALL, "...calculating world VBO ( %i verts %i tris )\n", numVerts, numTriangles);
|
||||
|
||||
// create arrays
|
||||
|
||||
verts = ri.Hunk_AllocateTempMemory(numVerts * sizeof(srfVert_t));
|
||||
|
||||
triangles = ri.Hunk_AllocateTempMemory(numTriangles * sizeof(srfTriangle_t));
|
||||
|
||||
// presort surfaces
|
||||
surfacesSorted = ri.Malloc(numSurfaces * sizeof(*surfacesSorted));
|
||||
surfacesSorted = ri.Malloc(numSortedSurfaces * sizeof(*surfacesSorted));
|
||||
|
||||
j = 0;
|
||||
for(k = 0, surface = &s_worldData.surfaces[0]; k < s_worldData.numsurfaces; k++, surface++)
|
||||
for(surface = &s_worldData.surfaces[0]; surface < &s_worldData.surfaces[s_worldData.numsurfaces]; surface++)
|
||||
{
|
||||
if(*surface->data == SF_FACE || *surface->data == SF_GRID || *surface->data == SF_TRIANGLES)
|
||||
{
|
||||
|
@ -1918,211 +1877,169 @@ static void R_CreateWorldVBO(void)
|
|||
}
|
||||
}
|
||||
|
||||
qsort(surfacesSorted, numSurfaces, sizeof(*surfacesSorted), BSPSurfaceCompare);
|
||||
qsort(surfacesSorted, numSortedSurfaces, sizeof(*surfacesSorted), BSPSurfaceCompare);
|
||||
|
||||
// set up triangle indices
|
||||
numVerts = 0;
|
||||
numTriangles = 0;
|
||||
for(k = 0, surface = surfacesSorted[k]; k < numSurfaces; k++, surface = surfacesSorted[k])
|
||||
k = 0;
|
||||
for(firstSurf = lastSurf = surfacesSorted; firstSurf < &surfacesSorted[numSortedSurfaces]; firstSurf = lastSurf)
|
||||
{
|
||||
if(*surface->data == SF_FACE)
|
||||
while(lastSurf < &surfacesSorted[numSortedSurfaces] && (*lastSurf)->shader->sortedIndex == (*firstSurf)->shader->sortedIndex)
|
||||
lastSurf++;
|
||||
|
||||
numVerts = 0;
|
||||
numTriangles = 0;
|
||||
numSurfaces = 0;
|
||||
for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)
|
||||
{
|
||||
srfSurfaceFace_t *srf = (srfSurfaceFace_t *) surface->data;
|
||||
srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data;
|
||||
|
||||
srf->firstIndex = numTriangles * 3;
|
||||
|
||||
if(srf->numTriangles)
|
||||
switch (bspSurf->surfaceType)
|
||||
{
|
||||
srfTriangle_t *tri;
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
if(bspSurf->numVerts)
|
||||
numVerts += bspSurf->numVerts;
|
||||
|
||||
srf->minIndex = numVerts + srf->triangles->indexes[0];
|
||||
srf->maxIndex = numVerts + srf->triangles->indexes[0];
|
||||
if(bspSurf->numTriangles)
|
||||
numTriangles += bspSurf->numTriangles;
|
||||
|
||||
for(i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
numSurfaces++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!numVerts || !numTriangles)
|
||||
continue;
|
||||
|
||||
ri.Printf(PRINT_ALL, "...calculating world VBO %d ( %i verts %i tris )\n", k, numVerts, numTriangles);
|
||||
|
||||
// create arrays
|
||||
verts = ri.Hunk_AllocateTempMemory(numVerts * sizeof(srfVert_t));
|
||||
triangles = ri.Hunk_AllocateTempMemory(numTriangles * sizeof(srfTriangle_t));
|
||||
|
||||
// set up triangle indices
|
||||
numVerts = 0;
|
||||
numTriangles = 0;
|
||||
for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)
|
||||
{
|
||||
srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data;
|
||||
|
||||
switch (bspSurf->surfaceType)
|
||||
{
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
bspSurf->firstIndex = numTriangles * 3;
|
||||
|
||||
if(bspSurf->numTriangles)
|
||||
{
|
||||
triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j];
|
||||
srf->minIndex = MIN(srf->minIndex, numVerts + tri->indexes[j]);
|
||||
srf->maxIndex = MAX(srf->maxIndex, numVerts + tri->indexes[j]);
|
||||
srfTriangle_t *tri;
|
||||
|
||||
bspSurf->minIndex = numVerts + bspSurf->triangles->indexes[0];
|
||||
bspSurf->maxIndex = numVerts + bspSurf->triangles->indexes[0];
|
||||
|
||||
for(i = 0, tri = bspSurf->triangles; i < bspSurf->numTriangles; i++, tri++)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j];
|
||||
bspSurf->minIndex = MIN(bspSurf->minIndex, numVerts + tri->indexes[j]);
|
||||
bspSurf->maxIndex = MAX(bspSurf->maxIndex, numVerts + tri->indexes[j]);
|
||||
}
|
||||
}
|
||||
|
||||
numTriangles += bspSurf->numTriangles;
|
||||
}
|
||||
}
|
||||
|
||||
numTriangles += srf->numTriangles;
|
||||
if(bspSurf->numVerts)
|
||||
numVerts += bspSurf->numVerts;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(srf->numVerts)
|
||||
numVerts += srf->numVerts;
|
||||
}
|
||||
else if(*surface->data == SF_GRID)
|
||||
|
||||
// build vertices
|
||||
numVerts = 0;
|
||||
for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)
|
||||
{
|
||||
srfGridMesh_t *srf = (srfGridMesh_t *) surface->data;
|
||||
srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data;
|
||||
|
||||
srf->firstIndex = numTriangles * 3;
|
||||
|
||||
if(srf->numTriangles)
|
||||
switch (bspSurf->surfaceType)
|
||||
{
|
||||
srfTriangle_t *tri;
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
bspSurf->firstVert = numVerts;
|
||||
|
||||
srf->minIndex = numVerts + srf->triangles->indexes[0];
|
||||
srf->maxIndex = numVerts + srf->triangles->indexes[0];
|
||||
|
||||
for(i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
if(bspSurf->numVerts)
|
||||
{
|
||||
triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j];
|
||||
srf->minIndex = MIN(srf->minIndex, numVerts + tri->indexes[j]);
|
||||
srf->maxIndex = MAX(srf->maxIndex, numVerts + tri->indexes[j]);
|
||||
for(i = 0; i < bspSurf->numVerts; i++)
|
||||
{
|
||||
CopyVert(&bspSurf->verts[i], &verts[numVerts + i]);
|
||||
}
|
||||
|
||||
numVerts += bspSurf->numVerts;
|
||||
}
|
||||
}
|
||||
|
||||
numTriangles += srf->numTriangles;
|
||||
}
|
||||
break;
|
||||
|
||||
if(srf->numVerts)
|
||||
numVerts += srf->numVerts;
|
||||
}
|
||||
else if(*surface->data == SF_TRIANGLES)
|
||||
{
|
||||
srfTriangles_t *srf = (srfTriangles_t *) surface->data;
|
||||
|
||||
srf->firstIndex = numTriangles * 3;
|
||||
|
||||
if(srf->numTriangles)
|
||||
{
|
||||
srfTriangle_t *tri;
|
||||
|
||||
srf->minIndex = numVerts + srf->triangles->indexes[0];
|
||||
srf->maxIndex = numVerts + srf->triangles->indexes[0];
|
||||
|
||||
for(i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++)
|
||||
{
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
triangles[numTriangles + i].indexes[j] = numVerts + tri->indexes[j];
|
||||
srf->minIndex = MIN(srf->minIndex, numVerts + tri->indexes[j]);
|
||||
srf->maxIndex = MAX(srf->maxIndex, numVerts + tri->indexes[j]);
|
||||
}
|
||||
}
|
||||
|
||||
numTriangles += srf->numTriangles;
|
||||
}
|
||||
|
||||
if(srf->numVerts)
|
||||
numVerts += srf->numVerts;
|
||||
}
|
||||
}
|
||||
|
||||
// build vertices
|
||||
numVerts = 0;
|
||||
for(k = 0, surface = surfacesSorted[k]; k < numSurfaces; k++, surface = surfacesSorted[k])
|
||||
{
|
||||
if(*surface->data == SF_FACE)
|
||||
{
|
||||
srfSurfaceFace_t *srf = (srfSurfaceFace_t *) surface->data;
|
||||
|
||||
srf->firstVert = numVerts;
|
||||
|
||||
if(srf->numVerts)
|
||||
{
|
||||
for(i = 0; i < srf->numVerts; i++)
|
||||
{
|
||||
CopyVert(&srf->verts[i], &verts[numVerts + i]);
|
||||
}
|
||||
|
||||
numVerts += srf->numVerts;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(*surface->data == SF_GRID)
|
||||
{
|
||||
srfGridMesh_t *srf = (srfGridMesh_t *) surface->data;
|
||||
|
||||
srf->firstVert = numVerts;
|
||||
|
||||
if(srf->numVerts)
|
||||
{
|
||||
for(i = 0; i < srf->numVerts; i++)
|
||||
{
|
||||
CopyVert(&srf->verts[i], &verts[numVerts + i]);
|
||||
}
|
||||
|
||||
numVerts += srf->numVerts;
|
||||
}
|
||||
}
|
||||
else if(*surface->data == SF_TRIANGLES)
|
||||
{
|
||||
srfTriangles_t *srf = (srfTriangles_t *) surface->data;
|
||||
|
||||
srf->firstVert = numVerts;
|
||||
|
||||
if(srf->numVerts)
|
||||
{
|
||||
for(i = 0; i < srf->numVerts; i++)
|
||||
{
|
||||
CopyVert(&srf->verts[i], &verts[numVerts + i]);
|
||||
}
|
||||
|
||||
numVerts += srf->numVerts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_VERT_TANGENT_SPACE
|
||||
s_worldData.vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", 0), numVerts, verts,
|
||||
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT |
|
||||
ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC);
|
||||
vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts,
|
||||
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_TANGENT | ATTR_BITANGENT |
|
||||
ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC);
|
||||
#else
|
||||
s_worldData.vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", 0), numVerts, verts,
|
||||
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD |
|
||||
ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC);
|
||||
vbo = R_CreateVBO2(va("staticBspModel0_VBO %i", k), numVerts, verts,
|
||||
ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD |
|
||||
ATTR_NORMAL | ATTR_COLOR | ATTR_LIGHTDIRECTION, VBO_USAGE_STATIC);
|
||||
#endif
|
||||
|
||||
s_worldData.ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", 0), numTriangles, triangles, VBO_USAGE_STATIC);
|
||||
ibo = R_CreateIBO2(va("staticBspModel0_IBO %i", k), numTriangles, triangles, VBO_USAGE_STATIC);
|
||||
|
||||
endTime = ri.Milliseconds();
|
||||
ri.Printf(PRINT_ALL, "world VBO calculation time = %5.2f seconds\n", (endTime - startTime) / 1000.0);
|
||||
|
||||
// point triangle surfaces to world VBO
|
||||
for(k = 0, surface = surfacesSorted[k]; k < numSurfaces; k++, surface = surfacesSorted[k])
|
||||
{
|
||||
if(*surface->data == SF_FACE)
|
||||
// point triangle surfaces to VBO
|
||||
for (currSurf = firstSurf; currSurf < lastSurf; currSurf++)
|
||||
{
|
||||
srfSurfaceFace_t *srf = (srfSurfaceFace_t *) surface->data;
|
||||
srfBspSurface_t *bspSurf = (srfBspSurface_t *) (*currSurf)->data;
|
||||
|
||||
if( srf->numVerts && srf->numTriangles)
|
||||
switch (bspSurf->surfaceType)
|
||||
{
|
||||
srf->vbo = s_worldData.vbo;
|
||||
srf->ibo = s_worldData.ibo;
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
if( bspSurf->numVerts && bspSurf->numTriangles)
|
||||
{
|
||||
bspSurf->vbo = vbo;
|
||||
bspSurf->ibo = ibo;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(*surface->data == SF_GRID)
|
||||
{
|
||||
srfGridMesh_t *srf = (srfGridMesh_t *) surface->data;
|
||||
|
||||
if( srf->numVerts && srf->numTriangles)
|
||||
{
|
||||
srf->vbo = s_worldData.vbo;
|
||||
srf->ibo = s_worldData.ibo;
|
||||
}
|
||||
}
|
||||
else if(*surface->data == SF_TRIANGLES)
|
||||
{
|
||||
srfTriangles_t *srf = (srfTriangles_t *) surface->data;
|
||||
ri.Hunk_FreeTempMemory(triangles);
|
||||
ri.Hunk_FreeTempMemory(verts);
|
||||
|
||||
k++;
|
||||
|
||||
if( srf->numVerts && srf->numTriangles)
|
||||
{
|
||||
srf->vbo = s_worldData.vbo;
|
||||
srf->ibo = s_worldData.ibo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ri.Free(surfacesSorted);
|
||||
|
||||
ri.Hunk_FreeTempMemory(triangles);
|
||||
ri.Hunk_FreeTempMemory(verts);
|
||||
endTime = ri.Milliseconds();
|
||||
ri.Printf(PRINT_ALL, "world VBOs calculation time = %5.2f seconds\n", (endTime - startTime) / 1000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2196,10 +2113,10 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) {
|
|||
// FIXME: do this
|
||||
break;
|
||||
case MST_TRIANGLE_SOUP:
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfTriangles_t), h_low);
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
|
||||
break;
|
||||
case MST_PLANAR:
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfSurfaceFace_t), h_low);
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfBspSurface_t), h_low);
|
||||
break;
|
||||
case MST_FLARE:
|
||||
out->data = ri.Hunk_Alloc( sizeof(srfFlare_t), h_low);
|
||||
|
@ -2216,13 +2133,13 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) {
|
|||
case MST_PATCH:
|
||||
ParseMesh ( in, dv, hdrVertColors, out );
|
||||
{
|
||||
srfGridMesh_t *surface = (srfGridMesh_t *)out->data;
|
||||
srfBspSurface_t *surface = (srfBspSurface_t *)out->data;
|
||||
|
||||
out->cullinfo.type = CULLINFO_BOX | CULLINFO_SPHERE;
|
||||
VectorCopy(surface->meshBounds[0], out->cullinfo.bounds[0]);
|
||||
VectorCopy(surface->meshBounds[1], out->cullinfo.bounds[1]);
|
||||
VectorCopy(surface->localOrigin, out->cullinfo.localOrigin);
|
||||
out->cullinfo.radius = surface->meshRadius;
|
||||
VectorCopy(surface->cullBounds[0], out->cullinfo.bounds[0]);
|
||||
VectorCopy(surface->cullBounds[1], out->cullinfo.bounds[1]);
|
||||
VectorCopy(surface->cullOrigin, out->cullinfo.localOrigin);
|
||||
out->cullinfo.radius = surface->cullRadius;
|
||||
}
|
||||
numMeshes++;
|
||||
break;
|
||||
|
@ -3006,6 +2923,7 @@ void R_MergeLeafSurfaces(void)
|
|||
int mergedSurfIndex;
|
||||
int numMergedSurfaces;
|
||||
int numUnmergedSurfaces;
|
||||
VBO_t *vbo;
|
||||
IBO_t *ibo;
|
||||
|
||||
msurface_t *mergedSurf;
|
||||
|
@ -3025,14 +2943,6 @@ void R_MergeLeafSurfaces(void)
|
|||
s_worldData.surfacesViewCount[i] = -1;
|
||||
}
|
||||
|
||||
// create ibo
|
||||
ibo = tr.ibos[tr.numIBOs++] = ri.Hunk_Alloc(sizeof(*ibo), h_low);
|
||||
memset(ibo, 0, sizeof(*ibo));
|
||||
Q_strncpyz(ibo->name, "staticWorldMesh_IBO_mergedSurfs", sizeof(ibo->name));
|
||||
|
||||
// allocate more than we need
|
||||
iboIndexes = outIboIndexes = ri.Malloc(s_worldData.ibo->indexesSize);
|
||||
|
||||
// mark matching surfaces
|
||||
for (i = 0; i < s_worldData.numnodes - s_worldData.numDecisionNodes; i++)
|
||||
{
|
||||
|
@ -3166,6 +3076,9 @@ void R_MergeLeafSurfaces(void)
|
|||
s_worldData.viewSurfaces[i] = s_worldData.marksurfaces[i];
|
||||
}
|
||||
|
||||
// need to be synched here
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
// actually merge surfaces
|
||||
numIboIndexes = 0;
|
||||
mergedSurfIndex = 0;
|
||||
|
@ -3181,13 +3094,27 @@ void R_MergeLeafSurfaces(void)
|
|||
int numVerts;
|
||||
int firstIndex;
|
||||
|
||||
srfVBOMesh_t *vboSurf;
|
||||
srfBspSurface_t *vboSurf;
|
||||
|
||||
if (s_worldData.surfacesViewCount[i] != i)
|
||||
continue;
|
||||
|
||||
|
||||
surf1 = s_worldData.surfaces + i;
|
||||
|
||||
// retrieve vbo
|
||||
switch(*surf1->data)
|
||||
{
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
vbo = ((srfBspSurface_t *)(surf1->data))->vbo;
|
||||
break;
|
||||
|
||||
default:
|
||||
vbo = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
// count verts, indexes, and surfaces
|
||||
numSurfsToMerge = 0;
|
||||
numTriangles = 0;
|
||||
|
@ -3195,42 +3122,21 @@ void R_MergeLeafSurfaces(void)
|
|||
for (j = 0; j < numWorldSurfaces; j++)
|
||||
{
|
||||
msurface_t *surf2;
|
||||
srfBspSurface_t *bspSurf;
|
||||
|
||||
if (s_worldData.surfacesViewCount[j] != i)
|
||||
continue;
|
||||
|
||||
surf2 = s_worldData.surfaces + j;
|
||||
|
||||
switch(*surf2->data)
|
||||
bspSurf = (srfBspSurface_t *) surf2->data;
|
||||
switch(bspSurf->surfaceType)
|
||||
{
|
||||
case SF_FACE:
|
||||
{
|
||||
srfSurfaceFace_t *face;
|
||||
|
||||
face = (srfSurfaceFace_t *) surf2->data;
|
||||
numTriangles += face->numTriangles;
|
||||
numVerts += face->numVerts;
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_GRID:
|
||||
{
|
||||
srfGridMesh_t *grid;
|
||||
|
||||
grid = (srfGridMesh_t *) surf2->data;
|
||||
numTriangles += grid->numTriangles;
|
||||
numVerts += grid->numVerts;
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_TRIANGLES:
|
||||
{
|
||||
srfTriangles_t *tris;
|
||||
|
||||
tris = (srfTriangles_t *) surf2->data;
|
||||
numTriangles += tris->numTriangles;
|
||||
numVerts += tris->numVerts;
|
||||
}
|
||||
numTriangles += bspSurf->numTriangles;
|
||||
numVerts += bspSurf->numVerts;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3245,12 +3151,22 @@ void R_MergeLeafSurfaces(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
// create ibo
|
||||
ibo = tr.ibos[tr.numIBOs] = ri.Hunk_Alloc(sizeof(*ibo), h_low);
|
||||
memset(ibo, 0, sizeof(*ibo));
|
||||
Q_strncpyz(ibo->name, va("staticWorldMesh_IBO_mergedSurfs%i", tr.numIBOs++), sizeof(ibo->name));
|
||||
numIboIndexes = 0;
|
||||
|
||||
// allocate indexes
|
||||
iboIndexes = outIboIndexes = ri.Malloc(numTriangles * 3 * sizeof(*outIboIndexes));
|
||||
|
||||
// Merge surfaces (indexes) and calculate bounds
|
||||
ClearBounds(bounds[0], bounds[1]);
|
||||
firstIndex = numIboIndexes;
|
||||
for (j = 0; j < numWorldSurfaces; j++)
|
||||
{
|
||||
msurface_t *surf2;
|
||||
srfBspSurface_t *bspSurf;
|
||||
|
||||
if (s_worldData.surfacesViewCount[j] != i)
|
||||
continue;
|
||||
|
@ -3260,53 +3176,18 @@ void R_MergeLeafSurfaces(void)
|
|||
AddPointToBounds(surf2->cullinfo.bounds[0], bounds[0], bounds[1]);
|
||||
AddPointToBounds(surf2->cullinfo.bounds[1], bounds[0], bounds[1]);
|
||||
|
||||
switch(*surf2->data)
|
||||
bspSurf = (srfBspSurface_t *) surf2->data;
|
||||
switch(bspSurf->surfaceType)
|
||||
{
|
||||
case SF_FACE:
|
||||
{
|
||||
srfSurfaceFace_t *face;
|
||||
|
||||
face = (srfSurfaceFace_t *) surf2->data;
|
||||
|
||||
for (k = 0; k < face->numTriangles; k++)
|
||||
{
|
||||
*outIboIndexes++ = face->triangles[k].indexes[0] + face->firstVert;
|
||||
*outIboIndexes++ = face->triangles[k].indexes[1] + face->firstVert;
|
||||
*outIboIndexes++ = face->triangles[k].indexes[2] + face->firstVert;
|
||||
numIboIndexes += 3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_GRID:
|
||||
{
|
||||
srfGridMesh_t *grid;
|
||||
|
||||
grid = (srfGridMesh_t *) surf2->data;
|
||||
|
||||
for (k = 0; k < grid->numTriangles; k++)
|
||||
{
|
||||
*outIboIndexes++ = grid->triangles[k].indexes[0] + grid->firstVert;
|
||||
*outIboIndexes++ = grid->triangles[k].indexes[1] + grid->firstVert;
|
||||
*outIboIndexes++ = grid->triangles[k].indexes[2] + grid->firstVert;
|
||||
numIboIndexes += 3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SF_TRIANGLES:
|
||||
for (k = 0; k < bspSurf->numTriangles; k++)
|
||||
{
|
||||
srfTriangles_t *tris;
|
||||
|
||||
tris = (srfTriangles_t *) surf2->data;
|
||||
|
||||
for (k = 0; k < tris->numTriangles; k++)
|
||||
{
|
||||
*outIboIndexes++ = tris->triangles[k].indexes[0] + tris->firstVert;
|
||||
*outIboIndexes++ = tris->triangles[k].indexes[1] + tris->firstVert;
|
||||
*outIboIndexes++ = tris->triangles[k].indexes[2] + tris->firstVert;
|
||||
numIboIndexes += 3;
|
||||
}
|
||||
*outIboIndexes++ = bspSurf->triangles[k].indexes[0] + bspSurf->firstVert;
|
||||
*outIboIndexes++ = bspSurf->triangles[k].indexes[1] + bspSurf->firstVert;
|
||||
*outIboIndexes++ = bspSurf->triangles[k].indexes[2] + bspSurf->firstVert;
|
||||
numIboIndexes += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3320,10 +3201,10 @@ void R_MergeLeafSurfaces(void)
|
|||
memset(vboSurf, 0, sizeof(*vboSurf));
|
||||
vboSurf->surfaceType = SF_VBO_MESH;
|
||||
|
||||
vboSurf->vbo = s_worldData.vbo;
|
||||
vboSurf->vbo = vbo;
|
||||
vboSurf->ibo = ibo;
|
||||
|
||||
vboSurf->numIndexes = numTriangles * 3;
|
||||
vboSurf->numTriangles = numTriangles;
|
||||
vboSurf->numVerts = numVerts;
|
||||
vboSurf->firstIndex = firstIndex;
|
||||
|
||||
|
@ -3336,12 +3217,8 @@ void R_MergeLeafSurfaces(void)
|
|||
vboSurf->maxIndex = MAX(vboSurf->maxIndex, *(iboIndexes + firstIndex + j));
|
||||
}
|
||||
|
||||
vboSurf->shader = surf1->shader;
|
||||
vboSurf->fogIndex = surf1->fogIndex;
|
||||
vboSurf->cubemapIndex = surf1->cubemapIndex;
|
||||
|
||||
VectorCopy(bounds[0], vboSurf->bounds[0]);
|
||||
VectorCopy(bounds[1], vboSurf->bounds[1]);
|
||||
VectorCopy(bounds[0], vboSurf->cullBounds[0]);
|
||||
VectorCopy(bounds[1], vboSurf->cullBounds[1]);
|
||||
|
||||
VectorCopy(bounds[0], mergedSurf->cullinfo.bounds[0]);
|
||||
VectorCopy(bounds[1], mergedSurf->cullinfo.bounds[1]);
|
||||
|
@ -3352,6 +3229,17 @@ void R_MergeLeafSurfaces(void)
|
|||
mergedSurf->cubemapIndex = surf1->cubemapIndex;
|
||||
mergedSurf->shader = surf1->shader;
|
||||
|
||||
// finish up the ibo
|
||||
qglGenBuffersARB(1, &ibo->indexesVBO);
|
||||
|
||||
R_BindIBO(ibo);
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, numIboIndexes * sizeof(*iboIndexes), iboIndexes, GL_STATIC_DRAW_ARB);
|
||||
R_BindNullIBO();
|
||||
|
||||
GL_CheckErrors();
|
||||
|
||||
ri.Free(iboIndexes);
|
||||
|
||||
// redirect view surfaces to this surf
|
||||
for (j = 0; j < numWorldSurfaces; j++)
|
||||
{
|
||||
|
@ -3372,21 +3260,6 @@ void R_MergeLeafSurfaces(void)
|
|||
mergedSurf++;
|
||||
}
|
||||
|
||||
// finish up the ibo
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
qglGenBuffersARB(1, &ibo->indexesVBO);
|
||||
|
||||
R_BindIBO(ibo);
|
||||
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, numIboIndexes * sizeof(*iboIndexes), iboIndexes, GL_STATIC_DRAW_ARB);
|
||||
|
||||
R_BindNullIBO();
|
||||
|
||||
GL_CheckErrors();
|
||||
|
||||
ri.Free(iboIndexes);
|
||||
|
||||
endTime = ri.Milliseconds();
|
||||
|
||||
ri.Printf(PRINT_ALL, "Processed %d surfaces into %d merged, %d unmerged in %5.2f seconds\n",
|
||||
|
@ -3407,41 +3280,20 @@ void R_CalcVertexLightDirs( void )
|
|||
|
||||
for(k = 0, surface = &s_worldData.surfaces[0]; k < s_worldData.numsurfaces /* s_worldData.numWorldSurfaces */; k++, surface++)
|
||||
{
|
||||
if(*surface->data == SF_FACE)
|
||||
{
|
||||
srfSurfaceFace_t *srf = (srfSurfaceFace_t *) surface->data;
|
||||
srfBspSurface_t *bspSurf = (srfBspSurface_t *) surface->data;
|
||||
|
||||
if(srf->numVerts)
|
||||
{
|
||||
for(i = 0; i < srf->numVerts; i++)
|
||||
{
|
||||
R_LightDirForPoint( srf->verts[i].xyz, srf->verts[i].lightdir, srf->verts[i].normal, &s_worldData );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(*surface->data == SF_GRID)
|
||||
switch(bspSurf->surfaceType)
|
||||
{
|
||||
srfGridMesh_t *srf = (srfGridMesh_t *) surface->data;
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
for(i = 0; i < bspSurf->numVerts; i++)
|
||||
R_LightDirForPoint( bspSurf->verts[i].xyz, bspSurf->verts[i].lightdir, bspSurf->verts[i].normal, &s_worldData );
|
||||
|
||||
if(srf->numVerts)
|
||||
{
|
||||
for(i = 0; i < srf->numVerts; i++)
|
||||
{
|
||||
R_LightDirForPoint( srf->verts[i].xyz, srf->verts[i].lightdir, srf->verts[i].normal, &s_worldData );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(*surface->data == SF_TRIANGLES)
|
||||
{
|
||||
srfTriangles_t *srf = (srfTriangles_t *) surface->data;
|
||||
break;
|
||||
|
||||
if(srf->numVerts)
|
||||
{
|
||||
for(i = 0; i < srf->numVerts; i++)
|
||||
{
|
||||
R_LightDirForPoint( srf->verts[i].xyz, srf->verts[i].lightdir, srf->verts[i].normal, &s_worldData );
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3743,7 +3595,7 @@ void RE_LoadWorldMap( const char *name ) {
|
|||
}
|
||||
|
||||
// create static VBOS from the world
|
||||
R_CreateWorldVBO();
|
||||
R_CreateWorldVBOs();
|
||||
if (r_mergeLeafSurfaces->integer)
|
||||
{
|
||||
R_MergeLeafSurfaces();
|
||||
|
|
|
@ -25,14 +25,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
/*
|
||||
|
||||
This file does all of the processing necessary to turn a raw grid of points
|
||||
read from the map file into a srfGridMesh_t ready for rendering.
|
||||
read from the map file into a srfBspSurface_t ready for rendering.
|
||||
|
||||
The level of detail solution is direction independent, based only on subdivided
|
||||
distance from the true curve.
|
||||
|
||||
Only a single entry point:
|
||||
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
|
||||
|
||||
*/
|
||||
|
@ -329,8 +329,6 @@ static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE
|
|||
}
|
||||
}
|
||||
|
||||
R_CalcSurfaceTriangleNeighbors(numTriangles, triangles);
|
||||
|
||||
// FIXME: use more elegant way
|
||||
for(i = 0; i < width; i++)
|
||||
{
|
||||
|
@ -341,8 +339,6 @@ static int MakeMeshTriangles(int width, int height, srfVert_t ctrl[MAX_GRID_SIZE
|
|||
}
|
||||
}
|
||||
|
||||
R_CalcSurfaceTrianglePlanes(numTriangles, triangles, ctrl2);
|
||||
|
||||
return numTriangles;
|
||||
}
|
||||
|
||||
|
@ -420,13 +416,13 @@ static void PutPointsOnCurve( srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
|
|||
R_CreateSurfaceGridMesh
|
||||
=================
|
||||
*/
|
||||
srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
||||
srfBspSurface_t *R_CreateSurfaceGridMesh(int width, int height,
|
||||
srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE], float errorTable[2][MAX_GRID_SIZE],
|
||||
int numTriangles, srfTriangle_t triangles[(MAX_GRID_SIZE-1)*(MAX_GRID_SIZE-1)*2]) {
|
||||
int i, j, size;
|
||||
srfVert_t *vert;
|
||||
vec3_t tmpVec;
|
||||
srfGridMesh_t *grid;
|
||||
srfBspSurface_t *grid;
|
||||
|
||||
// copy the results out to a grid
|
||||
size = (width * height - 1) * sizeof( srfVert_t ) + sizeof( *grid );
|
||||
|
@ -468,23 +464,23 @@ srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
|||
grid->width = width;
|
||||
grid->height = height;
|
||||
grid->surfaceType = SF_GRID;
|
||||
ClearBounds( grid->meshBounds[0], grid->meshBounds[1] );
|
||||
ClearBounds( grid->cullBounds[0], grid->cullBounds[1] );
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
vert = &grid->verts[j*width+i];
|
||||
*vert = ctrl[j][i];
|
||||
AddPointToBounds( vert->xyz, grid->meshBounds[0], grid->meshBounds[1] );
|
||||
AddPointToBounds( vert->xyz, grid->cullBounds[0], grid->cullBounds[1] );
|
||||
}
|
||||
}
|
||||
|
||||
// compute local origin and bounds
|
||||
VectorAdd( grid->meshBounds[0], grid->meshBounds[1], grid->localOrigin );
|
||||
VectorScale( grid->localOrigin, 0.5f, grid->localOrigin );
|
||||
VectorSubtract( grid->meshBounds[0], grid->localOrigin, tmpVec );
|
||||
grid->meshRadius = VectorLength( tmpVec );
|
||||
VectorAdd( grid->cullBounds[0], grid->cullBounds[1], grid->cullOrigin );
|
||||
VectorScale( grid->cullOrigin, 0.5f, grid->cullOrigin );
|
||||
VectorSubtract( grid->cullBounds[0], grid->cullOrigin, tmpVec );
|
||||
grid->cullRadius = VectorLength( tmpVec );
|
||||
|
||||
VectorCopy( grid->localOrigin, grid->lodOrigin );
|
||||
grid->lodRadius = grid->meshRadius;
|
||||
VectorCopy( grid->cullOrigin, grid->lodOrigin );
|
||||
grid->lodRadius = grid->cullRadius;
|
||||
//
|
||||
return grid;
|
||||
}
|
||||
|
@ -494,7 +490,7 @@ srfGridMesh_t *R_CreateSurfaceGridMesh(int width, int height,
|
|||
R_FreeSurfaceGridMesh
|
||||
=================
|
||||
*/
|
||||
void R_FreeSurfaceGridMesh( srfGridMesh_t *grid ) {
|
||||
void R_FreeSurfaceGridMesh( srfBspSurface_t *grid ) {
|
||||
ri.Free(grid->widthLodError);
|
||||
ri.Free(grid->heightLodError);
|
||||
ri.Free(grid->triangles);
|
||||
|
@ -507,7 +503,7 @@ void R_FreeSurfaceGridMesh( srfGridMesh_t *grid ) {
|
|||
R_SubdividePatchToGrid
|
||||
=================
|
||||
*/
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
|
||||
int i, j, k, l;
|
||||
srfVert_t_cleared( prev );
|
||||
|
@ -690,7 +686,7 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
|||
R_GridInsertColumn
|
||||
===============
|
||||
*/
|
||||
srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec3_t point, float loderror ) {
|
||||
srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror ) {
|
||||
int i, j;
|
||||
int width, height, oldwidth;
|
||||
srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
|
@ -750,7 +746,7 @@ srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec
|
|||
R_GridInsertRow
|
||||
===============
|
||||
*/
|
||||
srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t point, float loderror ) {
|
||||
srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror ) {
|
||||
int i, j;
|
||||
int width, height, oldheight;
|
||||
srfVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
|
|
|
@ -701,8 +701,10 @@ void GLimp_InitExtraExtensions()
|
|||
glRefConfig.seamlessCubeMap = qfalse;
|
||||
if( GLimp_HaveExtension( extension ) )
|
||||
{
|
||||
glRefConfig.seamlessCubeMap = qtrue;
|
||||
ri.Printf(PRINT_ALL, result[1], extension);
|
||||
if (r_arb_seamless_cube_map->integer)
|
||||
glRefConfig.seamlessCubeMap = qtrue;
|
||||
|
||||
ri.Printf(PRINT_ALL, result[glRefConfig.seamlessCubeMap], extension);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -106,6 +106,7 @@ static uniformInfo_t uniformsInfo[] =
|
|||
{ "u_LightUp", GLSL_VEC3 },
|
||||
{ "u_LightRight", GLSL_VEC3 },
|
||||
{ "u_LightOrigin", GLSL_VEC4 },
|
||||
{ "u_ModelLightDir", GLSL_VEC3 },
|
||||
{ "u_LightRadius", GLSL_FLOAT },
|
||||
{ "u_AmbientLight", GLSL_VEC3 },
|
||||
{ "u_DirectedLight", GLSL_VEC3 },
|
||||
|
@ -124,11 +125,12 @@ static uniformInfo_t uniformsInfo[] =
|
|||
{ "u_VertexLerp" , GLSL_FLOAT },
|
||||
{ "u_MaterialInfo", GLSL_VEC2 },
|
||||
|
||||
{ "u_ViewInfo", GLSL_VEC4 },
|
||||
{ "u_ViewOrigin", GLSL_VEC3 },
|
||||
{ "u_ViewForward", GLSL_VEC3 },
|
||||
{ "u_ViewLeft", GLSL_VEC3 },
|
||||
{ "u_ViewUp", GLSL_VEC3 },
|
||||
{ "u_ViewInfo", GLSL_VEC4 },
|
||||
{ "u_ViewOrigin", GLSL_VEC3 },
|
||||
{ "u_LocalViewOrigin", GLSL_VEC3 },
|
||||
{ "u_ViewForward", GLSL_VEC3 },
|
||||
{ "u_ViewLeft", GLSL_VEC3 },
|
||||
{ "u_ViewUp", GLSL_VEC3 },
|
||||
|
||||
{ "u_InvTexRes", GLSL_VEC2 },
|
||||
{ "u_AutoExposureMinMax", GLSL_VEC2 },
|
||||
|
@ -294,11 +296,9 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, cha
|
|||
"#define alphaGen_t\n"
|
||||
"#define AGEN_LIGHTING_SPECULAR %i\n"
|
||||
"#define AGEN_PORTAL %i\n"
|
||||
"#define AGEN_FRESNEL %i\n"
|
||||
"#endif\n",
|
||||
AGEN_LIGHTING_SPECULAR,
|
||||
AGEN_PORTAL,
|
||||
AGEN_FRESNEL));
|
||||
AGEN_PORTAL));
|
||||
|
||||
Q_strcat(dest, size,
|
||||
va("#ifndef texenv_t\n"
|
||||
|
@ -907,7 +907,7 @@ void GLSL_InitGPUShaders(void)
|
|||
if (i & GENERICDEF_USE_LIGHTMAP)
|
||||
Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n");
|
||||
|
||||
if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel))
|
||||
if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer))
|
||||
Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n");
|
||||
|
||||
if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackShader_generic_vp, fallbackShader_generic_fp))
|
||||
|
@ -1036,7 +1036,7 @@ void GLSL_InitGPUShaders(void)
|
|||
Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n");
|
||||
}
|
||||
|
||||
if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel))
|
||||
if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer))
|
||||
Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n");
|
||||
|
||||
if (i & LIGHTDEF_LIGHTTYPE_MASK)
|
||||
|
@ -1696,7 +1696,7 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
|
|||
// position/normal/tangent/bitangent are always set in case of animation
|
||||
oldFrame = glState.vertexAttribsOldFrame;
|
||||
newFrame = glState.vertexAttribsNewFrame;
|
||||
animated = (oldFrame != newFrame) && (glState.vertexAttribsInterpolation > 0.0f);
|
||||
animated = glState.vertexAnimation;
|
||||
|
||||
if((attribBits & ATTR_POSITION) && (!(glState.vertexAttribPointersSet & ATTR_POSITION) || animated))
|
||||
{
|
||||
|
@ -1829,7 +1829,6 @@ shaderProgram_t *GLSL_GetGenericShaderProgram(int stage)
|
|||
{
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_PORTAL:
|
||||
case AGEN_FRESNEL:
|
||||
shaderAttribs |= GENERICDEF_USE_RGBAGEN;
|
||||
break;
|
||||
default:
|
||||
|
@ -1846,7 +1845,7 @@ shaderProgram_t *GLSL_GetGenericShaderProgram(int stage)
|
|||
shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES;
|
||||
}
|
||||
|
||||
if (glState.vertexAttribsInterpolation > 0.0f && backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
|
||||
if (glState.vertexAnimation)
|
||||
{
|
||||
shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION;
|
||||
}
|
||||
|
|
|
@ -2303,6 +2303,9 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT
|
|||
qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
|
||||
qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
|
||||
|
||||
if (image->flags & IMGFLAG_MIPMAP)
|
||||
qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
image->uploadWidth = width;
|
||||
image->uploadHeight = height;
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ cvar_t *r_ext_framebuffer_object;
|
|||
cvar_t *r_ext_texture_float;
|
||||
cvar_t *r_arb_half_float_pixel;
|
||||
cvar_t *r_ext_framebuffer_multisample;
|
||||
cvar_t *r_arb_seamless_cube_map;
|
||||
|
||||
cvar_t *r_mergeMultidraws;
|
||||
cvar_t *r_mergeLeafSurfaces;
|
||||
|
@ -111,6 +112,7 @@ cvar_t *r_cameraExposure;
|
|||
cvar_t *r_softOverbright;
|
||||
|
||||
cvar_t *r_hdr;
|
||||
cvar_t *r_floatLightmap;
|
||||
cvar_t *r_postProcess;
|
||||
|
||||
cvar_t *r_toneMap;
|
||||
|
@ -952,16 +954,6 @@ void GL_SetDefaultState( void )
|
|||
qglDisable( GL_CULL_FACE );
|
||||
qglDisable( GL_BLEND );
|
||||
|
||||
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
qglClearDepth( 1.0 );
|
||||
|
||||
qglDrawBuffer( GL_FRONT );
|
||||
qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
|
||||
|
||||
qglDrawBuffer( GL_BACK );
|
||||
qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
|
||||
|
||||
if (glRefConfig.seamlessCubeMap)
|
||||
qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
}
|
||||
|
@ -1135,6 +1127,7 @@ void R_Register( void )
|
|||
r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_ext_framebuffer_multisample = ri.Cvar_Get( "r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
|
||||
r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic",
|
||||
"0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
@ -1170,6 +1163,7 @@ void R_Register( void )
|
|||
r_softOverbright = ri.Cvar_Get( "r_softOverbright", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
||||
r_hdr = ri.Cvar_Get( "r_hdr", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE );
|
||||
|
||||
r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
|
|
@ -94,12 +94,17 @@ void R_DlightBmodel( bmodel_t *bmodel ) {
|
|||
for ( i = 0 ; i < bmodel->numSurfaces ; i++ ) {
|
||||
surf = tr.world->surfaces + bmodel->firstSurface + i;
|
||||
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
((srfSurfaceFace_t *)surf->data)->dlightBits = mask;
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
((srfGridMesh_t *)surf->data)->dlightBits = mask;
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
((srfTriangles_t *)surf->data)->dlightBits = mask;
|
||||
switch(*surf->data)
|
||||
{
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
case SF_VBO_MESH:
|
||||
((srfBspSurface_t *)surf->data)->dlightBits = mask;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,8 +408,11 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
|
|||
((byte *)&ent->ambientLightInt)[3] = 0xff;
|
||||
|
||||
// transform the direction to local space
|
||||
// no need to do this if using lightentity glsl shader
|
||||
VectorNormalize( lightDir );
|
||||
ent->modelLightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
|
||||
ent->modelLightDir[1] = DotProduct( lightDir, ent->e.axis[1] );
|
||||
ent->modelLightDir[2] = DotProduct( lightDir, ent->e.axis[2] );
|
||||
|
||||
VectorCopy(lightDir, ent->lightDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,10 +47,6 @@ typedef unsigned int glIndex_t;
|
|||
#define SHADERNUM_BITS 14
|
||||
#define MAX_SHADERS (1<<SHADERNUM_BITS)
|
||||
|
||||
//#define MAX_SHADER_STATES 2048
|
||||
#define MAX_STATES_PER_SHADER 32
|
||||
#define MAX_STATE_NAME 32
|
||||
|
||||
#define MAX_FBOS 64
|
||||
#define MAX_VISCOUNTS 5
|
||||
#define MAX_VBOS 4096
|
||||
|
@ -84,7 +80,8 @@ typedef struct {
|
|||
qboolean needDlights; // true for bmodels that touch a dlight
|
||||
qboolean lightingCalculated;
|
||||
qboolean mirrored; // mirrored matrix, needs reversed culling
|
||||
vec3_t lightDir; // normalized direction towards light
|
||||
vec3_t lightDir; // normalized direction towards light, in world space
|
||||
vec3_t modelLightDir; // normalized direction towards light, in model space
|
||||
vec3_t ambientLight; // color normalized to 0-255
|
||||
int ambientLightInt; // 32 bit rgba packed
|
||||
vec3_t directedLight;
|
||||
|
@ -241,7 +238,6 @@ typedef enum {
|
|||
AGEN_WAVEFORM,
|
||||
AGEN_PORTAL,
|
||||
AGEN_CONST,
|
||||
AGEN_FRESNEL
|
||||
} alphaGen_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -354,7 +350,6 @@ typedef struct {
|
|||
|
||||
int videoMapHandle;
|
||||
qboolean isLightmap;
|
||||
qboolean vertexLightmap;
|
||||
qboolean isVideoMap;
|
||||
} textureBundle_t;
|
||||
|
||||
|
@ -486,16 +481,8 @@ typedef struct shader_s {
|
|||
float clampTime; // time this shader is clamped to
|
||||
float timeOffset; // current time offset for this shader
|
||||
|
||||
int numStates; // if non-zero this is a state shader
|
||||
struct shader_s *currentShader; // current state if this is a state shader
|
||||
struct shader_s *parentShader; // current state if this is a state shader
|
||||
int currentState; // current state index for cycle purposes
|
||||
long expireTime; // time in milliseconds this expires
|
||||
|
||||
struct shader_s *remappedShader; // current shader this one is remapped too
|
||||
|
||||
int shaderStates[MAX_STATES_PER_SHADER]; // index to valid shader states
|
||||
|
||||
struct shader_s *next;
|
||||
} shader_t;
|
||||
|
||||
|
@ -522,14 +509,6 @@ static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
typedef struct shaderState_s {
|
||||
char shaderName[MAX_QPATH]; // name of shader this state belongs to
|
||||
char name[MAX_STATE_NAME]; // name of this state
|
||||
char stateShader[MAX_QPATH]; // shader this name invokes
|
||||
int cycleTime; // time this cycle lasts, <= 0 is forever
|
||||
shader_t *shader;
|
||||
} shaderState_t;
|
||||
|
||||
enum
|
||||
{
|
||||
ATTR_INDEX_POSITION = 0,
|
||||
|
@ -765,6 +744,7 @@ typedef enum
|
|||
UNIFORM_LIGHTUP,
|
||||
UNIFORM_LIGHTRIGHT,
|
||||
UNIFORM_LIGHTORIGIN,
|
||||
UNIFORM_MODELLIGHTDIR,
|
||||
UNIFORM_LIGHTRADIUS,
|
||||
UNIFORM_AMBIENTLIGHT,
|
||||
UNIFORM_DIRECTEDLIGHT,
|
||||
|
@ -785,6 +765,7 @@ typedef enum
|
|||
|
||||
UNIFORM_VIEWINFO, // znear, zfar, width/2, height/2
|
||||
UNIFORM_VIEWORIGIN,
|
||||
UNIFORM_LOCALVIEWORIGIN,
|
||||
UNIFORM_VIEWFORWARD,
|
||||
UNIFORM_VIEWLEFT,
|
||||
UNIFORM_VIEWUP,
|
||||
|
@ -1026,13 +1007,10 @@ typedef struct
|
|||
{
|
||||
int indexes[3];
|
||||
int neighbors[3];
|
||||
vec4_t plane;
|
||||
qboolean facingLight;
|
||||
qboolean degenerated;
|
||||
} srfTriangle_t;
|
||||
|
||||
|
||||
typedef struct srfGridMesh_s
|
||||
// srfBspSurface_t covers SF_GRID, SF_TRIANGLES, SF_POLY, and SF_VBO_MESH
|
||||
typedef struct srfBspSurface_s
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
||||
|
@ -1041,9 +1019,30 @@ typedef struct srfGridMesh_s
|
|||
int pshadowBits;
|
||||
|
||||
// culling information
|
||||
vec3_t meshBounds[2];
|
||||
vec3_t localOrigin;
|
||||
float meshRadius;
|
||||
vec3_t cullBounds[2];
|
||||
vec3_t cullOrigin;
|
||||
float cullRadius;
|
||||
cplane_t cullPlane;
|
||||
|
||||
// triangle definitions
|
||||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
|
||||
// vertexes
|
||||
int numVerts;
|
||||
srfVert_t *verts;
|
||||
|
||||
// BSP VBO offsets
|
||||
int firstVert;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo;
|
||||
IBO_t *ibo;
|
||||
|
||||
// SF_GRID specific variables after here
|
||||
|
||||
// lod information, which may be different
|
||||
// than the culling information to allow for
|
||||
|
@ -1057,85 +1056,7 @@ typedef struct srfGridMesh_s
|
|||
int width, height;
|
||||
float *widthLodError;
|
||||
float *heightLodError;
|
||||
|
||||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
|
||||
int numVerts;
|
||||
srfVert_t *verts;
|
||||
|
||||
// BSP VBO offsets
|
||||
int firstVert;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo; // points to bsp model VBO
|
||||
IBO_t *ibo;
|
||||
} srfGridMesh_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
||||
// dynamic lighting information
|
||||
int dlightBits;
|
||||
int pshadowBits;
|
||||
|
||||
// culling information
|
||||
cplane_t plane;
|
||||
// vec3_t bounds[2];
|
||||
|
||||
// triangle definitions
|
||||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
|
||||
int numVerts;
|
||||
srfVert_t *verts;
|
||||
|
||||
// BSP VBO offsets
|
||||
int firstVert;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo; // points to bsp model VBO
|
||||
IBO_t *ibo;
|
||||
} srfSurfaceFace_t;
|
||||
|
||||
|
||||
// misc_models in maps are turned into direct geometry by xmap
|
||||
typedef struct
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
||||
// dynamic lighting information
|
||||
int dlightBits;
|
||||
int pshadowBits;
|
||||
|
||||
// culling information
|
||||
// vec3_t bounds[2];
|
||||
|
||||
// triangle definitions
|
||||
int numTriangles;
|
||||
srfTriangle_t *triangles;
|
||||
|
||||
int numVerts;
|
||||
srfVert_t *verts;
|
||||
|
||||
// BSP VBO offsets
|
||||
int firstVert;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo; // points to bsp model VBO
|
||||
IBO_t *ibo;
|
||||
} srfTriangles_t;
|
||||
} srfBspSurface_t;
|
||||
|
||||
// inter-quake-model
|
||||
typedef struct {
|
||||
|
@ -1144,6 +1065,7 @@ typedef struct {
|
|||
int num_frames;
|
||||
int num_surfaces;
|
||||
int num_joints;
|
||||
int num_poses;
|
||||
struct srfIQModel_s *surfaces;
|
||||
|
||||
float *positions;
|
||||
|
@ -1151,10 +1073,18 @@ typedef struct {
|
|||
float *normals;
|
||||
float *tangents;
|
||||
byte *blendIndexes;
|
||||
byte *blendWeights;
|
||||
union {
|
||||
float *f;
|
||||
byte *b;
|
||||
} blendWeights;
|
||||
byte *colors;
|
||||
int *triangles;
|
||||
|
||||
// depending upon the exporter, blend indices and weights might be int/float
|
||||
// as opposed to the recommended byte/byte, for example Noesis exports
|
||||
// int/float whereas the official IQM tool exports byte/byte
|
||||
byte blendWeightsType; // IQM_UBYTE or IQM_FLOAT
|
||||
|
||||
int *jointParents;
|
||||
float *jointMats;
|
||||
float *poseMats;
|
||||
|
@ -1172,33 +1102,6 @@ typedef struct srfIQModel_s {
|
|||
int first_triangle, num_triangles;
|
||||
} srfIQModel_t;
|
||||
|
||||
typedef struct srfVBOMesh_s
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
||||
struct shader_s *shader; // FIXME move this to somewhere else
|
||||
int fogIndex;
|
||||
int cubemapIndex;
|
||||
|
||||
// dynamic lighting information
|
||||
int dlightBits;
|
||||
int pshadowBits;
|
||||
|
||||
// culling information
|
||||
vec3_t bounds[2];
|
||||
|
||||
// backEnd stats
|
||||
int numIndexes;
|
||||
int numVerts;
|
||||
int firstIndex;
|
||||
glIndex_t minIndex;
|
||||
glIndex_t maxIndex;
|
||||
|
||||
// static render data
|
||||
VBO_t *vbo;
|
||||
IBO_t *ibo;
|
||||
} srfVBOMesh_t;
|
||||
|
||||
typedef struct srfVBOMDVMesh_s
|
||||
{
|
||||
surfaceType_t surfaceType;
|
||||
|
@ -1332,9 +1235,6 @@ typedef struct {
|
|||
int numDecisionNodes;
|
||||
mnode_t *nodes;
|
||||
|
||||
VBO_t *vbo;
|
||||
IBO_t *ibo;
|
||||
|
||||
int numWorldSurfaces;
|
||||
|
||||
int numsurfaces;
|
||||
|
@ -1564,6 +1464,7 @@ typedef struct {
|
|||
uint32_t vertexAttribsNewFrame;
|
||||
uint32_t vertexAttribsOldFrame;
|
||||
float vertexAttribsInterpolation;
|
||||
qboolean vertexAnimation;
|
||||
shaderProgram_t *currentProgram;
|
||||
FBO_t *currentFBO;
|
||||
VBO_t *currentVBO;
|
||||
|
@ -1916,6 +1817,7 @@ extern cvar_t *r_ext_framebuffer_object;
|
|||
extern cvar_t *r_ext_texture_float;
|
||||
extern cvar_t *r_arb_half_float_pixel;
|
||||
extern cvar_t *r_ext_framebuffer_multisample;
|
||||
extern cvar_t *r_arb_seamless_cube_map;
|
||||
|
||||
extern cvar_t *r_nobind; // turns off binding to appropriate textures
|
||||
extern cvar_t *r_singleShader; // make most world faces use default shader
|
||||
|
@ -1959,6 +1861,7 @@ extern cvar_t *r_mergeLeafSurfaces;
|
|||
extern cvar_t *r_softOverbright;
|
||||
|
||||
extern cvar_t *r_hdr;
|
||||
extern cvar_t *r_floatLightmap;
|
||||
extern cvar_t *r_postProcess;
|
||||
|
||||
extern cvar_t *r_toneMap;
|
||||
|
@ -2053,8 +1956,6 @@ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader,
|
|||
void R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, vec3_t normal,
|
||||
const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2);
|
||||
qboolean R_CalcTangentVectors(srfVert_t * dv[3]);
|
||||
void R_CalcSurfaceTriangleNeighbors(int numTriangles, srfTriangle_t * triangles);
|
||||
void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * triangles, srfVert_t * verts);
|
||||
|
||||
#define CULL_IN 0 // completely unclipped
|
||||
#define CULL_CLIP 1 // clipped by one or more planes
|
||||
|
@ -2349,11 +2250,11 @@ CURVE TESSELATION
|
|||
|
||||
#define PATCH_STITCHING
|
||||
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfBspSurface_t *R_SubdividePatchToGrid( int width, int height,
|
||||
srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] );
|
||||
srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec3_t point, float loderror );
|
||||
srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t point, float loderror );
|
||||
void R_FreeSurfaceGridMesh( srfGridMesh_t *grid );
|
||||
srfBspSurface_t *R_GridInsertColumn( srfBspSurface_t *grid, int column, int row, vec3_t point, float loderror );
|
||||
srfBspSurface_t *R_GridInsertRow( srfBspSurface_t *grid, int row, int column, vec3_t point, float loderror );
|
||||
void R_FreeSurfaceGridMesh( srfBspSurface_t *grid );
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
@ -2500,35 +2401,18 @@ void R_TransformClipToWindow( const vec4_t clip, const viewParms_t *view, vec4_t
|
|||
|
||||
void RB_DeformTessGeometry( void );
|
||||
|
||||
void RB_CalcEnvironmentTexCoords( float *dstTexCoords );
|
||||
void RB_CalcFogTexCoords( float *dstTexCoords );
|
||||
void RB_CalcScrollTexCoords( const float scroll[2], float *dstTexCoords );
|
||||
void RB_CalcRotateTexCoords( float rotSpeed, float *dstTexCoords );
|
||||
void RB_CalcScaleTexCoords( const float scale[2], float *dstTexCoords );
|
||||
void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *dstTexCoords );
|
||||
void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *dstTexCoords );
|
||||
|
||||
void RB_CalcScaleTexMatrix( const float scale[2], float *matrix );
|
||||
void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix );
|
||||
void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix );
|
||||
void RB_CalcTurbulentTexMatrix( const waveForm_t *wf, matrix_t matrix );
|
||||
void RB_CalcTurbulentFactors( const waveForm_t *wf, float *amplitude, float *now );
|
||||
void RB_CalcTransformTexMatrix( const texModInfo_t *tmi, float *matrix );
|
||||
void RB_CalcStretchTexMatrix( const waveForm_t *wf, float *matrix );
|
||||
|
||||
void RB_CalcModulateColorsByFog( unsigned char *dstColors );
|
||||
void RB_CalcModulateAlphasByFog( unsigned char *dstColors );
|
||||
void RB_CalcModulateRGBAsByFog( unsigned char *dstColors );
|
||||
void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors );
|
||||
float RB_CalcWaveAlphaSingle( const waveForm_t *wf );
|
||||
void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors );
|
||||
float RB_CalcWaveColorSingle( const waveForm_t *wf );
|
||||
void RB_CalcAlphaFromEntity( unsigned char *dstColors );
|
||||
void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors );
|
||||
void RB_CalcStretchTexCoords( const waveForm_t *wf, float *texCoords );
|
||||
void RB_CalcColorFromEntity( unsigned char *dstColors );
|
||||
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors );
|
||||
void RB_CalcSpecularAlpha( unsigned char *alphas );
|
||||
void RB_CalcDiffuseColor( unsigned char *colors );
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
|
|
@ -492,99 +492,6 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3])
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_FindSurfaceTriangleWithEdge
|
||||
|
||||
Recoded from Q2E
|
||||
=================
|
||||
*/
|
||||
static int R_FindSurfaceTriangleWithEdge(int numTriangles, srfTriangle_t * triangles, int start, int end, int ignore)
|
||||
{
|
||||
srfTriangle_t *tri;
|
||||
int count, match;
|
||||
int i;
|
||||
|
||||
count = 0;
|
||||
match = -1;
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
if((tri->indexes[0] == start && tri->indexes[1] == end) ||
|
||||
(tri->indexes[1] == start && tri->indexes[2] == end) || (tri->indexes[2] == start && tri->indexes[0] == end))
|
||||
{
|
||||
if(i != ignore)
|
||||
{
|
||||
match = i;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
else if((tri->indexes[1] == start && tri->indexes[0] == end) ||
|
||||
(tri->indexes[2] == start && tri->indexes[1] == end) || (tri->indexes[0] == start && tri->indexes[2] == end))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
// detect edges shared by three triangles and make them seams
|
||||
if(count > 2)
|
||||
{
|
||||
match = -1;
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CalcSurfaceTriangleNeighbors
|
||||
|
||||
Recoded from Q2E
|
||||
=================
|
||||
*/
|
||||
void R_CalcSurfaceTriangleNeighbors(int numTriangles, srfTriangle_t * triangles)
|
||||
{
|
||||
int i;
|
||||
srfTriangle_t *tri;
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
tri->neighbors[0] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[1], tri->indexes[0], i);
|
||||
tri->neighbors[1] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[2], tri->indexes[1], i);
|
||||
tri->neighbors[2] = R_FindSurfaceTriangleWithEdge(numTriangles, triangles, tri->indexes[0], tri->indexes[2], i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CalcSurfaceTrianglePlanes
|
||||
=================
|
||||
*/
|
||||
void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * triangles, srfVert_t * verts)
|
||||
{
|
||||
int i;
|
||||
srfTriangle_t *tri;
|
||||
|
||||
for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
|
||||
{
|
||||
float *v1, *v2, *v3;
|
||||
vec3_t d1, d2;
|
||||
|
||||
v1 = verts[tri->indexes[0]].xyz;
|
||||
v2 = verts[tri->indexes[1]].xyz;
|
||||
v3 = verts[tri->indexes[2]].xyz;
|
||||
|
||||
VectorSubtract(v2, v1, d1);
|
||||
VectorSubtract(v3, v1, d2);
|
||||
|
||||
CrossProduct(d2, d1, tri->plane);
|
||||
tri->plane[3] = DotProduct(tri->plane, v1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CullLocalBox
|
||||
|
@ -1365,7 +1272,7 @@ R_PlaneForSurface
|
|||
=============
|
||||
*/
|
||||
void R_PlaneForSurface (surfaceType_t *surfType, cplane_t *plane) {
|
||||
srfTriangles_t *tri;
|
||||
srfBspSurface_t *tri;
|
||||
srfPoly_t *poly;
|
||||
srfVert_t *v1, *v2, *v3;
|
||||
vec4_t plane4;
|
||||
|
@ -1377,10 +1284,10 @@ void R_PlaneForSurface (surfaceType_t *surfType, cplane_t *plane) {
|
|||
}
|
||||
switch (*surfType) {
|
||||
case SF_FACE:
|
||||
*plane = ((srfSurfaceFace_t *)surfType)->plane;
|
||||
*plane = ((srfBspSurface_t *)surfType)->cullPlane;
|
||||
return;
|
||||
case SF_TRIANGLES:
|
||||
tri = (srfTriangles_t *)surfType;
|
||||
tri = (srfBspSurface_t *)surfType;
|
||||
v1 = tri->verts + tri->triangles[0].indexes[0];
|
||||
v2 = tri->verts + tri->triangles[0].indexes[1];
|
||||
v3 = tri->verts + tri->triangles[0].indexes[2];
|
||||
|
|
|
@ -268,7 +268,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
vec3_t clipPoints[2][MAX_VERTS_ON_POLY];
|
||||
int numClipPoints;
|
||||
float *v;
|
||||
srfGridMesh_t *cv;
|
||||
srfBspSurface_t *cv;
|
||||
srfTriangle_t *tri;
|
||||
srfVert_t *dv;
|
||||
vec3_t normal;
|
||||
|
@ -327,7 +327,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
|
||||
if (*surfaces[i] == SF_GRID) {
|
||||
|
||||
cv = (srfGridMesh_t *) surfaces[i];
|
||||
cv = (srfBspSurface_t *) surfaces[i];
|
||||
for ( m = 0 ; m < cv->height - 1 ; m++ ) {
|
||||
for ( n = 0 ; n < cv->width - 1 ; n++ ) {
|
||||
// We triangulate the grid and chop all triangles within
|
||||
|
@ -407,10 +407,10 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
}
|
||||
else if (*surfaces[i] == SF_FACE) {
|
||||
|
||||
srfSurfaceFace_t *surf = ( srfSurfaceFace_t * ) surfaces[i];
|
||||
srfBspSurface_t *surf = ( srfBspSurface_t * ) surfaces[i];
|
||||
|
||||
// check the normal of this face
|
||||
if (DotProduct(surf->plane.normal, projectionDir) > -0.5) {
|
||||
if (DotProduct(surf->cullPlane.normal, projectionDir) > -0.5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -419,7 +419,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
v = surf->verts[tri->indexes[j]].xyz;
|
||||
VectorMA(v, MARKER_OFFSET, surf->plane.normal, clipPoints[0][j]);
|
||||
VectorMA(v, MARKER_OFFSET, surf->cullPlane.normal, clipPoints[0][j]);
|
||||
}
|
||||
|
||||
// add the fragments of this face
|
||||
|
@ -435,7 +435,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
}
|
||||
else if(*surfaces[i] == SF_TRIANGLES && r_marksOnTriangleMeshes->integer) {
|
||||
|
||||
srfTriangles_t *surf = (srfTriangles_t *) surfaces[i];
|
||||
srfBspSurface_t *surf = (srfBspSurface_t *) surfaces[i];
|
||||
|
||||
for(k = 0, tri = surf->triangles; k < surf->numTriangles; k++, tri++)
|
||||
{
|
||||
|
|
|
@ -562,8 +562,6 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
|
|||
tri->indexes[2] = LittleLong(md3Tri->indexes[2]);
|
||||
}
|
||||
|
||||
R_CalcSurfaceTriangleNeighbors(surf->numTriangles, surf->triangles);
|
||||
|
||||
// swap all the XyzNormals
|
||||
surf->numVerts = md3Surf->numVerts;
|
||||
surf->verts = v = ri.Hunk_Alloc(sizeof(*v) * (md3Surf->numVerts * md3Surf->numFrames), h_low);
|
||||
|
|
|
@ -25,6 +25,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#define LL(x) x=LittleLong(x)
|
||||
|
||||
// 3x4 identity matrix
|
||||
static float identityMatrix[12] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0
|
||||
};
|
||||
|
||||
static qboolean IQM_CheckRange( iqmHeader_t *header, int offset,
|
||||
int count,int size ) {
|
||||
// return true if the range specified by offset, count and size
|
||||
|
@ -143,6 +150,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
iqmData_t *iqmData;
|
||||
srfIQModel_t *surface;
|
||||
char meshName[MAX_QPATH];
|
||||
byte blendIndexesType, blendWeightsType;
|
||||
|
||||
if( filesize < sizeof(iqmHeader_t) ) {
|
||||
return qfalse;
|
||||
|
@ -198,6 +206,8 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
blendIndexesType = blendWeightsType = IQM_UBYTE;
|
||||
|
||||
// check and swap vertex arrays
|
||||
if( IQM_CheckRange( header, header->ofs_vertexarrays,
|
||||
header->num_vertexarrays,
|
||||
|
@ -264,11 +274,20 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
}
|
||||
break;
|
||||
case IQM_BLENDINDEXES:
|
||||
if( (vertexarray->format != IQM_INT &&
|
||||
vertexarray->format != IQM_UBYTE) ||
|
||||
vertexarray->size != 4 ) {
|
||||
return qfalse;
|
||||
}
|
||||
blendIndexesType = vertexarray->format;
|
||||
break;
|
||||
case IQM_BLENDWEIGHTS:
|
||||
if( vertexarray->format != IQM_UBYTE ||
|
||||
if( (vertexarray->format != IQM_FLOAT &&
|
||||
vertexarray->format != IQM_UBYTE) ||
|
||||
vertexarray->size != 4 ) {
|
||||
return qfalse;
|
||||
}
|
||||
blendWeightsType = vertexarray->format;
|
||||
break;
|
||||
case IQM_COLOR:
|
||||
if( vertexarray->format != IQM_UBYTE ||
|
||||
|
@ -343,7 +362,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
}
|
||||
}
|
||||
|
||||
if( header->num_poses != header->num_joints ) {
|
||||
if( header->num_poses != header->num_joints && header->num_poses != 0 ) {
|
||||
ri.Printf(PRINT_WARNING, "R_LoadIQM: %s has %d poses and %d joints, must have the same number or 0 poses\n",
|
||||
mod_name, header->num_poses, header->num_joints );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -379,7 +400,10 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
joint_names += strlen( (char *)header + header->ofs_text +
|
||||
joint->name ) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( header->num_poses )
|
||||
{
|
||||
// check and swap poses
|
||||
if( IQM_CheckRange( header, header->ofs_poses,
|
||||
header->num_poses, sizeof(iqmPose_t) ) ) {
|
||||
|
@ -438,7 +462,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
size = sizeof(iqmData_t);
|
||||
size += header->num_meshes * sizeof( srfIQModel_t );
|
||||
size += header->num_joints * 12 * sizeof( float ); // joint mats
|
||||
size += header->num_joints * header->num_frames * 12 * sizeof( float ); // pose mats
|
||||
size += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats
|
||||
if(header->ofs_bounds)
|
||||
size += header->num_frames * 6 * sizeof(float); // model bounds
|
||||
size += header->num_vertexes * 3 * sizeof(float); // positions
|
||||
|
@ -446,12 +470,18 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
size += header->num_vertexes * 3 * sizeof(float); // normals
|
||||
size += header->num_vertexes * 4 * sizeof(float); // tangents
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // blendIndexes
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // blendWeights
|
||||
size += header->num_vertexes * 4 * sizeof(byte); // colors
|
||||
size += header->num_joints * sizeof(int); // parents
|
||||
size += header->num_triangles * 3 * sizeof(int); // triangles
|
||||
size += joint_names; // joint names
|
||||
|
||||
// blendWeights
|
||||
if (blendWeightsType == IQM_FLOAT) {
|
||||
size += header->num_vertexes * 4 * sizeof(float);
|
||||
} else {
|
||||
size += header->num_vertexes * 4 * sizeof(byte);
|
||||
}
|
||||
|
||||
mod->type = MOD_IQM;
|
||||
iqmData = (iqmData_t *)ri.Hunk_Alloc( size, h_low );
|
||||
mod->modelData = iqmData;
|
||||
|
@ -462,28 +492,40 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
iqmData->num_frames = header->num_frames;
|
||||
iqmData->num_surfaces = header->num_meshes;
|
||||
iqmData->num_joints = header->num_joints;
|
||||
iqmData->num_poses = header->num_poses;
|
||||
iqmData->blendWeightsType = blendWeightsType;
|
||||
iqmData->surfaces = (srfIQModel_t *)(iqmData + 1);
|
||||
iqmData->jointMats = (float *) (iqmData->surfaces + iqmData->num_surfaces);
|
||||
iqmData->poseMats = iqmData->jointMats + 12 * header->num_joints;
|
||||
if(header->ofs_bounds)
|
||||
{
|
||||
iqmData->bounds = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
|
||||
iqmData->bounds = iqmData->poseMats + 12 * header->num_poses * header->num_frames;
|
||||
iqmData->positions = iqmData->bounds + 6 * header->num_frames;
|
||||
}
|
||||
else
|
||||
iqmData->positions = iqmData->poseMats + 12 * header->num_joints * header->num_frames;
|
||||
iqmData->positions = iqmData->poseMats + 12 * header->num_poses * header->num_frames;
|
||||
iqmData->texcoords = iqmData->positions + 3 * header->num_vertexes;
|
||||
iqmData->normals = iqmData->texcoords + 2 * header->num_vertexes;
|
||||
iqmData->tangents = iqmData->normals + 3 * header->num_vertexes;
|
||||
iqmData->blendIndexes = (byte *)(iqmData->tangents + 4 * header->num_vertexes);
|
||||
iqmData->blendWeights = iqmData->blendIndexes + 4 * header->num_vertexes;
|
||||
iqmData->colors = iqmData->blendWeights + 4 * header->num_vertexes;
|
||||
|
||||
if(blendWeightsType == IQM_FLOAT) {
|
||||
iqmData->blendWeights.f = (float *)(iqmData->blendIndexes + 4 * header->num_vertexes);
|
||||
iqmData->colors = (byte *)(iqmData->blendWeights.f + 4 * header->num_vertexes);
|
||||
} else {
|
||||
iqmData->blendWeights.b = iqmData->blendIndexes + 4 * header->num_vertexes;
|
||||
iqmData->colors = iqmData->blendWeights.b + 4 * header->num_vertexes;
|
||||
}
|
||||
|
||||
iqmData->jointParents = (int *)(iqmData->colors + 4 * header->num_vertexes);
|
||||
iqmData->triangles = iqmData->jointParents + header->num_joints;
|
||||
iqmData->names = (char *)(iqmData->triangles + 3 * header->num_triangles);
|
||||
|
||||
if ( header->num_joints == 0 )
|
||||
iqmData->jointMats = iqmData->poseMats = NULL;
|
||||
iqmData->jointMats = NULL;
|
||||
|
||||
if ( header->num_poses == 0 )
|
||||
iqmData->poseMats = NULL;
|
||||
|
||||
// calculate joint matrices and their inverses
|
||||
// joint inverses are needed only until the pose matrices are calculated
|
||||
|
@ -620,14 +662,27 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
|||
n * sizeof(float) );
|
||||
break;
|
||||
case IQM_BLENDINDEXES:
|
||||
Com_Memcpy( iqmData->blendIndexes,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
if( blendIndexesType == IQM_INT ) {
|
||||
int *data = (int*)((byte*)header + vertexarray->offset);
|
||||
for ( j = 0; j < n; j++ ) {
|
||||
iqmData->blendIndexes[j] = (byte)data[j];
|
||||
}
|
||||
} else {
|
||||
Com_Memcpy( iqmData->blendIndexes,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
}
|
||||
break;
|
||||
case IQM_BLENDWEIGHTS:
|
||||
Com_Memcpy( iqmData->blendWeights,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
if( blendWeightsType == IQM_FLOAT ) {
|
||||
Com_Memcpy( iqmData->blendWeights.f,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(float) );
|
||||
} else {
|
||||
Com_Memcpy( iqmData->blendWeights.b,
|
||||
(byte *)header + vertexarray->offset,
|
||||
n * sizeof(byte) );
|
||||
}
|
||||
break;
|
||||
case IQM_COLOR:
|
||||
Com_Memcpy( iqmData->colors,
|
||||
|
@ -895,9 +950,21 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
|||
int *joint = data->jointParents;
|
||||
int i;
|
||||
|
||||
if ( oldframe == frame ) {
|
||||
mat1 = data->poseMats + 12 * data->num_joints * frame;
|
||||
if ( data->num_poses == 0 ) {
|
||||
for( i = 0; i < data->num_joints; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
Matrix34Multiply( mat + 12 * *joint,
|
||||
identityMatrix, mat + 12*i );
|
||||
} else {
|
||||
Com_Memcpy( mat + 12*i, identityMatrix, 12 * sizeof(float) );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( oldframe == frame ) {
|
||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
Matrix34Multiply( mat + 12 * *joint,
|
||||
mat1 + 12*i, mat + 12*i );
|
||||
|
@ -906,10 +973,10 @@ static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
mat1 = data->poseMats + 12 * data->num_joints * frame;
|
||||
mat2 = data->poseMats + 12 * data->num_joints * oldframe;
|
||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
||||
mat2 = data->poseMats + 12 * data->num_poses * oldframe;
|
||||
|
||||
for( i = 0; i < data->num_joints; i++, joint++ ) {
|
||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
||||
if( *joint >= 0 ) {
|
||||
float tmpMat[12];
|
||||
InterpolateMatrix( mat1 + 12*i, mat2 + 12*i,
|
||||
|
@ -977,7 +1044,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
outColor = &tess.vertexColors[tess.numVertexes];
|
||||
|
||||
// compute interpolated joint matrices
|
||||
if ( data->num_joints > 0 ) {
|
||||
if ( data->num_poses > 0 ) {
|
||||
ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
|
||||
}
|
||||
|
||||
|
@ -988,28 +1055,31 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
|||
float vtxMat[12];
|
||||
float nrmMat[9];
|
||||
int vtx = i + surf->first_vertex;
|
||||
float blendWeights[4];
|
||||
int numWeights;
|
||||
|
||||
if ( data->num_joints == 0 || data->blendWeights[4*vtx] <= 0 ) {
|
||||
for ( numWeights = 0; numWeights < 4; numWeights++ ) {
|
||||
if ( data->blendWeightsType == IQM_FLOAT )
|
||||
blendWeights[numWeights] = data->blendWeights.f[4*vtx + numWeights];
|
||||
else
|
||||
blendWeights[numWeights] = (float)data->blendWeights.b[4*vtx + numWeights] / 255.0f;
|
||||
|
||||
if ( blendWeights[numWeights] <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( data->num_poses == 0 || numWeights == 0 ) {
|
||||
// no blend joint, use identity matrix.
|
||||
for( j = 0; j < 3; j++ ) {
|
||||
for( k = 0; k < 4; k++ )
|
||||
vtxMat[4*j+k] = ( k == j ) ? 1 : 0;
|
||||
}
|
||||
Com_Memcpy( vtxMat, identityMatrix, 12 * sizeof (float) );
|
||||
} else {
|
||||
// compute the vertex matrix by blending the up to
|
||||
// four blend weights
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] = data->blendWeights[4*vtx]
|
||||
* jointMats[12*data->blendIndexes[4*vtx] + k];
|
||||
for( j = 1; j < 4; j++ ) {
|
||||
if( data->blendWeights[4*vtx + j] <= 0 )
|
||||
break;
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] += data->blendWeights[4*vtx + j]
|
||||
* jointMats[12*data->blendIndexes[4*vtx + j] + k];
|
||||
Com_Memset( vtxMat, 0, 12 * sizeof (float) );
|
||||
for( j = 0; j < numWeights; j++ ) {
|
||||
for( k = 0; k < 12; k++ ) {
|
||||
vtxMat[k] += blendWeights[j] * jointMats[12*data->blendIndexes[4*vtx + j] + k];
|
||||
}
|
||||
}
|
||||
for( k = 0; k < 12; k++ )
|
||||
vtxMat[k] *= 1.0f / 255.0f;
|
||||
}
|
||||
|
||||
// compute the normal matrix as transpose of the adjoint
|
||||
|
|
|
@ -221,14 +221,22 @@ extern float EvalWaveForm( const waveForm_t *wf );
|
|||
extern float EvalWaveFormClamped( const waveForm_t *wf );
|
||||
|
||||
|
||||
static void ComputeTexMatrix( shaderStage_t *pStage, int bundleNum, float *outmatrix)
|
||||
static void ComputeTexMods( shaderStage_t *pStage, int bundleNum, float *outMatrix, float *outOffTurb)
|
||||
{
|
||||
int tm;
|
||||
float matrix[16], currentmatrix[16];
|
||||
float matrix[6], currentmatrix[6];
|
||||
textureBundle_t *bundle = &pStage->bundle[bundleNum];
|
||||
|
||||
Matrix16Identity(outmatrix);
|
||||
Matrix16Identity(currentmatrix);
|
||||
matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = 0.0f;
|
||||
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = 0.0f;
|
||||
|
||||
currentmatrix[0] = 1.0f; currentmatrix[2] = 0.0f; currentmatrix[4] = 0.0f;
|
||||
currentmatrix[1] = 0.0f; currentmatrix[3] = 1.0f; currentmatrix[5] = 0.0f;
|
||||
|
||||
outMatrix[0] = 1.0f; outMatrix[2] = 0.0f;
|
||||
outMatrix[1] = 0.0f; outMatrix[3] = 1.0f;
|
||||
|
||||
outOffTurb[0] = 0.0f; outOffTurb[1] = 0.0f; outOffTurb[2] = 0.0f; outOffTurb[3] = 0.0f;
|
||||
|
||||
for ( tm = 0; tm < bundle->numTexMods ; tm++ ) {
|
||||
switch ( bundle->texMods[tm].type )
|
||||
|
@ -239,59 +247,73 @@ static void ComputeTexMatrix( shaderStage_t *pStage, int bundleNum, float *outma
|
|||
break;
|
||||
|
||||
case TMOD_TURBULENT:
|
||||
RB_CalcTurbulentTexMatrix( &bundle->texMods[tm].wave,
|
||||
matrix );
|
||||
outmatrix[12] = matrix[12];
|
||||
outmatrix[13] = matrix[13];
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
RB_CalcTurbulentFactors(&bundle->texMods[tm].wave, &outOffTurb[2], &outOffTurb[3]);
|
||||
break;
|
||||
|
||||
case TMOD_ENTITY_TRANSLATE:
|
||||
RB_CalcScrollTexMatrix( backEnd.currentEntity->e.shaderTexCoord,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
RB_CalcScrollTexMatrix( backEnd.currentEntity->e.shaderTexCoord, matrix );
|
||||
break;
|
||||
|
||||
case TMOD_SCROLL:
|
||||
RB_CalcScrollTexMatrix( bundle->texMods[tm].scroll,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
case TMOD_SCALE:
|
||||
RB_CalcScaleTexMatrix( bundle->texMods[tm].scale,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
case TMOD_STRETCH:
|
||||
RB_CalcStretchTexMatrix( &bundle->texMods[tm].wave,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
case TMOD_TRANSFORM:
|
||||
RB_CalcTransformTexMatrix( &bundle->texMods[tm],
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
case TMOD_ROTATE:
|
||||
RB_CalcRotateTexMatrix( bundle->texMods[tm].rotateSpeed,
|
||||
matrix );
|
||||
Matrix16Multiply(matrix, currentmatrix, outmatrix);
|
||||
Matrix16Copy(outmatrix, currentmatrix);
|
||||
break;
|
||||
|
||||
default:
|
||||
ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'", bundle->texMods[tm].type, tess.shader->name );
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( bundle->texMods[tm].type )
|
||||
{
|
||||
case TMOD_NONE:
|
||||
case TMOD_TURBULENT:
|
||||
default:
|
||||
break;
|
||||
|
||||
case TMOD_ENTITY_TRANSLATE:
|
||||
case TMOD_SCROLL:
|
||||
case TMOD_SCALE:
|
||||
case TMOD_STRETCH:
|
||||
case TMOD_TRANSFORM:
|
||||
case TMOD_ROTATE:
|
||||
outMatrix[0] = matrix[0] * currentmatrix[0] + matrix[2] * currentmatrix[1];
|
||||
outMatrix[1] = matrix[1] * currentmatrix[0] + matrix[3] * currentmatrix[1];
|
||||
|
||||
outMatrix[2] = matrix[0] * currentmatrix[2] + matrix[2] * currentmatrix[3];
|
||||
outMatrix[3] = matrix[1] * currentmatrix[2] + matrix[3] * currentmatrix[3];
|
||||
|
||||
outOffTurb[0] = matrix[0] * currentmatrix[4] + matrix[2] * currentmatrix[5] + matrix[4];
|
||||
outOffTurb[1] = matrix[1] * currentmatrix[4] + matrix[3] * currentmatrix[5] + matrix[5];
|
||||
|
||||
currentmatrix[0] = outMatrix[0];
|
||||
currentmatrix[1] = outMatrix[1];
|
||||
currentmatrix[2] = outMatrix[2];
|
||||
currentmatrix[3] = outMatrix[3];
|
||||
currentmatrix[4] = outOffTurb[0];
|
||||
currentmatrix[5] = outOffTurb[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,44 +445,27 @@ static void ProjectDlightTexture( void ) {
|
|||
|
||||
static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor )
|
||||
{
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] =
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
|
||||
//
|
||||
// rgbGen
|
||||
//
|
||||
switch ( pStage->rgbGen )
|
||||
{
|
||||
case CGEN_IDENTITY:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] =
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_IDENTITY_LIGHTING:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] = tr.identityLight;
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_EXACT_VERTEX:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] =
|
||||
baseColor[3] = 0.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 1.0f;
|
||||
break;
|
||||
case CGEN_EXACT_VERTEX_LIT:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
|
@ -477,11 +482,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[1] = pStage->constantColor[1] / 255.0f;
|
||||
baseColor[2] = pStage->constantColor[2] / 255.0f;
|
||||
baseColor[3] = pStage->constantColor[3] / 255.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_VERTEX:
|
||||
baseColor[0] =
|
||||
|
@ -509,12 +509,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] = tr.identityLight;
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] = -tr.identityLight;
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_FOG:
|
||||
{
|
||||
|
@ -527,22 +525,11 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f;
|
||||
baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f;
|
||||
}
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_WAVEFORM:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] = RB_CalcWaveColorSingle( &pStage->rgbWave );
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_ENTITY:
|
||||
if (backEnd.currentEntity)
|
||||
|
@ -552,11 +539,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[2] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f;
|
||||
baseColor[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
|
||||
}
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_ONE_MINUS_ENTITY:
|
||||
if (backEnd.currentEntity)
|
||||
|
@ -566,23 +548,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[2] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f;
|
||||
baseColor[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
|
||||
}
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case CGEN_IDENTITY:
|
||||
case CGEN_LIGHTING_DIFFUSE:
|
||||
case CGEN_BAD:
|
||||
baseColor[0] =
|
||||
baseColor[1] =
|
||||
baseColor[2] =
|
||||
baseColor[3] = 1.0f;
|
||||
|
||||
vertColor[0] =
|
||||
vertColor[1] =
|
||||
vertColor[2] =
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -593,10 +562,6 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
{
|
||||
case AGEN_SKIP:
|
||||
break;
|
||||
case AGEN_IDENTITY:
|
||||
baseColor[3] = 1.0f;
|
||||
vertColor[3] = 0.0f;
|
||||
break;
|
||||
case AGEN_CONST:
|
||||
baseColor[3] = pStage->constantColor[3] / 255.0f;
|
||||
vertColor[3] = 0.0f;
|
||||
|
@ -627,9 +592,9 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t
|
|||
baseColor[3] = 1.0f;
|
||||
vertColor[3] = -1.0f;
|
||||
break;
|
||||
case AGEN_IDENTITY:
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_PORTAL:
|
||||
case AGEN_FRESNEL:
|
||||
// Done entirely in vertex program
|
||||
baseColor[3] = 1.0f;
|
||||
vertColor[3] = 0.0f;
|
||||
|
@ -749,7 +714,8 @@ static void ForwardDlight( void ) {
|
|||
dlight_t *dl;
|
||||
shaderProgram_t *sp;
|
||||
vec4_t vector;
|
||||
matrix_t matrix;
|
||||
vec4_t texMatrix;
|
||||
vec4_t texOffTurb;
|
||||
|
||||
if ( !( tess.dlightBits & ( 1 << l ) ) ) {
|
||||
continue; // this surface definately doesn't have any of this light
|
||||
|
@ -776,6 +742,7 @@ static void ForwardDlight( void ) {
|
|||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_LOCALVIEWORIGIN, backEnd.or.viewOrigin);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
|
||||
|
@ -851,13 +818,9 @@ static void ForwardDlight( void ) {
|
|||
GL_SelectTexture(0);
|
||||
}
|
||||
|
||||
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
|
||||
|
||||
VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector);
|
||||
|
||||
VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
|
||||
ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
|
||||
|
||||
GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
|
||||
|
||||
|
@ -982,7 +945,7 @@ static void RB_FogPass( void ) {
|
|||
if (deformGen != DGEN_NONE)
|
||||
index |= FOGDEF_USE_DEFORM_VERTEXES;
|
||||
|
||||
if (glState.vertexAttribsInterpolation)
|
||||
if (glState.vertexAnimation)
|
||||
index |= FOGDEF_USE_VERTEX_ANIMATION;
|
||||
|
||||
sp = &tr.fogShader[index];
|
||||
|
@ -1039,7 +1002,7 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input )
|
|||
{
|
||||
unsigned int vertexAttribs = input->shader->vertexAttribs;
|
||||
|
||||
if(glState.vertexAttribsInterpolation > 0.0f)
|
||||
if(glState.vertexAnimation)
|
||||
{
|
||||
vertexAttribs |= ATTR_POSITION2;
|
||||
if (vertexAttribs & ATTR_NORMAL)
|
||||
|
@ -1058,7 +1021,6 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input )
|
|||
static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
||||
{
|
||||
int stage;
|
||||
matrix_t matrix;
|
||||
|
||||
vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0};
|
||||
float eyeT = 0;
|
||||
|
@ -1074,6 +1036,8 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
{
|
||||
shaderStage_t *pStage = input->xstages[stage];
|
||||
shaderProgram_t *sp;
|
||||
vec4_t texMatrix;
|
||||
vec4_t texOffTurb;
|
||||
|
||||
if ( !pStage )
|
||||
{
|
||||
|
@ -1082,7 +1046,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
|
||||
if (backEnd.depthFill)
|
||||
{
|
||||
if (pStage->glslShaderGroup)
|
||||
if (pStage->glslShaderGroup == tr.lightallShader)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
|
@ -1107,7 +1071,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES;
|
||||
}
|
||||
|
||||
if (glState.vertexAttribsInterpolation > 0.0f && backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
|
||||
if (glState.vertexAnimation)
|
||||
{
|
||||
shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION;
|
||||
}
|
||||
|
@ -1120,7 +1084,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
sp = &tr.genericShader[shaderAttribs];
|
||||
}
|
||||
}
|
||||
else if (pStage->glslShaderGroup)
|
||||
else if (pStage->glslShaderGroup == tr.lightallShader)
|
||||
{
|
||||
int index = pStage->glslShaderIndex;
|
||||
|
||||
|
@ -1146,10 +1110,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
|
||||
sp = &pStage->glslShaderGroup[index];
|
||||
|
||||
if (pStage->glslShaderGroup == tr.lightallShader)
|
||||
{
|
||||
backEnd.pc.c_lightallDraws++;
|
||||
}
|
||||
backEnd.pc.c_lightallDraws++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1162,6 +1123,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
|
||||
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_LOCALVIEWORIGIN, backEnd.or.viewOrigin);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
|
||||
|
||||
|
@ -1210,8 +1172,9 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
VectorCopy(backEnd.currentEntity->lightDir, vec);
|
||||
vec[3] = 0.0f;
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, vec);
|
||||
GLSL_SetUniformVec3(sp, UNIFORM_MODELLIGHTDIR, backEnd.currentEntity->modelLightDir);
|
||||
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 999999.0f);
|
||||
GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 0.0f);
|
||||
}
|
||||
|
||||
if (pStage->alphaGen == AGEN_PORTAL)
|
||||
|
@ -1231,16 +1194,9 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask);
|
||||
}
|
||||
|
||||
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
|
||||
|
||||
{
|
||||
vec4_t vector;
|
||||
VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector);
|
||||
|
||||
VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
|
||||
}
|
||||
ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
|
||||
|
||||
GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
|
||||
if (pStage->bundle[0].tcGen == TCGEN_VECTOR)
|
||||
|
@ -1269,7 +1225,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 )
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP );
|
||||
}
|
||||
else if ( pStage->glslShaderGroup )
|
||||
else if ( pStage->glslShaderGroup == tr.lightallShader )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1285,13 +1241,27 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
{
|
||||
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
|
||||
{
|
||||
if (i == TB_LIGHTMAP)
|
||||
if (pStage->bundle[i].image[0])
|
||||
{
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[i], i);
|
||||
}
|
||||
else if (pStage->bundle[i].image[0])
|
||||
{
|
||||
GL_BindToTMU( tr.whiteImage, i);
|
||||
switch(i)
|
||||
{
|
||||
case TB_LIGHTMAP:
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i);
|
||||
break;
|
||||
|
||||
case TB_DIFFUSEMAP:
|
||||
case TB_SPECULARMAP:
|
||||
case TB_SHADOWMAP:
|
||||
case TB_CUBEMAP:
|
||||
default:
|
||||
GL_BindToTMU( tr.whiteImage, i);
|
||||
break;
|
||||
|
||||
case TB_NORMALMAP:
|
||||
case TB_DELUXEMAP:
|
||||
GL_BindToTMU( tr.greyImage, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1299,15 +1269,30 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
{
|
||||
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
|
||||
{
|
||||
if (i == TB_LIGHTMAP)
|
||||
if (pStage->bundle[i].image[0])
|
||||
{
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i);
|
||||
}
|
||||
else if (pStage->bundle[i].image[0])
|
||||
{
|
||||
GL_BindToTMU( tr.whiteImage, i);
|
||||
switch(i)
|
||||
{
|
||||
case TB_LIGHTMAP:
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i);
|
||||
break;
|
||||
|
||||
case TB_DIFFUSEMAP:
|
||||
case TB_SPECULARMAP:
|
||||
case TB_SHADOWMAP:
|
||||
case TB_CUBEMAP:
|
||||
default:
|
||||
GL_BindToTMU( tr.whiteImage, i);
|
||||
break;
|
||||
|
||||
case TB_NORMALMAP:
|
||||
case TB_DELUXEMAP:
|
||||
GL_BindToTMU( tr.greyImage, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1340,12 +1325,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
//
|
||||
// set state
|
||||
//
|
||||
if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer )
|
||||
{
|
||||
GL_BindToTMU( tr.whiteImage, 0 );
|
||||
}
|
||||
else
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 );
|
||||
R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 );
|
||||
|
||||
GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, 0);
|
||||
}
|
||||
|
@ -1369,7 +1349,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
}
|
||||
|
||||
// allow skipping out to show just lightmaps during development
|
||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) )
|
||||
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -84,42 +84,16 @@ static float EvalWaveFormClamped( const waveForm_t *wf )
|
|||
}
|
||||
|
||||
/*
|
||||
** RB_CalcStretchTexCoords
|
||||
** RB_CalcStretchTexMatrix
|
||||
*/
|
||||
void RB_CalcStretchTexCoords( const waveForm_t *wf, float *st )
|
||||
{
|
||||
float p;
|
||||
texModInfo_t tmi;
|
||||
|
||||
p = 1.0f / EvalWaveForm( wf );
|
||||
|
||||
tmi.matrix[0][0] = p;
|
||||
tmi.matrix[1][0] = 0;
|
||||
tmi.translate[0] = 0.5f - 0.5f * p;
|
||||
|
||||
tmi.matrix[0][1] = 0;
|
||||
tmi.matrix[1][1] = p;
|
||||
tmi.translate[1] = 0.5f - 0.5f * p;
|
||||
|
||||
RB_CalcTransformTexCoords( &tmi, st );
|
||||
}
|
||||
|
||||
void RB_CalcStretchTexMatrix( const waveForm_t *wf, float *matrix )
|
||||
{
|
||||
float p;
|
||||
texModInfo_t tmi;
|
||||
|
||||
p = 1.0f / EvalWaveForm( wf );
|
||||
|
||||
tmi.matrix[0][0] = p;
|
||||
tmi.matrix[1][0] = 0;
|
||||
tmi.translate[0] = 0.5f - 0.5f * p;
|
||||
|
||||
tmi.matrix[0][1] = 0;
|
||||
tmi.matrix[1][1] = p;
|
||||
tmi.translate[1] = 0.5f - 0.5f * p;
|
||||
|
||||
RB_CalcTransformTexMatrix( &tmi, matrix );
|
||||
matrix[0] = p; matrix[2] = 0; matrix[4] = 0.5f - 0.5f * p;
|
||||
matrix[1] = 0; matrix[3] = p; matrix[5] = 0.5f - 0.5f * p;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -618,88 +592,6 @@ COLORS
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
** RB_CalcColorFromEntity
|
||||
*/
|
||||
void RB_CalcColorFromEntity( unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
int *pColors = ( int * ) dstColors;
|
||||
int c;
|
||||
|
||||
if ( !backEnd.currentEntity )
|
||||
return;
|
||||
|
||||
c = * ( int * ) backEnd.currentEntity->e.shaderRGBA;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, pColors++ )
|
||||
{
|
||||
*pColors = c;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcColorFromOneMinusEntity
|
||||
*/
|
||||
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
int *pColors = ( int * ) dstColors;
|
||||
unsigned char invModulate[4];
|
||||
int c;
|
||||
|
||||
if ( !backEnd.currentEntity )
|
||||
return;
|
||||
|
||||
invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
|
||||
invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
|
||||
invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
|
||||
invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3]; // this trashes alpha, but the AGEN block fixes it
|
||||
|
||||
c = * ( int * ) invModulate;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, pColors++ )
|
||||
{
|
||||
*pColors = c;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcAlphaFromEntity
|
||||
*/
|
||||
void RB_CalcAlphaFromEntity( unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !backEnd.currentEntity )
|
||||
return;
|
||||
|
||||
dstColors += 3;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
|
||||
{
|
||||
*dstColors = backEnd.currentEntity->e.shaderRGBA[3];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcAlphaFromOneMinusEntity
|
||||
*/
|
||||
void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !backEnd.currentEntity )
|
||||
return;
|
||||
|
||||
dstColors += 3;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
|
||||
{
|
||||
*dstColors = 0xff - backEnd.currentEntity->e.shaderRGBA[3];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcWaveColorSingle
|
||||
*/
|
||||
|
@ -723,29 +615,6 @@ float RB_CalcWaveColorSingle( const waveForm_t *wf )
|
|||
return glow;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcWaveColor
|
||||
*/
|
||||
void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
int v;
|
||||
float glow;
|
||||
int *colors = ( int * ) dstColors;
|
||||
byte color[4];
|
||||
|
||||
glow = RB_CalcWaveColorSingle( wf );
|
||||
|
||||
v = ri.ftol(255 * glow);
|
||||
color[0] = color[1] = color[2] = v;
|
||||
color[3] = 255;
|
||||
v = *(int *)color;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, colors++ ) {
|
||||
*colors = v;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcWaveAlphaSingle
|
||||
*/
|
||||
|
@ -754,25 +623,6 @@ float RB_CalcWaveAlphaSingle( const waveForm_t *wf )
|
|||
return EvalWaveFormClamped( wf );
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcWaveAlpha
|
||||
*/
|
||||
void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors )
|
||||
{
|
||||
int i;
|
||||
int v;
|
||||
float glow;
|
||||
|
||||
glow = EvalWaveFormClamped( wf );
|
||||
|
||||
v = 255 * glow;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
|
||||
{
|
||||
dstColors[3] = v;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcModulateColorsByFog
|
||||
*/
|
||||
|
@ -793,45 +643,6 @@ void RB_CalcModulateColorsByFog( unsigned char *colors ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcModulateAlphasByFog
|
||||
*/
|
||||
void RB_CalcModulateAlphasByFog( unsigned char *colors ) {
|
||||
int i;
|
||||
float texCoords[SHADER_MAX_VERTEXES][2];
|
||||
|
||||
// calculate texcoords so we can derive density
|
||||
// this is not wasted, because it would only have
|
||||
// been previously called if the surface was opaque
|
||||
RB_CalcFogTexCoords( texCoords[0] );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
|
||||
float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
|
||||
colors[3] *= f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcModulateRGBAsByFog
|
||||
*/
|
||||
void RB_CalcModulateRGBAsByFog( unsigned char *colors ) {
|
||||
int i;
|
||||
float texCoords[SHADER_MAX_VERTEXES][2];
|
||||
|
||||
// calculate texcoords so we can derive density
|
||||
// this is not wasted, because it would only have
|
||||
// been previously called if the surface was opaque
|
||||
RB_CalcFogTexCoords( texCoords[0] );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
|
||||
float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
|
||||
colors[0] *= f;
|
||||
colors[1] *= f;
|
||||
colors[2] *= f;
|
||||
colors[3] *= f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
@ -928,118 +739,27 @@ void RB_CalcFogTexCoords( float *st ) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** RB_CalcEnvironmentTexCoords
|
||||
** RB_CalcTurbulentFactors
|
||||
*/
|
||||
void RB_CalcEnvironmentTexCoords( float *st )
|
||||
void RB_CalcTurbulentFactors( const waveForm_t *wf, float *amplitude, float *now )
|
||||
{
|
||||
int i;
|
||||
float *v, *normal;
|
||||
vec3_t viewer, reflected;
|
||||
float d;
|
||||
|
||||
v = tess.xyz[0];
|
||||
normal = tess.normal[0];
|
||||
|
||||
for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
|
||||
{
|
||||
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
|
||||
VectorNormalizeFast (viewer);
|
||||
|
||||
d = DotProduct (normal, viewer);
|
||||
|
||||
reflected[0] = normal[0]*2*d - viewer[0];
|
||||
reflected[1] = normal[1]*2*d - viewer[1];
|
||||
reflected[2] = normal[2]*2*d - viewer[2];
|
||||
|
||||
st[0] = 0.5 + reflected[1] * 0.5;
|
||||
st[1] = 0.5 - reflected[2] * 0.5;
|
||||
}
|
||||
*now = wf->phase + tess.shaderTime * wf->frequency;
|
||||
*amplitude = wf->amplitude;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcTurbulentTexCoords
|
||||
** RB_CalcScaleTexMatrix
|
||||
*/
|
||||
void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st )
|
||||
{
|
||||
int i;
|
||||
float now;
|
||||
|
||||
now = ( wf->phase + tess.shaderTime * wf->frequency );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, st += 2 )
|
||||
{
|
||||
float s = st[0];
|
||||
float t = st[1];
|
||||
|
||||
st[0] = s + tr.sinTable[ ( ( int ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] )* 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
|
||||
st[1] = t + tr.sinTable[ ( ( int ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcTurbulentTexMatrix( const waveForm_t *wf, matrix_t matrix )
|
||||
{
|
||||
float now;
|
||||
|
||||
now = ( wf->phase + tess.shaderTime * wf->frequency );
|
||||
|
||||
// bit of a hack here, hide amplitude and now in the matrix
|
||||
// the vertex program will extract them and perform a turbulent pass last if it's nonzero
|
||||
|
||||
matrix[ 0] = 1.0f; matrix[ 4] = 0.0f; matrix[ 8] = 0.0f; matrix[12] = wf->amplitude;
|
||||
matrix[ 1] = 0.0f; matrix[ 5] = 1.0f; matrix[ 9] = 0.0f; matrix[13] = now;
|
||||
matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f;
|
||||
matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcScaleTexCoords
|
||||
*/
|
||||
void RB_CalcScaleTexCoords( const float scale[2], float *st )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, st += 2 )
|
||||
{
|
||||
st[0] *= scale[0];
|
||||
st[1] *= scale[1];
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcScaleTexMatrix( const float scale[2], float *matrix )
|
||||
{
|
||||
matrix[ 0] = scale[0]; matrix[ 4] = 0.0f; matrix[ 8] = 0.0f; matrix[12] = 0.0f;
|
||||
matrix[ 1] = 0.0f; matrix[ 5] = scale[1]; matrix[ 9] = 0.0f; matrix[13] = 0.0f;
|
||||
matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f;
|
||||
matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f;
|
||||
matrix[0] = scale[0]; matrix[2] = 0.0f; matrix[4] = 0.0f;
|
||||
matrix[1] = 0.0f; matrix[3] = scale[1]; matrix[5] = 0.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcScrollTexCoords
|
||||
** RB_CalcScrollTexMatrix
|
||||
*/
|
||||
void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st )
|
||||
{
|
||||
int i;
|
||||
float timeScale = tess.shaderTime;
|
||||
float adjustedScrollS, adjustedScrollT;
|
||||
|
||||
adjustedScrollS = scrollSpeed[0] * timeScale;
|
||||
adjustedScrollT = scrollSpeed[1] * timeScale;
|
||||
|
||||
// clamp so coordinates don't continuously get larger, causing problems
|
||||
// with hardware limits
|
||||
adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
|
||||
adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, st += 2 )
|
||||
{
|
||||
st[0] += adjustedScrollS;
|
||||
st[1] += adjustedScrollT;
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
|
||||
{
|
||||
float timeScale = tess.shaderTime;
|
||||
|
@ -1053,73 +773,28 @@ void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
|
|||
adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
|
||||
adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
|
||||
|
||||
|
||||
matrix[ 0] = 1.0f; matrix[ 4] = 0.0f; matrix[ 8] = adjustedScrollS; matrix[12] = 0.0f;
|
||||
matrix[ 1] = 0.0f; matrix[ 5] = 1.0f; matrix[ 9] = adjustedScrollT; matrix[13] = 0.0f;
|
||||
matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f;
|
||||
matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f;
|
||||
matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = adjustedScrollS;
|
||||
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = adjustedScrollT;
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcTransformTexCoords
|
||||
** RB_CalcTransformTexMatrix
|
||||
*/
|
||||
void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *st )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, st += 2 )
|
||||
{
|
||||
float s = st[0];
|
||||
float t = st[1];
|
||||
|
||||
st[0] = s * tmi->matrix[0][0] + t * tmi->matrix[1][0] + tmi->translate[0];
|
||||
st[1] = s * tmi->matrix[0][1] + t * tmi->matrix[1][1] + tmi->translate[1];
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcTransformTexMatrix( const texModInfo_t *tmi, float *matrix )
|
||||
{
|
||||
matrix[ 0] = tmi->matrix[0][0]; matrix[ 4] = tmi->matrix[1][0]; matrix[ 8] = tmi->translate[0]; matrix[12] = 0.0f;
|
||||
matrix[ 1] = tmi->matrix[0][1]; matrix[ 5] = tmi->matrix[1][1]; matrix[ 9] = tmi->translate[1]; matrix[13] = 0.0f;
|
||||
matrix[ 2] = 0.0f; matrix[ 6] = 0.0f; matrix[10] = 1.0f; matrix[14] = 0.0f;
|
||||
matrix[ 3] = 0.0f; matrix[ 7] = 0.0f; matrix[11] = 0.0f; matrix[15] = 1.0f;
|
||||
matrix[0] = tmi->matrix[0][0]; matrix[2] = tmi->matrix[1][0]; matrix[4] = tmi->translate[0];
|
||||
matrix[1] = tmi->matrix[0][1]; matrix[3] = tmi->matrix[1][1]; matrix[5] = tmi->translate[1];
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcRotateTexCoords
|
||||
** RB_CalcRotateTexMatrix
|
||||
*/
|
||||
void RB_CalcRotateTexCoords( float degsPerSecond, float *st )
|
||||
{
|
||||
float timeScale = tess.shaderTime;
|
||||
float degs;
|
||||
int index;
|
||||
float sinValue, cosValue;
|
||||
texModInfo_t tmi;
|
||||
|
||||
degs = -degsPerSecond * timeScale;
|
||||
index = degs * ( FUNCTABLE_SIZE / 360.0f );
|
||||
|
||||
sinValue = tr.sinTable[ index & FUNCTABLE_MASK ];
|
||||
cosValue = tr.sinTable[ ( index + FUNCTABLE_SIZE / 4 ) & FUNCTABLE_MASK ];
|
||||
|
||||
tmi.matrix[0][0] = cosValue;
|
||||
tmi.matrix[1][0] = -sinValue;
|
||||
tmi.translate[0] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
|
||||
|
||||
tmi.matrix[0][1] = sinValue;
|
||||
tmi.matrix[1][1] = cosValue;
|
||||
tmi.translate[1] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
|
||||
|
||||
RB_CalcTransformTexCoords( &tmi, st );
|
||||
}
|
||||
|
||||
void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix )
|
||||
{
|
||||
float timeScale = tess.shaderTime;
|
||||
float degs;
|
||||
int index;
|
||||
float sinValue, cosValue;
|
||||
texModInfo_t tmi;
|
||||
|
||||
degs = -degsPerSecond * timeScale;
|
||||
index = degs * ( FUNCTABLE_SIZE / 360.0f );
|
||||
|
@ -1127,213 +802,6 @@ void RB_CalcRotateTexMatrix( float degsPerSecond, float *matrix )
|
|||
sinValue = tr.sinTable[ index & FUNCTABLE_MASK ];
|
||||
cosValue = tr.sinTable[ ( index + FUNCTABLE_SIZE / 4 ) & FUNCTABLE_MASK ];
|
||||
|
||||
tmi.matrix[0][0] = cosValue;
|
||||
tmi.matrix[1][0] = -sinValue;
|
||||
tmi.translate[0] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
|
||||
|
||||
tmi.matrix[0][1] = sinValue;
|
||||
tmi.matrix[1][1] = cosValue;
|
||||
tmi.translate[1] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
|
||||
|
||||
RB_CalcTransformTexMatrix( &tmi, matrix );
|
||||
matrix[0] = cosValue; matrix[2] = -sinValue; matrix[4] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
|
||||
matrix[1] = sinValue; matrix[3] = cosValue; matrix[5] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
|
||||
}
|
||||
/*
|
||||
** RB_CalcSpecularAlpha
|
||||
**
|
||||
** Calculates specular coefficient and places it in the alpha channel
|
||||
*/
|
||||
vec3_t lightOrigin = { -960, 1980, 96 }; // FIXME: track dynamically
|
||||
|
||||
void RB_CalcSpecularAlpha( unsigned char *alphas ) {
|
||||
int i;
|
||||
float *v, *normal;
|
||||
vec3_t viewer, reflected;
|
||||
float l, d;
|
||||
int b;
|
||||
vec3_t lightDir;
|
||||
int numVertexes;
|
||||
|
||||
v = tess.xyz[0];
|
||||
normal = tess.normal[0];
|
||||
|
||||
alphas += 3;
|
||||
|
||||
numVertexes = tess.numVertexes;
|
||||
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4, alphas += 4) {
|
||||
float ilength;
|
||||
|
||||
VectorSubtract( lightOrigin, v, lightDir );
|
||||
// ilength = Q_rsqrt( DotProduct( lightDir, lightDir ) );
|
||||
VectorNormalizeFast( lightDir );
|
||||
|
||||
// calculate the specular color
|
||||
d = DotProduct (normal, lightDir);
|
||||
// d *= ilength;
|
||||
|
||||
// we don't optimize for the d < 0 case since this tends to
|
||||
// cause visual artifacts such as faceted "snapping"
|
||||
reflected[0] = normal[0]*2*d - lightDir[0];
|
||||
reflected[1] = normal[1]*2*d - lightDir[1];
|
||||
reflected[2] = normal[2]*2*d - lightDir[2];
|
||||
|
||||
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
|
||||
ilength = Q_rsqrt( DotProduct( viewer, viewer ) );
|
||||
l = DotProduct (reflected, viewer);
|
||||
l *= ilength;
|
||||
|
||||
if (l < 0) {
|
||||
b = 0;
|
||||
} else {
|
||||
l = l*l;
|
||||
l = l*l;
|
||||
b = l * 255;
|
||||
if (b > 255) {
|
||||
b = 255;
|
||||
}
|
||||
}
|
||||
|
||||
*alphas = b;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** RB_CalcDiffuseColor
|
||||
**
|
||||
** The basic vertex lighting calc
|
||||
*/
|
||||
#if idppc_altivec
|
||||
static void RB_CalcDiffuseColor_altivec( unsigned char *colors )
|
||||
{
|
||||
int i;
|
||||
float *v, *normal;
|
||||
trRefEntity_t *ent;
|
||||
int ambientLightInt;
|
||||
vec3_t lightDir;
|
||||
int numVertexes;
|
||||
vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff);
|
||||
vector float ambientLightVec;
|
||||
vector float directedLightVec;
|
||||
vector float lightDirVec;
|
||||
vector float normalVec0, normalVec1;
|
||||
vector float incomingVec0, incomingVec1, incomingVec2;
|
||||
vector float zero, jVec;
|
||||
vector signed int jVecInt;
|
||||
vector signed short jVecShort;
|
||||
vector unsigned char jVecChar, normalPerm;
|
||||
ent = backEnd.currentEntity;
|
||||
ambientLightInt = ent->ambientLightInt;
|
||||
// A lot of this could be simplified if we made sure
|
||||
// entities light info was 16-byte aligned.
|
||||
jVecChar = vec_lvsl(0, ent->ambientLight);
|
||||
ambientLightVec = vec_ld(0, (vector float *)ent->ambientLight);
|
||||
jVec = vec_ld(11, (vector float *)ent->ambientLight);
|
||||
ambientLightVec = vec_perm(ambientLightVec,jVec,jVecChar);
|
||||
|
||||
jVecChar = vec_lvsl(0, ent->directedLight);
|
||||
directedLightVec = vec_ld(0,(vector float *)ent->directedLight);
|
||||
jVec = vec_ld(11,(vector float *)ent->directedLight);
|
||||
directedLightVec = vec_perm(directedLightVec,jVec,jVecChar);
|
||||
|
||||
jVecChar = vec_lvsl(0, ent->lightDir);
|
||||
lightDirVec = vec_ld(0,(vector float *)ent->lightDir);
|
||||
jVec = vec_ld(11,(vector float *)ent->lightDir);
|
||||
lightDirVec = vec_perm(lightDirVec,jVec,jVecChar);
|
||||
|
||||
zero = (vector float)vec_splat_s8(0);
|
||||
VectorCopy( ent->lightDir, lightDir );
|
||||
|
||||
v = tess.xyz[0];
|
||||
normal = tess.normal[0];
|
||||
|
||||
normalPerm = vec_lvsl(0,normal);
|
||||
numVertexes = tess.numVertexes;
|
||||
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
|
||||
normalVec0 = vec_ld(0,(vector float *)normal);
|
||||
normalVec1 = vec_ld(11,(vector float *)normal);
|
||||
normalVec0 = vec_perm(normalVec0,normalVec1,normalPerm);
|
||||
incomingVec0 = vec_madd(normalVec0, lightDirVec, zero);
|
||||
incomingVec1 = vec_sld(incomingVec0,incomingVec0,4);
|
||||
incomingVec2 = vec_add(incomingVec0,incomingVec1);
|
||||
incomingVec1 = vec_sld(incomingVec1,incomingVec1,4);
|
||||
incomingVec2 = vec_add(incomingVec2,incomingVec1);
|
||||
incomingVec0 = vec_splat(incomingVec2,0);
|
||||
incomingVec0 = vec_max(incomingVec0,zero);
|
||||
normalPerm = vec_lvsl(12,normal);
|
||||
jVec = vec_madd(incomingVec0, directedLightVec, ambientLightVec);
|
||||
jVecInt = vec_cts(jVec,0); // RGBx
|
||||
jVecShort = vec_pack(jVecInt,jVecInt); // RGBxRGBx
|
||||
jVecChar = vec_packsu(jVecShort,jVecShort); // RGBxRGBxRGBxRGBx
|
||||
jVecChar = vec_sel(jVecChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
|
||||
vec_ste((vector unsigned int)jVecChar,0,(unsigned int *)&colors[i*4]); // store color
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void RB_CalcDiffuseColor_scalar( unsigned char *colors )
|
||||
{
|
||||
int i, j;
|
||||
float *v, *normal;
|
||||
float incoming;
|
||||
trRefEntity_t *ent;
|
||||
int ambientLightInt;
|
||||
vec3_t ambientLight;
|
||||
vec3_t lightDir;
|
||||
vec3_t directedLight;
|
||||
int numVertexes;
|
||||
ent = backEnd.currentEntity;
|
||||
ambientLightInt = ent->ambientLightInt;
|
||||
VectorCopy( ent->ambientLight, ambientLight );
|
||||
VectorCopy( ent->directedLight, directedLight );
|
||||
VectorCopy( ent->lightDir, lightDir );
|
||||
|
||||
v = tess.xyz[0];
|
||||
normal = tess.normal[0];
|
||||
|
||||
numVertexes = tess.numVertexes;
|
||||
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
|
||||
incoming = DotProduct (normal, lightDir);
|
||||
if ( incoming <= 0 ) {
|
||||
*(int *)&colors[i*4] = ambientLightInt;
|
||||
continue;
|
||||
}
|
||||
j = ri.ftol(ambientLight[0] + incoming * directedLight[0]);
|
||||
if ( j > 255 ) {
|
||||
j = 255;
|
||||
}
|
||||
colors[i*4+0] = j;
|
||||
|
||||
j = ri.ftol(ambientLight[1] + incoming * directedLight[1]);
|
||||
if ( j > 255 ) {
|
||||
j = 255;
|
||||
}
|
||||
colors[i*4+1] = j;
|
||||
|
||||
j = ri.ftol(ambientLight[2] + incoming * directedLight[2]);
|
||||
if ( j > 255 ) {
|
||||
j = 255;
|
||||
}
|
||||
colors[i*4+2] = j;
|
||||
|
||||
colors[i*4+3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcDiffuseColor( unsigned char *colors )
|
||||
{
|
||||
#if idppc_altivec
|
||||
if (com_altivec->integer) {
|
||||
// must be in a seperate function or G3 systems will crash.
|
||||
RB_CalcDiffuseColor_altivec( colors );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
RB_CalcDiffuseColor_scalar( colors );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1109,10 +1109,6 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
|
|||
shader.portalRange = atof( token );
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( token, "fresnel" ) )
|
||||
{
|
||||
stage->alphaGen = AGEN_FRESNEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: unknown alphaGen parameter '%s' in shader '%s'\n", token, shader.name );
|
||||
|
@ -2011,7 +2007,6 @@ static void ComputeVertexAttribs(void)
|
|||
switch(pStage->alphaGen)
|
||||
{
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_FRESNEL:
|
||||
shader.vertexAttribs |= ATTR_NORMAL;
|
||||
break;
|
||||
|
||||
|
@ -2247,15 +2242,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse,
|
|||
defs |= LIGHTDEF_USE_PARALLAXMAP;
|
||||
}
|
||||
}
|
||||
|
||||
if (!diffuse->bundle[TB_NORMALMAP].image[0])
|
||||
{
|
||||
// use 0x80 image, shader will interpret as (0,0,1)
|
||||
diffuse->bundle[TB_NORMALMAP] = diffuse->bundle[0];
|
||||
diffuse->bundle[TB_NORMALMAP].numImageAnimations = 0;
|
||||
diffuse->bundle[TB_NORMALMAP].image[0] = tr.greyImage;
|
||||
//ri.Printf(PRINT_ALL, ", normalmap %s", diffuse->bundle[TB_NORMALMAP].image[0]->imgName);
|
||||
}
|
||||
}
|
||||
|
||||
if (r_specularMapping->integer)
|
||||
|
@ -2267,18 +2253,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse,
|
|||
diffuse->materialInfo[0] = specular->materialInfo[0];
|
||||
diffuse->materialInfo[1] = specular->materialInfo[1];
|
||||
}
|
||||
else if (lightmap || useLightVector || useLightVertex)
|
||||
{
|
||||
// use a white image, materialinfo will do the rest
|
||||
diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[0];
|
||||
diffuse->bundle[TB_SPECULARMAP].numImageAnimations = 0;
|
||||
diffuse->bundle[TB_SPECULARMAP].image[0] = tr.whiteImage;
|
||||
if (!diffuse->materialInfo[0])
|
||||
diffuse->materialInfo[0] = r_baseSpecular->value;
|
||||
if (!diffuse->materialInfo[1])
|
||||
diffuse->materialInfo[1] = r_baseGloss->value;
|
||||
//ri.Printf(PRINT_ALL, ", specularmap %s", diffuse->bundle[TB_SPECULARMAP].image[0]->imgName);
|
||||
}
|
||||
}
|
||||
|
||||
if (tcgen || diffuse->bundle[0].numTexMods)
|
||||
|
@ -2308,7 +2282,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
{
|
||||
// if 2+ stages and first stage is lightmap, switch them
|
||||
// this makes it easier for the later bits to process
|
||||
if (stages[0].active && stages[0].bundle[0].isLightmap && stages[1].active)
|
||||
if (stages[0].active && stages[0].bundle[0].tcGen == TCGEN_LIGHTMAP && stages[1].active)
|
||||
{
|
||||
int blendBits = stages[1].stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
|
||||
|
||||
|
@ -2345,7 +2319,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
break;
|
||||
}
|
||||
|
||||
if (pStage->bundle[0].isLightmap)
|
||||
if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
|
||||
{
|
||||
int blendBits = pStage->stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
|
||||
|
||||
|
@ -2362,6 +2336,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
case TCGEN_TEXTURE:
|
||||
case TCGEN_LIGHTMAP:
|
||||
case TCGEN_ENVIRONMENT_MAPPED:
|
||||
case TCGEN_VECTOR:
|
||||
break;
|
||||
default:
|
||||
skip = qtrue;
|
||||
|
@ -2372,7 +2347,6 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
{
|
||||
case AGEN_LIGHTING_SPECULAR:
|
||||
case AGEN_PORTAL:
|
||||
case AGEN_FRESNEL:
|
||||
skip = qtrue;
|
||||
break;
|
||||
default:
|
||||
|
@ -2397,7 +2371,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
continue;
|
||||
|
||||
// skip lightmaps
|
||||
if (pStage->bundle[0].isLightmap)
|
||||
if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
|
||||
continue;
|
||||
|
||||
diffuse = pStage;
|
||||
|
@ -2439,7 +2413,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
break;
|
||||
|
||||
case ST_COLORMAP:
|
||||
if (pStage2->bundle[0].isLightmap)
|
||||
if (pStage2->bundle[0].tcGen == TCGEN_LIGHTMAP)
|
||||
{
|
||||
lightmap = pStage2;
|
||||
}
|
||||
|
@ -2481,7 +2455,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
if (!pStage->active)
|
||||
continue;
|
||||
|
||||
if (pStage->bundle[0].isLightmap)
|
||||
if (pStage->bundle[0].tcGen == TCGEN_LIGHTMAP)
|
||||
{
|
||||
pStage->active = qfalse;
|
||||
}
|
||||
|
@ -2547,7 +2521,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
if (pStage->adjustColorsForFog)
|
||||
continue;
|
||||
|
||||
if (pStage->bundle[TB_DIFFUSEMAP].isLightmap)
|
||||
if (pStage->bundle[TB_DIFFUSEMAP].tcGen == TCGEN_LIGHTMAP)
|
||||
{
|
||||
pStage->glslShaderGroup = tr.lightallShader;
|
||||
pStage->glslShaderIndex = LIGHTDEF_USE_LIGHTMAP;
|
||||
|
@ -2556,6 +2530,7 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
pStage->bundle[TB_LIGHTMAP] = pStage->bundle[TB_DIFFUSEMAP];
|
||||
pStage->bundle[TB_DIFFUSEMAP].image[0] = tr.whiteImage;
|
||||
pStage->bundle[TB_DIFFUSEMAP].isLightmap = qfalse;
|
||||
pStage->bundle[TB_DIFFUSEMAP].tcGen = TCGEN_TEXTURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2577,11 +2552,14 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
{
|
||||
pStage->glslShaderGroup = tr.lightallShader;
|
||||
pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR;
|
||||
|
||||
if (pStage->bundle[0].tcGen != TCGEN_TEXTURE || pStage->bundle[0].numTexMods != 0)
|
||||
pStage->glslShaderIndex |= LIGHTDEF_USE_TCGEN_AND_TCMOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert any remaining lightingdiffuse stages to a lighting pass
|
||||
// insert default normal and specular textures if necessary
|
||||
for (i = 0; i < MAX_SHADER_STAGES; i++)
|
||||
{
|
||||
shaderStage_t *pStage = &stages[i];
|
||||
|
@ -2589,14 +2567,27 @@ static qboolean CollapseStagesToGLSL(void)
|
|||
if (!pStage->active)
|
||||
continue;
|
||||
|
||||
if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE)
|
||||
if (pStage->glslShaderGroup != tr.lightallShader)
|
||||
continue;
|
||||
|
||||
if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) == 0)
|
||||
continue;
|
||||
|
||||
if (!pStage->bundle[TB_NORMALMAP].image[0] && r_normalMapping->integer)
|
||||
{
|
||||
pStage->glslShaderGroup = tr.lightallShader;
|
||||
pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR;
|
||||
pStage->bundle[TB_NORMALMAP].image[0] = tr.greyImage;
|
||||
}
|
||||
|
||||
if (!pStage->bundle[TB_SPECULARMAP].image[0] && r_specularMapping->integer)
|
||||
{
|
||||
pStage->bundle[TB_SPECULARMAP].image[0] = tr.whiteImage;
|
||||
if (!pStage->materialInfo[0])
|
||||
pStage->materialInfo[0] = r_baseSpecular->value;
|
||||
if (!pStage->materialInfo[1])
|
||||
pStage->materialInfo[1] = r_baseGloss->value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return numStages;
|
||||
}
|
||||
|
||||
|
|
|
@ -522,7 +522,7 @@ static qboolean RB_SurfaceVbo(VBO_t *vbo, IBO_t *ibo, int numVerts, int numIndex
|
|||
RB_SurfaceTriangles
|
||||
=============
|
||||
*/
|
||||
static void RB_SurfaceTriangles( srfTriangles_t *srf ) {
|
||||
static void RB_SurfaceTriangles( srfBspSurface_t *srf ) {
|
||||
if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3,
|
||||
srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) )
|
||||
{
|
||||
|
@ -1247,7 +1247,7 @@ static void RB_SurfaceMesh(mdvSurface_t *surface) {
|
|||
RB_SurfaceFace
|
||||
==============
|
||||
*/
|
||||
static void RB_SurfaceFace( srfSurfaceFace_t *srf ) {
|
||||
static void RB_SurfaceFace( srfBspSurface_t *srf ) {
|
||||
if( RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3,
|
||||
srf->firstIndex, srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qtrue ) )
|
||||
{
|
||||
|
@ -1296,7 +1296,7 @@ RB_SurfaceGrid
|
|||
Just copy the grid of points and triangulate
|
||||
=============
|
||||
*/
|
||||
static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
|
||||
static void RB_SurfaceGrid( srfBspSurface_t *srf ) {
|
||||
int i, j;
|
||||
float *xyz;
|
||||
float *texCoords, *lightCoords;
|
||||
|
@ -1574,9 +1574,9 @@ static void RB_SurfaceFlare(srfFlare_t *surf)
|
|||
RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal);
|
||||
}
|
||||
|
||||
static void RB_SurfaceVBOMesh(srfVBOMesh_t * srf)
|
||||
static void RB_SurfaceVBOMesh(srfBspSurface_t * srf)
|
||||
{
|
||||
RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numIndexes, srf->firstIndex,
|
||||
RB_SurfaceVbo (srf->vbo, srf->ibo, srf->numVerts, srf->numTriangles * 3, srf->firstIndex,
|
||||
srf->minIndex, srf->maxIndex, srf->dlightBits, srf->pshadowBits, qfalse );
|
||||
}
|
||||
|
||||
|
@ -1621,11 +1621,12 @@ void RB_SurfaceVBOMDVMesh(srfVBOMDVMesh_t * surface)
|
|||
|
||||
glState.vertexAttribsOldFrame = refEnt->oldframe;
|
||||
glState.vertexAttribsNewFrame = refEnt->frame;
|
||||
glState.vertexAnimation = qtrue;
|
||||
|
||||
RB_EndSurface();
|
||||
|
||||
// So we don't lerp surfaces that shouldn't be lerped
|
||||
glState.vertexAttribsInterpolation = 0;
|
||||
glState.vertexAnimation = qfalse;
|
||||
}
|
||||
|
||||
static void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
|
||||
|
|
|
@ -608,6 +608,7 @@ void R_BindVBO(VBO_t * vbo)
|
|||
glState.vertexAttribsInterpolation = 0;
|
||||
glState.vertexAttribsOldFrame = 0;
|
||||
glState.vertexAttribsNewFrame = 0;
|
||||
glState.vertexAnimation = qfalse;
|
||||
|
||||
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vertexesVBO);
|
||||
|
||||
|
@ -856,6 +857,9 @@ void RB_UpdateVBOs(unsigned int attribBits)
|
|||
{
|
||||
R_BindVBO(tess.vbo);
|
||||
|
||||
// orphan old buffer so we don't stall on it
|
||||
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, tess.vbo->vertexesSize, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
if(attribBits & ATTR_BITS)
|
||||
{
|
||||
if(attribBits & ATTR_POSITION)
|
||||
|
@ -923,6 +927,9 @@ void RB_UpdateVBOs(unsigned int attribBits)
|
|||
{
|
||||
R_BindIBO(tess.ibo);
|
||||
|
||||
// orphan old buffer so we don't stall on it
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, tess.ibo->indexesSize, NULL, GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
qglBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, tess.numIndexes * sizeof(tess.indexes[0]), tess.indexes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,16 +208,18 @@ static int R_DlightSurface( msurface_t *surf, int dlightBits ) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
((srfSurfaceFace_t *)surf->data)->dlightBits = dlightBits;
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
((srfGridMesh_t *)surf->data)->dlightBits = dlightBits;
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
((srfTriangles_t *)surf->data)->dlightBits = dlightBits;
|
||||
} else if ( *surf->data == SF_VBO_MESH ) {
|
||||
((srfVBOMesh_t *)surf->data)->dlightBits = dlightBits;
|
||||
} else {
|
||||
dlightBits = 0;
|
||||
switch(*surf->data)
|
||||
{
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
case SF_VBO_MESH:
|
||||
((srfBspSurface_t *)surf->data)->dlightBits = dlightBits;
|
||||
break;
|
||||
|
||||
default:
|
||||
dlightBits = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( dlightBits ) {
|
||||
|
@ -292,16 +294,18 @@ static int R_PshadowSurface( msurface_t *surf, int pshadowBits ) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
((srfSurfaceFace_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
((srfGridMesh_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
((srfTriangles_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
} else if ( *surf->data == SF_VBO_MESH ) {
|
||||
((srfVBOMesh_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
} else {
|
||||
pshadowBits = 0;
|
||||
switch(*surf->data)
|
||||
{
|
||||
case SF_FACE:
|
||||
case SF_GRID:
|
||||
case SF_TRIANGLES:
|
||||
case SF_VBO_MESH:
|
||||
((srfBspSurface_t *)surf->data)->pshadowBits = pshadowBits;
|
||||
break;
|
||||
|
||||
default:
|
||||
pshadowBits = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( pshadowBits ) {
|
||||
|
|
|
@ -849,7 +849,7 @@ void UI_ParseMenu(const char *menuFile) {
|
|||
int handle;
|
||||
pc_token_t token;
|
||||
|
||||
Com_Printf("Parsing menu file:%s\n", menuFile);
|
||||
Com_Printf("Parsing menu file: %s\n", menuFile);
|
||||
|
||||
handle = trap_PC_LoadSource(menuFile);
|
||||
if (!handle) {
|
||||
|
|
Loading…
Reference in a new issue