Compare commits

..
37 Commits
Author SHA1 Message Date
OM cf51e14cf5 Added FPS counter 2023-05-19 20:52:10 +02:00
OM 7fb383c810 Updated README with new screenshot 2023-05-19 20:51:51 +02:00
OM 34f66963e3 Implemented DrawStatCompass 2023-05-19 19:26:46 +02:00
OM 6059063b67 Added "constant" parameter for "rgbGen" 2023-05-19 17:48:24 +02:00
OM 8bf57017ac Proper implementation of *RE_AddPolyToScene*
+ Increased *MAX_POLYS* and *MAX_POLYVERTS*
2023-05-19 17:48:09 +02:00
OM 9f1d35a11b Statbar fix
Implemented *UIFakkLabel::DrawStatbar*
2023-05-19 17:34:01 +02:00
OM aa51987077 Moved *BG_EvaluateTrajectory* from *game/bg_misc.cpp* to *cgame/cg_ents.c* 2023-05-19 17:27:38 +02:00
OM 64055d2580 Using RT_MODEL instead of ET_MODELANIM_SKEL 2023-05-19 16:59:44 +02:00
OM 45e82c590e Set numSpheresUsed to 0 2023-05-19 16:59:20 +02:00
OM 0c92890ef2 Implemented CGEN_STATIC 2023-05-19 16:59:08 +02:00
OM 03e8a64283 Added parent support in *RE_AddRefEntityToScene* 2023-05-19 16:58:46 +02:00
OM 4e14535f08 Fixed stats not drawing properly 2023-05-19 15:44:42 +02:00
OM 356e7c51fc Fixed widget alignment problem 2023-05-19 15:44:31 +02:00
OM 52a146d664 Updated README (added screenshot) 2023-05-19 14:09:03 +02:00
OM 76f107230c Exchanged SURF_NOLIGHTMAP and SURF_HINT 2023-05-19 13:57:35 +02:00
OM 4a49b15649 Removed CONTENTS_FOG
Added more surface params
2023-05-19 13:56:07 +02:00
OM 6c448694b6 Fixed static models color rendering 2023-05-19 13:40:29 +02:00
OM 34a1cee89b Made sure to unpack static models correctly 2023-05-19 13:40:18 +02:00
OM 29239dadfa Don't call ri.Hunk_Alloc when there are no texmods 2023-05-19 13:40:03 +02:00
OM e5a4574f92 Added *R_DistanceCullPointAndRadius* 2023-05-19 13:39:31 +02:00
OM 2d70547f9d Cleanup 2023-05-19 03:21:04 +02:00
OM f6279e8c17 *R_RecursiveWorldNode* now take the fog frustum into account, it also calls *R_AddPermanentMarkFragmentSurfaces* and set the vis static models 2023-05-19 03:20:50 +02:00
OM 18ade839c6 Added more shader commands
More fox support
2023-05-19 03:19:56 +02:00
OM b72eb8c6cc Using PLANE_NON_AXIAL instead of 3 2023-05-19 03:13:37 +02:00
OM e0446db81d Added one more mark function 2023-05-19 03:13:23 +02:00
OM a8bb9aaa77 Using qglFogi instead 2023-05-19 03:12:55 +02:00
OM 6595c3c673 Added sprites and ter marks to the render scene 2023-05-19 02:12:03 +02:00
OM 4ecf3195a5 Added *R_CullLocalBoxOffset* 2023-05-19 02:11:45 +02:00
OM 02f0e309e3 Implemented *R_ClearRealDlights*, *R_UploadDlights* and *R_AllocLMBlock* 2023-05-19 02:11:28 +02:00
OM 0fdfcf48f9 Added *RB_ComputeShadowVolume* (not implemented) 2023-05-19 02:10:56 +02:00
OM e9b5c7efd5 Initialize extension and level marks
Initialize the font debug string
2023-05-19 02:10:38 +02:00
OM 2a32b75815 Added GL flags 2023-05-19 02:10:19 +02:00
OM d966afe4ef Added *g_bInfoworldtris* 2023-05-19 02:10:03 +02:00
OM 92e2d42e19 Pre-added marks functions 2023-05-19 02:09:28 +02:00
OM 58e5e3fd63 Added multi-texture GL values
Don't iterate the stage if it has a skyAlpha gen near invisibility
2023-05-19 02:09:13 +02:00
OM b61c7b3988 Fog fixes 2023-05-19 02:08:32 +02:00
OM ee030f27e2 Early implementation of fog and sky portal 2023-05-19 00:29:13 +02:00
41 changed files with 1994 additions and 854 deletions

No files matched your search

+5
View File
@@ -85,6 +85,11 @@ These are the tools required on Unix :
Visual Studio (2019 or 2022) is generally preferred.
## Screenshots
![](docs/images/opm_50b_1.png)
![](docs/images/opm_50b_2.png)
## Third party
### SDL
+30 -14
View File
@@ -414,6 +414,25 @@ void CG_Portal(centity_t* cent)
{
}
/*
================
BG_EvaluateTrajectory
================
*/
void BG_EvaluateTrajectory(const trajectory_t* tr, int atTime, const vec3_t base, vec3_t result) {
float deltaTime;
if (atTime > cg_smoothClientsTime->integer + tr->trTime) {
atTime = cg_smoothClientsTime->integer + tr->trTime;
}
deltaTime = (float)(atTime - tr->trTime) / 1000.0;
result[0] = tr->trDelta[0] * deltaTime + base[0];
result[1] = tr->trDelta[1] * deltaTime + base[1];
result[2] = tr->trDelta[2] * deltaTime + base[2];
}
/*
===============
CG_CalcEntityLerpPositions
@@ -477,8 +496,8 @@ void CG_CalcEntityLerpPositions( centity_t *cent )
// this will linearize a sine or parabolic curve, but it is important
// to not extrapolate player positions if more recent data is available
BG_EvaluateTrajectory(&cent->currentState.pos, cg.snap->serverTime, current);
BG_EvaluateTrajectory(&cent->nextState.pos, cg.nextSnap->serverTime, next);
BG_EvaluateTrajectory(&cent->currentState.pos, cg.snap->serverTime, cent->currentState.origin, current);
BG_EvaluateTrajectory(&cent->nextState.pos, cg.nextSnap->serverTime, cent->nextState.origin, next);
cent->lerpOrigin[0] = current[0] + f * (next[0] - current[0]);
cent->lerpOrigin[1] = current[1] + f * (next[1] - current[1]);
@@ -494,17 +513,11 @@ void CG_CalcEntityLerpPositions( centity_t *cent )
QuatToMat(quat, mat);
MatrixToEulerAngles(mat, cent->lerpAngles);
}
// Lerp legs, torso, and head angles
for (i = 0; i < 3; i++) {
cent->lerpAngles[i] = LerpAngle(current[i], next[i], f);
}
}
else {
// just use the current frame and evaluate as best we can
BG_EvaluateTrajectory(&cent->currentState.pos, cg.time, cent->lerpOrigin);
BG_EvaluateTrajectory(&cent->currentState.pos, cg.time, cent->currentState.origin, cent->lerpOrigin);
VectorCopy(cent->currentState.angles, cent->lerpAngles);
//BG_EvaluateTrajectory(&cent->currentState.apos, cg.time, cent->lerpAngles);
}
}
@@ -545,10 +558,10 @@ void CG_AddCEntity(centity_t* cent)
CG_ModelAnim(cent, qtrue);
break;
case ET_PLAYER:
CG_Player(cent);
case ET_ITEM:
case ET_EXEC_COMMANDS:
CG_ModelAnim(cent, qfalse);
CG_Player(cent);
CG_Splash(cent);
case ET_ITEM:
CG_ModelAnim(cent, qfalse);
break;
case ET_GENERAL:
CG_General(cent);
@@ -575,7 +588,10 @@ void CG_AddCEntity(centity_t* cent)
break;
case ET_ROPE: // skip
CG_Rope(cent);
break;
break;
case ET_EXEC_COMMANDS:
CG_ModelAnim(cent, qfalse);
break;
}
}
+1
View File
@@ -590,6 +590,7 @@ void CG_PredictPlayerState( void );
//
// cg_ents.c
//
void BG_EvaluateTrajectory(const trajectory_t* tr, int atTime, const vec3_t base, vec3_t result);
void CG_SetEntitySoundPosition( centity_t *cent );
void CG_AddPacketEntities( void );
void CG_Beam( centity_t *cent );
+1 -1
View File
@@ -956,7 +956,7 @@ void CG_ModelAnim(centity_t* cent, qboolean bDoShaderTime)
VectorCopy(model.origin, cg.sky_origin);
}
model.reType = ET_MODELANIM_SKEL;
model.reType = RT_MODEL;
if (!(s1->renderfx & RF_DONTDRAW))
{
cgi.R_Model_GetHandle(model.hModel);
-137
View File
@@ -29,14 +29,10 @@ key up events are sent even if in console mode
*/
field_t historyEditLines[COMMAND_HISTORY];
int nextHistoryLine; // the last line in the history buffer, not masked
int historyLine; // the line being displayed from history buffer
// will be <= nextHistoryLine
field_t g_consoleField;
field_t chatField;
qboolean chat_team;
int chat_playerNum;
@@ -1198,136 +1194,3 @@ Key_SetCatcher
void Key_SetCatcher( int catcher ) {
keyCatchers = catcher;
}
// This must not exceed MAX_CMD_LINE
#define MAX_CONSOLE_SAVE_BUFFER 1024
#define CONSOLE_HISTORY_FILE "omhistory"
static char consoleSaveBuffer[ MAX_CONSOLE_SAVE_BUFFER ];
static int consoleSaveBufferSize = 0;
/*
================
CL_LoadConsoleHistory
Load the console history from cl_consoleHistory
================
*/
void CL_LoadConsoleHistory( void )
{
const char *token;
char *text_p;
int i, numChars, numLines = 0;
fileHandle_t f;
consoleSaveBufferSize = FS_FOpenFileRead( CONSOLE_HISTORY_FILE, &f, qfalse, qtrue );
if( !f )
{
Com_Printf( "Couldn't read %s.\n", CONSOLE_HISTORY_FILE );
return;
}
if( consoleSaveBufferSize <= MAX_CONSOLE_SAVE_BUFFER &&
FS_Read( consoleSaveBuffer, consoleSaveBufferSize, f ) == consoleSaveBufferSize )
{
text_p = consoleSaveBuffer;
for( i = COMMAND_HISTORY - 1; i >= 0; i-- )
{
if( !*( token = COM_Parse( &text_p ) ) )
break;
historyEditLines[ i ].cursor = atoi( token );
if( !*( token = COM_Parse( &text_p ) ) )
break;
historyEditLines[ i ].scroll = atoi( token );
if( !*( token = COM_Parse( &text_p ) ) )
break;
numChars = atoi( token );
text_p++;
if( numChars > ( strlen( consoleSaveBuffer ) - ( text_p - consoleSaveBuffer ) ) )
{
Com_DPrintf( S_COLOR_YELLOW "WARNING: probable corrupt history\n" );
break;
}
Com_Memcpy( historyEditLines[ i ].buffer,
text_p, numChars );
historyEditLines[ i ].buffer[ numChars ] = '\0';
text_p += numChars;
numLines++;
}
memmove( &historyEditLines[ 0 ], &historyEditLines[ i + 1 ],
numLines * sizeof( field_t ) );
for( i = numLines; i < COMMAND_HISTORY; i++ )
Field_Clear( &historyEditLines[ i ] );
historyLine = nextHistoryLine = numLines;
}
else
Com_Printf( "Couldn't read %s.\n", CONSOLE_HISTORY_FILE );
FS_FCloseFile( f );
}
/*
================
CL_SaveConsoleHistory
Save the console history into the cvar cl_consoleHistory
so that it persists across invocations of q3
================
*/
void CL_SaveConsoleHistory( void )
{
int i;
int lineLength, saveBufferLength, additionalLength;
fileHandle_t f;
consoleSaveBuffer[ 0 ] = '\0';
i = ( nextHistoryLine - 1 ) % COMMAND_HISTORY;
do
{
if( historyEditLines[ i ].buffer[ 0 ] )
{
lineLength = strlen( historyEditLines[ i ].buffer );
saveBufferLength = strlen( consoleSaveBuffer );
//ICK
additionalLength = lineLength + strlen( "999 999 999 " );
if( saveBufferLength + additionalLength < MAX_CONSOLE_SAVE_BUFFER )
{
Q_strcat( consoleSaveBuffer, MAX_CONSOLE_SAVE_BUFFER,
va( "%d %d %d %s ",
historyEditLines[ i ].cursor,
historyEditLines[ i ].scroll,
lineLength,
historyEditLines[ i ].buffer ) );
}
else
break;
}
i = ( i - 1 + COMMAND_HISTORY ) % COMMAND_HISTORY;
}
while( i != ( nextHistoryLine - 1 ) % COMMAND_HISTORY );
consoleSaveBufferSize = strlen( consoleSaveBuffer );
f = FS_FOpenFileWrite( CONSOLE_HISTORY_FILE );
if( !f )
{
Com_Printf( "Couldn't write %s.\n", CONSOLE_HISTORY_FILE );
return;
}
if( FS_Write( consoleSaveBuffer, consoleSaveBufferSize, f ) < consoleSaveBufferSize )
Com_Printf( "Couldn't write %s.\n", CONSOLE_HISTORY_FILE );
FS_FCloseFile( f );
}
+1
View File
@@ -42,6 +42,7 @@ void CL_ShutdownUI( void );
//
extern inventory_t client_inv;
extern bind_t client_bind;
extern cvar_t* cl_greenfps;
const char *CvarGetForUI( const char *name, const char *defval );
void UI_ClearState( void );
+380 -12
View File
@@ -438,7 +438,173 @@ void UIFakkLabel::LayoutRenderModelAnim( Event *ev )
void UIFakkLabel::DrawStatbar( float frac )
{
// FIXME: stub
vec4_t col;
float alpha;
col[0] = col[1] = col[2] = col[3] = 1.0;
switch (m_statbar_or)
{
case L_STATBAR_CIRCULAR:
DrawStatCircle(frac);
return;
case L_STATBAR_NEEDLE:
DrawStatNeedle(frac);
return;
case L_STATBAR_ROTATOR:
DrawStatRotator(frac);
return;
case L_STATBAR_COMPASS:
DrawStatCompass(frac);
return;
case L_STATBAR_SPINNER:
case L_STATBAR_HEADING_SPINNER:
DrawStatSpinner(frac);
return;
default:
break;
}
if (!frac) {
return;
}
if (frac != m_lastfrac) {
m_flashtime = uid.time;
}
m_lastfrac = frac;
alpha = 1.0 - ((float)uid.time - m_flashtime) / 1500.0;
if (alpha < 0.0) alpha = 0.0;
else if (alpha > 1.0) alpha = 1.0;
col[3] = alpha;
if (m_statbar_material)
{
if (m_flags & WF_TILESHADER)
{
switch (m_statbar_or)
{
case L_STATBAR_HORIZONTAL:
{
float width = frac * m_frame.size.width;
m_statbar_material->ReregisterMaterial();
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash)
{
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
}
break;
}
case L_STATBAR_VERTICAL:
case L_STATBAR_VERTICAL_REVERSE:
case L_STATBAR_VERTICAL_STAGGER_EVEN:
case L_STATBAR_VERTICAL_STAGGER_ODD:
{
float y = m_frame.size.height * (1.0 - frac);
m_statbar_material->ReregisterMaterial();
re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash)
{
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
}
break;
}
}
}
else
{
switch (m_statbar_or)
{
case L_STATBAR_HORIZONTAL:
{
float width = frac * m_frame.size.width;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material->GetMaterial());
if(alpha != 0.0 && m_statbar_material_flash)
{
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material_flash->GetMaterial());
}
break;
}
case L_STATBAR_VERTICAL:
case L_STATBAR_VERTICAL_STAGGER_EVEN:
case L_STATBAR_VERTICAL_STAGGER_ODD:
{
float y = m_frame.size.height * (1.0 - frac);
float height = m_frame.size.height * frac;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash)
{
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material_flash->GetMaterial());
}
break;
}
case L_STATBAR_VERTICAL_REVERSE:
{
float height = m_frame.size.height * frac;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash)
{
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material_flash->GetMaterial());
}
break;
}
}
}
}
else
{
switch (m_statbar_or)
{
case L_STATBAR_VERTICAL:
case L_STATBAR_VERTICAL_STAGGER_EVEN:
case L_STATBAR_VERTICAL_STAGGER_ODD:
DrawBox(
0.0,
m_frame.size.height * (1.0 - frac),
m_frame.size.width,
m_frame.size.height,
m_foreground_color,
1.0
);
break;
case L_STATBAR_HORIZONTAL:
DrawBox(
0.0,
0.0,
frac * m_frame.size.width,
m_frame.size.height,
m_foreground_color,
1.0
);
break;
}
}
}
void UIFakkLabel::DrawStatCircle( float frac )
@@ -458,7 +624,212 @@ void UIFakkLabel::DrawStatRotator( float frac )
void UIFakkLabel::DrawStatCompass( float frac )
{
// FIXME: stub
vec4_t col;
float fTargAng;
float fSinVal, fCosVal;
vec2_t vCenter;
vec2_t vVerts[3];
vec2_t vTexCoords[3];
vec2_t vCompassDir;
vec2_t vSideDir;
col[0] = col[1] = col[2] = col[3] = 1.0;
if (!cge) {
return;
}
static int iLastCompassTime = -9999, iLastTimeDelta = 0;
static float fLastPitch = 0, fLastYaw = 0, fLastYawDelta = 0;
static float fYawOffset = 0, fYawSpeed = 0;
static float fNeedleOffset = 0, fNeedleSpeed = 0;
int iTimeCount, iTimeDelta;
float fYawDelta, fYawDeltaDiff;
vec3_t vViewAngles;
cge->CG_EyeAngles(&vViewAngles);
vViewAngles[1] -= cl.snap.ps.stats[STAT_COMPASSNORTH] / 182.0f;
iTimeCount = uid.time - iLastCompassTime;
if (iTimeCount <= 1000)
{
fYawDelta = AngleSubtract(vViewAngles[1], fLastYaw);
if (fYawDelta > 0.1)
{
if ((fYawDelta > 0.0 && fLastYawDelta < fYawDelta)
|| (fYawDelta < 0.0 && fLastYawDelta > fYawDelta))
{
fYawSpeed += (fYawDelta - fLastYawDelta) * 0.75;
fYawOffset += (fYawDelta - fLastYawDelta) * 0.75;
}
if (fYawSpeed > 90.0) {
fYawSpeed = 90.0;
}
else if (fYawSpeed < 0.05) {
fYawSpeed = 0.05;
}
}
while (iTimeCount > 0)
{
iTimeDelta = iTimeCount;
if (iTimeCount > 15) {
iTimeDelta = 15;
}
iTimeCount -= iTimeDelta;
if (fabs(fYawOffset) >= 0.1 || fabs(fYawSpeed) >= 0.01)
{
fYawOffset += fYawSpeed * iTimeDelta;
if (fYawOffset > 0.0) {
fYawSpeed -= iTimeDelta * 0.00175;
}
else if (fYawOffset < 0.0) {
fYawSpeed += iTimeDelta * 0.00175;
}
if (fYawOffset > 40.0) {
fYawOffset = 40.0;
fYawSpeed = 0.0;
}
else if (fYawOffset < -40.0) {
fYawOffset = -40.0;
fYawSpeed = 0.0;
}
fYawSpeed -= iTimeDelta * 0.003;
if (fYawSpeed > 0.0) {
fYawSpeed -= iTimeDelta * 0.0004;
}
else {
fYawSpeed += iTimeDelta * 0.0004;
if (fYawSpeed > 0.0) {
fYawSpeed = 0.0;
}
}
}
else
{
iTimeCount = 0;
fYawOffset = 0.0;
fYawSpeed = 0.0;
}
}
fLastYawDelta = fYawDelta;
iLastTimeDelta = uid.time - iLastCompassTime;
}
else
{
fLastYawDelta = 0;
fYawOffset = 0;
fYawSpeed = 0;
iLastTimeDelta = 0;
}
fLastPitch = vViewAngles[0];
fLastYaw = vViewAngles[1];
iLastCompassTime = uid.time;
if (iLastTimeDelta)
{
if (fabs(fLastYawDelta) > 0.1) {
fNeedleOffset -= fLastYawDelta;
}
iTimeCount = iLastTimeDelta;
while (iTimeCount > 0)
{
iTimeDelta = iTimeCount;
if (iTimeCount > 15) {
iTimeDelta = 15;
}
iTimeCount -= iTimeDelta;
if (fabs(fNeedleOffset) >= 0.1 || fabs(fNeedleSpeed) >= 0.01) {
fNeedleOffset += iTimeDelta * fNeedleSpeed;
if (fNeedleOffset > 180.0) {
fNeedleOffset -= 360.0;
}
else if (fNeedleOffset < -180.0) {
fNeedleOffset += 360.0;
}
if (fNeedleOffset > 0.0) {
fNeedleSpeed -= iTimeDelta * 0.00175;
}
else if (fNeedleOffset < 0.0) {
fNeedleSpeed += iTimeDelta * 0.00175;
}
fNeedleSpeed -= fNeedleSpeed * 0.0025 * iTimeDelta;
if (fNeedleSpeed > 0.0) {
fNeedleSpeed -= iTimeDelta * 0.00035;
if (fNeedleSpeed < 0.0) {
fNeedleSpeed = 0.0;
}
}
else {
fNeedleSpeed += iTimeDelta * 0.00035;
if (fNeedleSpeed > 0.0) {
fNeedleSpeed = 0.0;
}
}
} else {
iTimeCount = 0;
fNeedleOffset = 0.0;
fNeedleSpeed = 0.0;
}
}
}
else
{
fNeedleOffset = 0.0;
fNeedleSpeed = 0.0;
}
fSinVal = sin(anglemod(fNeedleOffset + fLastYaw) / (180 / M_PI));
fCosVal = cos(anglemod(fNeedleOffset + fLastYaw) / (180 / M_PI));
vCompassDir[0] = fSinVal;
vCompassDir[1] = -fCosVal;
vCenter[0] = m_frame.size.width * 0.5;
vCenter[1] = m_frame.size.height * 0.5;
vTexCoords[0][0] = 0.0;
vTexCoords[0][1] = 0.0;
vTexCoords[1][0] = 1.0;
vTexCoords[1][1] = 0.0;
vTexCoords[2][0] = 0.0;
vTexCoords[2][1] = 1.0;
vVerts[0][0] = vCenter[0] + vCompassDir[0] * vCenter[0] - fCosVal * vCenter[1];
vVerts[1][0] = vCenter[0] + vCompassDir[0] * vCenter[0] + fCosVal * vCenter[1];
vVerts[2][0] = vCenter[0] - vCompassDir[0] * vCenter[0] - fCosVal * vCenter[1];
vVerts[0][1] = vCenter[1] + vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
vVerts[1][1] = vCenter[1] + vCompassDir[1] * vCenter[1] + fSinVal * vCenter[0];
vVerts[2][1] = vCenter[1] - vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
vVerts[0][0] = vVerts[2][0];
vVerts[0][1] = vVerts[2][1];
vTexCoords[0][0] = vTexCoords[2][0];
vTexCoords[0][1] = vTexCoords[2][1];
vTexCoords[2][0] = 1.0;
vTexCoords[2][1] = 1.0;
vVerts[2][0] = vCenter[0] + fCosVal * vCenter[1] - vCompassDir[0] * vCenter[0];
vVerts[2][1] = vCenter[1] * fSinVal + vCenter[0] - vCompassDir[1] * vCenter[1];
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
}
void UIFakkLabel::DrawStatSpinner( float frac )
@@ -506,7 +877,7 @@ void UIFakkLabel::Draw( void )
return;
}
if( m_stat != -1 )
if( m_stat == -1 )
{
float scale;
qhandle_t handle;
@@ -516,7 +887,7 @@ void UIFakkLabel::Draw( void )
vec3_t angles;
vec3_t offset;
vec3_t rotateoffset;
vec3_t color;
vec4_t color;
str sAnimName;
float height;
@@ -686,23 +1057,20 @@ _shitlabel01:
float frac;
if( m_maxstat )
if( m_maxstat >= 0 )
{
frac = delta / ( m_statbar_max - m_statbar_min );
frac = (float)delta / (float)cl.snap.ps.stats[m_maxstat];
}
else
{
frac = delta / cl.snap.ps.stats[ m_maxstat ];
frac = (float)delta / (float)(m_statbar_max - m_statbar_min);
}
if( frac > 1.0 )
frac = 1.0;
if( frac < 0.0 )
frac = 0.0;
if( frac > 1.0 ) frac = 1.0;
else if( frac < 0.0 ) frac = 0.0;
DrawStatbar( frac );
return;
}
+66 -1
View File
@@ -126,7 +126,72 @@ void View3D::DrawFPS
)
{
// FIXME: stub
char string[128];
setFont("verdana-14");
if (fps->integer == 2)
{
re.SetColor(UBlack);
re.DrawBox(
0.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
m_frame.pos.x + m_frame.size.width,
m_font->getHeight(qfalse) * 4.0
);
}
sprintf(string, "FPS %4.1f", currentfps);
if (currentfps > 23.94) {
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
} else {
m_font->setColor(UWhite);
}
} else if (currentfps > 18.0) {
m_font->setColor(UYellow);
} else {
// low fps
m_font->setColor(URed);
}
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
string,
-1,
qfalse
);
// Draw elements count
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
}
else {
m_font->setColor(UWhite);
}
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
string,
-1,
qfalse
);
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
string,
-1,
qfalse
);
m_font->setColor(UBlack);
}
void View3D::DrawProf
-3
View File
@@ -578,9 +578,6 @@ void Con_PageDown( void );
void Con_Top( void );
void Con_Bottom( void );
void CL_LoadConsoleHistory( void );
void CL_SaveConsoleHistory( void );
//
// cl_scrn.c
//
-11
View File
@@ -34,17 +34,6 @@ typedef struct {
extern qboolean key_overstrikeMode;
extern qkey_t keys[K_LASTKEY];
// NOTE TTimo the declaration of field_t and Field_Clear is now in qcommon/qcommon.h
void Field_KeyDownEvent( field_t *edit, int key );
void Field_CharEvent( field_t *edit, int ch );
void Field_Draw(fontInfo_t *font, field_t *edit, int x, int y, int width, qboolean showCursor, qboolean noColorEscape );
void Field_BigDraw(fontInfo_t *font, field_t *edit, int x, int y, int width, qboolean showCursor, qboolean noColorEscape );
#define COMMAND_HISTORY 32
extern field_t historyEditLines[COMMAND_HISTORY];
extern field_t g_consoleField;
extern field_t chatField;
extern int anykeydown;
extern qboolean chat_team;
extern int chat_playerNum;
-9
View File
@@ -25,15 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/q_shared.h"
#include "bg_public.h"
/*
================
BG_EvaluateTrajectory
================
*/
void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result ) {
}
/*
================
BG_EvaluateTrajectoryDelta
-3
View File
@@ -609,9 +609,6 @@ typedef enum {
ET_EXEC_COMMANDS
} entityType_t;
// su44; yes, I know there is no q3 trajectory_t in MoHAA,
// but I need it for fgame rotating doors code.
void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result );
void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result );
void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap );
+31 -210
View File
@@ -31,6 +31,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <winsock.h>
#endif
// FPS
#include <chrono>
#include <tiki.h>
qboolean CL_FinishedIntro(void);
@@ -72,7 +75,6 @@ fileHandle_t com_journalDataFile; // config files are written here
cvar_t *paused;
cvar_t *config;
cvar_t *fps;
float currentfps;
cvar_t *com_speeds;
cvar_t *developer;
cvar_t *com_dedicated;
@@ -126,6 +128,18 @@ static char *rd_buffer;
static int rd_buffersize;
static void (*rd_flush)( char *buffer );
#define MAX_FPS_TIMES 16
using fps_clock_t = std::chrono::high_resolution_clock;
using fps_time_t = fps_clock_t::time_point;
using fps_delta_t = fps_clock_t::duration;
static int fpsindex;
static fps_delta_t fpstimes[MAX_FPS_TIMES];
static fps_delta_t fpstotal;
static fps_time_t fpslasttime;
float currentfps;
void Com_BeginRedirect (char *buffer, int buffersize, void (*flush)( char *) )
{
if (!buffer || !buffersize || !flush)
@@ -1752,6 +1766,22 @@ void Com_Frame( void ) {
com_frameNumber, all, sv, ev, cl, time_game, time_frontend, time_backend );
}
if (fps->integer) {
fps_time_t fpstime = fps_clock_t::now();
fps_delta_t delta = fpstime - fpslasttime;
fpstotal = (fpstime - fpslasttime) + (fpstotal - fpstimes[fpsindex]);
fpstimes[fpsindex] = fpstime - fpslasttime;
fpsindex = (fpsindex + 1) % MAX_FPS_TIMES;
fpslasttime = fpstime;
if (fpstotal.count()) {
currentfps = 16.0 / std::chrono::duration<long double>(fpstotal).count();
} else {
currentfps = 0.0;
}
}
//
// trace optimization tracking
//
@@ -1893,23 +1923,10 @@ command line completion
===========================================
*/
/*
==================
Field_Clear
==================
*/
void Field_Clear( field_t *edit ) {
memset(edit->buffer, 0, MAX_EDIT_LINE);
edit->cursor = 0;
edit->scroll = 0;
}
static const char *completionString;
static char shortestMatch[MAX_TOKEN_CHARS];
static int matchCount;
// field we are working on, passed to Field_AutoComplete(&g_consoleCommand for instance)
static field_t *completionField;
/*
===============
FindMatches
@@ -1968,200 +1985,4 @@ static void PrintCvarMatches( const char *s ) {
}
}
/*
===============
Field_FindFirstSeparator
===============
*/
static char *Field_FindFirstSeparator( char *s )
{
int i;
for( i = 0; i < strlen( s ); i++ )
{
if( s[ i ] == ';' )
return &s[ i ];
}
return NULL;
}
#ifndef DEDICATED
/*
===============
Field_CompleteKeyname
===============
*/
static void Field_CompleteKeyname( void )
{
matchCount = 0;
shortestMatch[ 0 ] = 0;
Key_KeynameCompletion( FindMatches );
if( matchCount == 0 )
return;
Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) -
strlen( completionString ) ], shortestMatch,
sizeof( completionField->buffer ) );
completionField->cursor = ( int )strlen( completionField->buffer );
if( matchCount == 1 )
{
Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " );
completionField->cursor++;
return;
}
Com_Printf( "]%s\n", completionField->buffer );
Key_KeynameCompletion( PrintMatches );
}
#endif
/*
===============
Field_CompleteFilename
===============
*/
static void Field_CompleteFilename( const char *dir,
const char *ext, qboolean stripExt )
{
size_t pos;
matchCount = 0;
shortestMatch[ 0 ] = 0;
FS_FilenameCompletion( dir, ext, stripExt, FindMatches );
if( matchCount == 0 )
return;
pos = strlen( completionField->buffer ) - strlen( completionString );
Q_strncpyz( &completionField->buffer[ pos ], shortestMatch,
sizeof( completionField->buffer ) - pos );
completionField->cursor = ( int )strlen( completionField->buffer );
if( matchCount == 1 )
{
Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " );
completionField->cursor++;
return;
}
Com_Printf( "]%s\n", completionField->buffer );
FS_FilenameCompletion( dir, ext, stripExt, PrintMatches );
}
static void keyConcatArgs(void) {
int i;
char* arg;
for (i = 1; i < Cmd_Argc(); i++) {
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
arg = Cmd_Argv(i);
while (*arg) {
if (*arg == ' ') {
Q_strcat(completionField->buffer, sizeof(completionField->buffer), "\"");
break;
}
arg++;
}
Q_strcat(completionField->buffer, sizeof(completionField->buffer), Cmd_Argv(i));
if (*arg == ' ') {
Q_strcat(completionField->buffer, sizeof(completionField->buffer), "\"");
}
}
}
static void ConcatRemaining(const char* src, const char* start) {
const char* str;
str = strstr(src, start);
if (!str) {
keyConcatArgs();
return;
}
str += strlen(start);
Q_strcat(completionField->buffer, sizeof(completionField->buffer), str);
}
/*
===============
Field_CompleteCommand
perform Tab expansion
NOTE TTimo this was originally client code only
moved to common code when writing tty console for *nix dedicated server
===============
*/
void Field_CompleteCommand(field_t* field) {
field_t temp;
completionField = field;
// only look at the first token for completion purposes
Cmd_TokenizeString(completionField->buffer);
completionString = Cmd_Argv(0);
if (completionString[0] == '\\' || completionString[0] == '/') {
completionString++;
}
matchCount = 0;
shortestMatch[0] = 0;
if (strlen(completionString) == 0) {
return;
}
Cmd_CommandCompletion(FindMatches);
Cvar_CommandCompletion(FindMatches);
if (matchCount == 0) {
return; // no matches
}
Com_Memcpy(&temp, completionField, sizeof(field_t));
if (matchCount == 1) {
Com_sprintf(completionField->buffer, sizeof(completionField->buffer), "\\%s", shortestMatch);
if (Cmd_Argc() == 1) {
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
}
else {
ConcatRemaining(temp.buffer, completionString);
}
completionField->cursor = strlen(completionField->buffer);
return;
}
// multiple matches, complete to shortest
Com_sprintf(completionField->buffer, sizeof(completionField->buffer), "\\%s", shortestMatch);
completionField->cursor = strlen(completionField->buffer);
ConcatRemaining(temp.buffer, completionString);
Com_Printf("]%s\n", completionField->buffer);
// run through again, printing matches
Cmd_CommandCompletion(PrintMatches);
Cvar_CommandCompletion(PrintMatches);
}
/*
===============
Field_AutoComplete
Perform Tab expansion
===============
*/
void Field_AutoComplete( field_t *field )
{
completionField = field;
Field_CompleteCommand(field);
}
}
+1 -21
View File
@@ -798,26 +798,6 @@ MISC
/*
==============================================================
Edit fields and command line history/completion
==============================================================
*/
#define MAX_EDIT_LINE 256
typedef struct {
int cursor;
int scroll;
int widthInChars;
char buffer[MAX_EDIT_LINE];
} field_t;
void Field_Clear( field_t *edit );
void Field_CompleteCommand( field_t *edit );
void Field_AutoComplete( field_t *edit );
/*
==============================================================
MISC
==============================================================
@@ -882,10 +862,10 @@ void Com_StartupVariable( const char *match );
// only a set with the exact name. Only used during startup.
extern float currentfps;
extern cvar_t *paused;
extern cvar_t *config;
extern cvar_t *fps;
extern float currentfps;
extern cvar_t *developer;
extern cvar_t *com_dedicated;
extern cvar_t *com_speeds;
+3 -3
View File
@@ -555,9 +555,9 @@ typedef struct cTerraPatch_s {
} cTerraPatch_t;
typedef struct cStaticModel_s {
char model[ 128 ];
float origin[ 3 ];
float angles[ 3 ];
char model[128];
vec3_t origin;
vec3_t angles;
float scale;
int firstVertexData;
int numVertexData;
+2 -2
View File
@@ -87,7 +87,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define SURF_NOMARKS 0x20 // don't leave missile marks
#define SURF_CASTSHADOW 0x40
#define SURF_NODRAW 0x80 // don't generate a drawsurface at all
#define SURF_HINT 0x100 // make a primary bsp splitter
#define SURF_NOLIGHTMAP 0x100 // surface doesn't need a lightmap
#define SURF_ALPHASHADOW 0x200 // do per-pixel light shadow casting in q3map
#define SURF_NOSTEPS 0x400 // no footstep sounds
#define SURF_NONSOLID 0x800 // don't collide against curves with this set
@@ -109,7 +109,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define SURF_CARPET 0x8000000 // carpet effects
#define SURF_BACKSIDE 0x10000000 // su44: backside
#define SURF_NODLIGHT 0x20000000 // don't dlight even if solid (solid lava, skies)
#define SURF_NOLIGHTMAP 0x40000000 // surface doesn't need a lightmap
#define SURF_HINT 0x40000000 // make a primary bsp splitter
#define SURF_UNKNOWN3 0x80000000 // IneQuation: WTF?
#define SURF_FLESH 0x40 // make flesh sounds and effects
+19
View File
@@ -92,6 +92,25 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define GL_COMBINE 0x8570
#define GL_COMBINE4_NV 0x8503
#define GL_COMBINE_RGB 0x8571
#define GL_COMBINE_ALPHA 0x8572
#define GL_SOURCE0_RGB 0x8580
#define GL_SOURCE1_RGB 0x8581
#define GL_SOURCE2_RGB 0x8582
#define GL_SOURCE3_RGB 0x8583
#define GL_SOURCE0_ALPHA 0x8588
#define GL_SOURCE1_ALPHA 0x8589
#define GL_SOURCE2_ALPHA 0x858A
#define GL_SOURCE3_ALPHA 0x858B
#define GL_OPERAND0_RGB 0x8590
#define GL_OPERAND1_RGB 0x8591
#define GL_OPERAND2_RGB 0x8592
#define GL_OPERAND3_RGB 0x8593
#define GL_OPERAND0_ALPHA 0x8598
#define GL_OPERAND1_ALPHA 0x8599
#define GL_OPERAND2_ALPHA 0x859A
#define GL_OPERAND3_ALPHA 0x859B
// NOTE: some Linux platforms would need those prototypes
#if defined(MACOS_X)
+167 -11
View File
@@ -34,6 +34,16 @@ static float s_flipMatrix[16] = {
0, 0, 0, 1
};
void GL_SetFogColor(const vec4_t fColor) {
glState.fFogColor[0] = fColor[0];
glState.fFogColor[1] = fColor[1];
glState.fFogColor[2] = fColor[2];
glState.fFogColor[3] = fColor[3];
if (!(glState.glStateBits & GLS_FOG_COLOR)) {
qglFogfv(GL_FOG_COLOR, glState.fFogColor);
}
}
/*
** GL_Bind
@@ -206,7 +216,7 @@ void GL_TexEnv( int env )
*/
void GL_State( unsigned long stateBits )
{
unsigned long diff = stateBits ^ glState.glStateBits;
unsigned long diff = glState.glStateBits ^ (glState.externalSetState | stateBits);
if ( !diff )
{
@@ -358,6 +368,35 @@ void GL_State( unsigned long stateBits )
}
}
if ((diff & GLS_MULTITEXTURE_ENV) || (diff & GLS_MULTITEXTURE))
{
if (stateBits & GLS_MULTITEXTURE_ENV)
{
GL_TexEnv(GL_COMBINE4_NV);
}
else if (stateBits & GLS_MULTITEXTURE)
{
if (glState.cntTexEnvExt != GLS_MULTITEXTURE)
{
qglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, 34165.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, 8448.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, 0x47057700);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, 5890.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB, 0x47057700);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, 770.0);
glState.cntTexEnvExt = GLS_MULTITEXTURE;
}
GL_TexEnv(GL_COMBINE);
}
else
{
GL_TexEnv(GL_MODULATE);
}
}
//
// alpha test
//
@@ -386,7 +425,109 @@ void GL_State( unsigned long stateBits )
}
}
glState.glStateBits = stateBits;
if (diff & GLS_CLAMP_EDGE)
{
float clampValue;
if (r_forceClampToEdge->value)
{
if (stateBits & GLS_CLAMP_EDGE) {
clampValue = 33071.0;
}
else {
clampValue = 10497.0;
}
}
else
{
if (stateBits & GLS_CLAMP_EDGE) {
clampValue = 10496.0;
}
else {
clampValue = 10497.0;
}
}
if (qglActiveTextureARB)
{
int currenttmu = glState.currenttmu;
GL_SelectTexture(0);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clampValue);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clampValue);
GL_SelectTexture(1);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clampValue);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clampValue);
GL_SelectTexture(currenttmu);
}
else
{
GL_SelectTexture(0);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clampValue);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clampValue);
}
}
if (diff & GLS_FOG)
{
if (glState.externalSetState & GLS_FOG)
{
qglEnable(GL_FOG);
if (stateBits & GLS_FOG_BLACK)
{
vec4_t fBlackFogColor = { 0, 0, 0, 1 };
qglFogfv(GL_FOG_COLOR, fBlackFogColor);
}
else if (stateBits & GLS_FOG_WHITE)
{
vec4_t fWhiteFogColor = { 1, 1, 1, 1 };
qglFogfv(GL_FOG_COLOR, fWhiteFogColor);
}
else
{
//
// Use the global fog
qglFogfv(GL_FOG_COLOR, glState.fFogColor);
}
}
else
{
qglDisable(GL_FOG);
}
}
else if (glState.externalSetState & GLS_FOG)
{
if (diff & GLS_FOG_ENABLED)
{
if (stateBits & GLS_FOG_ENABLED) {
qglEnable(GL_FOG);
}
else {
qglDisable(GL_FOG);
}
}
if (diff & GLS_FOG_COLOR)
{
if (stateBits & GLS_FOG_BLACK)
{
vec4_t fBlackFogColor = { 0, 0, 0, 1 };
qglFogfv(GL_FOG_COLOR, fBlackFogColor);
}
else if (stateBits & GLS_FOG_WHITE)
{
vec4_t fWhiteFogColor = { 1, 1, 1, 1 };
qglFogfv(GL_FOG_COLOR, fWhiteFogColor);
}
}
}
glState.glStateBits = stateBits | glState.externalSetState;
}
@@ -454,23 +595,33 @@ void RB_BeginDrawingView (void) {
//
SetViewportAndScissor();
R_UploadDlights();
// ensures that depth writes are enabled for the depth clear
GL_State( GLS_DEFAULT );
// clear relevant buffers
clearBits = GL_DEPTH_BUFFER_BIT;
if ( r_measureOverdraw->integer || r_shadows->integer == 2 )
if ( r_measureOverdraw->integer || r_shadows->integer == 3 )
{
clearBits |= GL_STENCIL_BUFFER_BIT;
}
if ( r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) )
if (!( backEnd.refdef.rdflags & RDF_NOWORLDMODEL))
{
clearBits |= GL_COLOR_BUFFER_BIT; // FIXME: only if sky shaders have been used
#ifdef _DEBUG
qglClearColor( 0.8f, 0.7f, 0.4f, 1.0f ); // FIXME: get color of sky
#else
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // FIXME: get color of sky
#endif
if (backEnd.viewParms.farplane_distance && tr.skyRendered && tr.portalRendered)
{
clearBits |= GL_COLOR_BUFFER_BIT;
qglClearColor(glState.fFogColor[0], glState.fFogColor[1], glState.fFogColor[2], glState.fFogColor[3]);
}
else
{
if (r_fastsky->integer)
{
clearBits |= GL_COLOR_BUFFER_BIT;
qglClearColor(0.5, 0.5, 1.0, 1.0);
}
}
}
qglClear( clearBits );
@@ -557,6 +708,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
depthRange = qfalse;
backEnd.pc.c_surfaces += numDrawSurfs;
backEnd.numSpheresUsed = 0;
for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) {
if ( drawSurf->sort == oldSort ) {
@@ -701,7 +853,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
}
else
{
backEnd.currentSphere = &backEnd.spheres[backEnd.currentEntity->lightingSphere];
backEnd.currentSphere = &backEnd.spheres[backEnd.numSpheresUsed];
backEnd.currentEntity->lightingSphere = backEnd.numSpheresUsed++;
backEnd.currentEntity->sphereCalculated = 1;
}
@@ -973,6 +1125,10 @@ const void *RB_StretchPic ( const void *data ) {
return (const void *)(cmd + 1);
}
void RB_SetupFog() {
// FIXME: unimplemented
}
/*
=============
+15 -12
View File
@@ -2087,17 +2087,16 @@ void R_LoadStaticModelData(gamelump_t* lump) {
}
s_worldData.numStaticModelData = lump->length / (sizeof(byte) * 3);
s_worldData.staticModelData = ri.Hunk_Alloc(s_worldData.numStaticModelData * (sizeof(byte) * 4));
s_worldData.staticModelData = (byte*)ri.Hunk_Alloc(s_worldData.numStaticModelData * sizeof(color4ub_t));
pSrcColors = lump->buffer;
pDstColors = s_worldData.staticModelData;
for (i = 0; i < lump->length; i += 3)
{
pDstColors[0] = pSrcColors[0];
pDstColors[1] = pSrcColors[1];
pDstColors[2] = pSrcColors[2];
pDstColors[3] = -1;
for (i = 0; i < lump->length; i += sizeof(byte) * 3)
{
// Colors are stored as integers
*(unsigned int*)pDstColors = LittleLong(*(unsigned int*)pSrcColors);
pDstColors[3] = 0xFF;
pSrcColors += sizeof(byte) * 3;
pDstColors += sizeof(byte) * 4;
@@ -2111,11 +2110,15 @@ R_CopyStaticModel
*/
void R_CopyStaticModel(cStaticModel_t* pSM, cStaticModelUnpacked_t* pUnpackedSM) {
pUnpackedSM->visCount = 0;
VectorCopy(pSM->angles, pUnpackedSM->angles);
VectorCopy(pSM->origin, pUnpackedSM->origin);
pUnpackedSM->scale = pSM->scale;
pUnpackedSM->firstVertexData = pSM->firstVertexData * 4 / 3;
pUnpackedSM->numVertexData = pSM->numVertexData;
pUnpackedSM->angles[0] = LittleFloat(pSM->angles[0]);
pUnpackedSM->angles[1] = LittleFloat(pSM->angles[1]);
pUnpackedSM->angles[2] = LittleFloat(pSM->angles[2]);
pUnpackedSM->origin[0] = LittleFloat(pSM->origin[0]);
pUnpackedSM->origin[1] = LittleFloat(pSM->origin[1]);
pUnpackedSM->origin[2] = LittleFloat(pSM->origin[2]);
pUnpackedSM->scale = LittleFloat(pSM->scale);
pUnpackedSM->firstVertexData = LittleLong(pSM->firstVertexData) * sizeof(color4ub_t) / (sizeof(byte) * 3);
pUnpackedSM->numVertexData = LittleLong(pSM->numVertexData);
memcpy(pUnpackedSM->model, pSM->model, sizeof(pUnpackedSM->model));
}
+10
View File
@@ -42,6 +42,16 @@ R_PerformanceCounters
=====================
*/
void R_PerformanceCounters( void ) {
if (fps->integer) {
ri.SetPerformanceCounters(
backEnd.pc.c_totalIndexes / 3,
backEnd.pc.c_vertexes,
R_SumOfUsedImages(pc_save.c_totalIndexes / 3, pc_save.c_vertexes),
pc_save.c_totalIndexes / 3,
pc_save.c_vertexes,
backEnd.pc.c_characterlights
);
}
if ( !r_speeds->integer ) {
// clear the counters even if we aren't printing
Com_Memset( &tr.pc, 0, sizeof( tr.pc ) );
-55
View File
@@ -2057,61 +2057,6 @@ static void R_CreateDlightImage( void ) {
tr.dlightImage = R_CreateImage("*dlight", (byte *)data, DLIGHT_SIZE, DLIGHT_SIZE, 0, 1, qfalse, qfalse, qfalse, qfalse, GL_CLAMP, GL_CLAMP);
}
/*
=================
R_InitFogTable
=================
*/
void R_InitFogTable( void ) {
int i;
float d;
float exp;
exp = 0.5;
for ( i = 0 ; i < FOG_TABLE_SIZE ; i++ ) {
d = pow ( (float)i/(FOG_TABLE_SIZE-1), exp );
tr.fogTable[i] = d;
}
}
/*
================
R_FogFactor
Returns a 0.0 to 1.0 fog density value
This is called for each texel of the fog texture on startup
and for each vertex of transparent shaders in fog dynamically
================
*/
float R_FogFactor( float s, float t ) {
float d;
s -= 1.0/512;
if ( s < 0 ) {
return 0;
}
if ( t < 1.0/32 ) {
return 0;
}
if ( t < 31.0/32 ) {
s *= (t - 1.0f/32.0f) / (30.0f/32.0f);
}
// we need to leave a lot of clamp range
s *= 8;
if ( s > 1.0 ) {
s = 1.0;
}
d = tr.fogTable[ (int)(s * (FOG_TABLE_SIZE-1)) ];
return d;
}
/*
==================
R_CreateDefaultImage
+36 -2
View File
@@ -841,6 +841,13 @@ void GL_SetDefaultState( void )
qglEnable( GL_SCISSOR_TEST );
qglDisable( GL_CULL_FACE );
qglDisable( GL_BLEND );
qglFogi(GL_FOG_MODE, GL_LINEAR);
glState.fFogColor[0] = 0.0;
glState.fFogColor[1] = 0.0;
glState.fFogColor[2] = 0.0;
glState.fFogColor[3] = 1.0;
}
const char* RE_GetGraphicsInfo() {
@@ -1201,7 +1208,18 @@ void R_Register( void )
}
void R_InitExtensions() {
// FIXME: unimplemented
// FIXME: qglTextureEnvCombineExists
glState.cntTexEnvExt = 0;
glState.cntnvblendmode = 0;
qglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, 34165.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, 8448.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, 0x47057700);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, 5890.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB, 0x47057700);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, 770.0);
}
/*
@@ -1228,6 +1246,11 @@ void R_Init( void ) {
}
Com_Memset( tess.constantColor255, 255, sizeof( tess.constantColor255 ) );
tr.worldEntity.e.shaderRGBA[0] = -1;
tr.worldEntity.e.shaderRGBA[1] = 0;
tr.worldEntity.e.shaderRGBA[2] = -1;
tr.worldEntity.e.shaderRGBA[3] = -1;
//
// init function tables
//
@@ -1255,10 +1278,16 @@ void R_Init( void ) {
}
}
R_InitFogTable();
tr.rendererhandle = ri.Milliseconds();
if (!tr.rendererhandle) {
tr.rendererhandle = -1;
}
R_NoiseInit();
R_Sky_Init();
R_Register();
max_polys = r_maxpolys->integer;
@@ -1304,6 +1333,11 @@ void R_Init( void ) {
R_ModelInit();
R_LevelMarksInit();
tr.pFontDebugStrings = R_LoadFont("verdana-14");
g_bInfoworldtris = qfalse;
err = qglGetError();
if ( err != GL_NO_ERROR )
ri.Printf (PRINT_ALL, "glGetError() = 0x%x\n", err);
+94 -2
View File
@@ -29,6 +29,23 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define DLIGHT_MINIMUM_RADIUS 16
// never calculate a range less than this to prevent huge light numbers
typedef struct {
dlight_t *dl;
float power;
vec3_t origin;
} incidentLight_t;
typedef struct {
int dlightMap;
int allocated[128];
byte lightmap_buffer[65536];
byte* srcBase;
byte* dstBase;
incidentLight_t lights[32];
int numLights;
} dlightInfo_t;
dlightInfo_t dli;
/*
===============
@@ -313,10 +330,10 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
vec3_t lightOrigin;
// lighting calculations
if ( ent->lightingCalculated ) {
if ( ent->bLightGridCalculated ) {
return;
}
ent->lightingCalculated = qtrue;
ent->bLightGridCalculated = qtrue;
//
// trace a sample point down to find ambient light
@@ -413,3 +430,78 @@ int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, ve
return qtrue;
}
void R_ClearRealDlights() {
memset(dli.allocated, 0, sizeof(dli.allocated));
dli.dlightMap = 0;
}
void R_UploadDlights() {
int i, h;
if (!tr.pc.c_dlightSurfaces) {
return;
}
h = 0;
for (i = 0; i < 128; ++i)
{
if (h < dli.allocated[i]) {
h = dli.allocated[i];
}
}
if (h)
{
if (h > 128) {
ri.Error(ERR_DROP, "R_UploadDlights: bad allocated height");
}
GL_Bind(tr.dlightImages[dli.dlightMap]);
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, h, GL_RGBA, GL_UNSIGNED_BYTE, dli.lightmap_buffer);
tr.pc.c_dlightMaps++;
memset(dli.allocated, 0, sizeof(dli.allocated));
}
}
qboolean R_AllocLMBlock(int w, int h, int* x, int* y) {
int i, j;
int best, best2;
for (;;)
{
best = 128;
for (i = 0; i < 128 - w; i++)
{
best2 = 0;
for (j = 0; j < w && dli.allocated[i] < best; j++)
{
if (best2 < dli.allocated[i]) {
best2 = dli.allocated[i];
}
}
if (j == w)
{
*x = i;
*y = best2;
best = best2;
}
}
if (h + best <= 128) {
break;
}
if (dli.dlightMap == 14) {
return qfalse;
}
R_UploadDlights();
dli.dlightMap++;
}
return qtrue;
}
+60 -29
View File
@@ -129,7 +129,7 @@ typedef struct {
vec3_t traceOrigin;
float radius;
struct mnode_s* leaves[8];
void(*TessFunction) ();
void(*TessFunction) (unsigned char* dstColors);
union {
unsigned char level[4];
int value;
@@ -170,17 +170,19 @@ typedef struct {
float axisLength; // compensate for non-normalized axis
qboolean needDlights; // true for bmodels that touch a dlight
qboolean lightingCalculated;
vec3_t lightDir; // normalized direction towards light
vec3_t ambientLight; // color normalized to 0-255
int ambientLightInt; // 32 bit rgba packed
vec3_t directedLight;
qboolean bLightGridCalculated;
int iGridLighting;
float lodpercentage[2];
qboolean sphereCalculated;
int lightingSphere;
//
// old lighting variables
//
vec3_t lightDir; // normalized direction towards light
vec3_t ambientLight; // color normalized to 0-255
int ambientLightInt; // 32 bit rgba packed
vec3_t directedLight;
} trRefEntity_t;
typedef struct refSprite_s {
@@ -613,21 +615,29 @@ typedef struct {
int num_entities;
trRefEntity_t *entities;
int num_sprites;
refSprite_t *sprites;
int num_dlights;
struct dlight_s *dlights;
int numTerMarks;
struct srfMarkFragment_s *terMarks;
int numPolys;
struct srfPoly_s *polys;
int numDrawSurfs;
struct drawSurf_s *drawSurfs;
int numSpriteSurfs;
struct drawSurf_s* spriteSurfs;
int numStaticModels;
struct cStaticModelUnpacked_s* staticModels;
int numStaticModelData;
unsigned char* staticModelData;
int numSpriteSurfs;
struct drawSurf_s *spriteSurfs;
int numStaticModels;
struct cStaticModelUnpacked_s *staticModels;
int numStaticModelData;
unsigned char *staticModelData;
qboolean sky_portal;
float sky_alpha;
vec3_t sky_origin;
@@ -683,7 +693,7 @@ typedef struct {
int viewportX, viewportY, viewportWidth, viewportHeight;
float fovX, fovY;
float projectionMatrix[16];
cplane_t frustum[4];
cplane_t frustum[5];
vec3_t visBounds[2];
float zFar;
depthfog_t fog;
@@ -716,9 +726,9 @@ typedef struct drawSurf_s {
typedef struct srfPoly_s {
surfaceType_t surfaceType;
qhandle_t hShader;
int fogIndex;
int numVerts;
polyVert_t *verts;
int renderfx;
} srfPoly_t;
typedef struct srfMarkFragment_s {
@@ -1024,6 +1034,7 @@ typedef struct {
int numShaders;
dshader_t *shaders;
int numBmodels;
bmodel_t *bmodels;
int numplanes;
@@ -1156,6 +1167,8 @@ typedef struct {
int c_leafs;
int c_dlightSurfaces;
int c_dlightSurfacesCulled;
int c_dlightMaps;
int c_dlightTexels;
} frontEndCounters_t;
#define FOG_TABLE_SIZE 256
@@ -1180,7 +1193,7 @@ typedef struct {
typedef struct {
int c_surfaces, c_shaders, c_vertexes, c_indexes, c_totalIndexes;
int c_surfaces, c_shaders, c_vertexes, c_indexes, c_totalIndexes, c_characterlights;
float c_overDraw;
int c_dlightVertexes;
@@ -1252,6 +1265,7 @@ typedef struct {
image_t *flareImage;
image_t *whiteImage; // full of 0xff
image_t *identityLightImage; // full of tr.identityLightByte
image_t *dlightImages[15];
shader_t *defaultShader;
shader_t *shadowShader;
@@ -1281,6 +1295,9 @@ typedef struct {
orientationr_t ori; // for current entity
portalsky_t portalsky;
qboolean skyRendered;
qboolean portalRendered;
trRefdef_t refdef;
int viewCluster;
@@ -1316,7 +1333,6 @@ typedef struct {
float triangleTable[FUNCTABLE_SIZE];
float sawToothTable[FUNCTABLE_SIZE];
float inverseSawToothTable[FUNCTABLE_SIZE];
float fogTable[FOG_TABLE_SIZE];
spherel_t sSunLight;
spherel_t sLights[1532];
@@ -1560,6 +1576,8 @@ void R_DebugCircle(const vec3_t org, float radius, float r, float g, float b, fl
void R_DebugLine(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha);
void R_RenderView( viewParms_t *parms );
qboolean SurfIsOffscreen(const srfSurfaceFace_t* surface, shader_t* shader, int entityNum);
void R_AddMD3Surfaces( trRefEntity_t *e );
void R_AddNullModelSurfaces( trRefEntity_t *e );
void R_AddBeamSurfaces( trRefEntity_t *e );
@@ -1576,18 +1594,24 @@ void R_AddDrawSurf(surfaceType_t* surface, shader_t* shader, int dlightMap);
#define CULL_IN 0 // completely unclipped
#define CULL_CLIP 1 // clipped by one or more planes
#define CULL_OUT 2 // completely outside the clipping planes
void R_LocalNormalToWorld (vec3_t local, vec3_t world);
void R_LocalPointToWorld (vec3_t local, vec3_t world);
void R_LocalNormalToWorld (const vec3_t local, vec3_t world);
void R_LocalPointToWorld (const vec3_t local, vec3_t world);
int R_CullLocalBoxOffset(const vec3_t offset, vec3_t bounds[2]);
int R_CullLocalBox (vec3_t bounds[2]);
int R_CullPointAndRadius( vec3_t origin, float radius );
int R_CullLocalPointAndRadius( vec3_t origin, float radius );
int R_DistanceCullLocalPointAndRadius(float fDist, const vec3_t pt, float radius);
int R_DistanceCullPointAndRadius(float fDist, const vec3_t pt, float radius);
void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, orientationr_t *ori );
void R_RotateForStaticModel(cStaticModelUnpacked_t* SM, const viewParms_t* viewParms, orientationr_t* ori );
void R_RotateForViewer(void);
void R_SetupFrustum(void);
/*
** GL wrapper/helper functions
*/
void GL_SetFogColor(const vec4_t fColor);
void GL_Bind( image_t *image );
void GL_SetDefaultState (void);
void GL_SelectTexture( int unit );
@@ -1619,12 +1643,19 @@ void GL_Cull( int cullType );
#define GLS_DSTBLEND_BITS 0x000000f0
#define GLS_DEPTHMASK_TRUE 0x00000100
#define GLS_POLYMODE_LINE 0x00000200
#define GLS_DEPTHTEST_DISABLE 0x00000400
#define GLS_DEPTHFUNC_EQUAL 0x00000800
#define GLS_POLYMODE_LINE 0x00001000
#define GLS_CLAMP_EDGE 0x00001000
#define GLS_MULTITEXTURE 0x00002000
#define GLS_MULTITEXTURE_ENV 0x00004000
#define GLS_FOG 0x00008000
#define GLS_DEPTHFUNC_EQUAL 0x00020000
#define GLS_FOG_ENABLED 0x00010000
#define GLS_FOG_BLACK 0x00020000
#define GLS_FOG_WHITE 0x00040000
#define GLS_FOG_COLOR (GLS_FOG_BLACK | GLS_FOG_WHITE)
#define GLS_ATEST_GT_0 0x10000000
#define GLS_ATEST_LT_80 0x20000000
@@ -1688,8 +1719,6 @@ void R_SkinList_f( void );
const void *RB_TakeScreenshotCmd( const void *data );
void R_ScreenShot_f( void );
void R_InitFogTable( void );
float R_FogFactor( float s, float t );
void R_InitImages( void );
void R_DeleteTextures( void );
int R_SumOfUsedImages( void );
@@ -1815,6 +1844,7 @@ extern terrainVert_t* g_pVert;
void R_AddBrushModelSurfaces( trRefEntity_t *e );
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs);
mnode_t* R_PointInLeaf(const vec3_t p);
int R_DlightTerrain(cTerraPatchUnpacked_t* surf, int dlightBits);
int R_CheckDlightTerrain(cTerraPatchUnpacked_t* surf, int dlightBits);
void R_AddWorldSurfaces( void );
@@ -1857,6 +1887,7 @@ void RB_Grid_SetupStaticModel();
void RB_Light_Fullbright(const color4ub_t colors);
void R_Sphere_InitLights();
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights);
void R_UploadDlights();
/*
@@ -1868,6 +1899,7 @@ SHADOWS
*/
void RB_ShadowTessEnd( void );
void RB_ComputeShadowVolume();
void RB_ShadowFinish( void );
void RB_ProjectionShadowDeform( void );
@@ -1932,7 +1964,7 @@ void RE_AddRefEntityToScene( const refEntity_t *ent, int parentEntityNumber);
void RE_AddRefSpriteToScene(const refEntity_t* ent);
void RE_AddTerrainMarkToScene(int iTerrainIndex, qhandle_t hShader, int numVerts, const polyVert_t* verts, int renderfx);
refEntity_t* RE_GetRenderEntity(int entityNumber);
qboolean RE_AddPolyToScene(qhandle_t hShader, int numVerts, const polyVert_t* verts, int numPolys);
qboolean RE_AddPolyToScene(qhandle_t hShader, int numVerts, polyVert_t* verts, int renderfx);
void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b, int type );
void RE_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b );
void RE_RenderScene( const refdef_t *fd );
@@ -1972,6 +2004,7 @@ void R_LevelMarksLoad(const char* szBSPName);
void R_LevelMarksInit();
void R_LevelMarksFree();
void R_UpdateLevelMarksSystem();
void R_AddPermanentMarkFragmentSurfaces(void** pFirstMarkFragment, int iNumMarkFragment);
/*
=============================================================
@@ -2060,6 +2093,7 @@ float R_CalcLod(const vec3_t origin, float radius);
extern int g_nStaticSurfaces;
extern qboolean g_bInfostaticmodels;
extern qboolean g_bInfoworldtris;
/*
=============================================================
@@ -2106,9 +2140,6 @@ 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_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 );
void RB_CalcWaveColor(const waveForm_t* wf, unsigned char* dstColors, unsigned char* constantColor);
void RB_CalcAlphaFromEntity( unsigned char *dstColors );
@@ -2224,8 +2255,8 @@ typedef enum {
// these are sort of arbitrary limits.
// the limits apply to the sum of all scenes in a frame --
// the main view, all the 3D icons, etc
#define MAX_POLYS 600
#define MAX_POLYVERTS 3000
#define MAX_POLYS 4096
#define MAX_POLYVERTS 16384
#define MAX_TERMARKS 1024
// all of the information needed by the back end must be
+130 -26
View File
@@ -49,7 +49,7 @@ R_CullLocalBox
Returns CULL_IN, CULL_CLIP, or CULL_OUT
=================
*/
int R_CullLocalBox (vec3_t bounds[2]) {
int R_CullLocalBoxOffset(const vec3_t offset, vec3_t bounds[2]) {
int i, j;
vec3_t transformed[8];
float dists[8];
@@ -69,6 +69,7 @@ int R_CullLocalBox (vec3_t bounds[2]) {
v[2] = bounds[(i>>2)&1][2];
VectorCopy( tr.ori.origin, transformed[i] );
VectorAdd(transformed[i], offset, transformed[i]);
VectorMA( transformed[i], v[0], tr.ori.axis[0], transformed[i] );
VectorMA( transformed[i], v[1], tr.ori.axis[1], transformed[i] );
VectorMA( transformed[i], v[2], tr.ori.axis[2], transformed[i] );
@@ -76,7 +77,7 @@ int R_CullLocalBox (vec3_t bounds[2]) {
// check against frustum planes
anyBack = 0;
for (i = 0 ; i < 4 ; i++) {
for (i = 0 ; i < tr.viewParms.fog.extrafrustums + 4 ; i++) {
frust = &tr.viewParms.frustum[i];
front = back = 0;
@@ -105,6 +106,10 @@ int R_CullLocalBox (vec3_t bounds[2]) {
return CULL_CLIP; // partially clipped
}
int R_CullLocalBox(vec3_t bounds[2]) {
return R_CullLocalBoxOffset(vec3_origin, bounds);
}
/*
** R_CullLocalPointAndRadius
*/
@@ -155,6 +160,35 @@ int R_CullPointAndRadius( vec3_t pt, float radius )
return CULL_IN; // completely inside frustum
}
int R_DistanceCullLocalPointAndRadius(float fDist, const vec3_t pt, float radius) {
vec3_t transformed;
R_LocalPointToWorld(pt, transformed);
return R_DistanceCullPointAndRadius(fDist, transformed, radius);
}
int R_DistanceCullPointAndRadius(float fDist, const vec3_t pt, float radius) {
if (!r_nocull->integer)
{
vec3_t vDelta;
float fLengthSquared;
float fTotalDistSquared;
VectorSubtract(pt, tr.viewParms.ori.origin, vDelta);
fLengthSquared = VectorLengthSquared(vDelta);
fTotalDistSquared = (fDist + radius) * (fDist + radius);
if ((fDist + radius) * (fDist + radius) < vDelta[2] + fLengthSquared) {
return CULL_OUT;
} else if ((fDist - radius) * (fDist - radius) > vDelta[2] + fLengthSquared) {
return CULL_IN;
}
}
return CULL_CLIP;
// FIXME: unimplemented
}
/*
=================
@@ -162,7 +196,7 @@ R_LocalNormalToWorld
=================
*/
void R_LocalNormalToWorld (vec3_t local, vec3_t world) {
void R_LocalNormalToWorld (const vec3_t local, vec3_t world) {
world[0] = local[0] * tr.ori.axis[0][0] + local[1] * tr.ori.axis[1][0] + local[2] * tr.ori.axis[2][0];
world[1] = local[0] * tr.ori.axis[0][1] + local[1] * tr.ori.axis[1][1] + local[2] * tr.ori.axis[2][1];
world[2] = local[0] * tr.ori.axis[0][2] + local[1] * tr.ori.axis[1][2] + local[2] * tr.ori.axis[2][2];
@@ -174,7 +208,7 @@ R_LocalPointToWorld
=================
*/
void R_LocalPointToWorld (vec3_t local, vec3_t world) {
void R_LocalPointToWorld (const vec3_t local, vec3_t world) {
world[0] = local[0] * tr.ori.axis[0][0] + local[1] * tr.ori.axis[1][0] + local[2] * tr.ori.axis[2][0] + tr.ori.origin[0];
world[1] = local[0] * tr.ori.axis[0][1] + local[1] * tr.ori.axis[1][1] + local[2] * tr.ori.axis[2][1] + tr.ori.origin[1];
world[2] = local[0] * tr.ori.axis[0][2] + local[1] * tr.ori.axis[1][2] + local[2] * tr.ori.axis[2][2] + tr.ori.origin[2];
@@ -581,6 +615,70 @@ void R_SetupFrustum (void) {
tr.viewParms.frustum[i].dist = DotProduct (tr.viewParms.ori.origin, tr.viewParms.frustum[i].normal);
SetPlaneSignbits( &tr.viewParms.frustum[i] );
}
if (tr.portalsky.inUse) {
tr.viewParms.farplane_distance = 0.0;
}
else if (r_farplane->integer)
{
tr.viewParms.farplane_distance = r_farplane->value;
sscanf(
r_farplane_color->string,
"%f %f %f",
&tr.viewParms.farplane_color[0],
&tr.viewParms.farplane_color[1],
&tr.viewParms.farplane_color[2]);
tr.viewParms.farplane_cull = !r_farplane_nocull->integer;
}
if (tr.viewParms.farplane_distance)
{
vec3_t farPoint;
float realPlaneLen;
float tmp;
vec4_t fogColor;
tr.viewParms.fog.len = tr.viewParms.farplane_distance;
tr.viewParms.fog.oolen = 1.0 / tr.viewParms.farplane_distance;
farPoint[0] = tr.viewParms.ori.origin[0] + tr.viewParms.ori.axis[0][0] * tr.viewParms.farplane_distance;
farPoint[1] = tr.viewParms.ori.origin[1] + tr.viewParms.ori.axis[0][1] * tr.viewParms.farplane_distance;
farPoint[2] = tr.viewParms.ori.origin[2] + tr.viewParms.ori.axis[0][2] * tr.viewParms.farplane_distance;
VectorNegate(tr.viewParms.ori.axis[0], tr.viewParms.frustum[4].normal);
tr.viewParms.frustum[4].type = PLANE_NON_AXIAL;
tr.viewParms.frustum[4].dist = DotProduct(farPoint, tr.viewParms.frustum[4].normal);
SetPlaneSignbits(&tr.viewParms.frustum[4]);
tr.viewParms.fog.enabled = r_farplane_nofog->integer == 0;
tr.viewParms.fog.extrafrustums = tr.viewParms.farplane_cull;
if (!r_farplane_nofog->integer)
{
qglFogf(GL_FOG_END, tr.viewParms.farplane_distance);
fogColor[0] = tr.viewParms.farplane_color[0] * tr.identityLight;
fogColor[1] = tr.viewParms.farplane_color[1] * tr.identityLight;
fogColor[2] = tr.viewParms.farplane_color[2] * tr.identityLight;
fogColor[3] = 1.0;
GL_SetFogColor(fogColor);
glState.externalSetState |= GLS_FOG;
}
else
{
glState.externalSetState &= ~GLS_FOG;
}
}
else
{
tr.viewParms.fog.enabled = 0;
tr.viewParms.fog.extrafrustums = 0;
glState.externalSetState &= ~GLS_FOG;
}
}
@@ -837,27 +935,26 @@ static qboolean IsMirror( const drawSurf_t *drawSurf, int entityNum )
**
** Determines if a surface is completely offscreen.
*/
static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128] ) {
qboolean SurfIsOffscreen(const srfSurfaceFace_t* surface, shader_t* shader, int entityNum) {
float shortest = 100000000;
int entityNum;
int numTriangles;
shader_t *shader;
int dlighted;
qboolean bStaticModel;
qboolean doRange;
orientationr_t surfOr;
unsigned int* indices;
vec4_t clip, eye;
int i;
unsigned int pointOr = 0;
unsigned int pointAnd = (unsigned int)~0;
if ( glConfig.smpActive ) { // FIXME! we can't do RB_BeginSurface/RB_EndSurface stuff with smp!
return qfalse;
}
R_RotateForViewer();
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &dlighted, &bStaticModel );
RB_BeginSurface( shader );
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
if (entityNum == ENTITYNUM_WORLD) {
surfOr = tr.viewParms.world;
} else {
R_RotateForEntity(&tr.refdef.entities[entityNum], &tr.viewParms, &surfOr);
}
assert( tess.numVertexes < 128 );
@@ -920,21 +1017,27 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128
return qtrue;
}
// mirrors can early out at this point, since we don't do a fade over distance
// with them (although we could)
if ( IsMirror( drawSurf, entityNum ) )
if (shader->fDistRange > 0.0)
{
return qfalse;
}
if ( shortest > (tess.shader->portalRange*tess.shader->portalRange) )
{
return qtrue;
if (shortest > (tess.shader->portalRange * tess.shader->portalRange))
{
return qtrue;
}
}
return qfalse;
}
static qboolean DrawSurfIsOffscreen(drawSurf_t* drawSurf) {
int entityNum;
shader_t* shader;
int dlighted;
qboolean bStaticModel;
R_DecomposeSort(drawSurf->sort, &entityNum, &shader, &dlighted, &bStaticModel);
return SurfIsOffscreen((srfSurfaceFace_t*)drawSurf->surface, shader, entityNum);
}
/*
========================
R_MirrorViewBySurface
@@ -943,7 +1046,6 @@ Returns qtrue if another view has been rendered
========================
*/
qboolean R_MirrorViewBySurface (drawSurf_t *drawSurf, int entityNum) {
vec4_t clipDest[128];
viewParms_t newParms;
viewParms_t oldParms;
orientation_t surface, camera;
@@ -959,7 +1061,7 @@ qboolean R_MirrorViewBySurface (drawSurf_t *drawSurf, int entityNum) {
}
// trivially reject portal/mirror
if ( SurfIsOffscreen( drawSurf, clipDest ) ) {
if (DrawSurfIsOffscreen( drawSurf ) ) {
return qfalse;
}
@@ -1602,6 +1704,8 @@ void R_RenderView (viewParms_t *parms) {
R_SetupFrustum ();
R_Sky_Reset();
R_GenerateDrawSurfs();
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf );
+38 -2
View File
@@ -158,8 +158,7 @@ void R_BoxSurfaces_r(mnode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **li
//
surf = *mark;
// check if the surface has NOIMPACT or NOMARKS set
if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) )
|| ( surf->shader->contentFlags & CONTENTS_FOG ) ) {
if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) ) ) {
surf->viewCount = tr.viewCount;
}
// extra check for surfaces to avoid list overflows
@@ -244,6 +243,38 @@ void R_AddMarkFragments(int numClipPoints, vec3_t clipPoints[2][MAX_VERTS_ON_POL
(*returnedFragments)++;
}
void R_AddMarkFragmentsToTerrain(
cTerraPatchUnpacked_t* pTerPatch,
int numPlanes,
vec3_t* normals,
float* dists,
int maxPoints,
const vec3_t pointBuffer,
markFragment_t* fragmentBuffer,
int* returnedPoints,
int* returnedFragments
)
{
// FIXME: unimplemented
}
void R_TessellateMarkFragments(
int* pReturnedPoints,
int* pReturnedFragments,
int numsurfaces, surfaceType_t** surfaces,
const vec3_t projectionDir, int numPlanes,
vec3_t* normals,
float* dists,
int maxPoints,
const vec3_t pointBuffer,
int maxFragments,
markFragment_t* fragmentBuffer,
float fRadiusSquared
)
{
// FIXME: unimplemented
}
/*
=================
R_MarkFragments
@@ -441,6 +472,11 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
return returnedFragments;
}
void R_BoxSurfacesForBModel_r(bmodel_t* pBmodel, const vec3_t mins, const vec3_t maxs, surfaceType_t** list, int listsize, int* listlength, const vec3_t dir)
{
// FIXME: unimplemented
}
int R_MarkFragmentsForInlineModel(clipHandle_t bmodel, const vec3_t angles, const vec3_t origin, int numPoints,
const vec3_t* points, const vec3_t projection, int maxPoints, vec3_t pointBuffer,
int maxFragments, markFragment_t* fragmentBuffer, float radiusSquared)
+305 -2
View File
@@ -24,22 +24,325 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "tr_local.h"
typedef struct lmEditPoly_s {
srfMarkFragment_t surf;
shader_t* shader;
int viewCount;
polyVert_t verts[8];
mnode_t* pLeafs[8];
int iNumLeafs;
} lmEditPoly_t;
typedef struct lmEditMarkDef_s {
struct lmEditMarkDef_s* pNextMark;
struct lmEditMarkDef_s* pPrevMark;
shader_t* markShader;
vec3_t vPos;
vec3_t vProjection;
float fRadius;
float fHeightScale;
float fWidthScale;
float fRotation;
float color[4];
qboolean bDoLighting;
lmEditPoly_t* pMarkEditPolys;
int iNumEditPolys;
vec3_t vPathCorners[4];
} lmEditMarkDef_t;
typedef struct lmPoly_s {
srfMarkFragment_t surf;
shader_t* shader;
int viewCount;
} lmPoly_t;
typedef struct {
qboolean bLevelMarksLoaded;
char szDCLFilename[MAX_QPATH];
lmPoly_t* pMarkFragments;
qboolean bAutoApplySettings;
lmEditPoly_t* pFreeEditPolys;
lmEditMarkDef_t activeMarkDefs;
lmEditMarkDef_t* pFreeMarkDefs;
lmEditMarkDef_t* pCurrentMark;
qboolean bPathLayingMode;
treadMark_t treadMark;
lmEditMarkDef_t* pTreadMarkStartDecal;
lmEditMarkDef_t* pTreadMarkEndDecal;
} lmGlobals_t;
typedef struct {
int ident;
int version;
int checksum;
int iNumDecals;
int iNumFragments;
} dclHeader_t;
typedef struct {
char shader[MAX_RES_NAME];
vec3_t vPos;
vec3_t vProjection;
float fRadius;
float fHeightScale;
float fWidthScale;
float fRotation;
float color[4];
qboolean bDoLighting;
} dclSavedMarkDef_t;
typedef struct {
char shader[MAX_RES_NAME];
int fogIndex;
int iIndex;
int iNumVerts;
} dclSavedMarkPoly_t;
cvar_t* dcl_editmode;
cvar_t* dcl_showcurrent;
cvar_t* dcl_autogetinfo;
cvar_t* dcl_shiftstep;
cvar_t* dcl_shader;
cvar_t* dcl_radius;
cvar_t* dcl_heightscale;
cvar_t* dcl_widthscale;
cvar_t* dcl_rotation;
cvar_t* dcl_r;
cvar_t* dcl_g;
cvar_t* dcl_b;
cvar_t* dcl_alpha;
cvar_t* dcl_dolighting;
cvar_t* dcl_doworld;
cvar_t* dcl_doterrain;
cvar_t* dcl_dobmodels;
cvar_t* dcl_dostring;
cvar_t* dcl_pathmode;
cvar_t* dcl_maxsegment;
cvar_t* dcl_minsegment;
cvar_t* dcl_maxoffset;
cvar_t* dcl_texturescale;
lmGlobals_t lm;
vec3_t vec_upwards;
void DCLC_Save(void)
{
// FIXME: unimplemented
}
void R_LevelMarksLoad(const char* szBSPName)
{
// FIXME: unimplemented
}
void R_RemoveEditPolyFromPointerList(lmEditPoly_t* pPoly, void** pFragmentList, int* piNumFragments)
{
// FIXME: unimplemented
}
void R_FreeMarkFragments(lmEditMarkDef_t* pMark)
{
// FIXME: unimplemented
}
void R_InitMarkDef(lmEditMarkDef_t* pMark)
{
// FIXME: unimplemented
}
lmEditMarkDef_t* R_AllocateMarkDef(void)
{
// FIXME: unimplemented
return NULL;
}
lmEditPoly_t* R_AllocateEditPoly(void)
{
// FIXME: unimplemented
return NULL;
}
qboolean R_AddEditPolyToPointerList(lmEditPoly_t* pPoly, void*** pFragmentList, int* piNumFragments)
{
// FIXME: unimplemented
return qfalse;
}
lmEditMarkDef_t* R_ApplyLevelDecal(const vec3_t vPos, const vec3_t vDir, qboolean bUseCurrent, qboolean bUseCurrentSettings, int iPathIndex)
{
// FIXME: unimplemented
return NULL;
}
void DCLC_Make(void)
{
// FIXME: unimplemented
}
void DCLC_Reapply(void)
{
// FIXME: unimplemented
}
void DCLC_Delete(void)
{
// FIXME: unimplemented
}
void DCLC_SelectNext(void)
{
// FIXME: unimplemented
}
void DCLC_SelectPrev(void)
{
// FIXME: unimplemented
}
void DCLC_SelectCh(void)
{
// FIXME: unimplemented
}
void DCLC_SelectChNxt(void)
{
// FIXME: unimplemented
}
void DCLC_GetInfo(void)
{
// FIXME: unimplemented
}
void DCLC_ShiftUp(void)
{
// FIXME: unimplemented
}
void DCLC_ShiftDown(void)
{
// FIXME: unimplemented
}
void DCLC_ShiftLeft(void)
{
// FIXME: unimplemented
}
void DCLC_ShiftRight(void)
{
// FIXME: unimplemented
}
void DCLC_RandomRoll(void)
{
// FIXME: unimplemented
}
void R_LevelMarksInit()
{
// FIXME: unimplemented
memset(&lm, 0, sizeof(lm));
dcl_editmode = ri.Cvar_Get("dcl_editmode", "0", CVAR_LATCH);
dcl_showcurrent = ri.Cvar_Get("dcl_showcurrent", "1", 0);
dcl_autogetinfo = ri.Cvar_Get("dcl_autogetinfo", "1", 0);
dcl_shiftstep = ri.Cvar_Get("dcl_shiftstep", "4", 0);
dcl_shader = ri.Cvar_Get("dcl_shader", "blastmark", 0);
dcl_radius = ri.Cvar_Get("dcl_radius", "16", 0);
dcl_heightscale = ri.Cvar_Get("dcl_heightscale", "1", 0);
dcl_widthscale = ri.Cvar_Get("dcl_widthscale", "1", 0);
dcl_rotation = ri.Cvar_Get("dcl_rotation", "0", 0);
dcl_r = ri.Cvar_Get("dcl_r", "1", 0);
dcl_g = ri.Cvar_Get("dcl_g", "1", 0);
dcl_b = ri.Cvar_Get("dcl_b", "1", 0);
dcl_alpha = ri.Cvar_Get("dcl_alpha", "1", 0);
dcl_dolighting = ri.Cvar_Get("dcl_dolighting", "1", 0);
dcl_doworld = ri.Cvar_Get("dcl_doworld", "1", 0);
dcl_doterrain = ri.Cvar_Get("dcl_doterrain", "1", 0);
dcl_dobmodels = ri.Cvar_Get("dcl_dobmodels", "1", 0);
dcl_dostring = ri.Cvar_Get("dcl_dostring", "apply to all", 0);
dcl_pathmode = ri.Cvar_Get("dcl_pathmode", "0", 0);
dcl_maxsegment = ri.Cvar_Get("dcl_maxsegment", "512", 0);
dcl_minsegment = ri.Cvar_Get("dcl_minsegment", "24", 0);
dcl_maxoffset = ri.Cvar_Get("dcl_maxoffset", "10", 0);
dcl_texturescale = ri.Cvar_Get("dcl_texturescale", "32", 0);
if (dcl_editmode->integer)
{
ri.Cmd_AddCommand("dclc_make", DCLC_Make);
ri.Cmd_AddCommand("dclc_reapply", DCLC_Reapply);
ri.Cmd_AddCommand("dclc_delete", DCLC_Delete);
ri.Cmd_AddCommand("dclc_selectnext", DCLC_SelectNext);
ri.Cmd_AddCommand("dclc_selectprev", DCLC_SelectPrev);
ri.Cmd_AddCommand("dclc_selectch", DCLC_SelectCh);
ri.Cmd_AddCommand("dclc_selectchnxt", DCLC_SelectChNxt);
ri.Cmd_AddCommand("dclc_getinfo", DCLC_GetInfo);
ri.Cmd_AddCommand("dclc_shiftup", DCLC_ShiftUp);
ri.Cmd_AddCommand("dclc_shiftdown", DCLC_ShiftDown);
ri.Cmd_AddCommand("dclc_shiftleft", DCLC_ShiftLeft);
ri.Cmd_AddCommand("dclc_shiftright", DCLC_ShiftRight);
ri.Cmd_AddCommand("dclc_randomroll", DCLC_RandomRoll);
ri.Cmd_AddCommand("dclc_save", DCLC_Save);
lm.activeMarkDefs.pNextMark = &lm.activeMarkDefs;
lm.activeMarkDefs.pPrevMark = &lm.activeMarkDefs;
}
}
void R_LevelMarksFree()
{
// FIXME: unimplemented
int i;
if (!dcl_editmode->integer) {
return;
}
ri.Cmd_RemoveCommand("dclc_make");
ri.Cmd_RemoveCommand("dclc_reapply");
ri.Cmd_RemoveCommand("dclc_delete");
ri.Cmd_RemoveCommand("dclc_selectnext");
ri.Cmd_RemoveCommand("dclc_selectprev");
ri.Cmd_RemoveCommand("dclc_selectch");
ri.Cmd_RemoveCommand("dclc_selectchnxt");
ri.Cmd_RemoveCommand("dclc_getinfo");
ri.Cmd_RemoveCommand("dclc_shiftup");
ri.Cmd_RemoveCommand("dclc_shiftdown");
ri.Cmd_RemoveCommand("dclc_shiftleft");
ri.Cmd_RemoveCommand("dclc_shiftright");
ri.Cmd_RemoveCommand("dclc_randomroll");
ri.Cmd_RemoveCommand("dclc_save");
for (i = 0; i < tr.world->numBmodels; i++)
{
bmodel_t* pBmodel = &tr.world->bmodels[i];
if (pBmodel->iNumMarkFragment && pBmodel->pFirstMarkFragment)
{
ri.Free(pBmodel->pFirstMarkFragment);
pBmodel->pFirstMarkFragment = NULL;
pBmodel->iNumMarkFragment = 0;
}
}
for (i = tr.world->numDecisionNodes; i < tr.world->numnodes; i++)
{
mnode_t* pLeaf = &tr.world->nodes[i];
if (pLeaf->iNumMarkFragment)
{
if (pLeaf->pFirstMarkFragment)
{
ri.Free(pLeaf->pFirstMarkFragment);
pLeaf->pFirstMarkFragment = NULL;
pLeaf->iNumMarkFragment = 0;
}
}
}
}
void R_UpdateLevelMarksSystem()
{
// FIXME: unimplemented
}
void R_AddPermanentMarkFragmentSurfaces(void** pFirstMarkFragment, int iNumMarkFragment) {
// FIXME: unimplemented
}
+2
View File
@@ -28,6 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define LL(x) x=LittleLong(x)
qboolean g_bInfoworldtris;
/*
** R_GetModelByHandle
*/
+81 -68
View File
@@ -32,6 +32,12 @@ int r_firstSceneDlight;
int r_numentities;
int r_firstSceneEntity;
int r_numsprites;
int r_firstSceneSprite;
int r_numtermarks;
int r_firstSceneTerMark;
int r_numpolys;
int r_firstScenePoly;
@@ -63,6 +69,12 @@ void R_ToggleSmpFrame( void ) {
r_numentities = 0;
r_firstSceneEntity = 0;
r_numsprites = 0;
r_firstSceneSprite = 0;
r_numtermarks = 0;
r_firstSceneTerMark = 0;
r_numpolys = 0;
r_firstScenePoly = 0;
@@ -79,6 +91,8 @@ RE_ClearScene
void RE_ClearScene( void ) {
r_firstSceneDlight = r_numdlights;
r_firstSceneEntity = r_numentities;
r_firstSceneSprite = r_numsprites;
r_firstSceneTerMark = r_numtermarks;
r_firstScenePoly = r_numpolys;
}
@@ -117,83 +131,28 @@ RE_AddPolyToScene
=====================
*/
qboolean RE_AddPolyToScene( qhandle_t hShader, int numVerts, const polyVert_t *verts, int numPolys ) {
qboolean RE_AddPolyToScene(qhandle_t hShader, int numVerts, polyVert_t* verts, int renderfx) {
srfPoly_t *poly;
int i, j;
int fogIndex;
fog_t *fog;
vec3_t bounds[2];
if ( !tr.registered ) {
return qfalse;
}
if ( !hShader ) {
ri.Printf( PRINT_WARNING, "WARNING: RE_AddPolyToScene: NULL poly shader\n");
if (numVerts + r_numpolyverts > max_polyverts || r_numpolys >= max_polys) {
ri.Printf(PRINT_WARNING, "Exceeded MAX POLYS\n");
return qfalse;
}
for ( j = 0; j < numPolys; j++ ) {
if ( r_numpolyverts + numVerts > max_polyverts || r_numpolys >= max_polys ) {
/*
NOTE TTimo this was initially a PRINT_WARNING
but it happens a lot with high fighting scenes and particles
since we don't plan on changing the const and making for room for those effects
simply cut this message to developer only
*/
ri.Printf( PRINT_DEVELOPER, "WARNING: RE_AddPolyToScene: r_max_polys or r_max_polyverts reached\n");
return qfalse;
}
poly = &backEndData[tr.smpFrame]->polys[r_numpolys];
poly->surfaceType = SF_POLY;
poly->hShader = hShader;
poly->numVerts = numVerts;
poly->verts = &backEndData[tr.smpFrame]->polyVerts[r_numpolyverts];
poly->renderfx = renderfx;
poly = &backEndData[tr.smpFrame]->polys[r_numpolys];
poly->surfaceType = SF_POLY;
poly->hShader = hShader;
poly->numVerts = numVerts;
poly->verts = &backEndData[tr.smpFrame]->polyVerts[r_numpolyverts];
Com_Memcpy( poly->verts, &verts[numVerts*j], numVerts * sizeof( *verts ) );
if ( glConfig.hardwareType == GLHW_RAGEPRO ) {
poly->verts->modulate[0] = 255;
poly->verts->modulate[1] = 255;
poly->verts->modulate[2] = 255;
poly->verts->modulate[3] = 255;
}
// done.
r_numpolys++;
r_numpolyverts += numVerts;
// if no world is loaded
if ( tr.world == NULL ) {
fogIndex = 0;
}
// see if it is in a fog volume
else if ( tr.world->numfogs == 1 ) {
fogIndex = 0;
} else {
// find which fog volume the poly is in
VectorCopy( poly->verts[0].xyz, bounds[0] );
VectorCopy( poly->verts[0].xyz, bounds[1] );
for ( i = 1 ; i < poly->numVerts ; i++ ) {
AddPointToBounds( poly->verts[i].xyz, bounds[0], bounds[1] );
}
for ( fogIndex = 1 ; fogIndex < tr.world->numfogs ; fogIndex++ ) {
fog = &tr.world->fogs[fogIndex];
if ( bounds[1][0] >= fog->bounds[0][0]
&& bounds[1][1] >= fog->bounds[0][1]
&& bounds[1][2] >= fog->bounds[0][2]
&& bounds[0][0] <= fog->bounds[1][0]
&& bounds[0][1] <= fog->bounds[1][1]
&& bounds[0][2] <= fog->bounds[1][2] ) {
break;
}
}
if ( fogIndex == tr.world->numfogs ) {
fogIndex = 0;
}
}
poly->fogIndex = fogIndex;
}
Com_Memcpy(poly->verts, verts, sizeof(polyVert_t) * numVerts);
++r_numpolys;
r_numpolyverts += numVerts;
return qtrue;
}
@@ -254,7 +213,33 @@ void RE_AddRefEntityToScene( const refEntity_t *ent, int parentEntityNumber) {
}
backEndData[tr.smpFrame]->entities[r_numentities].e = *ent;
backEndData[tr.smpFrame]->entities[r_numentities].lightingCalculated = qfalse;
backEndData[tr.smpFrame]->entities[r_numentities].bLightGridCalculated = qfalse;
backEndData[tr.smpFrame]->entities[r_numentities].sphereCalculated = qfalse;
if (parentEntityNumber != ENTITYNUM_NONE)
{
int i;
//
// Find the parent entity to attach to
//
for (i = r_firstSceneEntity; i < r_numentities; i++)
{
if (backEndData[tr.smpFrame]->entities[i].e.entityNumber == parentEntityNumber)
{
backEndData[tr.smpFrame]->entities[r_numentities].e.parentEntity = i - r_firstSceneEntity;
break;
}
}
if (i == r_numentities) {
backEndData[tr.smpFrame]->entities[i].e.parentEntity = ENTITYNUM_NONE;
}
}
else
{
backEndData[tr.smpFrame]->entities[r_numentities].e.parentEntity = ENTITYNUM_NONE;
}
r_numentities++;
}
@@ -387,6 +372,14 @@ void RE_RenderScene( const refdef_t *fd ) {
}
}
// copy the sky data
tr.refdef.sky_alpha = fd->sky_alpha;
tr.refdef.sky_portal = fd->sky_portal;
VectorCopy(fd->sky_origin, tr.refdef.sky_origin);
VectorCopy(fd->sky_axis[0], tr.refdef.sky_axis[0]);
VectorCopy(fd->sky_axis[1], tr.refdef.sky_axis[1]);
VectorCopy(fd->sky_axis[2], tr.refdef.sky_axis[2]);
// derived info
@@ -398,12 +391,20 @@ void RE_RenderScene( const refdef_t *fd ) {
tr.refdef.num_entities = r_numentities - r_firstSceneEntity;
tr.refdef.entities = &backEndData[tr.smpFrame]->entities[r_firstSceneEntity];
tr.refdef.num_sprites = r_numsprites - r_firstSceneSprite;
tr.refdef.sprites = &backEndData[tr.smpFrame]->sprites[r_firstSceneSprite];
tr.refdef.num_dlights = r_numdlights - r_firstSceneDlight;
tr.refdef.dlights = &backEndData[tr.smpFrame]->dlights[r_firstSceneDlight];
tr.refdef.numTerMarks = r_numtermarks - r_firstSceneTerMark;
tr.refdef.terMarks = &backEndData[tr.smpFrame]->terMarks[r_firstSceneTerMark];
tr.refdef.numPolys = r_numpolys - r_firstScenePoly;
tr.refdef.polys = &backEndData[tr.smpFrame]->polys[r_firstScenePoly];
backEndData[tr.smpFrame]->staticModelData = tr.refdef.staticModelData;
// turn off dynamic lighting globally by clearing all the
// dlights if it needs to be disabled or if vertex lighting is enabled
if (r_vertexLight->integer == 1 ) {
@@ -424,6 +425,8 @@ void RE_RenderScene( const refdef_t *fd ) {
// The refdef takes 0-at-the-top y coordinates, so
// convert to GL's 0-at-the-bottom space
//
tr.skyRendered = qfalse;
tr.portalRendered = qfalse;
Com_Memset( &parms, 0, sizeof( parms ) );
parms.viewportX = tr.refdef.x;
parms.viewportY = glConfig.vidHeight - ( tr.refdef.y + tr.refdef.height );
@@ -441,12 +444,22 @@ void RE_RenderScene( const refdef_t *fd ) {
VectorCopy( fd->vieworg, parms.pvsOrigin );
// copy the farplane data
parms.farplane_distance = fd->farplane_distance;
parms.farplane_color[0] = fd->farplane_color[0];
parms.farplane_color[1] = fd->farplane_color[1];
parms.farplane_color[2] = fd->farplane_color[2];
parms.farplane_cull = fd->farplane_cull;
R_ClearRealDlights();
R_RenderView( &parms );
// the next scene rendered in this frame will tack on after this one
r_firstSceneDrawSurf = tr.refdef.numDrawSurfs;
r_firstSceneEntity = r_numentities;
r_firstSceneSprite = r_numsprites;
r_firstSceneDlight = r_numdlights;
r_firstSceneTerMark = r_numtermarks;
r_firstScenePoly = r_numpolys;
tr.frontEndMsec += ri.Milliseconds() - startTime;
+158 -52
View File
@@ -361,23 +361,23 @@ static void DrawMultitextured( shaderCommands_t *input, int stage ) {
if (pStage->multitextureEnv == GL_ADD)
{
qglTexEnvf(8960, 34161, 260.0);
qglTexEnvf(8960, 34176, 33984.0);
qglTexEnvf(8960, 34192, 1145044992);
qglTexEnvf(8960, 34177, 0);
qglTexEnvf(8960, 34193, 1145061376);
qglTexEnvf(8960, 34178, 33985.0);
qglTexEnvf(8960, 34194, 1145044992);
qglTexEnvf(8960, 34179, 0);
qglTexEnvf(8960, 34195, 1145061376);
qglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, 260.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, 33984.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, 0);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 33985.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE3_RGB, 0);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND3_RGB, 0x44404000);
}
else if (pStage->multitextureEnv == GL_MODULATE)
{
qglTexEnvf(8960, 34161, 8448.0);
qglTexEnvf(8960, 34176, 33984.0);
qglTexEnvf(8960, 34192, 1145044992);
qglTexEnvf(8960, 34177, 33985.0);
qglTexEnvf(8960, 34193, 1145044992);
qglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, 33984.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, 33985.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 0x44400000);
}
else
{
@@ -398,13 +398,13 @@ static void DrawMultitextured( shaderCommands_t *input, int stage ) {
glState.cntTexEnvExt = GLS_MULTITEXTURE_ENV;
GL_TexEnv(GL_COMBINE);
qglTexEnvf(GL_TEXTURE_ENV, 34161, 34165.0);
qglTexEnvf(GL_TEXTURE_ENV, 34176, 0x47057700);
qglTexEnvf(GL_TEXTURE_ENV, 34192, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, 34177, 34168.0);
qglTexEnvf(GL_TEXTURE_ENV, 34193, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, 34178, 0x47057700);
qglTexEnvf(GL_TEXTURE_ENV, 34194, 770.0);
qglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, 34165);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, 0x47057700);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, 34168);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 0x44400000);
qglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB, 0x47057700);
qglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, 0x44407700000);
} else {
GL_TexEnv( pStage->multitextureEnv );
}
@@ -810,9 +810,98 @@ static void ComputeColors( shaderStage_t *pStage )
break;
case CGEN_LIGHTING_SPHERICAL:
case CGEN_STATIC:
if (!r_drawspherelights->integer)
if (!r_drawspherelights->integer) {
break;
// FIXME: unimplemented
}
if (!backEnd.currentStaticModel) {
if (backEnd.currentSphere->TessFunction) {
backEnd.currentSphere->TessFunction((unsigned char*)tess.svars.colors);
}
break;
}
if (!tess.vertexColorValid) {
ri.Printf(PRINT_WARNING, "Vertex color specified for shader '%s', but vertex colors are not valid for this model\n", tess.shader->name);
}
if (backEnd.currentStaticModel->useSpecialLighting)
{
for (i = 0; i < tess.numVertexes; i++)
{
int j;
vec3_t colorout;
int r, g, b;
colorout[0] = tess.vertexColors[i][0];
colorout[1] = tess.vertexColors[i][1];
colorout[2] = tess.vertexColors[i][2];
for (j = 0; j < backEnd.currentStaticModel->numdlights; j++)
{
float ooLightDistSquared;
float dot;
vec3_t diff;
dlight_t* dl;
dl = &backEnd.refdef.dlights[backEnd.currentStaticModel->dlights[j].index];
VectorSubtract(backEnd.currentStaticModel->dlights[j].transformed, tess.xyz[i], diff);
dot = DotProduct(diff, tess.normal[i]);
if (dot >= 0)
{
float ooLen;
ooLen = 1.0 / VectorLengthSquared(diff);
ooLightDistSquared = dot * (7500.0 * dl->radius * ooLen * sqrt(ooLen));
colorout[0] = dl->color[0] * ooLightDistSquared + colorout[0];
colorout[1] = dl->color[1] * ooLightDistSquared + colorout[1];
colorout[2] = dl->color[2] * ooLightDistSquared + colorout[2];
}
}
r = colorout[0];
g = colorout[1];
b = colorout[2];
if (tr.overbrightShift)
{
r = (int)((float)r * tr.overbrightMult);
g = (int)((float)g * tr.overbrightMult);
b = (int)((float)b * tr.overbrightMult);
}
if (r > 0xFF || g > 0xFF || b > 0xFF)
{
float t;
t = 255.0 / (float)max(r, max(g, b));
r = (int)((float)r * t);
g = (int)((float)g * t);
b = (int)((float)b * t);
}
tess.svars.colors[i][0] = r;
tess.svars.colors[i][1] = g;
tess.svars.colors[i][2] = b;
}
}
else
{
if (tr.identityLight == 1.0)
{
Com_Memcpy(tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof(tess.vertexColors[0]));
}
else
{
for (i = 0; i < tess.numVertexes; i++) {
tess.svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight;
tess.svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight;
tess.svars.colors[i][2] = tess.vertexColors[i][2] * tr.identityLight;
}
}
}
break;
case CGEN_CONSTANT:
RB_CalcColorFromConstant((unsigned char*)tess.svars.colors, pStage->colorConst);
@@ -1094,54 +1183,64 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
{
int stage;
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
for (stage = 0; stage < MAX_SHADER_STAGES; stage++)
{
shaderStage_t *pStage = tess.xstages[stage];
shaderStage_t* pStage = tess.xstages[stage];
if ( !pStage )
if (!pStage)
{
break;
}
ComputeColors( pStage );
ComputeTexCoords( pStage );
if (pStage->alphaGen == AGEN_SKYALPHA && tr.refdef.sky_alpha < 0.01) {
continue;
}
else if (pStage->alphaGen == AGEN_ONE_MINUS_SKYALPHA && tr.refdef.sky_alpha > 0.99) {
continue;
}
if ( !setArraysOnce )
ComputeTexCoords(pStage);
ComputeColors(pStage);
if (!setArraysOnce)
{
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors );
qglEnableClientState(GL_COLOR_ARRAY);
qglColorPointer(4, GL_UNSIGNED_BYTE, 0, input->svars.colors);
}
//
// do multitexture
//
if ( pStage->bundle[1].image[0] != 0 )
if (pStage->bundle[1].image[0] != 0)
{
DrawMultitextured( input, stage );
DrawMultitextured(input, stage);
}
else
{
if (backEnd.in2D) {
GL_State(pStage->stateBits | GLS_DEPTHTEST_DISABLE);
} else {
}
else {
GL_State(pStage->stateBits);
}
if ( !setArraysOnce )
if (!setArraysOnce)
{
qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] );
qglTexCoordPointer(2, GL_FLOAT, 0, input->svars.texcoords[0]);
}
//
// set state
//
if ( pStage->bundle[0].vertexLightmap && r_vertexLight->integer && r_lightmap->integer )
if (pStage->bundle[0].vertexLightmap && r_vertexLight->integer && r_lightmap->integer)
{
GL_Bind( tr.whiteImage );
} else {
GL_Bind(tr.whiteImage);
}
else {
if (input->dlightMap && tess.xstages[stage]->bundle[0].isLightmap) {
GL_Bind(&tr.identityLightImage[input->dlightMap]);
} else {
}
else {
R_BindAnimatedImage(&pStage->bundle[0]);
}
}
@@ -1149,10 +1248,10 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
//
// draw
//
R_DrawElements( input->numIndexes, input->indexes );
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 || pStage->bundle[0].vertexLightmap))
{
break;
}
@@ -1465,7 +1564,6 @@ void RB_EndSurface( void ) {
if (input->numIndexes == 0) {
return;
}
if (input->indexes[SHADER_MAX_INDEXES-1] != 0) {
ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_INDEXES hit");
}
@@ -1473,8 +1571,12 @@ void RB_EndSurface( void ) {
ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_VERTEXES hit");
}
if (tess.xyz[SHADER_MAX_VERTEXES - 1][0] && r_shadows->integer != 3) {
tess.xyz[SHADER_MAX_VERTEXES - 1][0] = 0;
}
if ( tess.shader == tr.shadowShader ) {
RB_ShadowTessEnd();
RB_ComputeShadowVolume();
return;
}
@@ -1496,15 +1598,19 @@ void RB_EndSurface( void ) {
//
tess.currentStageIteratorFunc();
//
// draw debugging stuff
//
if ( r_showtris->integer ) {
DrawTris (input);
}
if ( r_shownormals->integer ) {
DrawNormals (input);
if (!(tr.refdef.rdflags & RDF_NOWORLDMODEL) && !backEnd.in2D)
{
//
// draw debugging stuff
//
if (r_showtris->integer && developer->integer) {
DrawTris(input);
}
if (r_shownormals->integer && developer->integer) {
DrawNormals(input);
}
}
// clear shader so we can tell we don't have any unclosed surfaces
tess.numIndexes = 0;
-59
View File
@@ -792,65 +792,6 @@ void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors )
}
}
/*
** RB_CalcModulateColorsByFog
*/
void RB_CalcModulateColorsByFog( 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;
}
}
/*
** 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;
}
}
/*
====================================================================
+132 -56
View File
@@ -641,6 +641,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
int depthMaskBits = GLS_DEPTHMASK_TRUE, blendSrcBits = 0, blendDstBits = 0, atestBits = 0, depthFuncBits = 0;
qboolean depthMaskExplicit = qfalse;
int cntBundle = 0;
int depthTestBits = 0;
int fogBits = 0;
stage->active = qtrue;
stage->noMipMaps = shader_noMipMaps;
@@ -660,6 +662,24 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
{
break;
}
// no picmip adjustment
else if ( !Q_stricmp( token, "nomipmaps" ) )
{
stage->noMipMaps = qtrue;
continue;
}
// no picmip adjustment
else if ( !Q_stricmp( token, "nopicmip" ) )
{
stage->noPicMip = qtrue;
continue;
}
// no picmip adjustment
else if ( !Q_stricmp( token, "nofog" ) )
{
fogBits = GLS_FOG;
continue;
}
//
// map <name>
//
@@ -778,11 +798,11 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
if ( !Q_stricmp( token, "lequal" ) )
{
depthFuncBits = 0;
depthTestBits = 0;
}
else if ( !Q_stricmp( token, "equal" ) )
{
depthFuncBits = GLS_DEPTHFUNC_EQUAL;
depthTestBits = GLS_DEPTHFUNC_EQUAL;
}
else
{
@@ -851,7 +871,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
ParseWaveForm( text, &stage->rgbWave );
stage->rgbGen = CGEN_WAVEFORM;
}
else if ( !Q_stricmp( token, "const" ) )
else if ( !Q_stricmp( token, "const" ) || !Q_stricmp(token, "constant"))
{
vec3_t color;
@@ -1286,7 +1306,9 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->stateBits = depthMaskBits |
blendSrcBits | blendDstBits |
atestBits |
depthFuncBits;
depthFuncBits |
depthTestBits |
fogBits;
return qtrue;
}
@@ -1611,8 +1633,11 @@ infoParm_t infoParms[] = {
{"lava", 1, 0, CONTENTS_LAVA }, // very damaging
{"playerclip", 1, 0, CONTENTS_PLAYERCLIP },
{"monsterclip", 1, 0, CONTENTS_MONSTERCLIP },
{"fence", 1, 0, CONTENTS_FENCE },
{"weaponclip", 1, 0, CONTENTS_WEAPONCLIP },
{"vehicleclip", 1, 0, CONTENTS_VEHICLECLIP },
{"nodrop", 1, 0, CONTENTS_NODROP }, // don't drop items or leave bodies (death fog, lava, etc)
{"nonsolid", 1, SURF_NONSOLID, 0}, // clears the solid flag
{"nonsolid", 1, SURF_NONSOLID, 0 }, // clears the solid flag
// utility relevant attributes
{"origin", 1, 0, CONTENTS_ORIGIN }, // center of rotating brushes
@@ -1620,14 +1645,9 @@ infoParm_t infoParms[] = {
{"detail", 0, 0, CONTENTS_DETAIL }, // don't include in structural bsp
{"structural", 0, 0, CONTENTS_STRUCTURAL }, // force into structural bsp even if trnas
{"areaportal", 1, 0, CONTENTS_AREAPORTAL }, // divides areas
{"clusterportal", 1,0, CONTENTS_CLUSTERPORTAL }, // for bots
{"donotenter", 1, 0, CONTENTS_DONOTENTER }, // for bots
{"fog", 1, 0, CONTENTS_FOG}, // carves surfaces entering
{"sky", 0, SURF_SKY, 0 }, // emit light from an environment map
{"lightfilter", 0, SURF_LIGHTFILTER, 0 }, // filter light going through it
{"alphashadow", 0, SURF_ALPHASHADOW, 0 }, // test light on a per-pixel basis
{"hint", 0, SURF_HINT, 0 }, // use as a primary splitter
{"sky", 0, SURF_SKY, 0 }, // emit light from an environment map
{"alphashadow", 1, SURF_ALPHASHADOW, 0 }, // carves surfaces entering
// server attributes
{"slick", 0, SURF_SLICK, 0 },
@@ -1635,16 +1655,29 @@ infoParm_t infoParms[] = {
{"nomarks", 0, SURF_NOMARKS, 0 }, // don't make impact marks, but still explode
{"ladder", 0, SURF_LADDER, 0 },
{"nodamage", 0, SURF_NODAMAGE, 0 },
{"metalsteps", 0, SURF_METALSTEPS,0 },
{"flesh", 0, SURF_FLESH, 0 },
{"nosteps", 0, SURF_NOSTEPS, 0 },
{"paper", 0, SURF_PAPER, 0 },
{"wood", 0, SURF_WOOD, 0 },
{"metal", 0, SURF_METAL, 0 },
{"rock", 0, SURF_ROCK, 0 },
{"dirt", 0, SURF_DIRT, 0 },
{"grill", 0, SURF_GRILL, 0 },
{"grass", 0, SURF_GRASS, 0 },
{"mud", 0, SURF_MUD, 0 },
{"puddle", 0, SURF_PUDDLE, 0 },
{"glass", 0, SURF_GLASS, 0 },
{"gravel", 0, SURF_GRAVEL, 0 },
{"sand", 0, SURF_SAND, 0 },
{"foliage", 0, SURF_FOLIAGE, 0 },
{"snow", 0, SURF_SNOW, 0 },
{"carpet", 0, SURF_CARPET, 0 },
// drawsurf attributes
{"nodraw", 0, SURF_NODRAW, 0 }, // don't generate a drawsurface (or a lightmap)
{"pointlight", 0, SURF_POINTLIGHT, 0 }, // sample lighting at vertexes
{"nolightmap", 0, SURF_NOLIGHTMAP,0 }, // don't generate a lightmap
{"nodlight", 0, SURF_NODLIGHT, 0 }, // don't ever add dynamic lights
{"dust", 0, SURF_DUST, 0} // leave a dust trail when walking on this surface
{"nodraw", 0, SURF_NODRAW, 0 }, // don't generate a drawsurface (or a lightmap)
{"castshadow", 0, SURF_CASTSHADOW, 0 }, // sample lighting at vertexes
{"nolightmap", 0, SURF_NOLIGHTMAP, 0 }, // don't generate a lightmap
{"nodlight", 0, SURF_NODLIGHT, 0 }, // don't ever add dynamic lights
{"hint", 0, SURF_HINT, 0} // leave a dust trail when walking on this surface
};
@@ -2309,12 +2342,6 @@ static shader_t *GeneratePermanentShader( void ) {
newShader->next = currentShader->shader;
currentShader->shader = newShader;
if ( shader.sort <= SS_OPAQUE ) {
newShader->fogPass = FP_EQUAL;
} else if ( shader.contentFlags & CONTENTS_FOG ) {
newShader->fogPass = FP_LE;
}
tr.shaders[ tr.numShaders ] = newShader;
newShader->index = tr.numShaders;
@@ -2332,8 +2359,10 @@ static shader_t *GeneratePermanentShader( void ) {
for ( b = 0 ; b < NUM_TEXTURE_BUNDLES ; b++ ) {
size = newShader->unfoggedStages[i]->bundle[b].numTexMods * sizeof( texModInfo_t );
newShader->unfoggedStages[i]->bundle[b].texMods = ri.Hunk_Alloc( size );
Com_Memcpy( newShader->unfoggedStages[i]->bundle[b].texMods, unfoggedStages[i].bundle[b].texMods, size );
if (size) {
newShader->unfoggedStages[i]->bundle[b].texMods = ri.Hunk_Alloc(size);
Com_Memcpy(newShader->unfoggedStages[i]->bundle[b].texMods, unfoggedStages[i].bundle[b].texMods, size);
}
}
}
@@ -2443,9 +2472,9 @@ from the current global working shader
*/
static shader_t *FinishShader( void ) {
int stage;
int i;
int bundle;
qboolean hasLightmapStage;
qboolean vertexLightmap;
qboolean hasLightmapStage;
if (!currentShader) {
currentShader = FindShaderText(shader.name);
@@ -2459,11 +2488,13 @@ static shader_t *FinishShader( void ) {
}
hasLightmapStage = qfalse;
vertexLightmap = qfalse;
//
// set sky stuff appropriate
//
if ( shader.isPortalSky ) {
shader.sort = SS_PORTALSKY;
}
if ( shader.isSky ) {
shader.sort = SS_ENVIRONMENT;
}
@@ -2475,13 +2506,15 @@ static shader_t *FinishShader( void ) {
shader.sort = SS_DECAL;
}
shader.needsLGrid = qfalse;
shader.needsLSpherical = qfalse;
//
// set appropriate stage information
//
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) {
shaderStage_t *pStage = &unfoggedStages[stage];
// check for a missing texture
stage = 0;
for (shaderStage_t* pStage = &unfoggedStages[0]; pStage->active; pStage++, stage++) {
// check for a missing texture
if ( !pStage->bundle[0].image[0] ) {
ri.Printf( PRINT_WARNING, "Shader %s has a stage with no image\n", shader.name );
pStage->active = qfalse;
@@ -2511,19 +2544,13 @@ static shader_t *FinishShader( void ) {
}
}
// not a true lightmap but we want to leave existing
// behaviour in place and not print out a warning
//if (pStage->rgbGen == CGEN_VERTEX) {
// vertexLightmap = qtrue;
//}
if (pStage->multitextureEnv && pStage->bundle[0].isLightmap) {
//
// exchange bundle
//
textureBundle_t tmp = pStage->bundle[0];
textureBundle_t tmpBundle = pStage->bundle[0];
pStage->bundle[0] = pStage->bundle[1];
pStage->bundle[1] = tmp;
pStage->bundle[1] = tmpBundle;
}
//
@@ -2555,23 +2582,70 @@ static shader_t *FinishShader( void ) {
//
// if we are in r_vertexLight mode, never use a lightmap texture
//
if ( stage > 1 && r_vertexLight->integer ) {
VertexLightingCollapse();
stage = 1;
hasLightmapStage = qfalse;
if (stage > 1)
{
if (r_vertexLight->integer) {
VertexLightingCollapse();
stage = 1;
hasLightmapStage = qfalse;
}
//
// look for multitexture potential
//
if (qglActiveTextureARB) {
CollapseMultitexture(&stage);
};
}
//
// look for multitexture potential
//
if (stage > 1 && qglActiveTextureARB) {
CollapseMultitexture(&stage);
};
for (i = 0; i < stage; i++) {
int blendSrcBits, blendDstBits;
// FIXME: fog shader
shaderStage_t* pStage = &unfoggedStages[i];
if (pStage->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS))
{
blendSrcBits = pStage->stateBits & GLS_SRCBLEND_BITS;
blendDstBits = pStage->stateBits & GLS_DSTBLEND_BITS;
if (blendSrcBits == GLS_SRCBLEND_ONE && blendDstBits == GLS_DSTBLEND_ONE
|| blendSrcBits == GLS_SRCBLEND_ZERO && blendDstBits == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR
|| blendSrcBits == GLS_SRCBLEND_SRC_ALPHA && blendDstBits == GLS_DSTBLEND_ONE
|| blendSrcBits == GLS_SRCBLEND_DST_COLOR && blendDstBits == GLS_DSTBLEND_ONE
|| blendSrcBits == GLS_SRCBLEND_ONE_MINUS_DST_COLOR && blendDstBits == GLS_DSTBLEND_ONE)
{
pStage->stateBits |= GLS_FOG_ENABLED | GLS_FOG_BLACK;
}
else if (blendSrcBits == GLS_SRCBLEND_DST_COLOR && blendDstBits == GLS_DSTBLEND_ZERO
|| blendSrcBits == GLS_SRCBLEND_ZERO && blendDstBits == GLS_DSTBLEND_SRC_COLOR)
{
pStage->stateBits |= GLS_FOG_ENABLED | GLS_FOG_WHITE;
}
else if (blendSrcBits == GLS_SRCBLEND_SRC_ALPHA && blendDstBits == GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA
|| blendSrcBits == GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA && blendDstBits == GLS_DSTBLEND_SRC_ALPHA
|| blendSrcBits == GLS_SRCBLEND_SRC_ALPHA && blendDstBits == GLS_DSTBLEND_ONE)
{
pStage->stateBits |= GLS_FOG_ENABLED;
}
else {
ri.Printf(PRINT_WARNING, "Shader '%s' stage# %i is unfoggable\n", shader.name, i + 1);
}
if (shader.sort == SS_BAD)
{
if (pStage->stateBits & GLS_DEPTHMASK_TRUE) {
shader.sort = SS_SEE_THROUGH;
}
else {
shader.sort = SS_BLEND0;
}
}
}
else {
pStage->stateBits |= GLS_FOG_ENABLED;
}
}
// fogonly shaders don't have any normal passes
if (stage == 0) {
if (shader.sort == SS_BAD) {
shader.sort = SS_OPAQUE;
}
@@ -2586,9 +2660,11 @@ static shader_t *FinishShader( void ) {
shader.numUnfoggedPasses = 0;
for (stage = 0; stage < MAX_SHADER_STAGES; stage++) {
shaderStage_t* pStage = &unfoggedStages[stage];
if (pStage->active) {
shader.numUnfoggedPasses++;
if (!pStage->active) {
break;
}
shader.numUnfoggedPasses++;
}
// determine which stage iterator function is appropriate
+16 -13
View File
@@ -45,19 +45,6 @@ static edgeDef_t edgeDefs[SHADER_MAX_VERTEXES][MAX_EDGE_DEFS];
static int numEdgeDefs[SHADER_MAX_VERTEXES];
static int facing[SHADER_MAX_INDEXES/3];
void R_AddEdgeDef( int i1, int i2, int facing ) {
int c;
c = numEdgeDefs[ i1 ];
if ( c == MAX_EDGE_DEFS ) {
return; // overflow
}
edgeDefs[ i1 ][ c ].i2 = i2;
edgeDefs[ i1 ][ c ].facing = facing;
numEdgeDefs[ i1 ]++;
}
void R_RenderShadowEdges( void ) {
int i;
@@ -139,6 +126,19 @@ void R_RenderShadowEdges( void ) {
#endif
}
void R_AddEdgeDef(int i1, int i2, int facing) {
int c;
c = numEdgeDefs[i1];
if (c == MAX_EDGE_DEFS) {
return; // overflow
}
edgeDefs[i1][c].i2 = i2;
edgeDefs[i1][c].facing = facing;
numEdgeDefs[i1]++;
}
/*
=================
RB_ShadowTessEnd
@@ -248,6 +248,9 @@ void RB_ShadowTessEnd( void ) {
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
}
void RB_ComputeShadowVolume() {
// FIXME: unimplemented
}
/*
=================
+117 -3
View File
@@ -26,15 +26,129 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
void R_Sky_Init()
{
// FIXME: unimplemented
tr.portalsky.inUse = qfalse;
tr.portalsky.numSurfs = 0;
}
void R_Sky_Reset()
{
// FIXME: unimplemented
if (tr.portalsky.inUse) {
return;
}
tr.portalsky.mins[0] = 8192.0;
tr.portalsky.mins[1] = 8192.0;
tr.portalsky.mins[2] = 8192.0;
tr.portalsky.maxs[0] = -8192.0;
tr.portalsky.maxs[1] = -8192.0;
tr.portalsky.maxs[2] = -8192.0;
tr.portalsky.cntNode = 0;
tr.portalsky.numSurfs = 0;
}
void R_Sky_AddSurf(msurface_t* surf)
{
// FIXME: unimplemented
if (tr.portalsky.inUse)
{
static int last_sky_warning = 0;
if (tr.refdef.time - 1000 > last_sky_warning)
{
ri.Printf(3, "WARNING: sky being drawn in a sky portal! Bad! Bad!\n");
last_sky_warning = tr.refdef.time;
}
return;
}
if (tr.portalsky.numSurfs < 32) {
tr.portalsky.skySurfs[tr.portalsky.numSurfs++] = surf;
}
if (tr.portalsky.cntNode)
{
int i;
for (i = 0; i < 3; i++) {
if (tr.portalsky.mins[i] >= tr.portalsky.cntNode->mins[i]) {
tr.portalsky.mins[i] = tr.portalsky.cntNode->mins[i];
}
if (tr.portalsky.maxs[i] >= tr.portalsky.cntNode->maxs[i]) {
tr.portalsky.maxs[i] = tr.portalsky.cntNode->maxs[i];
}
}
}
}
void R_Sky_Render() {
int i;
viewParms_t newParms, oldParms;
mnode_t* leaf;
if (!tr.portalsky.numSurfs) {
return;
}
if (!tr.refdef.sky_portal) {
return;
}
if (tr.skyRendered) {
// already rendered
return;
}
if (tr.portalsky.inUse)
{
ri.Printf(PRINT_WARNING, "WARNING: Recursive skies found! Make that not happen!\n");
return;
}
for (i = 0; i < tr.portalsky.numSurfs; i++) {
if (!SurfIsOffscreen((const srfSurfaceFace_t*)tr.portalsky.skySurfs[i]->data, tr.portalsky.skySurfs[i]->shader, ENTITYNUM_WORLD)) {
break;
}
}
if (i == tr.portalsky.numSurfs) {
return;
}
tr.skyRendered = qtrue;
oldParms = tr.viewParms;
newParms = tr.viewParms;
if (r_skyportal->integer)
{
if (sscanf(r_skyportal_origin->string, "%f %f %f", &newParms.ori.origin[0], &newParms.ori.origin[1], &newParms.ori.origin[2]) != 3)
{
ri.Printf(PRINT_WARNING, "WARNING: Invalid sky portal origin: %s\n", r_skyportal_origin->string);
return;
}
}
else
{
VectorCopy(tr.refdef.sky_origin, newParms.ori.origin);
MatrixMultiply(newParms.ori.axis, tr.refdef.sky_axis, newParms.ori.axis);
}
tr.portalsky.inUse = qtrue;
VectorCopy(newParms.ori.origin, newParms.pvsOrigin);
leaf = R_PointInLeaf(newParms.pvsOrigin);
if (leaf) {
R_RenderView(&newParms);
}
tr.viewParms = oldParms;
tr.portalsky.inUse = qfalse;
tr.portalsky.numSurfs = 0;
R_RotateForViewer();
R_SetupFrustum();
}
void R_Sky_ChangeFrustum() {
// FIXME: unimplemented
}
+48 -21
View File
@@ -56,14 +56,11 @@ void R_InitStaticModels(void) {
g = (int)((float)tr.world->staticModelData[i * 4 + 1] * tr.overbrightMult);
b = (int)((float)tr.world->staticModelData[i * 4 + 2] * tr.overbrightMult);
if ((r | g | b) & 0xFFFFFF00)
if (r > 0xFF || g > 0xFF || b > 0xFF)
{
float t;
unsigned long long rgb;
rgb = (g + (~((unsigned long long)(r - g) >> 32) & (r - g)) - b);
t = 255.0 / (float)(b + (~(rgb & 0x00000000FFFFFFFF) & rgb));
t = 255.0 / (float)max(r, max(g, b));
r = (int)((float)r * t);
g = (int)((float)g * t);
@@ -326,6 +323,7 @@ void R_AddStaticModelSurfaces(void) {
{
skelHeaderGame_t* skelmodel = TIKI_GetSkel(tiki->mesh[mesh]);
skelSurfaceGame_t* surface;
staticSurface_t* s_surface;
shader_t* shader;
if (!skelmodel) {
@@ -336,7 +334,7 @@ void R_AddStaticModelSurfaces(void) {
// draw all surfaces
//
surface = skelmodel->pSurfaces;
for (j = 0; j < skelmodel->numSurfaces; j++, surface = surface->pNext, dsurf++)
for (j = 0; j < skelmodel->numSurfaces; j++, ofsStaticData += surface->numVerts, surface = surface->pNext, dsurf++)
{
if (g_nStaticSurfaces >= MAX_STATIC_MODELS_SURFS)
{
@@ -344,18 +342,44 @@ void R_AddStaticModelSurfaces(void) {
continue;
}
g_staticSurfaces[g_nStaticSurfaces].ident = SF_TIKI_STATIC;
g_staticSurfaces[g_nStaticSurfaces].ofsStaticData = ofsStaticData;
g_staticSurfaces[g_nStaticSurfaces].surface = surface;
g_staticSurfaces[g_nStaticSurfaces].meshNum = mesh;
s_surface = &g_staticSurfaces[g_nStaticSurfaces++];
s_surface->ident = SF_TIKI_STATIC;
s_surface->ofsStaticData = ofsStaticData;
s_surface->surface = surface;
s_surface->meshNum = mesh;
shader = tr.shaders[dsurf->hShader[0]];
SM->bRendered = qtrue;
R_AddDrawSurf((surfaceType_t*)&g_staticSurfaces[g_nStaticSurfaces], shader, 0);
if (shader->numUnfoggedPasses == 1)
{
if (shader->unfoggedStages[0]->alphaGen == AGEN_DIST_FADE)
{
if (R_DistanceCullPointAndRadius(shader->fDistNear + shader->fDistRange, tiki_worldorigin, SM->cull_radius) == CULL_OUT) {
continue;
}
}
else if (shader->unfoggedStages[0]->alphaGen == AGEN_ONE_MINUS_DIST_FADE)
{
if (R_DistanceCullPointAndRadius(shader->fDistNear, tiki_worldorigin, SM->cull_radius) == CULL_IN) {
continue;
}
}
}
g_nStaticSurfaces++;
ofsStaticData += surface->numVerts;
SM->bRendered = qtrue;
R_AddDrawSurf((surfaceType_t*)s_surface, shader, 0);
if (r_showstaticlod->integer) {
//
// FIXME: draw debug lods
//
}
if (r_showstaticbboxes->integer) {
//
// FIXME: draw debug bbox
//
}
}
}
}
@@ -456,15 +480,18 @@ void RB_StaticMesh(staticSurface_t* staticSurf) {
}
if (backEndData[backEnd.smpFrame]->staticModelData) {
color4ub_t* in = (color4ub_t*)&backEndData[backEnd.smpFrame]->staticModelData[backEnd.currentStaticModel->firstVertexData + staticSurf->ofsStaticData];
color4ub_t* out = &tess.vertexColors[baseVertex];
const size_t offset = backEnd.currentStaticModel->firstVertexData + staticSurf->ofsStaticData * sizeof(color4ub_t);
assert(offset < tr.world->numStaticModelData * sizeof(color4ub_t));
assert(offset + render_count * sizeof(color4ub_t) <= tr.world->numStaticModelData * sizeof(color4ub_t));
for (i = 0; i < render_count; i++, in++, out++)
const color4ub_t* in = (const color4ub_t*)&backEndData[backEnd.smpFrame]->staticModelData[offset];
for (i = 0; i < render_count; i++)
{
(*out)[0] = (*in)[0];
(*out)[1] = (*in)[1];
(*out)[2] = (*in)[2];
(*out)[3] = (*in)[3];
tess.vertexColors[baseVertex + i][0] = in[i][0];
tess.vertexColors[baseVertex + i][1] = in[i][1];
tess.vertexColors[baseVertex + i][2] = in[i][2];
tess.vertexColors[baseVertex + i][3] = in[i][3];
}
}
else {
+36 -12
View File
@@ -407,46 +407,56 @@ static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits )
if ( !r_nocull->integer ) {
int r;
if ( planeBits & 1 ) {
if (planeBits & 1) {
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[0]);
if (r == 2) {
return; // culled
}
if ( r == 1 ) {
if (r == 1) {
planeBits &= ~1; // all descendants will also be in front
}
}
if ( planeBits & 2 ) {
if (planeBits & 2) {
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[1]);
if (r == 2) {
return; // culled
}
if ( r == 1 ) {
if (r == 1) {
planeBits &= ~2; // all descendants will also be in front
}
}
if ( planeBits & 4 ) {
if (planeBits & 4) {
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[2]);
if (r == 2) {
return; // culled
}
if ( r == 1 ) {
if (r == 1) {
planeBits &= ~4; // all descendants will also be in front
}
}
if ( planeBits & 8 ) {
if (planeBits & 8) {
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[3]);
if (r == 2) {
return; // culled
}
if ( r == 1 ) {
if (r == 1) {
planeBits &= ~8; // all descendants will also be in front
}
}
if (planeBits & 16) {
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[4]);
if (r == 2) {
return; // culled
}
if (r == 1) {
planeBits &= ~16; // all descendants will also be in front
}
}
}
if ( node->contents != -1 ) {
@@ -488,6 +498,8 @@ static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits )
tr.viewParms.visBounds[1][2] = node->maxs[2];
}
tr.portalsky.cntNode = node;
if (r_drawbrushes->integer) {
// add the individual surfaces
mark = node->firstmarksurface;
@@ -509,8 +521,20 @@ static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits )
R_MarkTerrainPatch(tr.world->visTerraPatches[node->firstTerraPatch + i]);
}
}
// FIXME: static decals
// FIXME: static models
if (r_drawstaticdecals->integer) {
if (node->pFirstMarkFragment) {
R_AddPermanentMarkFragmentSurfaces(node->pFirstMarkFragment, node->iNumMarkFragment);
}
}
if (r_drawstaticmodels->integer) {
int i;
for (i = 0; i < node->numStaticModels; i++) {
tr.world->visStaticModels[node->firstStaticModel + i]->visCount = tr.visCount;
}
}
}
}
@@ -521,7 +545,7 @@ static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits )
R_PointInLeaf
===============
*/
static mnode_t *R_PointInLeaf( const vec3_t p ) {
mnode_t *R_PointInLeaf( const vec3_t p ) {
mnode_t *node;
float d;
cplane_t *plane;
@@ -692,7 +716,7 @@ void R_AddWorldSurfaces (void) {
tr.refdef.num_dlights = 32;
}
R_TransformDlights(tr.refdef.num_dlights, tr.refdef.dlights, &tr.viewParms.world);
R_RecursiveWorldNode(tr.world->nodes, 15, (1 << tr.refdef.num_dlights) - 1);
R_RecursiveWorldNode(tr.world->nodes, tr.viewParms.fog.extrafrustums ? 31 : 15, (1 << tr.refdef.num_dlights) - 1);
if (r_drawterrain->integer) {
R_AddTerrainSurfaces();
+8 -1
View File
@@ -600,7 +600,14 @@ void MenuManager::RealignMenus
)
{
// FIXME: stub
int i;
int num;
num = m_menulist.NumObjects();
for (i = 1; i <= num; i++)
{
m_menulist.ObjectAt(i)->RealignWidgets();
}
}
void MenuManager::AddMenu
+1 -1
View File
@@ -1601,7 +1601,7 @@ void UIWidget::TextAlignment
)
{
for( int i = 1; i < ev->NumArgs(); i++ )
for( int i = 1; i <= ev->NumArgs(); i++ )
{
str align = ev->GetString( 1 );
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 KiB