Compare commits

...

51 Commits

Author SHA1 Message Date
Alibek Omarov
da4c4bb76a ref: remove unused sprite_radius global variable 2026-04-19 00:32:45 +05:00
Alibek Omarov
95b3271d68 engine: client: move input stuff to input subfolder 2026-04-18 22:18:50 +05:00
Alibek Omarov
3361a5d760 engine: client: split OSK into it's own file 2026-04-18 22:18:50 +05:00
Alibek Omarov
b725d2ece0 engine: client: moving beds 2026-04-18 22:18:50 +05:00
Alibek Omarov
66bee8b468 engine: client: fix trimmed autocomplete output for keys 2026-04-18 22:18:50 +05:00
Alibek Omarov
5e664dc3e9 engine: client: check for upper bound limit in Key_StringToKeynum 2026-04-18 22:18:50 +05:00
Alibek Omarov
bfdfeb3dc0 engine: client: fix Joy_GetHatValueForAxis threshold for forward axis, fix bindings limit 2026-04-18 22:18:50 +05:00
Alibek Omarov
49248f5e14 engine: client: touch fixes, fix division-by-zero in Touch_AspectRatio, GRID_COUNT, fix Touch_RemoveButtonFromList 2026-04-18 22:18:50 +05:00
Владислав Сухов
d03ea4c10a engine: client: in_gyro: fix inverted yaw axis 2026-04-18 00:41:46 +05:00
ksagameng
780dbd6183 scripts: gha: fix ios ci builds not including game libs 2026-04-17 19:41:30 +05:00
GLoOoccK
50da79f1e0 Update cl_parse_gs.c 2026-04-17 19:40:58 +05:00
Alibek Omarov
62201900cf ref: null: remove unused function 2026-04-16 23:25:32 +05:00
Alibek Omarov
ae233ac491 Merge branch 'refapi-15' 2026-04-16 23:19:06 +05:00
Владислав Сухов
dd1cb04cb7 engine: client: sdl: add support for built-in device gyroscope using SDL2 Sensor API (Android/iOS) 2026-04-16 00:15:35 +05:00
Alibek Omarov
74869c8f5d ref: make R_GatherPlayerLight shared between renderers 2026-04-14 22:36:15 +05:00
Alibek Omarov
dd712a0df9 engine: update Mod_PointInLeaf signature for RefAPI 2026-04-14 22:36:15 +05:00
Alibek Omarov
bfdb62d31e engine: ref_api: complete the RefAPI 15 changelog 2026-04-14 22:36:15 +05:00
Alibek Omarov
ae7b9eb28d engine: move creation of default textures to the engnie 2026-04-14 22:36:15 +05:00
Alibek Omarov
c63e13c8f4 engine: move handling of AVI textures into the engine 2026-04-14 22:36:15 +05:00
Alibek Omarov
d3e1407675 engine: remove unused R_Flush and VGUI_UploadTextureBlock from RefAPI 2026-04-14 22:36:15 +05:00
Alibek Omarov
e2e4728c7c engine: remove R_BeamCull from RefAPI 2026-04-14 22:36:15 +05:00
Alibek Omarov
dd3583d11a engine: move details textures parser to the engine 2026-04-14 21:18:57 +05:00
Alibek Omarov
e6924844da engine: move FillRenderAPI and FillTriAPI to renderers to reduce amount of exports 2026-04-14 21:18:56 +05:00
Alibek Omarov
a49db03561 engine: move StudioAPI negotiation to the engine 2026-04-14 21:18:03 +05:00
Alibek Omarov
84b7b5803b ref: soft: remove mistakingly put const on RI.rvp 2026-04-13 23:13:49 +05:00
Alibek Omarov
c224d39ba7 ref: soft: replace RI.onlyClientDraw with RF_ONLY_CLIENTDRAW flag in viewpass 2026-04-13 23:13:49 +05:00
Alibek Omarov
9b24b08df1 ref: gl: remove onlyClientDraw, drawOrtho, RI.params with viewpass flag check. RF_DRAW_OVERVIEW and RF_DRAW_CUBEMAP are cannot be set at the same time, so drawOrtho check replaced by RF_DRAW_CUBEMAP only 2026-04-13 23:13:49 +05:00
Alibek Omarov
a37b0e58f1 ref: soft: get rid of RI.drawOrtho, it's a debugging/development tool, not suited for software renderer use 2026-04-13 23:13:49 +05:00
Alibek Omarov
afca422e35 ref: soft: read ref_viewpass_t flags instead of cached RI.drawWorld 2026-04-13 23:13:49 +05:00
Alibek Omarov
3440ddf443 ref: gl: read ref_viewpass_t flags instead of cached RI.drawWorld 2026-04-13 23:13:49 +05:00
Alibek Omarov
6730ed9555 ref: soft: remove unused isSkyVisible 2026-04-13 23:13:49 +05:00
Alibek Omarov
fdd3a44fa0 ref: gl: remove unused isSkyVisible 2026-04-13 23:13:49 +05:00
Alibek Omarov
241c926076 ref: soft: replace RI.{vieworg,viewangles,pvsorigin} by ref_viewpass_t fields 2026-04-13 23:13:49 +05:00
Alibek Omarov
148a9a5a8c ref: gl: replace RI.{vieworg,viewangles,pvsorigin} by ref_viewpass_t fields 2026-04-13 23:13:49 +05:00
Alibek Omarov
513984d7fd ref: soft: save original viewpass and access viewport and fov through it 2026-04-13 23:13:49 +05:00
Alibek Omarov
1009795d5c ref: gl: save original viewpass and access viewport and fov through it 2026-04-13 23:13:49 +05:00
Alibek Omarov
e3d2da74db engine: move underwater fov effect handling to the engine 2026-04-13 23:13:49 +05:00
Alibek Omarov
ff3a57ae8a ref: gl: drop legacy mirror viewpass code 2026-04-13 23:13:49 +05:00
Alibek Omarov
271a6e2210 ref: soft: drop broken code for all non-viewer viewpasses 2026-04-13 23:13:49 +05:00
Alibek Omarov
0d40357b93 ref: common: wscript: fix psvita build 2026-04-13 13:01:18 +05:00
Alibek Omarov
a9dcdd034c ref: soft: fix build 2026-04-13 13:01:18 +05:00
Alibek Omarov
7324ff43fc ref: add GL_ResampleTexture to libref_common 2026-04-13 13:01:18 +05:00
Alibek Omarov
d85e7fc2b1 ref: move remaining light functions to libref_common 2026-04-13 13:01:18 +05:00
Alibek Omarov
d91ecfa3df ref: gl: refactor R_LightVec 2026-04-13 13:01:18 +05:00
Alibek Omarov
b7a3a02aad ref: common: add R_PushDlightsForBmodel 2026-04-13 13:01:18 +05:00
Alibek Omarov
5aca78951c ref: move R_PushDlights and R_MarkLights to ref_common 2026-04-13 13:01:18 +05:00
Alibek Omarov
81abae65b5 ref: move RunLightstyles to ref_common 2026-04-13 13:01:18 +05:00
Alibek Omarov
f5f6d9bbe4 engine: move sprite texture loading back to engine, only leave rendering for renderer 2026-04-13 13:01:18 +05:00
Alibek Omarov
ef73b55413 ref: common: move malloc and GL_InitRandomTable 2026-04-13 13:01:18 +05:00
Alibek Omarov
8334695522 ref: common: draft new static library, containing shared code for ref_gl and ref_soft 2026-04-13 13:01:18 +05:00
Alibek Omarov
d7f416d659 engine: draft new RefAPI 14: remove reserved functions from render api, remove CL_AddCustomBeam 2026-04-13 13:01:18 +05:00
89 changed files with 2553 additions and 3896 deletions

View File

@@ -444,13 +444,16 @@ qboolean AVI_Think( movie_state_t *Avi )
if( Avi->texture == 0 ) if( Avi->texture == 0 )
{ {
int cinTexture = SCR_GetCinematicTexture();
int w = Avi->w >= 0 ? Avi->w : refState.width; int w = Avi->w >= 0 ? Avi->w : refState.width;
int h = Avi->h >= 0 ? Avi->h : refState.height; int h = Avi->h >= 0 ? Avi->h : refState.height;
ref.dllFuncs.R_DrawStretchRaw( Avi->x, Avi->y, w, h, Avi->xres, Avi->yres, Avi->dst, redraw ); if( redraw )
ref.dllFuncs.GL_UpdateTexture( cinTexture, Avi->xres, Avi->yres, Avi->xres, Avi->yres, Avi->dst, PF_BGRA_32 );
ref.dllFuncs.R_DrawStretchPic( Avi->x, Avi->y, w, h, 0, 0, 1, 1, cinTexture );
} }
else if( redraw && Avi->texture > 0 ) else if( redraw && Avi->texture > 0 )
ref.dllFuncs.AVI_UploadRawFrame( Avi->texture, Avi->xres, Avi->yres, Avi->w, Avi->h, Avi->dst ); ref.dllFuncs.GL_UpdateTexture( Avi->texture, Avi->xres, Avi->yres, Avi->w, Avi->h, Avi->dst, PF_BGRA_32 );
if( flushing && !decoded ) if( flushing && !decoded )
return false; // probably hit an EOF return false; // probably hit an EOF

View File

@@ -849,6 +849,31 @@ BEAM * GAME_EXPORT R_BeamEnts( int startEnt, int endEnt, int modelIndex, float l
return pbeam; return pbeam;
} }
static qboolean R_BeamVisible( const vec3_t start, const vec3_t end )
{
vec3_t mins, maxs;
for( int i = 0; i < 3; i++ )
{
if( start[i] < end[i] )
{
mins[i] = start[i];
maxs[i] = end[i];
}
else
{
mins[i] = end[i];
maxs[i] = start[i];
}
// don't let it be zero sized
if( mins[i] == maxs[i] )
maxs[i] += 1.0f;
}
return Mod_BoxVisible( mins, maxs, ref.dllFuncs.Mod_GetCurrentVis( ));
}
/* /*
============== ==============
R_BeamPoints R_BeamPoints
@@ -861,7 +886,7 @@ BEAM * GAME_EXPORT R_BeamPoints( vec3_t start, vec3_t end, int modelIndex, float
{ {
BEAM *pbeam; BEAM *pbeam;
if( life != 0 && ref.dllFuncs.R_BeamCull( start, end, true )) if( life != 0 && !R_BeamVisible( start, end ))
return NULL; return NULL;
pbeam = R_BeamAlloc(); pbeam = R_BeamAlloc();

View File

@@ -981,15 +981,8 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
if( !draw_player ) if( !draw_player )
return false; return false;
if( entityType == ET_BEAM ) if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
{
ref.dllFuncs.CL_AddCustomBeam( ent );
return true;
}
else if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
{
return false; return false;
}
// because pTemp->entity.curstate.effects // because pTemp->entity.curstate.effects
// is already occupied by FTENT_FLICKER // is already occupied by FTENT_FLICKER

360
engine/client/cl_sprite.c Normal file
View File

@@ -0,0 +1,360 @@
/*
cl_sprite.c - sprite loading
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "common.h"
#include "client.h"
#include "sprite.h"
#include "ref_common.h"
static char sprite_name[MAX_QPATH];
static char group_suffix[8];
static uint r_texFlags = 0;
static int sprite_version;
/*
================
R_GetSpriteFrame
assume pModel is valid
================
*/
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe = NULL;
float *pintervals, fullinterval;
int i, numframes;
float targettime;
if( !pModel )
return NULL;
psprite = pModel->cache.data;
if( frame < 0 )
{
frame = 0;
}
else if( frame >= psprite->numframes )
{
if( frame > psprite->numframes )
Con_Printf( S_WARN "%s: no such frame %d (%s)\n", __func__, frame, pModel->name );
frame = psprite->numframes - 1;
}
if( psprite->frames[frame].type == SPR_SINGLE )
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if( psprite->frames[frame].type == SPR_GROUP )
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by zero
targettime = cl.time - ((int)( cl.time / fullinterval )) * fullinterval;
for( i = 0; i < ( numframes - 1 ); i++ )
{
if( pintervals[i] > targettime )
break;
}
pspriteframe = pspritegroup->frames[i];
}
else if( psprite->frames[frame].type == FRAME_ANGLED )
{
int angleframe = (int)( Q_rint(( refState.viewangles[1] - yaw + 45.0f ) / 360 * 8 ) - 4 ) & 7;
// e.g. doom-style sprite monsters
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[angleframe];
}
return pspriteframe;
}
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite )
{
mspriteframe_t *pFrame;
if( !pSprite || pSprite->type != mod_sprite )
return;
pFrame = R_GetSpriteFrame( pSprite, currentFrame, 0.0f );
if( frameWidth )
*frameWidth = pFrame->width;
if( frameHeight )
*frameHeight = pFrame->height;
if( numFrames )
*numFrames = pSprite->numframes;
}
int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
if( !m_pSpriteModel || m_pSpriteModel->type != mod_sprite || !m_pSpriteModel->cache.data )
return 0;
return R_GetSpriteFrame( m_pSpriteModel, frame, 0.0f )->gl_texturenum;
}
static void Mod_SpriteTextureReplacementReport( const char *modelname, int gl_texturenum, const char *foundpath )
{
if( host_allow_materials.value != 2.0f )
return;
if( gl_texturenum > 0 )
Con_Printf( "Looking for %s tex replacement..." S_GREEN "OK (%s)\n", modelname, foundpath );
else if( gl_texturenum < 0 )
Con_Printf( "Looking for %s tex replacement..." S_YELLOW "MISS (%s)\n", modelname, foundpath );
else
Con_Printf( "Looking for %s tex replacement..." S_RED "FAIL (%s)\n", modelname, foundpath );
}
static qboolean Mod_SpriteSearchForTextureReplacement( char *out, size_t size, const char *modelname, const char *fmt, ... )
{
va_list ap;
int ret;
va_start( ap, fmt );
ret = Q_vsnprintf( out, size, fmt, ap );
va_end( ap );
if( ret < 0 )
{
Mod_SpriteTextureReplacementReport( modelname, -1, "overflow" );
return false;
}
if( FS_FileExists( out, false ))
return true;
Mod_SpriteTextureReplacementReport( modelname, -1, out );
return false;
}
static const byte *Mod_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
{
dspriteframe_t pinframe;
mspriteframe_t *pspriteframe;
int gl_texturenum = 0;
char texname[128];
int bytes = 1;
memcpy( &pinframe, pin, sizeof( dspriteframe_t ));
if( sprite_version == SPRITE_VERSION_32 )
bytes = 4;
// build unique frame name
if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite
{
Q_snprintf( texname, sizeof( texname ), "#HUD/%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
else
{
// partial HD-textures support
if( Mod_AllowMaterials( ))
{
if( Mod_SpriteSearchForTextureReplacement( texname, sizeof( texname ), sprite_name, "materials/%s/%s%i%i.tga", sprite_name, group_suffix, num / 10, num % 10 ))
{
gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, NULL, 0, r_texFlags );
Mod_SpriteTextureReplacementReport( sprite_name, gl_texturenum, texname );
}
}
if( gl_texturenum == 0 )
{
Q_snprintf( texname, sizeof( texname ), "#%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
}
// setup frame description
pspriteframe = Mem_Malloc( mod->mempool, sizeof( mspriteframe_t ));
pspriteframe->width = pinframe.width;
pspriteframe->height = pinframe.height;
pspriteframe->up = pinframe.origin[1];
pspriteframe->left = pinframe.origin[0];
pspriteframe->down = pinframe.origin[1] - pinframe.height;
pspriteframe->right = pinframe.width + pinframe.origin[0];
pspriteframe->gl_texturenum = gl_texturenum;
*ppframe = pspriteframe;
return (const byte *)pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes;
}
static const byte *Mod_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
{
const dspritegroup_t *pingroup;
mspritegroup_t *pspritegroup;
const dspriteinterval_t *pin_intervals;
float *poutintervals;
int i, groupsize, numframes;
const void *ptemp;
pingroup = (const dspritegroup_t *)pin;
numframes = pingroup->numframes;
groupsize = sizeof( mspritegroup_t ) + ( numframes - 1 ) * sizeof( pspritegroup->frames[0] );
pspritegroup = Mem_Calloc( mod->mempool, groupsize );
pspritegroup->numframes = numframes;
*ppframe = (mspriteframe_t *)pspritegroup;
pin_intervals = (const dspriteinterval_t *)( pingroup + 1 );
poutintervals = Mem_Calloc( mod->mempool, numframes * sizeof( float ));
pspritegroup->intervals = poutintervals;
for( i = 0; i < numframes; i++ )
{
*poutintervals = pin_intervals->interval;
if( *poutintervals <= 0.0f )
*poutintervals = 1.0f; // set error value
poutintervals++;
pin_intervals++;
}
ptemp = (const void *)pin_intervals;
for( i = 0; i < numframes; i++ )
{
ptemp = Mod_SpriteLoadFrame( mod, ptemp, &pspritegroup->frames[i], framenum * 10 + i );
}
return ptemp;
}
void Mod_SpriteLoadTextures( model_t *mod, const void *buffer )
{
const dsprite_t *pin = buffer;
const short *numi = NULL;
const byte *pframetype;
msprite_t *psprite = mod->cache.data;
int i;
if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 )
numi = NULL;
else if( pin->version == SPRITE_VERSION_HL )
numi = (const short *)((const byte *)buffer + sizeof( dsprite_hl_t ));
r_texFlags = mod->numtexinfo;
sprite_version = pin->version;
Q_strncpy( sprite_name, mod->name, sizeof( sprite_name ));
COM_StripExtension( sprite_name );
if( numi == NULL )
{
rgbdata_t *pal;
pal = FS_LoadImage( "#id.pal", (byte *)&i, 768 );
pframetype = (const byte *)buffer + sizeof( dsprite_q1_t );
FS_FreeImage( pal );
}
else if( *numi <= 256 )
{
const byte *src = (const byte *)( numi + 1 );
rgbdata_t *pal;
size_t pal_bytes = *numi * 3;
// install palette
switch( psprite->texFormat )
{
case SPR_INDEXALPHA:
pal = FS_LoadImage( "#gradient.pal", src, pal_bytes );
break;
case SPR_ALPHTEST:
pal = FS_LoadImage( "#masked.pal", src, pal_bytes );
break;
default:
pal = FS_LoadImage( "#texgamma.pal", src, pal_bytes );
break;
}
pframetype = (const byte *)( src + pal_bytes );
FS_FreeImage( pal );
}
else
{
Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be less or equal than 256)\n", mod->name, *numi );
return;
}
if( mod->numframes < 1 )
return;
for( i = 0; i < mod->numframes; i++ )
{
frametype_t frametype;
dframetype_t dframetype;
memcpy( &dframetype, pframetype, sizeof( dframetype ));
frametype = dframetype.type;
psprite->frames[i].type = (spriteframetype_t)frametype;
switch( frametype )
{
case FRAME_SINGLE:
Q_strncpy( group_suffix, "frame", sizeof( group_suffix ));
pframetype = Mod_SpriteLoadFrame( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_GROUP:
Q_strncpy( group_suffix, "group", sizeof( group_suffix ));
pframetype = Mod_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_ANGLED:
Q_strncpy( group_suffix, "angle", sizeof( group_suffix ));
pframetype = Mod_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
}
if( pframetype == NULL )
break;
}
}
void Mod_SpriteUnloadTextures( void *data )
{
msprite_t *psprite = data;
int i;
if( !data )
return;
// release all textures
for( i = 0; i < psprite->numframes; i++ )
{
if( !psprite->frames[i].frameptr )
continue;
if( psprite->frames[i].type == SPR_SINGLE )
{
ref.dllFuncs.GL_FreeTexture( psprite->frames[i].frameptr->gl_texturenum );
}
else
{
mspritegroup_t *pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr;
int j;
for( j = 0; j < pspritegroup->numframes; j++ )
{
if( pspritegroup->frames[j] )
ref.dllFuncs.GL_FreeTexture( pspritegroup->frames[j]->gl_texturenum );
}
}
}
}

View File

@@ -25,6 +25,7 @@ AVI PLAYING
*/ */
static movie_state_t *cin_state; static movie_state_t *cin_state;
static int cin_texture;
/* /*
================== ==================
@@ -281,6 +282,12 @@ void SCR_InitCinematic( void )
{ {
AVI_Initailize (); AVI_Initailize ();
cin_state = AVI_GetState( CIN_MAIN ); cin_state = AVI_GetState( CIN_MAIN );
cin_texture = ref.dllFuncs.GL_CreateTexture( "*cintexture", 64, 64, NULL, TF_NOMIPMAP|TF_CLAMP );
}
int SCR_GetCinematicTexture( void )
{
return cin_texture;
} }
/* /*

View File

@@ -360,6 +360,29 @@ qboolean V_PreRender( void )
//============================================================================ //============================================================================
/*
====================
V_ApplyRefUnderwater
apply underwater fov effect
====================
*/
static void V_ApplyRefUnderwater( ref_viewpass_t *rvp )
{
if( !FBitSet( rvp->flags, RF_DRAW_CUBEMAP|RF_DRAW_OVERVIEW ))
return;
if( !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
return;
if( cl.local.waterlevel < 3 )
return;
rvp->fov_x = atan( tan( DEG2RAD( rvp->fov_x ) / 2 ) * ( 0.97f + sin( cl.time * 1.5f ) * 0.03f )) * 2 / (M_PI_F / 180.0f);
rvp->fov_y = atan( tan( DEG2RAD( rvp->fov_y ) / 2 ) * ( 1.03f - sin( cl.time * 1.5f ) * 0.03f )) * 2 / (M_PI_F / 180.0f);
}
/* /*
================== ==================
V_RenderView V_RenderView
@@ -389,6 +412,7 @@ void V_RenderView( void )
clgame.dllFuncs.pfnCalcRefdef( &rp ); clgame.dllFuncs.pfnCalcRefdef( &rp );
V_GetRefParams( &rp, &rvp ); V_GetRefParams( &rp, &rvp );
V_RefApplyOverview( &rvp ); V_RefApplyOverview( &rvp );
V_ApplyRefUnderwater( &rvp );
if( viewnum == 0 && FBitSet( rvp.flags, RF_ONLY_CLIENTDRAW )) if( viewnum == 0 && FBitSet( rvp.flags, RF_ONLY_CLIENTDRAW ))
{ {

View File

@@ -874,7 +874,6 @@ struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend );
void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int height ); void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int height );
void CL_DisableScissor( scissor_state_t *scissor ); void CL_DisableScissor( scissor_state_t *scissor );
qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 ); qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 );
static inline cl_entity_t *CL_EDICT_NUM( int index ) static inline cl_entity_t *CL_EDICT_NUM( int index )
{ {
if( unlikely( !clgame.entities )) // not in game yet if( unlikely( !clgame.entities )) // not in game yet
@@ -972,6 +971,13 @@ void SCR_DrawPos( void );
void SCR_DrawEnts( void ); void SCR_DrawEnts( void );
void SCR_DrawUserCmd( void ); void SCR_DrawUserCmd( void );
//
// cl_sprite.c
//
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw );
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite );
int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame );
// //
// cl_netgraph.c // cl_netgraph.c
// //
@@ -1209,6 +1215,7 @@ void SteamBroker_TerminateGameConnection( void );
// cl_video.c // cl_video.c
// //
void SCR_InitCinematic( void ); void SCR_InitCinematic( void );
int SCR_GetCinematicTexture( void );
void SCR_FreeCinematic( void ); void SCR_FreeCinematic( void );
qboolean SCR_PlayCinematic( const char *name ); qboolean SCR_PlayCinematic( const char *name );
qboolean SCR_DrawCinematic( void ); qboolean SCR_DrawCinematic( void );
@@ -1234,7 +1241,6 @@ void Key_EnumCmds_f( void );
void Key_SetKeyDest( int key_dest ); void Key_SetKeyDest( int key_dest );
void Key_EnableTextInput( qboolean enable, qboolean force ); void Key_EnableTextInput( qboolean enable, qboolean force );
int Key_ToUpper( int key ); int Key_ToUpper( int key );
void OSK_Draw( void );
qboolean Cmd_GetKeysList( const char *s, char *completedname, int length, qboolean print_suggestions ); qboolean Cmd_GetKeysList( const char *s, char *completedname, int length, qboolean print_suggestions );
// //

View File

@@ -23,6 +23,8 @@ GNU General Public License for more details.
#include "client.h" #include "client.h"
#include "const.h" #include "const.h"
#include "triangleapi.h" #include "triangleapi.h"
#include "r_studioint.h"
#include "mod_local.h"
#include "r_efx.h" #include "r_efx.h"
#include "demo_api.h" #include "demo_api.h"
#include "ivoicetweak.h" #include "ivoicetweak.h"
@@ -374,13 +376,13 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
int w, h; int w, h;
// assume we get sizes from image // assume we get sizes from image
ref.dllFuncs.R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite ); R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
width = w; width = w;
height = h; height = h;
} }
texnum = ref.dllFuncs.R_GetSpriteTexture( clgame.ds.pSprite, frame ); texnum = R_GetSpriteTexture( clgame.ds.pSprite, frame );
if( prc ) if( prc )
{ {
@@ -1424,7 +1426,7 @@ int EXPORT pfnSPR_Frames( HSPRITE hPic )
{ {
int numFrames = 0; int numFrames = 0;
ref.dllFuncs.R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic )); R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
return numFrames; return numFrames;
} }
@@ -1439,7 +1441,7 @@ static int GAME_EXPORT pfnSPR_Height( HSPRITE hPic, int frame )
{ {
int sprHeight = 0; int sprHeight = 0;
ref.dllFuncs.R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic )); R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
return sprHeight; return sprHeight;
} }
@@ -1454,7 +1456,7 @@ static int GAME_EXPORT pfnSPR_Width( HSPRITE hPic, int frame )
{ {
int sprWidth = 0; int sprWidth = 0;
ref.dllFuncs.R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic )); R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
return sprWidth; return sprWidth;
} }
@@ -2173,7 +2175,7 @@ pfnGetViewModel
============= =============
*/ */
static cl_entity_t* GAME_EXPORT CL_GetViewModel( void ) static cl_entity_t *GAME_EXPORT CL_GetViewModel( void )
{ {
return &clgame.viewent; return &clgame.viewent;
} }
@@ -3324,7 +3326,7 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
{ {
int gl_texturenum; int gl_texturenum;
if(( gl_texturenum = ref.dllFuncs.R_GetSpriteTexture( pSpriteModel, frame )) <= 0 ) if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
return 0; return 0;
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum ); ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum );
@@ -3929,6 +3931,69 @@ void CL_UnloadProgs( void )
memset( &clgame, 0, sizeof( clgame )); memset( &clgame, 0, sizeof( clgame ));
} }
static model_t *pfnStudio_Mod_ForName( const char *name, int crash )
{
return Mod_ForName( name, crash, false );
}
static void *pfnStudio_Mod_Extradata( model_t *mod )
{
return Mod_StudioExtradata( mod );
}
static void pfnStudio_GetAliasScale( float *x, float *y )
{
if( x ) *x = 1.0f;
if( y ) *y = 1.0f;
}
static float ***pfnStudio_GetAliasTransform( void )
{
return NULL;
}
static model_t *pfnStudio_GetChromeSprite( void )
{
return cl_sprite_shell;
}
static int pfnStudio_IsHardware( void )
{
return 1;
}
static engine_studio_api_t gStudioAPI =
{
.Mem_Calloc = Mod_Calloc,
.Cache_Check = Mod_CacheCheck,
.LoadCacheFile = Mod_LoadCacheFile,
.Mod_ForName = pfnStudio_Mod_ForName,
.Mod_Extradata = pfnStudio_Mod_Extradata,
.GetModelByIndex = CL_ModelHandle,
.GetCvar = pfnCVarGetPointer,
.GetChromeSprite = pfnStudio_GetChromeSprite,
.GetAliasScale = pfnStudio_GetAliasScale,
.StudioGetAliasTransform = pfnStudio_GetAliasTransform,
.GetViewEntity = CL_GetViewModel,
.IsHardware = pfnStudio_IsHardware,
};
static void CL_InitStudioAPI( void )
{
static r_studio_interface_t gDefaultStudioDraw;
r_studio_interface_t *pStudioDraw;
if( !ref.dllFuncs.R_StudioFillAPI( &gStudioAPI, &gDefaultStudioDraw ))
return;
pStudioDraw = &gDefaultStudioDraw;
if( clgame.dllFuncs.pfnGetStudioModelInterface )
clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI );
ref.dllFuncs.R_StudioSetDrawInterface( pStudioDraw );
}
qboolean CL_LoadProgs( const char *name ) qboolean CL_LoadProgs( const char *name )
{ {
static playermove_t gpMove; static playermove_t gpMove;
@@ -4066,7 +4131,7 @@ qboolean CL_LoadProgs( const char *name )
// initialize game // initialize game
clgame.dllFuncs.pfnInit(); clgame.dllFuncs.pfnInit();
ref.dllFuncs.CL_InitStudioAPI(); CL_InitStudioAPI();
return true; return true;
} }

View File

@@ -214,6 +214,11 @@ static void pfnAVI_StreamSound( movie_state_t *avi, int entnum, float fvol, floa
return; // stub, use AVI_SetParm and AVI_Think to stream AVI sound return; // stub, use AVI_SetParm and AVI_Think to stream AVI sound
} }
static void pfnAVI_UploadRawFrame( int texture, int cols, int rows, int width, int height, const byte *data )
{
ref.dllFuncs.GL_UpdateTexture( texture, cols, rows, width, height, data, PF_BGRA_32 );
}
static render_api_t gRenderAPI = static render_api_t gRenderAPI =
{ {
pfnRenderGetParm, // GL_RenderGetParm, pfnRenderGetParm, // GL_RenderGetParm,
@@ -243,7 +248,7 @@ static render_api_t gRenderAPI =
AVI_GetVideoInfo, AVI_GetVideoInfo,
AVI_GetVideoFrameNumber, AVI_GetVideoFrameNumber,
AVI_GetVideoFrame, AVI_GetVideoFrame,
NULL, // R_UploadStretchRaw, pfnAVI_UploadRawFrame, // AVI_UploadRawFrame
AVI_FreeVideo, AVI_FreeVideo,
AVI_IsActive, AVI_IsActive,
pfnAVI_StreamSound, pfnAVI_StreamSound,
@@ -283,40 +288,6 @@ static render_api_t gRenderAPI =
COM_SetRandomSeed, COM_SetRandomSeed,
}; };
static void R_FillRenderAPIFromRef( render_api_t *to, const ref_interface_t *from )
{
to->GetDetailScaleForTexture = from->GetDetailScaleForTexture;
to->GetExtraParmsForTexture = from->GetExtraParmsForTexture;
to->GetFrameTime = from->GetFrameTime;
to->R_SetCurrentEntity = from->R_SetCurrentEntity;
to->R_SetCurrentModel = from->R_SetCurrentModel;
to->GL_FindTexture = from->GL_FindTexture;
to->GL_TextureName = from->GL_TextureName;
to->GL_TextureData = from->GL_TextureData;
to->GL_LoadTexture = from->GL_LoadTexture;
to->GL_CreateTexture = from->GL_CreateTexture;
to->GL_LoadTextureArray = from->GL_LoadTextureArray;
to->GL_CreateTextureArray = from->GL_CreateTextureArray;
to->GL_FreeTexture = from->GL_FreeTexture;
to->DrawSingleDecal = from->DrawSingleDecal;
to->R_DecalSetupVerts = from->R_DecalSetupVerts;
to->R_EntityRemoveDecals = from->R_EntityRemoveDecals;
to->AVI_UploadRawFrame = from->AVI_UploadRawFrame;
to->GL_Bind = from->GL_Bind;
to->GL_SelectTexture = from->GL_SelectTexture;
to->GL_LoadTextureMatrix = from->GL_LoadTextureMatrix;
to->GL_TexMatrixIdentity = from->GL_TexMatrixIdentity;
to->GL_CleanUpTextureUnits = from->GL_CleanUpTextureUnits;
to->GL_TexGen = from->GL_TexGen;
to->GL_TextureTarget = from->GL_TextureTarget;
to->GL_TexCoordArrayMode = from->GL_TexCoordArrayMode;
to->GL_UpdateTexSize = from->GL_UpdateTexSize;
to->GL_DrawParticles = from->GL_DrawParticles;
to->LightVec = from->LightVec;
to->StudioGetTexture = from->StudioGetTexture;
to->GL_GetProcAddress = from->R_GetProcAddress;
}
/* /*
=============== ===============
R_InitRenderAPI R_InitRenderAPI
@@ -329,8 +300,15 @@ qboolean R_InitRenderAPI( void )
// make sure what render functions is cleared // make sure what render functions is cleared
memset( &clgame.drawFuncs, 0, sizeof( clgame.drawFuncs )); memset( &clgame.drawFuncs, 0, sizeof( clgame.drawFuncs ));
// fill missing functions from renderer gRenderAPI.GetDetailScaleForTexture = ref.dllFuncs.R_GetDetailScaleForTexture;
R_FillRenderAPIFromRef( &gRenderAPI, &ref.dllFuncs ); gRenderAPI.GL_FindTexture = ref.dllFuncs.GL_FindTexture;
gRenderAPI.GL_TextureName = ref.dllFuncs.GL_TextureName;
gRenderAPI.GL_TextureData = ref.dllFuncs.GL_TextureData;
gRenderAPI.GL_LoadTexture = ref.dllFuncs.GL_LoadTexture;
gRenderAPI.GL_FreeTexture = ref.dllFuncs.GL_FreeTexture;
gRenderAPI.GL_Bind = ref.dllFuncs.GL_Bind;
ref.dllFuncs.R_FillRenderAPI( &gRenderAPI );
if( clgame.dllFuncs.pfnGetRenderInterface ) if( clgame.dllFuncs.pfnGetRenderInterface )
{ {

View File

@@ -287,13 +287,6 @@ static entity_state_t *R_StudioGetPlayerState( int index )
return &cl.frames[cl.parsecountmod].playerstate[index]; return &cl.frames[cl.parsecountmod].playerstate[index];
} }
static int pfnGetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio )
{
return clgame.dllFuncs.pfnGetStudioModelInterface ?
clgame.dllFuncs.pfnGetStudioModelInterface( version, ppinterface, pstudio ) :
0;
}
static const bpc_desc_t *pfnImage_GetPFDesc( int idx ) static const bpc_desc_t *pfnImage_GetPFDesc( int idx )
{ {
return &PFDesc[idx]; return &PFDesc[idx];
@@ -329,11 +322,6 @@ static qboolean R_Init_Video_( ref_graphic_apis_t type )
return R_Init_Video( type ); return R_Init_Video( type );
} }
static mleaf_t *pfnMod_PointInLeaf( const vec3_t p, mnode_t *node )
{
// FIXME: get rid of this on next RefAPI update
return Mod_PointInLeaf( p, node, cl.models[1] );
}
static const ref_api_t gEngfuncs = static const ref_api_t gEngfuncs =
{ {
@@ -375,7 +363,7 @@ static const ref_api_t gEngfuncs =
Mod_SampleSizeForFace, Mod_SampleSizeForFace,
Mod_BoxVisible, Mod_BoxVisible,
pfnMod_PointInLeaf, Mod_PointInLeaf,
R_DrawWorldHull, R_DrawWorldHull,
R_DrawModelHull, R_DrawModelHull,
@@ -411,7 +399,6 @@ static const ref_api_t gEngfuncs =
Mod_CacheCheck, Mod_CacheCheck,
Mod_LoadCacheFile, Mod_LoadCacheFile,
Mod_Calloc, Mod_Calloc,
pfnGetStudioModelInterface,
_Mem_AllocPool, _Mem_AllocPool,
_Mem_FreePool, _Mem_FreePool,
@@ -465,6 +452,7 @@ static const ref_api_t gEngfuncs =
&g_fsapi, &g_fsapi,
R_GetWindowHandle, R_GetWindowHandle,
R_GetSpriteFrame,
}; };
static void R_UnloadProgs( void ) static void R_UnloadProgs( void )
@@ -487,28 +475,82 @@ static void R_UnloadProgs( void )
memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs )); memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs ));
} }
static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src ) static void CL_FillTriAPI( triangleapi_t *dst )
{ {
dst->version = TRI_API_VERSION; dst->version = TRI_API_VERSION;
dst->Begin = src->Begin;
dst->RenderMode = TriRenderMode; dst->RenderMode = TriRenderMode;
dst->End = src->End;
dst->Color4f = TriColor4f; dst->Color4f = TriColor4f;
dst->Color4ub = TriColor4ub; dst->Color4ub = TriColor4ub;
dst->TexCoord2f = src->TexCoord2f;
dst->Vertex3f = src->Vertex3f;
dst->Vertex3fv = src->Vertex3fv;
dst->Brightness = TriBrightness; dst->Brightness = TriBrightness;
dst->CullFace = TriCullFace; dst->CullFace = TriCullFace;
dst->SpriteTexture = TriSpriteTexture; dst->SpriteTexture = TriSpriteTexture;
dst->WorldToScreen = TriWorldToScreen; dst->WorldToScreen = TriWorldToScreen;
dst->Fog = src->Fog;
dst->ScreenToWorld = src->ScreenToWorld;
dst->GetMatrix = src->GetMatrix;
dst->BoxInPVS = TriBoxInPVS; dst->BoxInPVS = TriBoxInPVS;
dst->LightAtPoint = TriLightAtPoint; dst->LightAtPoint = TriLightAtPoint;
dst->Color4fRendermode = TriColor4fRendermode; dst->Color4fRendermode = TriColor4fRendermode;
dst->FogParams = src->FogParams; dst->Begin = ref.dllFuncs.Begin;
dst->End = ref.dllFuncs.End;
dst->Vertex3f = ref.dllFuncs.Vertex3f;
dst->Vertex3fv = ref.dllFuncs.Vertex3fv;
ref.dllFuncs.R_FillTriAPI( dst );
}
static const byte dottexture[8][8] =
{
{ 0, 1, 1, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
};
static void R_CreateBuiltinTextures( void )
{
uint data4x4[16];
uint data16x16[256];
byte particle[8 * 8 * 4];
int x, y;
// default checkerboard
for( y = 0; y < 16; y++ )
{
for( x = 0; x < 16; x++ )
{
if(( y < 8 ) ^ ( x < 8 ))
data16x16[y * 16 + x] = 0xFFFF00FF;
else
data16x16[y * 16 + x] = 0xFF000000;
}
}
ref.dllFuncs.GL_CreateTexture( REF_DEFAULT_TEXTURE, 16, 16, data16x16, TF_COLORMAP );
// particle texture
memset( particle, 0, sizeof( particle ));
for( x = 0; x < 8; x++ )
{
for( y = 0; y < 8; y++ )
{
if( dottexture[x][y] )
particle[( y * 8 + x ) * 4 + 3] = 255;
}
}
ref.dllFuncs.GL_CreateTexture( REF_PARTICLE_TEXTURE, 8, 8, particle, TF_CLAMP );
// solid colors
memset( data4x4, 0xFF, sizeof( data4x4 ));
ref.dllFuncs.GL_CreateTexture( REF_WHITE_TEXTURE, 4, 4, data4x4, TF_COLORMAP );
for( x = 0; x < 16; x++ )
data4x4[x] = 0xFF7F7F7F;
ref.dllFuncs.GL_CreateTexture( REF_GRAY_TEXTURE, 4, 4, data4x4, TF_COLORMAP );
for( x = 0; x < 16; x++ )
data4x4[x] = 0xFF000000;
ref.dllFuncs.GL_CreateTexture( REF_BLACK_TEXTURE, 4, 4, data4x4, TF_COLORMAP );
} }
static qboolean R_LoadProgs( const char *name ) static qboolean R_LoadProgs( const char *name )
@@ -554,8 +596,8 @@ static qboolean R_LoadProgs( const char *name )
Cvar_FullSet( "host_refloaded", "1", FCVAR_READ_ONLY ); Cvar_FullSet( "host_refloaded", "1", FCVAR_READ_ONLY );
ref.initialized = true; ref.initialized = true;
// initialize TriAPI callbacks R_CreateBuiltinTextures();
CL_FillTriAPIFromRef( &gTriApi, &ref.dllFuncs ); CL_FillTriAPI( &gTriApi );
return true; return true;
} }

View File

@@ -39,6 +39,10 @@ void IN_DeactivateMouse( void );
void IN_MouseSavePos( void ); void IN_MouseSavePos( void );
void IN_MouseRestorePos( void ); void IN_MouseRestorePos( void );
void IN_ToggleClientMouse( int newstate, int oldstate ); void IN_ToggleClientMouse( int newstate, int oldstate );
void IN_GyroInit( void );
void IN_GyroCheckAvailability( void );
void IN_GyroEvent( vec3_t data );
void IN_GyroFinalizeMove( float *fw, float *side, float *dpitch, float *dyaw );
uint IN_CollectInputDevices( void ); uint IN_CollectInputDevices( void );
void IN_LockInputDevices( qboolean lock ); void IN_LockInputDevices( qboolean lock );
@@ -95,6 +99,15 @@ qboolean Touch_WantVisibleCursor( void );
void Touch_NotifyResize( void ); void Touch_NotifyResize( void );
#endif #endif
//
// in_osk.c
//
extern convar_t osk_enable;
void OSK_Init( void );
qboolean OSK_KeyEvent( int key, int down );
void OSK_EnableTextInput( qboolean enable, qboolean force );
void OSK_Draw( void );
// //
// in_joy.c // in_joy.c
// //

View File

@@ -0,0 +1,120 @@
/*
in_gyro.c - System gyroscope input code
Copyright (C) 2026 Xash3D FWGS contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "common.h"
#include "input.h"
#include "client.h"
static CVAR_DEFINE_AUTO( gyro_enable, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enables aiming with built-in device gyroscope" );
static CVAR_DEFINE_AUTO( gyro_available, "0", FCVAR_READ_ONLY, "tells whether system gyroscope hardware is available or not" );
static CVAR_DEFINE_AUTO( gyro_pitch, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "built-in gyroscope sensitivity for looking up and down" );
static CVAR_DEFINE_AUTO( gyro_yaw, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "built-in gyroscope sensitivity for turning left and right" );
static CVAR_DEFINE_AUTO( gyro_roll, "0.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "built-in gyroscope sensitivity when tilting the device sideways" );
static CVAR_DEFINE_AUTO( gyro_pitch_deadzone, "0.5", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "built-in gyroscope pitch axis deadzone (deg/s)" );
static CVAR_DEFINE_AUTO( gyro_yaw_deadzone, "0.5", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "built-in gyroscope yaw axis deadzone (deg/s)" );
static CVAR_DEFINE_AUTO( gyro_roll_deadzone, "0.5", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "built-in gyroscope roll axis deadzone (deg/s)" );
// stores the latest instantaneous rotation rates from built-in gyroscope
static vec3_t gyro_speed;
/*
==============
IN_GyroInit
==============
*/
void IN_GyroInit( void )
{
Cvar_RegisterVariable( &gyro_enable );
Cvar_RegisterVariable( &gyro_available );
Cvar_RegisterVariable( &gyro_pitch );
Cvar_RegisterVariable( &gyro_yaw );
Cvar_RegisterVariable( &gyro_roll );
Cvar_RegisterVariable( &gyro_pitch_deadzone );
Cvar_RegisterVariable( &gyro_yaw_deadzone );
Cvar_RegisterVariable( &gyro_roll_deadzone );
}
/*
==============
IN_GyroCheckAvailability
One-time late check called after startup and configs
==============
*/
void IN_GyroCheckAvailability( void )
{
#if XASH_SDL
if( gyro_available.value )
return;
if( SDLash_GyroIsAvailable() )
{
Cvar_FullSet( "gyro_available", "1", FCVAR_READ_ONLY );
}
#endif
}
/*
=============
IN_GyroEvent
System gyroscope events from platform
=============
*/
void IN_GyroEvent( vec3_t data )
{
VectorCopy( data, gyro_speed );
}
/*
=============
IN_GyroFinalizeMove
Apply gyro movement to view angles
=============
*/
void IN_GyroFinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
{
platform_orientation_t orient;
float orient_scale = 1.0f;
if( !gyro_enable.value || !gyro_available.value )
return;
orient = Platform_GetDisplayOrientation();
if( orient == ORIENTATION_LANDSCAPE_FLIPPED )
orient_scale = -1.0f;
// In Landscape mode axes are swapped relative to natural (Portrait) orientation
// Y axis rotation becomes Pitch (up/down)
// X axis rotation becomes Yaw (left/right)
float pitch_speed = -orient_scale * gyro_speed[1] * ( 180.0f / M_PI );
float yaw_speed = orient_scale * gyro_speed[0] * ( 180.0f / M_PI );
float roll_speed = orient_scale * gyro_speed[2] * ( 180.0f / M_PI );
if( fabs( pitch_speed ) < gyro_pitch_deadzone.value )
pitch_speed = 0.0f;
if( fabs( yaw_speed ) < gyro_yaw_deadzone.value )
yaw_speed = 0.0f;
if( fabs( roll_speed ) < gyro_roll_deadzone.value )
roll_speed = 0.0f;
*dpitch -= gyro_pitch.value * pitch_speed * host.realframetime;
*dyaw += gyro_yaw.value * yaw_speed * host.realframetime;
*dyaw += gyro_roll.value * roll_speed * host.realframetime;
VectorClear( gyro_speed );
}

View File

@@ -197,7 +197,7 @@ static int Joy_GetHatValueForAxis( const engineAxis_t engineAxis )
positive = JOY_HAT_RIGHT; positive = JOY_HAT_RIGHT;
break; break;
case JOY_AXIS_FWD: case JOY_AXIS_FWD:
threshold = joy_side_key_threshold.value; threshold = joy_forward_key_threshold.value;
negative = JOY_HAT_UP; negative = JOY_HAT_UP;
positive = JOY_HAT_DOWN; positive = JOY_HAT_DOWN;
break; break;
@@ -318,7 +318,7 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
const char *bind = joy_axis_binding.string; const char *bind = joy_axis_binding.string;
size_t i; size_t i;
for( i = 0; bind[i]; i++ ) for( i = 0; bind[i] && i < MAX_AXES; i++ )
{ {
switch( bind[i] ) switch( bind[i] )
{ {

View File

@@ -158,9 +158,6 @@ static const keyname_t keynames[] =
{ "INTERNATIONAL9", K_INTERNATIONAL + 8, "" }, { "INTERNATIONAL9", K_INTERNATIONAL + 8, "" },
}; };
static void OSK_EnableTextInput( qboolean enable, qboolean force );
static qboolean OSK_KeyEvent( int key, int down );
static CVAR_DEFINE_AUTO( osk_enable, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
static CVAR_DEFINE_AUTO( key_rotate, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rotate arrow keys (0-3)" ); static CVAR_DEFINE_AUTO( key_rotate, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
/* /*
@@ -200,7 +197,14 @@ static int Key_StringToKeynum( const char *str )
// check for hex code // check for hex code
if( str[0] == '0' && str[1] == 'x' ) if( str[0] == '0' && str[1] == 'x' )
return Q_atoi( str ); {
int key = Q_atoi( str );
if( key >= ARRAYSIZE( keys ))
return -1;
return key;
}
// scan for a text match // scan for a text match
for( i = 0; i < ARRAYSIZE( keynames ); i++ ) for( i = 0; i < ARRAYSIZE( keynames ); i++ )
@@ -520,7 +524,7 @@ qboolean Cmd_GetKeysList( const char *s, char *completedname, int length, qboole
const char *keyname = Key_KeynumToString( i ); const char *keyname = Key_KeynumToString( i );
if(( *s == '*' ) || !Q_strnicmp( keyname, s, len )) if(( *s == '*' ) || !Q_strnicmp( keyname, s, len ))
Q_strncpy( keys_strings[numkeys++], keyname, sizeof( keys[0] )); Q_strncpy( keys_strings[numkeys++], keyname, sizeof( keys_strings[0] ));
} }
if( !numkeys ) return false; if( !numkeys ) return false;
@@ -579,7 +583,6 @@ void Key_Init( void )
for( i = 0; i < ARRAYSIZE( keynames ); i++ ) for( i = 0; i < ARRAYSIZE( keynames ); i++ )
Key_SetBinding( keynames[i].keynum, keynames[i].binding ); Key_SetBinding( keynames[i].keynum, keynames[i].binding );
Cvar_RegisterVariable( &osk_enable );
Cvar_RegisterVariable( &key_rotate ); Cvar_RegisterVariable( &key_rotate );
} }
@@ -985,288 +988,3 @@ int Key_ToUpper( int keynum )
return Q_toupper( keynum ); return Q_toupper( keynum );
} }
/* On-screen keyboard:
*
* 4 lines with 13 buttons each
* Left trigger == backspace
* Right trigger == space
* Any button press is button press on keyboard
*
* Our layout:
* 0 1 2 3 4 5 6 7 8 9 10 11 12
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
* |` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= | 0
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
* |q |w |e |r |t |y |u |i |o |p |[ |] |\ | 1
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
* |CL|a |s |d |f |g |h |j |k |l |; |' |BS| 2
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
* |SH|z |x |c |v |b |n |m |, |. |/ |SP|EN| 3
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
#define MAX_OSK_ROWS 13
#define MAX_OSK_LINES 4
enum
{
OSK_DEFAULT = 0,
OSK_UPPER, // on caps, shift
/*
OSK_RUSSIAN,
OSK_RUSSIAN_UPPER,
*/
OSK_LAST
};
enum
{
OSK_TAB = 16,
OSK_SHIFT,
OSK_BACKSPACE,
OSK_ENTER,
OSK_SPECKEY_LAST
};
static const char *osk_keylayout[][4] =
{
{
"`1234567890-=", // 13
"qwertyuiop[]\\", // 13
"\x10" "asdfghjkl;'" "\x12", // 11 + caps on a left, enter on a right
"\x11" "zxcvbnm,./ " "\x13" // 10 + esc on left + shift on a left/right
},
{
"~!@#$%^&*()_+",
"QWERTYUIOP{}|",
"\x10" "ASDFGHJKL:\"" "\x12",
"\x11" "ZXCVBNM<>? " "\x13"
}
};
struct osk_s
{
qboolean enable;
int curlayout;
qboolean shift;
qboolean sending;
struct {
signed char x;
signed char y;
char val;
} curbutton;
} osk;
static qboolean OSK_KeyEvent( int key, int down )
{
if( !osk.enable || !osk_enable.value )
return false;
if( osk.sending )
{
osk.sending = false;
return false;
}
if( osk.curbutton.val == 0 )
{
if( key == K_ENTER || key == K_A_BUTTON )
{
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
return true;
}
return false;
}
switch ( key )
{
case K_A_BUTTON:
case K_ENTER:
switch( osk.curbutton.val )
{
case OSK_ENTER:
osk.sending = true;
Key_Event( K_ENTER, down );
//osk_enable = false; // TODO: handle multiline
break;
case OSK_SHIFT:
if( !down )
break;
if( osk.curlayout & 1 )
osk.curlayout--;
else
osk.curlayout++;
osk.shift = true;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
break;
case OSK_BACKSPACE:
Key_Event( K_BACKSPACE, down ); break;
case OSK_TAB:
Key_Event( K_TAB, down ); break;
default:
{
int ch;
if( !down )
{
if( osk.shift && osk.curlayout & 1 )
osk.curlayout--;
osk.shift = false;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
break;
}
ch = (byte)osk.curbutton.val;
// do not pass UTF-8 sequence into the engine, convert it here
if( !cls.accept_utf8 )
ch = Con_UtfProcessCharForce( ch );
if( !ch )
break;
CL_CharEvent( ch );
break;
}
}
break;
case K_UPARROW:
if( down && --osk.curbutton.y < 0 )
{
osk.curbutton.y = MAX_OSK_LINES - 1;
osk.curbutton.val = 0;
return true;
}
break;
case K_DOWNARROW:
if( down && ++osk.curbutton.y >= MAX_OSK_LINES )
{
osk.curbutton.y = 0;
osk.curbutton.val = 0;
return true;
}
break;
case K_LEFTARROW:
if( down && --osk.curbutton.x < 0 )
osk.curbutton.x = MAX_OSK_ROWS - 1;
break;
case K_RIGHTARROW:
if( down && ++osk.curbutton.x >= MAX_OSK_ROWS )
osk.curbutton.x = 0;
break;
default:
return false;
}
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
return true;
}
/*
=============
OSK_EnableTextInput
Enables built-in IME
=============
*/
static void OSK_EnableTextInput( qboolean enable, qboolean force )
{
qboolean old = osk.enable;
osk.enable = enable;
if( osk.enable && (!old || force) )
{
osk.curlayout = 0;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
}
}
#define X_START 0.1347475f
#define Y_START 0.567f
#define X_STEP 0.05625
#define Y_STEP 0.0825
/*
============
Joy_DrawSymbolButton
Draw button with symbol on it
============
*/
static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float height )
{
cl_font_t *font = Con_GetCurFont();
byte color[] = { 255, 255, 255, 255 };
int x1 = x * refState.width,
y1 = y * refState.height,
w = width * refState.width,
h = height * refState.height;
if( symb == osk.curbutton.val )
ref.dllFuncs.FillRGBA( kRenderTransTexture, x1, y1, w, h, 255, 160, 0, 100 );
if( !symb || symb == ' ' || (symb >= OSK_TAB && symb < OSK_SPECKEY_LAST ) )
return;
CL_DrawCharacter(
x1 + width * 0.4 * refState.width,
y1 + height * 0.4 * refState.height,
symb, color, font, 0 );
}
/*
=============
Joy_DrawSpecialButton
Draw special button, like shift, enter or esc
=============
*/
static void OSK_DrawSpecialButton( const char *name, float x, float y, float width, float height )
{
byte color[] = { 0, 255, 0, 255 };
Con_DrawString(
x * refState.width + width * 0.4 * refState.width,
y * refState.height + height * 0.4 * refState.height,
name,
color );
}
/*
=============
Joy_DrawOnScreenKeyboard
Draw on screen keyboard, if enabled
=============
*/
void OSK_Draw( void )
{
const char **curlayout = osk_keylayout[osk.curlayout]; // shortcut :)
float x, y;
int i, j;
if( !osk.enable || !osk_enable.value || !osk.curbutton.val )
return;
// draw keyboard
ref.dllFuncs.FillRGBA( kRenderTransTexture, X_START * refState.width, Y_START * refState.height,
X_STEP * MAX_OSK_ROWS * refState.width,
Y_STEP * MAX_OSK_LINES * refState.height, 100, 100, 100, 100 );
OSK_DrawSpecialButton( "-]", X_START, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "<-", X_START + X_STEP * 12, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "sh", X_START, Y_START + Y_STEP * 3, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "en", X_START + X_STEP * 12, Y_START + Y_STEP * 3, X_STEP, Y_STEP );
for( y = Y_START, j = 0; j < MAX_OSK_LINES; j++, y += Y_STEP )
for( x = X_START, i = 0; i < MAX_OSK_ROWS; i++, x += X_STEP )
OSK_DrawSymbolButton( curlayout[j][i], x, y, X_STEP, Y_STEP );
}

View File

@@ -0,0 +1,312 @@
/*
in_osk.c - on-screen keyboard input
Copyright (C) 2016-2026 Alibek Omarov
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "common.h"
#include "input.h"
#include "client.h"
CVAR_DEFINE_AUTO( osk_enable, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
/* On-screen keyboard:
*
* 4 lines with 13 buttons each
* Left trigger == backspace
* Right trigger == space
* Any button press is button press on keyboard
*
* Our layout:
* 0 1 2 3 4 5 6 7 8 9 10 11 12
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
* |` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= | 0
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
* |q |w |e |r |t |y |u |i |o |p |[ |] |\ | 1
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
* |CL|a |s |d |f |g |h |j |k |l |; |' |BS| 2
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
* |SH|z |x |c |v |b |n |m |, |. |/ |SP|EN| 3
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
#define MAX_OSK_ROWS 13
#define MAX_OSK_LINES 4
enum
{
OSK_DEFAULT = 0,
OSK_UPPER, // on caps, shift
/*
OSK_RUSSIAN,
OSK_RUSSIAN_UPPER,
*/
OSK_LAST
};
enum
{
OSK_TAB = 16,
OSK_SHIFT,
OSK_BACKSPACE,
OSK_ENTER,
OSK_SPECKEY_LAST
};
static const char *osk_keylayout[][4] =
{
{
"`1234567890-=", // 13
"qwertyuiop[]\\", // 13
"\x10" "asdfghjkl;'" "\x12", // 11 + caps on a left, enter on a right
"\x11" "zxcvbnm,./ " "\x13" // 10 + esc on left + shift on a left/right
},
{
"~!@#$%^&*()_+",
"QWERTYUIOP{}|",
"\x10" "ASDFGHJKL:\"" "\x12",
"\x11" "ZXCVBNM<>? " "\x13"
}
};
static struct osk_s
{
qboolean enable;
int curlayout;
qboolean shift;
qboolean sending;
struct
{
signed char x;
signed char y;
char val;
} curbutton;
} osk;
qboolean OSK_KeyEvent( int key, int down )
{
if( !osk.enable || !osk_enable.value )
return false;
if( osk.sending )
{
osk.sending = false;
return false;
}
if( osk.curbutton.val == 0 )
{
if( key == K_ENTER || key == K_A_BUTTON )
{
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
return true;
}
return false;
}
switch( key )
{
case K_A_BUTTON:
case K_ENTER:
switch( osk.curbutton.val )
{
case OSK_ENTER:
osk.sending = true;
Key_Event( K_ENTER, down );
// osk_enable = false; // TODO: handle multiline
break;
case OSK_SHIFT:
if( !down )
break;
if( osk.curlayout & 1 )
osk.curlayout--;
else
osk.curlayout++;
osk.shift = true;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
break;
case OSK_BACKSPACE:
Key_Event( K_BACKSPACE, down );
break;
case OSK_TAB:
Key_Event( K_TAB, down );
break;
default:
{
int ch;
if( !down )
{
if( osk.shift && osk.curlayout & 1 )
osk.curlayout--;
osk.shift = false;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
break;
}
ch = (byte)osk.curbutton.val;
// do not pass UTF-8 sequence into the engine, convert it here
if( !cls.accept_utf8 )
ch = Con_UtfProcessCharForce( ch );
if( !ch )
break;
CL_CharEvent( ch );
break;
}
}
break;
case K_UPARROW:
if( down && --osk.curbutton.y < 0 )
{
osk.curbutton.y = MAX_OSK_LINES - 1;
osk.curbutton.val = 0;
return true;
}
break;
case K_DOWNARROW:
if( down && ++osk.curbutton.y >= MAX_OSK_LINES )
{
osk.curbutton.y = 0;
osk.curbutton.val = 0;
return true;
}
break;
case K_LEFTARROW:
if( down && --osk.curbutton.x < 0 )
osk.curbutton.x = MAX_OSK_ROWS - 1;
break;
case K_RIGHTARROW:
if( down && ++osk.curbutton.x >= MAX_OSK_ROWS )
osk.curbutton.x = 0;
break;
default:
return false;
}
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
return true;
}
/*
=============
OSK_EnableTextInput
Enables built-in IME
=============
*/
void OSK_EnableTextInput( qboolean enable, qboolean force )
{
qboolean old = osk.enable;
osk.enable = enable;
if( osk.enable && ( !old || force ))
{
osk.curlayout = 0;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
}
}
#define X_START 0.1347475f
#define Y_START 0.567f
#define X_STEP 0.05625
#define Y_STEP 0.0825
/*
============
OSK_DrawSymbolButton
Draw button with symbol on it
============
*/
static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float height )
{
cl_font_t *font = Con_GetCurFont();
byte color[] = { 255, 255, 255, 255 };
int x1 = x * refState.width,
y1 = y * refState.height,
w = width * refState.width,
h = height * refState.height;
if( symb == osk.curbutton.val )
ref.dllFuncs.FillRGBA( kRenderTransTexture, x1, y1, w, h, 255, 160, 0, 100 );
if( !symb || symb == ' ' || ( symb >= OSK_TAB && symb < OSK_SPECKEY_LAST ))
return;
CL_DrawCharacter(
x1 + width * 0.4 * refState.width,
y1 + height * 0.4 * refState.height,
symb, color, font, 0 );
}
/*
=============
OSK_DrawSpecialButton
Draw special button, like shift, enter or esc
=============
*/
static void OSK_DrawSpecialButton( const char *name, float x, float y, float width, float height )
{
byte color[] = { 0, 255, 0, 255 };
Con_DrawString(
x * refState.width + width * 0.4 * refState.width,
y * refState.height + height * 0.4 * refState.height,
name,
color );
}
/*
=============
OSK_Draw
Draw on screen keyboard, if enabled
=============
*/
void OSK_Draw( void )
{
const char **curlayout = osk_keylayout[osk.curlayout]; // shortcut :)
float x, y;
int i, j;
if( !osk.enable || !osk_enable.value || !osk.curbutton.val )
return;
// draw keyboard
ref.dllFuncs.FillRGBA( kRenderTransTexture, X_START * refState.width, Y_START * refState.height,
X_STEP * MAX_OSK_ROWS * refState.width,
Y_STEP * MAX_OSK_LINES * refState.height, 100, 100, 100, 100 );
OSK_DrawSpecialButton( "-]", X_START, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "<-", X_START + X_STEP * 12, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "sh", X_START, Y_START + Y_STEP * 3, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "en", X_START + X_STEP * 12, Y_START + Y_STEP * 3, X_STEP, Y_STEP );
for( y = Y_START, j = 0; j < MAX_OSK_LINES; j++, y += Y_STEP )
for( x = X_START, i = 0; i < MAX_OSK_ROWS; i++, x += X_STEP )
OSK_DrawSymbolButton( curlayout[j][i], x, y, X_STEP, Y_STEP );
}
void OSK_Init( void )
{
Cvar_RegisterVariable( &osk_enable );
}

View File

@@ -185,10 +185,10 @@ void Touch_NotifyResize( void )
static inline float Touch_AspectRatio( void ) static inline float Touch_AspectRatio( void )
{ {
if( touch.config_aspect_ratio ) if( touch.config_aspect_ratio >= 0.25f )
return touch.config_aspect_ratio; return touch.config_aspect_ratio;
if( touch.actual_aspect_ratio ) if( touch.actual_aspect_ratio >= 0.25f )
return touch.actual_aspect_ratio; return touch.actual_aspect_ratio;
if( refState.width && refState.height ) if( refState.width && refState.height )
@@ -369,7 +369,7 @@ static void Touch_ExportConfig_f( void )
string profilebase; string profilebase;
COM_FileBase( name, profilebase, sizeof( profilebase )); COM_FileBase( name, profilebase, sizeof( profilebase ));
Q_snprintf( profilename, sizeof( profilebase ), "touch_profiles/%s (copy).cfg", profilebase ); Q_snprintf( profilename, sizeof( profilename ), "touch_profiles/%s (copy).cfg", profilebase );
} }
else Q_strncpy( profilename, name, sizeof( profilename )); else Q_strncpy( profilename, name, sizeof( profilename ));
@@ -588,7 +588,7 @@ static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *nam
IN_TouchEditClear(); IN_TouchEditClear();
while(( button = Touch_FindFirst( &touch.list_user, name, privileged ))) while(( button = Touch_FindFirst( list, name, privileged )))
{ {
if( button->prev ) if( button->prev )
button->prev->next = button->next; button->prev->next = button->next;
@@ -860,8 +860,7 @@ void Touch_AddClientButton( const char *name, const char *texture, const char *c
if( !touch.initialized ) if( !touch.initialized )
return; return;
if( round ) IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
if( round == round_aspect ) if( round == round_aspect )
y2 = y1 + ( x2 - x1 ) / (Touch_AspectRatio()) * aspect; y2 = y1 + ( x2 - x1 ) / (Touch_AspectRatio()) * aspect;
@@ -1068,7 +1067,7 @@ static void Touch_InitEditor( void )
temp = Touch_AddButton( &touch.list_edit, "close", "touch_default/edit_close", "touch_disableedit", 0, y, x, y + 0.1f, color, true ); temp = Touch_AddButton( &touch.list_edit, "close", "touch_default/edit_close", "touch_disableedit", 0, y, x, y + 0.1f, color, true );
SetBits( temp->flags, TOUCH_FL_NOEDIT ); SetBits( temp->flags, TOUCH_FL_NOEDIT );
temp = Touch_AddButton( &touch.list_edit, "close", "#Close and save", "", x, y, x + 0.2f, y + 0.1f, color, true ); temp = Touch_AddButton( &touch.list_edit, "close_label", "#Close and save", "", x, y, x + 0.2f, y + 0.1f, color, true );
SetBits( temp->flags, TOUCH_FL_NOEDIT ); SetBits( temp->flags, TOUCH_FL_NOEDIT );
y += 0.2f; y += 0.2f;
@@ -1076,7 +1075,7 @@ static void Touch_InitEditor( void )
temp = Touch_AddButton( &touch.list_edit, "cancel", "touch_default/edit_reset", "touch_reloadconfig", 0, y, x, y + 0.1f, color, true ); temp = Touch_AddButton( &touch.list_edit, "cancel", "touch_default/edit_reset", "touch_reloadconfig", 0, y, x, y + 0.1f, color, true );
SetBits( temp->flags, TOUCH_FL_NOEDIT ); SetBits( temp->flags, TOUCH_FL_NOEDIT );
temp = Touch_AddButton( &touch.list_edit, "close", "#Cancel and reset", "", x, y, x + 0.2f, y + 0.1f, color, true ); temp = Touch_AddButton( &touch.list_edit, "cancel_label", "#Cancel and reset", "", x, y, x + 0.2f, y + 0.1f, color, true );
SetBits( temp->flags, TOUCH_FL_NOEDIT ); SetBits( temp->flags, TOUCH_FL_NOEDIT );
y += 0.2f; y += 0.2f;
@@ -1256,12 +1255,21 @@ static void Touch_DrawTexture( float x1, float y1, float x2, float y2, int textu
0, 0, 1, 1, texture ); 0, 0, 1, 1, texture );
} }
#define GRID_COUNT_X ((int)touch_grid_count.value ) static inline int Touch_GridCountX( void )
#define GRID_COUNT_Y (((int)touch_grid_count.value ) * Touch_AspectRatio( )) {
#define GRID_X ( 1.0f / GRID_COUNT_X ) return Q_max((int)touch_grid_count.value, 1 );
#define GRID_Y ( 1.0f / Touch_AspectRatio() / GRID_COUNT_X ) }
#define GRID_ROUND_X( x ) ((float)round(( x ) * GRID_COUNT_X ) / GRID_COUNT_X )
#define GRID_ROUND_Y( x ) ((float)round(( x ) * GRID_COUNT_Y ) / GRID_COUNT_Y ) static inline int Touch_GridCountY( void )
{
float grid_count_y = touch_grid_count.value * Touch_AspectRatio();
return Q_max((int)grid_count_y, 1 );
}
#define GRID_X ( 1.0f / Touch_GridCountX( ))
#define GRID_Y ( 1.0f / Touch_GridCountY( ))
#define GRID_ROUND_X( x ) ((float)round(( x ) * Touch_GridCountX() ) / Touch_GridCountX())
#define GRID_ROUND_Y( x ) ((float)round(( x ) * Touch_GridCountY() ) / Touch_GridCountY())
static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 ) static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 )
{ {

View File

@@ -445,6 +445,10 @@ void IN_Init( void )
{ {
IN_StartupMouse( ); IN_StartupMouse( );
IN_GyroInit();
OSK_Init();
Joy_Init(); // common joystick support init Joy_Init(); // common joystick support init
Touch_Init(); Touch_Init();
@@ -560,6 +564,7 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
#endif #endif
} }
IN_GyroFinalizeMove( forward, side, pitch, yaw );
Joy_FinalizeMove( forward, side, pitch, yaw ); Joy_FinalizeMove( forward, side, pitch, yaw );
Touch_GetMove( forward, side, pitch, yaw ); Touch_GetMove( forward, side, pitch, yaw );

View File

@@ -15,6 +15,7 @@ GNU General Public License for more details.
#include "common.h" #include "common.h"
#include "client.h" #include "client.h"
#include "mod_local.h"
#include "net_encode.h" #include "net_encode.h"
#include "cl_tent.h" #include "cl_tent.h"
#include "shake.h" #include "shake.h"
@@ -1738,6 +1739,8 @@ void CL_RegisterResources( sizebuf_t *msg, connprotocol_t proto )
// tell rendering system we have a new set of models. // tell rendering system we have a new set of models.
ref.dllFuncs.R_NewMap (); ref.dllFuncs.R_NewMap ();
Mod_LoadDetailTextures( cl.worldmodel );
// check if this map must start from dark screen // check if this map must start from dark screen
CL_StartDark (); CL_StartDark ();

View File

@@ -514,17 +514,26 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
static void CL_ParseSpawnStaticSound( sizebuf_t *msg ) static void CL_ParseSpawnStaticSound( sizebuf_t *msg )
{ {
vec3_t pos; vec3_t pos;
int handle, entnum, pitch, flags; int sound, entnum, pitch, flags;
float volume, attn; float volume, attn;
sound_t handle = 0;
MSG_ReadVec3Coord( msg, pos ); MSG_ReadVec3Coord( msg, pos );
handle = MSG_ReadShort( msg ); sound = MSG_ReadShort( msg );
volume = MSG_ReadByte( msg ) * ( 1.0f / 255.0f ); volume = MSG_ReadByte( msg ) * ( 1.0f / 255.0f );
attn = MSG_ReadByte( msg ) * ( 1.0f / 64.0f ); attn = MSG_ReadByte( msg ) * ( 1.0f / 64.0f );
entnum = MSG_ReadShort( msg ); entnum = MSG_ReadShort( msg );
pitch = MSG_ReadByte( msg ); pitch = MSG_ReadByte( msg );
flags = MSG_ReadByte( msg ); flags = MSG_ReadByte( msg );
if( FBitSet( flags, SND_SENTENCE ))
{
char sentenceName[32];
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
handle = S_RegisterSound( sentenceName );
}
else handle = cl.sound_index[sound]; // see precached sound
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags ); S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
} }

View File

@@ -1276,6 +1276,10 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cbuf_ExecStuffCmds(); // execute stuffcmds (commandline) Cbuf_ExecStuffCmds(); // execute stuffcmds (commandline)
SCR_CheckStartupVids(); // must be last SCR_CheckStartupVids(); // must be last
#ifndef XASH_DEDICATED
IN_GyroCheckAvailability();
#endif
if( Sys_GetParmFromCmdLine( "-timedemo", demoname )) if( Sys_GetParmFromCmdLine( "-timedemo", demoname ))
Cbuf_AddTextf( "timedemo %s\n", demoname ); Cbuf_AddTextf( "timedemo %s\n", demoname );

View File

@@ -2989,6 +2989,105 @@ static void Mod_LoadTextures( model_t *mod, dbspmodel_t *bmod )
Mod_SequenceAllAnimatedTextures( mod ); Mod_SequenceAllAnimatedTextures( mod );
} }
#if !XASH_DEDICATED
static void Mod_ParseDetailTextures( model_t *mod )
{
byte *afile;
char *pfile;
string token, texname;
string detail_texname;
string detail_path;
float xScale, yScale;
texture_t *tex;
int i;
string filepath;
Q_strncpy( filepath, mod->name, sizeof( filepath ));
COM_StripExtension( filepath );
Q_strncat( filepath, "_detail.txt", sizeof( filepath ));
afile = FS_LoadFile( filepath, NULL, false );
if( !afile )
return;
pfile = (char *)afile;
// format: 'texturename' 'detailtexture' 'xScale' 'yScale'
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
{
texname[0] = '\0';
detail_texname[0] = '\0';
// read texname
if( token[0] == '{' )
{
// NOTE: COM_ParseFile handled some symbols seperately
// this code will be fix it
pfile = COM_ParseFile( pfile, token, sizeof( token ));
Q_snprintf( texname, sizeof( texname ), "{%s", token );
}
else
Q_strncpy( texname, token, sizeof( texname ));
// read detailtexture name
pfile = COM_ParseFile( pfile, token, sizeof( token ));
Q_strncpy( detail_texname, token, sizeof( detail_texname ));
// trying the scales or '{'
pfile = COM_ParseFile( pfile, token, sizeof( token ));
// read second part of detailtexture name
if( token[0] == '{' )
{
Q_strncat( detail_texname, token, sizeof( detail_texname ));
pfile = COM_ParseFile( pfile, token, sizeof( token )); // read scales
Q_strncat( detail_texname, token, sizeof( detail_texname ));
pfile = COM_ParseFile( pfile, token, sizeof( token )); // parse scales
}
Q_snprintf( detail_path, sizeof( detail_path ), "gfx/%s", detail_texname );
// read scales
xScale = Q_atof( token );
pfile = COM_ParseFile( pfile, token, sizeof( token ));
yScale = Q_atof( token );
if( xScale <= 0.0f || yScale <= 0.0f )
continue;
// search for existing texture and uploading detail texture
for( i = 0; i < mod->numtextures; i++ )
{
tex = mod->textures[i];
if( Q_stricmp( tex->name, texname ))
continue;
tex->dt_texturenum = ref.dllFuncs.GL_LoadTexture( detail_path, NULL, 0, TF_FORCE_COLOR|TF_NOFLIP_TGA );
if( tex->dt_texturenum )
ref.dllFuncs.R_SetDetailScaleForTexture( tex->gl_texturenum, xScale, yScale );
break;
}
}
Mem_Free( afile );
}
void Mod_LoadDetailTextures( model_t *mod )
{
convar_t *r_detailtextures = Cvar_FindVar( "r_detailtextures" );
if( !r_detailtextures || !r_detailtextures->value )
return;
Mod_ParseDetailTextures( mod );
}
#endif // !XASH_DEDICATED
/* /*
================= =================
Mod_LoadTexInfo Mod_LoadTexInfo

View File

@@ -156,6 +156,7 @@ model_t *Mod_ForName( const char *name, qboolean crash, qboolean trackCRC );
qboolean Mod_ValidateCRC( const char *name, uint32_t crc ); qboolean Mod_ValidateCRC( const char *name, uint32_t crc );
void Mod_NeedCRC( const char *name, qboolean needCRC ); void Mod_NeedCRC( const char *name, qboolean needCRC );
void Mod_FreeUnused( void ); void Mod_FreeUnused( void );
void Mod_LoadDetailTextures( model_t *mod );
// //
// mod_alias.c // mod_alias.c
@@ -197,6 +198,8 @@ void Mod_ClearStudioCache( void );
// mod_sprite.c // mod_sprite.c
// //
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, size_t buffersize, qboolean *loaded ); void Mod_LoadSpriteModel( model_t *mod, const void *buffer, size_t buffersize, qboolean *loaded );
#endif void Mod_SpriteLoadTextures( model_t *mod, const void *buffer );
void Mod_SpriteUnloadTextures( void *data );
#endif
#endif//MOD_LOCAL_H #endif//MOD_LOCAL_H

View File

@@ -17,9 +17,6 @@ GNU General Public License for more details.
#include "common.h" #include "common.h"
#include "sprite.h" #include "sprite.h"
#include "studio.h" #include "studio.h"
#if !XASH_DEDICATED
#include "ref_common.h"
#endif // XASH_DEDICATED
#include "mod_local.h" #include "mod_local.h"
@@ -147,4 +144,8 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, size_t buffersize, q
psprite->numframes = 0; psprite->numframes = 0;
return; return;
} }
#if !XASH_DEDICATED
Mod_SpriteLoadTextures( mod, buffer );
#endif
} }

View File

@@ -88,6 +88,22 @@ static void Mod_Modellist_f( void )
Con_Printf( "\n" ); Con_Printf( "\n" );
} }
static void Mod_UnloadRenderData( model_t *mod )
{
#if !XASH_DEDICATED
switch( mod->type )
{
case mod_sprite:
Mod_SpriteUnloadTextures( mod->cache.data );
break;
default:
break;
}
ref.dllFuncs.Mod_ProcessRenderData( mod, false, NULL, 0 );
#endif
}
/* /*
================ ================
Mod_FreeUserData Mod_FreeUserData
@@ -107,12 +123,10 @@ static void Mod_FreeUserData( model_t *mod )
svgame.physFuncs.Mod_ProcessUserData( mod, false, NULL ); svgame.physFuncs.Mod_ProcessUserData( mod, false, NULL );
} }
} }
#if !XASH_DEDICATED
else else
{ {
ref.dllFuncs.Mod_ProcessRenderData( mod, false, NULL, 0 ); Mod_UnloadRenderData( mod );
} }
#endif
} }
/* /*

View File

@@ -40,6 +40,17 @@ void Platform_MessageBox( const char *title, const char *message, qboolean paren
void Platform_SetStatus( const char *status ); void Platform_SetStatus( const char *status );
qboolean Platform_DebuggerPresent( void ); qboolean Platform_DebuggerPresent( void );
typedef enum
{
ORIENTATION_UNKNOWN = 0,
ORIENTATION_LANDSCAPE,
ORIENTATION_LANDSCAPE_FLIPPED,
ORIENTATION_PORTRAIT,
ORIENTATION_PORTRAIT_FLIPPED
} platform_orientation_t;
platform_orientation_t Platform_GetDisplayOrientation( void );
// legacy iOS port functions // legacy iOS port functions
#if XASH_IOS #if XASH_IOS
int IOS_GetArgs( char ***argv ); int IOS_GetArgs( char ***argv );
@@ -64,6 +75,7 @@ char *Posix_Input( void );
void SDLash_Init( void ); void SDLash_Init( void );
void SDLash_Shutdown( void ); void SDLash_Shutdown( void );
void SDLash_NanoSleep( int nsec ); void SDLash_NanoSleep( int nsec );
qboolean SDLash_GyroIsAvailable( void );
#endif #endif
#if XASH_ANDROID #if XASH_ANDROID

View File

@@ -368,6 +368,11 @@ static void SDLash_EventHandler( SDL_Event *event )
#endif #endif
SDLash_HandleGameControllerEvent( event ); SDLash_HandleGameControllerEvent( event );
break; break;
#if SDL_VERSION_ATLEAST( 2, 0, 14 )
case SDL_SENSORUPDATE:
SDLash_SensorUpdate( event->sensor );
break;
#endif
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
if( event->window.windowID != SDL_GetWindowID( host.hWnd ) ) if( event->window.windowID != SDL_GetWindowID( host.hWnd ) )

View File

@@ -35,5 +35,15 @@ void SDLash_FreeCursors( void );
// //
void SDLash_HandleGameControllerEvent( SDL_Event *ev ); void SDLash_HandleGameControllerEvent( SDL_Event *ev );
//
// sensor_sdl2.c
//
void SDLash_InitSensors( void );
void SDLash_ShutdownSensors( void );
qboolean SDLash_GyroIsAvailable( void );
#if SDL_VERSION_ATLEAST( 2, 0, 14 )
void SDLash_SensorUpdate( SDL_SensorEvent sensor );
#endif
#endif // XASH_SDL #endif // XASH_SDL
#endif // KEYWRAPPER_H #endif // KEYWRAPPER_H

View File

@@ -0,0 +1,103 @@
/*
sensor_sdl2.c - SDL2 sensor handling
Copyright (C) 2026 Xash3D FWGS contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <SDL.h>
#include "common.h"
#include "input.h"
#include "platform_sdl2.h"
#if SDL_VERSION_ATLEAST( 2, 0, 14 )
static SDL_SensorID g_system_gyro_id = -1;
static SDL_Sensor *g_system_gyro;
/*
==============
SDLash_InitSensors
==============
*/
void SDLash_InitSensors( void )
{
if( SDL_InitSubSystem( SDL_INIT_SENSOR ) == 0 )
{
int num_sensors = SDL_NumSensors();
for( int i = 0; i < num_sensors; i++ )
{
if( SDL_SensorGetDeviceType( i ) == SDL_SENSOR_GYRO )
{
g_system_gyro = SDL_SensorOpen( i );
if( g_system_gyro )
{
g_system_gyro_id = SDL_SensorGetInstanceID( g_system_gyro );
Con_Printf( "SDL: Opened built-in gyroscope: %s\n", SDL_SensorGetName( g_system_gyro ) );
break;
}
}
}
}
else
{
Con_Reportf( S_ERROR "Failed to init SDL Sensor subsystem: %s\n", SDL_GetError() );
}
}
/*
==============
SDLash_ShutdownSensors
==============
*/
void SDLash_ShutdownSensors( void )
{
if( g_system_gyro )
{
SDL_SensorClose( g_system_gyro );
g_system_gyro = NULL;
g_system_gyro_id = -1;
}
SDL_QuitSubSystem( SDL_INIT_SENSOR );
}
/*
==============
SDLash_GyroIsAvailable
==============
*/
qboolean SDLash_GyroIsAvailable( void )
{
return ( g_system_gyro != NULL );
}
/*
==============
SDLash_SensorUpdate
==============
*/
void SDLash_SensorUpdate( SDL_SensorEvent sensor )
{
if( sensor.which == g_system_gyro_id )
{
IN_GyroEvent( sensor.data );
}
}
#else
void SDLash_InitSensors( void ) { }
void SDLash_ShutdownSensors( void ) { }
qboolean SDLash_GyroIsAvailable( void ) { return false; }
#endif

View File

@@ -146,10 +146,12 @@ void SDLash_Init( void )
SDL_StopTextInput(); SDL_StopTextInput();
SDLash_InitCursors(); SDLash_InitCursors();
SDLash_InitSensors();
} }
void SDLash_Shutdown( void ) void SDLash_Shutdown( void )
{ {
SDLash_ShutdownSensors();
SDLash_FreeCursors(); SDLash_FreeCursors();
SDL_Quit(); SDL_Quit();

View File

@@ -1204,3 +1204,29 @@ void VID_Info_f( void )
else else
Con_Printf( "Window display mode: " S_RED "fail: " S_DEFAULT "%s\n", SDL_GetError( )); Con_Printf( "Window display mode: " S_RED "fail: " S_DEFAULT "%s\n", SDL_GetError( ));
} }
platform_orientation_t Platform_GetDisplayOrientation( void )
{
if( host.hWnd )
{
int display_index = SDL_GetWindowDisplayIndex( host.hWnd );
if( display_index >= 0 )
{
switch( SDL_GetDisplayOrientation( display_index ) )
{
case SDL_ORIENTATION_LANDSCAPE:
return ORIENTATION_LANDSCAPE;
case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
return ORIENTATION_LANDSCAPE_FLIPPED;
case SDL_ORIENTATION_PORTRAIT:
return ORIENTATION_PORTRAIT;
case SDL_ORIENTATION_PORTRAIT_FLIPPED:
return ORIENTATION_PORTRAIT_FLIPPED;
default:
return ORIENTATION_UNKNOWN;
}
}
}
return ORIENTATION_UNKNOWN;
}

View File

@@ -19,11 +19,11 @@ GNU General Public License for more details.
#include <stdarg.h> #include <stdarg.h>
#include "com_image.h" #include "com_image.h"
#include "vgui_api.h" #include "vgui_api.h"
#include "const.h"
#include "com_model.h"
#include "cl_entity.h"
#include "render_api.h" #include "render_api.h"
#include "triangleapi.h" #include "triangleapi.h"
#include "const.h"
#include "cl_entity.h"
#include "com_model.h"
#include "studio.h" #include "studio.h"
#include "r_efx.h" #include "r_efx.h"
#include "filesystem.h" #include "filesystem.h"
@@ -62,7 +62,17 @@ GNU General Public License for more details.
// 11. Added size argument to Mod_ProcessRenderData // 11. Added size argument to Mod_ProcessRenderData
// 12. Added Image_CalcImageSize // 12. Added Image_CalcImageSize
// 13. Removed ignore_flags argument from GetCvarPointer // 13. Removed ignore_flags argument from GetCvarPointer
#define REF_API_VERSION 13 // 14. Removed reserved functions, they are leftover from RenderAPI
// Removed CL_AddCustomBeam, it's now handled through R_AddEntity
// 15. Replaced CL_InitStudioAPI with R_StudioFillAPI + R_StudioSetDrawInterface
// Engine now builds engine_studio_api_t and handles client DLL negotiation
// Replaced R_DrawStretchRaw and AVI_UploadRawFrame with GL_UpdateTexture
// Added GL_CreateTexture, R_GetDetailScaleForTexture, R_SetDetailScaleForTexture
// Removed R_Flush, VGUI_UploadTextureBlock, R_BeamCull, pfnGetStudioModelInterface
// Moved RenderAPI and TriAPI filling to renderer via R_FillRenderAPI and R_FillTriAPI
// Moved detail textures parsing and cinematic texture management to engine
// Moved creation of default textures to the engine
#define REF_API_VERSION 15
#define TF_SKY (TF_SKYSIDE|TF_NOMIPMAP|TF_ALLOW_NEAREST) #define TF_SKY (TF_SKYSIDE|TF_NOMIPMAP|TF_ALLOW_NEAREST)
#define TF_FONT (TF_NOMIPMAP|TF_CLAMP|TF_ALLOW_NEAREST) #define TF_FONT (TF_NOMIPMAP|TF_CLAMP|TF_ALLOW_NEAREST)
@@ -221,7 +231,7 @@ enum ref_defaultsprite_e
}; };
// the order of first three is important! // the order of first three is important!
// so you can use this value in IEngineStudio.StudioIsHardware // so you can use this value in IEngineStudio.StudioIsHardware (but shouldn't)
typedef enum ref_graphic_apis_e typedef enum ref_graphic_apis_e
{ {
REF_SOFTWARE, // hypothetical: just make a surface to draw on, in software REF_SOFTWARE, // hypothetical: just make a surface to draw on, in software
@@ -387,7 +397,7 @@ typedef struct ref_api_s
// brushes // brushes
int (*Mod_SampleSizeForFace)( const struct msurface_s *surf ); int (*Mod_SampleSizeForFace)( const struct msurface_s *surf );
qboolean (*Mod_BoxVisible)( const vec3_t mins, const vec3_t maxs, const byte *visbits ); qboolean (*Mod_BoxVisible)( const vec3_t mins, const vec3_t maxs, const byte *visbits );
mleaf_t *(*Mod_PointInLeaf)( const vec3_t p, mnode_t *node ); mleaf_t *(*Mod_PointInLeaf)( const vec3_t p, mnode_t *node, struct model_s *mod );
void (*R_DrawWorldHull)( void ); void (*R_DrawWorldHull)( void );
void (*R_DrawModelHull)( model_t *mod ); void (*R_DrawModelHull)( model_t *mod );
@@ -429,7 +439,6 @@ typedef struct ref_api_s
void *(*Mod_CacheCheck)( struct cache_user_s *c ); void *(*Mod_CacheCheck)( struct cache_user_s *c );
void (*Mod_LoadCacheFile)( const char *path, struct cache_user_s *cu ); void (*Mod_LoadCacheFile)( const char *path, struct cache_user_s *cu );
void *(*Mod_Calloc)( int number, size_t size ); void *(*Mod_Calloc)( int number, size_t size );
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
// memory // memory
poolhandle_t (*_Mem_AllocPool)( const char *name, const char *filename, int fileline ) poolhandle_t (*_Mem_AllocPool)( const char *name, const char *filename, int fileline )
@@ -499,6 +508,9 @@ typedef struct ref_api_s
// for abstracting the engine's rendering // for abstracting the engine's rendering
ref_window_type_t (*R_GetWindowHandle)( void **handle, ref_window_type_t type ); ref_window_type_t (*R_GetWindowHandle)( void **handle, ref_window_type_t type );
// sprites
struct mspriteframe_s *(*R_GetSpriteFrame)( const struct model_s *pModel, int frame, float yaw );
} ref_api_t; } ref_api_t;
struct mip_s; struct mip_s;
@@ -533,10 +545,7 @@ typedef struct ref_interface_s
void (*GL_SetRenderMode)( int renderMode ); void (*GL_SetRenderMode)( int renderMode );
qboolean (*R_AddEntity)( struct cl_entity_s *clent, int type ); qboolean (*R_AddEntity)( struct cl_entity_s *clent, int type );
void (*CL_AddCustomBeam)( cl_entity_t *pEnvBeam );
void (*R_ProcessEntData)( qboolean allocate, cl_entity_t *entities, unsigned int max_entities ); void (*R_ProcessEntData)( qboolean allocate, cl_entity_t *entities, unsigned int max_entities );
void (*R_Flush)( unsigned int flush_flags );
// debug // debug
void (*R_ShowTextures)( void ); void (*R_ShowTextures)( void );
@@ -548,7 +557,6 @@ typedef struct ref_interface_s
// 2D // 2D
void (*R_Set2DMode)( qboolean enable ); void (*R_Set2DMode)( qboolean enable );
void (*R_DrawStretchRaw)( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty );
void (*R_DrawStretchPic)( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ); void (*R_DrawStretchPic)( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum );
void (*FillRGBA)( int rendermode, float x, float y, float w, float h, byte r, byte g, byte b, byte a ); // in screen space void (*FillRGBA)( int rendermode, float x, float y, float w, float h, byte r, byte g, byte b, byte a ); // in screen space
int (*WorldToScreen)( const vec3_t world, vec3_t screen ); // Returns 1 if it's z clipped int (*WorldToScreen)( const vec3_t world, vec3_t screen ); // Returns 1 if it's z clipped
@@ -570,16 +578,14 @@ typedef struct ref_interface_s
// studio interface // studio interface
float (*R_StudioEstimateFrame)( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time ); float (*R_StudioEstimateFrame)( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time );
void (*R_StudioLerpMovement)( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); void (*R_StudioLerpMovement)( cl_entity_t *e, double time, vec3_t origin, vec3_t angles );
void (*CL_InitStudioAPI)( void ); qboolean (*R_StudioFillAPI)( struct engine_studio_api_s *api, struct r_studio_interface_s *pDefaultDraw );
void (*R_StudioSetDrawInterface)( struct r_studio_interface_s *pDraw );
// bmodel // bmodel
void (*R_SetSkyCloudsTextures)( int solidskyTexture, int alphaskyTexture ); void (*R_SetSkyCloudsTextures)( int solidskyTexture, int alphaskyTexture );
void (*GL_SubdivideSurface)( model_t *mod, msurface_t *fa ); void (*GL_SubdivideSurface)( model_t *mod, msurface_t *fa );
void (*CL_RunLightStyles)( lightstyle_t *ls ); void (*CL_RunLightStyles)( lightstyle_t *ls );
// sprites
void (*R_GetSpriteParms)( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite );
int (*R_GetSpriteTexture)( const model_t *m_pSpriteModel, int frame );
// model management // model management
// flags ignored for everything except spritemodels // flags ignored for everything except spritemodels
@@ -590,55 +596,27 @@ typedef struct ref_interface_s
void (*CL_DrawParticles)( double frametime, particle_t *particles, float partsize ); void (*CL_DrawParticles)( double frametime, particle_t *particles, float partsize );
void (*CL_DrawTracers)( double frametime, particle_t *tracers ); void (*CL_DrawTracers)( double frametime, particle_t *tracers );
void (*CL_DrawBeams)( int fTrans , BEAM *beams ); void (*CL_DrawBeams)( int fTrans , BEAM *beams );
qboolean (*R_BeamCull)( const vec3_t start, const vec3_t end, qboolean pvsOnly );
// Xash3D Render Interface // Xash3D Render Interface
// Get renderer info (doesn't changes engine state at all)
int (*RefGetParm)( int parm, int arg ); // generic int (*RefGetParm)( int parm, int arg ); // generic
void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha );
float (*GetFrameTime)( void );
// Set renderer info (tell engine about changes) // detail texture scale
void (*R_SetCurrentEntity)( struct cl_entity_s *ent ); // tell engine about both currententity and currentmodel void (*R_GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
void (*R_SetCurrentModel)( struct model_s *mod ); // change currentmodel but leave currententity unchanged void (*R_SetDetailScaleForTexture)( int texture, float xScale, float yScale );
// Texture tools // Texture tools (used by engine directly)
int (*GL_CreateTexture)( const char *name, int width, int height, const void *buffer, texFlags_t flags );
int (*GL_FindTexture)( const char *name ); int (*GL_FindTexture)( const char *name );
const char* (*GL_TextureName)( unsigned int texnum ); const char* (*GL_TextureName)( unsigned int texnum );
const byte* (*GL_TextureData)( unsigned int texnum ); // may be NULL const byte* (*GL_TextureData)( unsigned int texnum ); // may be NULL
int (*GL_LoadTexture)( const char *name, const byte *buf, size_t size, int flags ); int (*GL_LoadTexture)( const char *name, const byte *buf, size_t size, int flags );
int (*GL_CreateTexture)( const char *name, int width, int height, const void *buffer, texFlags_t flags );
int (*GL_LoadTextureArray)( const char **names, int flags );
int (*GL_CreateTextureArray)( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags );
void (*GL_FreeTexture)( unsigned int texnum ); void (*GL_FreeTexture)( unsigned int texnum );
void (*R_OverrideTextureSourceSize)( unsigned int texnum, unsigned int srcWidth, unsigned int srcHeight ); // used to override decal size for texture replacement void (*R_OverrideTextureSourceSize)( unsigned int texnum, unsigned int srcWidth, unsigned int srcHeight ); // used to override decal size for texture replacement
// Decals manipulating (draw & remove) void (*GL_UpdateTexture)( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt );
void (*DrawSingleDecal)( struct decal_s *pDecal, struct msurface_s *fa );
float *(*R_DecalSetupVerts)( struct decal_s *pDecal, struct msurface_s *surf, int texture, int *outCount );
void (*R_EntityRemoveDecals)( struct model_s *mod ); // remove all the decals from specified entity (BSP only)
// AVI // glState related calls (used by engine directly)
void (*AVI_UploadRawFrame)( int texture, int cols, int rows, int width, int height, const byte *data );
// glState related calls (must use this instead of normal gl-calls to prevent de-synchornize local states between engine and the client)
void (*GL_Bind)( int tmu, unsigned int texnum ); void (*GL_Bind)( int tmu, unsigned int texnum );
void (*GL_SelectTexture)( int tmu );
void (*GL_LoadTextureMatrix)( const float *glmatrix );
void (*GL_TexMatrixIdentity)( void );
void (*GL_CleanUpTextureUnits)( int last ); // pass 0 for clear all the texture units
void (*GL_TexGen)( unsigned int coord, unsigned int mode );
void (*GL_TextureTarget)( unsigned int target ); // change texture unit mode without bind texture
void (*GL_TexCoordArrayMode)( unsigned int texmode );
void (*GL_UpdateTexSize)( int texnum, int width, int height, int depth ); // recalc statistics
void (*GL_Reserved0)( void ); // for potential interface expansion without broken compatibility
void (*GL_Reserved1)( void );
// Misc renderer functions
void (*GL_DrawParticles)( const struct ref_viewpass_s *rvp, qboolean trans_pass, float frametime );
colorVec (*LightVec)( const float *start, const float *end, float *lightspot, float *lightvec );
struct mstudiotex_s *( *StudioGetTexture )( struct cl_entity_s *e );
// passed through R_RenderFrame (0 - use engine renderer, 1 - use custom client renderer) // passed through R_RenderFrame (0 - use engine renderer, 1 - use custom client renderer)
void (*GL_RenderFrame)( const struct ref_viewpass_s *rvp ); void (*GL_RenderFrame)( const struct ref_viewpass_s *rvp );
@@ -652,28 +630,23 @@ typedef struct ref_interface_s
void (*R_NewMap)( void ); void (*R_NewMap)( void );
// clear the render entities before each frame // clear the render entities before each frame
void (*R_ClearScene)( void ); void (*R_ClearScene)( void );
// GL_GetProcAddress for client renderer
void* (*R_GetProcAddress)( const char *name );
// TriAPI Interface // TriAPI Interface (functions used by engine wrappers)
// NOTE: implementation isn't required to be compatible
void (*TriRenderMode)( int mode ); void (*TriRenderMode)( int mode );
void (*Begin)( int primitiveCode ); void (*Begin)( int primitiveCode );
void (*End)( void ); void (*End)( void );
void (*Color4f)( float r, float g, float b, float a ); // real glColor4f void (*Color4f)( float r, float g, float b, float a ); // real glColor4f
void (*Color4ub)( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); // real glColor4ub void (*Color4ub)( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); // real glColor4ub
void (*TexCoord2f)( float u, float v );
void (*Vertex3fv)( const float *worldPnt ); void (*Vertex3fv)( const float *worldPnt );
void (*Vertex3f)( float x, float y, float z ); void (*Vertex3f)( float x, float y, float z );
void (*Fog)( float flFogColor[3], float flStart, float flEnd, int bOn ); //Works just like GL_FOG, flFogColor is r/g/b.
void (*ScreenToWorld)( const float *screen, float *world );
void (*GetMatrix)( const int pname, float *matrix );
void (*FogParams)( float flDensity, int iFogSkybox );
void (*CullFace)( TRICULLSTYLE mode ); void (*CullFace)( TRICULLSTYLE mode );
// fill render_api_t and triangleapi_t with renderer-specific functions
void (*R_FillRenderAPI)( struct render_api_s *api );
void (*R_FillTriAPI)( struct triangleapi_s *api );
// vgui drawing implementation // vgui drawing implementation
void (*VGUI_SetupDrawing)( qboolean rect ); void (*VGUI_SetupDrawing)( qboolean rect );
void (*VGUI_UploadTextureBlock)( int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight );
} ref_interface_t; } ref_interface_t;
typedef int (*REFAPI)( int version, ref_interface_t *pFunctionTable, ref_api_t* engfuncs, ref_globals_t *pGlobals ); typedef int (*REFAPI)( int version, ref_interface_t *pFunctionTable, ref_api_t* engfuncs, ref_globals_t *pGlobals );

92
ref/common/ref_common.h Normal file
View File

@@ -0,0 +1,92 @@
/*
ref_common.h - shared renderer code
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef REF_COMMON_H
#define REF_COMMON_H
#include "xash3d_mathlib.h"
#include "ref_api.h"
//
// ref_context.c
//
extern ref_api_t gEngfuncs;
extern ref_globals_t *gpGlobals;
extern ref_client_t *gp_cl;
extern ref_host_t *gp_host;
extern const ref_interface_t gReffuncs;
DECLARE_ENGINE_SHARED_CVAR_LIST()
#define Assert( x ) if( !( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ )
#define ENGINE_GET_PARM_ (*gEngfuncs.EngineGetParm)
#define ENGINE_GET_PARM( parm ) ENGINE_GET_PARM_( (parm), 0 )
extern uint16_t rtable[MOD_FRAMES][MOD_FRAMES];
void GL_InitRandomTable( void );
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 3 ) WARN_UNUSED_RESULT;
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )
extern dlight_t *gp_dlights;
extern int g_lightstylevalue[MAX_LIGHTSTYLES];
extern poolhandle_t r_temppool;
//
// ref_common cvars
//
extern convar_t r_dlight_virtual_radius;
extern convar_t r_lighting_extended;
//
// ref_math.c
//
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z );
void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z );
void Matrix4x4_CreateProjection( matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar );
void Matrix4x4_CreateOrtho( matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar );
void Matrix4x4_CreateModelview( matrix4x4 out );
void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] );
//
// ref_light.c
//
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlightsForBmodel( model_t *model, int framecount, const matrix4x4 object_matrix );
int R_PushDlights( model_t *model, int framecount );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec );
colorVec R_LightPoint( const vec3_t p0 );
void R_GatherPlayerLight( cl_entity_t *view );
void R_UpdateSurfaceCachedLight( msurface_t *surf );
//
// ref_image.c
//
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
#endif // REF_COMMON_H

81
ref/common/ref_context.c Normal file
View File

@@ -0,0 +1,81 @@
/*
ref_context.c - shared renderer context
Copyright (C) 2018 a1batross
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "ref_common.h"
#include "com_strings.h"
DEFINE_ENGINE_SHARED_CVAR_LIST()
ref_api_t gEngfuncs;
ref_globals_t *gpGlobals;
ref_client_t *gp_cl;
ref_host_t *gp_host;
uint16_t rtable[MOD_FRAMES][MOD_FRAMES];
dlight_t *gp_dlights;
int g_lightstylevalue[MAX_LIGHTSTYLES];
poolhandle_t r_temppool;
void _Mem_Free( void *data, const char *filename, int fileline )
{
gEngfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Realloc( poolptr, memptr, size, clear, filename, fileline );
}
void GL_InitRandomTable( void )
{
int tu, tv;
for( tu = 0; tu < MOD_FRAMES; tu++ )
{
for( tv = 0; tv < MOD_FRAMES; tv++ )
{
rtable[tu][tv] = gEngfuncs.COM_RandomLong( 0, 0x7FFF );
}
}
gEngfuncs.COM_SetRandomSeed( 0 );
}
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals );
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals )
{
if( version != REF_API_VERSION )
return 0;
// fill in our callbacks
*funcs = gReffuncs;
gEngfuncs = *engfuncs;
gpGlobals = globals;
gp_cl = (ref_client_t *)ENGINE_GET_PARM( PARM_GET_CLIENT_PTR );
gp_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR );
gp_dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
RETRIEVE_ENGINE_SHARED_CVAR_LIST();
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );
gEngfuncs.Cvar_RegisterVariable( &r_lighting_extended );
return REF_API_VERSION;
}

108
ref/common/ref_image.c Normal file
View File

@@ -0,0 +1,108 @@
/*
ref_image.c - shared image code
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "ref_common.h"
#include "xash3d_mathlib.h"
/*
================
GL_ResampleTexture
Assume input buffer is RGBA
=================
*/
byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int outWidth, int outHeight, qboolean isNormalMap )
{
uint frac, fracStep;
uint *in = (uint *)source;
uint p1[0x1000], p2[0x1000];
byte *pix1, *pix2, *pix3, *pix4;
uint *out, *inRow1, *inRow2;
static byte *scaledImage = NULL; // pointer to a scaled image
vec3_t normal;
int i, x, y;
if( !source ) return NULL;
scaledImage = Mem_Realloc( r_temppool, scaledImage, outWidth * outHeight * 4 );
fracStep = inWidth * 0x10000 / outWidth;
out = (uint *)scaledImage;
frac = fracStep >> 2;
for( i = 0; i < outWidth; i++ )
{
p1[i] = 4 * (frac >> 16);
frac += fracStep;
}
frac = (fracStep >> 2) * 3;
for( i = 0; i < outWidth; i++ )
{
p2[i] = 4 * (frac >> 16);
frac += fracStep;
}
if( isNormalMap )
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f) * inHeight / outHeight);
inRow2 = in + inWidth * (int)(((float)y + 0.75f) * inHeight / outHeight);
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
normal[0] = MAKE_SIGNED( pix1[0] ) + MAKE_SIGNED( pix2[0] ) + MAKE_SIGNED( pix3[0] ) + MAKE_SIGNED( pix4[0] );
normal[1] = MAKE_SIGNED( pix1[1] ) + MAKE_SIGNED( pix2[1] ) + MAKE_SIGNED( pix3[1] ) + MAKE_SIGNED( pix4[1] );
normal[2] = MAKE_SIGNED( pix1[2] ) + MAKE_SIGNED( pix2[2] ) + MAKE_SIGNED( pix3[2] ) + MAKE_SIGNED( pix4[2] );
if( !VectorNormalizeLength( normal ))
VectorSet( normal, 0.5f, 0.5f, 1.0f );
((byte *)(out+x))[0] = 128 + (byte)(127.0f * normal[0]);
((byte *)(out+x))[1] = 128 + (byte)(127.0f * normal[1]);
((byte *)(out+x))[2] = 128 + (byte)(127.0f * normal[2]);
((byte *)(out+x))[3] = 255;
}
}
}
else
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f) * inHeight / outHeight);
inRow2 = in + inWidth * (int)(((float)y + 0.75f) * inHeight / outHeight);
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
((byte *)(out+x))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0]) >> 2;
((byte *)(out+x))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1]) >> 2;
((byte *)(out+x))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2]) >> 2;
((byte *)(out+x))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3]) >> 2;
}
}
}
return scaledImage;
}

View File

@@ -1,5 +1,5 @@
/* /*
gl_rlight.c - dynamic and static lights ref_light.c - shared light code
Copyright (C) 2010 Uncle Mike Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@@ -13,19 +13,13 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
*/ */
#include "gl_local.h" #include "ref_common.h"
#include "pm_local.h"
#include "studio.h"
#include "xash3d_mathlib.h" #include "xash3d_mathlib.h"
#include "ref_params.h" #include "pm_local.h"
/* CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount" );
============================================================================= CVAR_DEFINE_AUTO( r_lighting_extended, "1", FCVAR_GLCONFIG, "allow to get lighting from world and bmodels" );
DYNAMIC LIGHTS
=============================================================================
*/
/* /*
================== ==================
CL_RunLightStyles CL_RunLightStyles
@@ -34,16 +28,17 @@ CL_RunLightStyles
*/ */
void CL_RunLightStyles( lightstyle_t *ls ) void CL_RunLightStyles( lightstyle_t *ls )
{ {
const model_t *world = gp_cl->models[1];
int i; int i;
float frametime = (gp_cl->time - gp_cl->oldtime); float frametime = gp_cl->time - gp_cl->oldtime;
if( !WORLDMODEL ) if( !world )
return; return;
if( !WORLDMODEL->lightdata ) if( r_fullbright->value || !world->lightdata )
{ {
for( i = 0; i < MAX_LIGHTSTYLES; i++ ) for( i = 0; i < MAX_LIGHTSTYLES; i++ )
tr.lightstylevalue[i] = 256 * 256; g_lightstylevalue[i] = 256 * 256;
return; return;
} }
@@ -59,13 +54,13 @@ void CL_RunLightStyles( lightstyle_t *ls )
if( !ls[i].length ) if( !ls[i].length )
{ {
tr.lightstylevalue[i] = 256; g_lightstylevalue[i] = 256;
continue; continue;
} }
else if( ls[i].length == 1 ) else if( ls[i].length == 1 )
{ {
// single length style so don't bother interpolating // single length style so don't bother interpolating
tr.lightstylevalue[i] = ( ls[i].map[0] ) * 22; g_lightstylevalue[i] = ls[i].map[0] * 22;
continue; continue;
} }
@@ -73,7 +68,7 @@ void CL_RunLightStyles( lightstyle_t *ls )
if( !ls[i].interp || !cl_lightstyle_lerping->value ) if( !ls[i].interp || !cl_lightstyle_lerping->value )
{ {
tr.lightstylevalue[i] = ls[i].map[flight%ls[i].length] * 22; g_lightstylevalue[i] = ls[i].map[flight % ls[i].length] * 22;
continue; continue;
} }
@@ -90,7 +85,7 @@ void CL_RunLightStyles( lightstyle_t *ls )
k = ls[i].map[clight % ls[i].length]; k = ls[i].map[clight % ls[i].length];
l += (float)( k * 22.0f ) * lerpfrac; l += (float)( k * 22.0f ) * lerpfrac;
tr.lightstylevalue[i] = (int)l; g_lightstylevalue[i] = (int)l;
} }
} }
@@ -99,44 +94,39 @@ void CL_RunLightStyles( lightstyle_t *ls )
R_MarkLights R_MarkLights
============= =============
*/ */
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node ) static void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node, model_t *model, int dlightframecount )
{ {
const float virtual_radius = light->radius * Q_max( 1.0f, r_dlight_virtual_radius.value ); const float virtual_radius = light->radius * Q_max( 1.0f, r_dlight_virtual_radius.value );
const float maxdist = light->radius * light->radius; const float maxdist = light->radius * light->radius;
float dist;
int i;
int firstsurface, numsurfaces;
start: start:
if( !node || node->contents < 0 ) if( !node || node->contents < 0 )
return; return;
dist = PlaneDiff( light->origin, node->plane ); float dist = PlaneDiff( light->origin, node->plane );
if( dist > virtual_radius ) if( dist > virtual_radius )
{ {
node = node_child( node, 0, RI.currentmodel ); node = node_child( node, 0, model );
goto start; goto start;
} }
if( dist < -virtual_radius ) if( dist < -virtual_radius )
{ {
node = node_child( node, 1, RI.currentmodel ); node = node_child( node, 1, model );
goto start; goto start;
} }
const float dist_sq = dist * dist; const float dist_sq = dist * dist;
// mark the polygons // mark the polygons
firstsurface = node_firstsurface( node, RI.currentmodel ); int firstsurface = node_firstsurface( node, model );
numsurfaces = node_numsurfaces( node, RI.currentmodel ); int numsurfaces = node_numsurfaces( node, model );
for( i = 0; i < numsurfaces && dist_sq < maxdist; i++ ) for( int i = 0; i < numsurfaces && dist_sq < maxdist; i++ )
{ {
vec3_t impact; vec3_t impact;
float s, t, l; float s, t, l;
msurface_t *surf = &RI.currentmodel->surfaces[firstsurface + i]; msurface_t *surf = &model->surfaces[firstsurface + i];
const mextrasurf_t *info = surf->info; const mextrasurf_t *info = surf->info;
if( surf->plane->type < 3 ) if( surf->plane->type < 3 )
@@ -162,16 +152,17 @@ start:
if( s * s + t * t + dist_sq >= maxdist ) if( s * s + t * t + dist_sq >= maxdist )
continue; continue;
if( surf->dlightframe != tr.dlightframecount ) if( surf->dlightframe != dlightframecount )
{ {
surf->dlightbits = bit; surf->dlightbits = bit;
surf->dlightframe = tr.dlightframecount; surf->dlightframe = dlightframecount;
} }
else surf->dlightbits |= bit; else surf->dlightbits |= bit;
} }
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel )); R_MarkLights( light, bit, node_child( node, 0, model ), model, dlightframecount );
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel )); node = node_child( node, 1, model );
goto start;
} }
/* /*
@@ -179,31 +170,40 @@ start:
R_PushDlights R_PushDlights
============= =============
*/ */
void R_PushDlights( void ) int R_PushDlights( model_t *model, int framecount )
{ {
int i; if( !model )
return framecount;
tr.dlightframecount = tr.framecount; for( int i = 0; i < MAX_DLIGHTS; i++ )
RI.currententity = CL_GetEntityByIndex( 0 );
// no world -- no dlights
if( !RI.currententity )
return;
RI.currentmodel = RI.currententity->model;
for( i = 0; i < MAX_DLIGHTS; i++ )
{ {
dlight_t *l = &tr.dlights[i]; const dlight_t *l = &gp_dlights[i];
if( l->die < gp_cl->time || !l->radius ) if( l->die < gp_cl->time || !l->radius )
continue; continue;
if( GL_FrustumCullSphere( &RI.frustum, l->origin, l->radius, 15 )) R_MarkLights( l, 1 << i, model->nodes, model, framecount );
}
return framecount;
}
void R_PushDlightsForBmodel( model_t *model, int framecount, const matrix4x4 object_matrix )
{
for( int i = 0; i < MAX_DLIGHTS; i++ )
{
dlight_t *l = &gp_dlights[i];
if( l->die < gp_cl->time || !l->radius )
continue; continue;
R_MarkLights( l, 1<<i, RI.currentmodel->nodes ); vec3_t oldorigin;
VectorCopy( l->origin, oldorigin );
Matrix4x4_VectorITransform( object_matrix, oldorigin, l->origin );
R_MarkLights( l, 1 << i, model->nodes + model->hulls[0].firstclipnode, model, framecount );
VectorCopy( oldorigin, l->origin );
} }
} }
@@ -225,18 +225,7 @@ R_RecursiveLightPoint
*/ */
static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, float p2f, colorVec *cv, const vec3_t start, const vec3_t end ) static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, float p2f, colorVec *cv, const vec3_t start, const vec3_t end )
{ {
float front, back, frac, midf; start:
int i, map, side, size;
float ds, dt, s, t;
int sample_size;
color24 *lm, *dm;
mextrasurf_t *info;
msurface_t *surf;
mtexinfo_t *tex;
matrix3x4 tbn;
vec3_t mid;
int firstsurface, numsurfaces;
// didn't hit anything // didn't hit anything
if( !node || node->contents < 0 ) if( !node || node->contents < 0 )
{ {
@@ -244,21 +233,23 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
return false; return false;
} }
firstsurface = node_firstsurface( node, model );
numsurfaces = node_numsurfaces( node, model );
// calculate mid point // calculate mid point
front = PlaneDiff( start, node->plane ); float front = PlaneDiff( start, node->plane );
back = PlaneDiff( end, node->plane ); float back = PlaneDiff( end, node->plane );
side = front < 0; int side = front < 0;
if(( back < 0 ) == side ) if(( back < 0 ) == side )
return R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, p2f, cv, start, end ); {
node = node_child( node, side, model );
goto start;
}
frac = front / ( front - back ); float frac = front / ( front - back );
vec3_t mid;
VectorLerp( start, frac, end, mid ); VectorLerp( start, frac, end, mid );
midf = p1f + ( p2f - p1f ) * frac;
float midf = p1f + ( p2f - p1f ) * frac;
// co down front side // co down front side
if( R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, midf, cv, start, mid )) if( R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, midf, cv, start, mid ))
@@ -271,27 +262,27 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
} }
// check for impact on this node // check for impact on this node
surf = model->surfaces + firstsurface; int firstsurface = node_firstsurface( node, model );
int numsurfaces = node_numsurfaces( node, model );
VectorCopy( mid, g_trace_lightspot ); VectorCopy( mid, g_trace_lightspot );
for( i = 0; i < numsurfaces; i++, surf++ ) for( int i = 0; i < numsurfaces; i++ )
{ {
int smax, tmax; const msurface_t *surf = &model->surfaces[firstsurface + i];
const mextrasurf_t *info = surf->info;
tex = surf->texinfo;
info = surf->info;
if( FBitSet( surf->flags, SURF_DRAWTILED )) if( FBitSet( surf->flags, SURF_DRAWTILED ))
continue; // no lightmaps continue; // no lightmaps
s = DotProduct( mid, info->lmvecs[0] ) + info->lmvecs[0][3]; float s = DotProduct( mid, info->lmvecs[0] ) + info->lmvecs[0][3];
t = DotProduct( mid, info->lmvecs[1] ) + info->lmvecs[1][3]; float t = DotProduct( mid, info->lmvecs[1] ) + info->lmvecs[1][3];
if( s < info->lightmapmins[0] || t < info->lightmapmins[1] ) if( s < info->lightmapmins[0] || t < info->lightmapmins[1] )
continue; continue;
ds = s - info->lightmapmins[0]; float ds = s - info->lightmapmins[0];
dt = t - info->lightmapmins[1]; float dt = t - info->lightmapmins[1];
if ( ds > info->lightextents[0] || dt > info->lightextents[1] ) if ( ds > info->lightextents[0] || dt > info->lightextents[1] )
continue; continue;
@@ -301,21 +292,25 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
if( !surf->samples ) if( !surf->samples )
return true; return true;
sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); int sample_size = gEngfuncs.Mod_SampleSizeForFace( surf );
smax = (info->lightextents[0] / sample_size) + 1; int smax = (info->lightextents[0] / sample_size) + 1;
tmax = (info->lightextents[1] / sample_size) + 1; int tmax = (info->lightextents[1] / sample_size) + 1;
ds /= sample_size; ds /= sample_size;
dt /= sample_size; dt /= sample_size;
lm = surf->samples + Q_rint( dt ) * smax + Q_rint( ds );
g_trace_fraction = midf; g_trace_fraction = midf;
size = smax * tmax;
dm = NULL; const color24 *lm = surf->samples + Q_rint( dt ) * smax + Q_rint( ds );
const color24 *dm = NULL;
matrix3x4 tbn;
if( surf->info->deluxemap ) if( surf->info->deluxemap )
{ {
vec3_t faceNormal; vec3_t faceNormal;
dm = surf->info->deluxemap + Q_rint( dt ) * smax + Q_rint( ds );
if( FBitSet( surf->flags, SURF_PLANEBACK )) if( FBitSet( surf->flags, SURF_PLANEBACK ))
VectorNegate( surf->plane->normal, faceNormal ); VectorNegate( surf->plane->normal, faceNormal );
else VectorCopy( surf->plane->normal, faceNormal ); else VectorCopy( surf->plane->normal, faceNormal );
@@ -333,12 +328,13 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
VectorNormalize( tbn[0] ); VectorNormalize( tbn[0] );
VectorNormalize( tbn[1] ); VectorNormalize( tbn[1] );
VectorNormalize( tbn[2] ); VectorNormalize( tbn[2] );
dm = surf->info->deluxemap + Q_rint( dt ) * smax + Q_rint( ds );
} }
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ ) int size = smax * tmax;
for( int map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
{ {
uint scale = tr.lightstylevalue[surf->styles[map]]; uint scale = g_lightstylevalue[surf->styles[map]];
cv->r += lm->r * scale; cv->r += lm->r * scale;
cv->g += lm->g * scale; cv->g += lm->g * scale;
@@ -368,83 +364,75 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
/* /*
================= =================
R_LightVec R_LightVecInternal
check bspmodels to get light from check bspmodels to get light from
================= =================
*/ */
static colorVec R_LightVecInternal( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec ) static colorVec R_LightVecInternal( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
{ {
float last_fraction; if( lspot )
int i, maxEnts = 1; VectorClear( lspot );
colorVec light, cv;
if( lspot ) VectorClear( lspot ); if( lvec )
if( lvec ) VectorClear( lvec ); VectorClear( lvec );
if( WORLDMODEL && WORLDMODEL->lightdata ) if( !gp_cl->models[1] || !gp_cl->models[1]->lightdata )
return (colorVec){ 255, 255, 255, 0 };
float last_fraction = 1.0f;
int max_ents = r_lighting_extended.value ? MAX_PHYSENTS : 1; // get light from bmodels too
colorVec light = { 0 };
// check all the bsp-models
for( int i = 0; i < max_ents; i++ )
{ {
light.r = light.g = light.b = light.a = 0; const physent_t *pe = gEngfuncs.EV_GetPhysent( i );
last_fraction = 1.0f;
// get light from bmodels too if( !pe )
if( r_lighting_extended.value ) break;
maxEnts = MAX_PHYSENTS;
// check all the bsp-models if( !pe->model || pe->model->type != mod_brush )
for( i = 0; i < maxEnts; i++ ) continue; // skip non-bsp models
mnode_t *pnodes = &pe->model->nodes[pe->model->hulls[0].firstclipnode];
vec3_t offset, start_l, end_l;
VectorSubtract( pe->model->hulls[0].clip_mins, vec3_origin, offset );
VectorAdd( offset, pe->origin, offset );
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
// rotate start and end into the models frame of reference
if( !VectorIsNull( pe->angles ))
{ {
physent_t *pe = gEngfuncs.EV_GetPhysent( i ); matrix4x4 matrix;
vec3_t offset, start_l, end_l; Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
mnode_t *pnodes; Matrix4x4_VectorITransform( matrix, start, start_l );
matrix4x4 matrix; Matrix4x4_VectorITransform( matrix, end, end_l );
}
if( !pe )
break; VectorClear( g_trace_lightspot );
VectorClear( g_trace_lightvec );
if( !pe->model || pe->model->type != mod_brush ) g_trace_fraction = 1.0f;
continue; // skip non-bsp models
colorVec cv;
pnodes = &pe->model->nodes[pe->model->hulls[0].firstclipnode]; if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l ))
VectorSubtract( pe->model->hulls[0].clip_mins, vec3_origin, offset ); continue; // didn't hit anything
VectorAdd( offset, pe->origin, offset );
VectorSubtract( start, offset, start_l ); if( g_trace_fraction < last_fraction )
VectorSubtract( end, offset, end_l ); {
if( lspot ) VectorCopy( g_trace_lightspot, lspot );
// rotate start and end into the models frame of reference if( lvec ) VectorNormalize2( g_trace_lightvec, lvec );
if( !VectorIsNull( pe->angles ))
{ light.r = Q_min(( cv.r >> 8 ), 255 );
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f ); light.g = Q_min(( cv.g >> 8 ), 255 );
Matrix4x4_VectorITransform( matrix, start, start_l ); light.b = Q_min(( cv.b >> 8 ), 255 );
Matrix4x4_VectorITransform( matrix, end, end_l ); last_fraction = g_trace_fraction;
}
if(( light.r + light.g + light.b ) != 0 )
VectorClear( g_trace_lightspot ); break; // we get light now
VectorClear( g_trace_lightvec );
g_trace_fraction = 1.0f;
if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l ))
continue; // didn't hit anything
if( g_trace_fraction < last_fraction )
{
if( lspot ) VectorCopy( g_trace_lightspot, lspot );
if( lvec ) VectorNormalize2( g_trace_lightvec, lvec );
light.r = Q_min(( cv.r >> 8 ), 255 );
light.g = Q_min(( cv.g >> 8 ), 255 );
light.b = Q_min(( cv.b >> 8 ), 255 );
last_fraction = g_trace_fraction;
if(( light.r + light.g + light.b ) != 0 )
break; // we get light now
}
} }
}
else
{
light.r = light.g = light.b = 255;
light.a = 0;
} }
return light; return light;
@@ -459,7 +447,7 @@ check bspmodels to get light from
*/ */
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec ) colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
{ {
colorVec light = R_LightVecInternal( start, end, lspot, lvec ); colorVec light = R_LightVecInternal( start, end, lspot, lvec );
if( r_lighting_extended.value && lspot != NULL && lvec != NULL ) if( r_lighting_extended.value && lspot != NULL && lvec != NULL )
{ {
@@ -480,9 +468,34 @@ light from floor
*/ */
colorVec R_LightPoint( const vec3_t p0 ) colorVec R_LightPoint( const vec3_t p0 )
{ {
vec3_t p1; vec3_t p1;
VectorSet( p1, p0[0], p0[1], p0[2] - 2048.0f ); VectorSet( p1, p0[0], p0[1], p0[2] - 2048.0f );
return R_LightVec( p0, p1, NULL, NULL ); return R_LightVec( p0, p1, NULL, NULL );
} }
/*
=================
R_GatherPlayerLight
get light level of an entity and set it as player's light level
=================
*/
void R_GatherPlayerLight( cl_entity_t *view )
{
colorVec c = R_LightPoint( view->origin );
gEngfuncs.SetLocalLightLevel(( c.r + c.g + c.b ) / 3 );
}
/*
================
R_SetCacheState
================
*/
void R_UpdateSurfaceCachedLight( msurface_t *surf )
{
for( int i = 0; i < MAXLIGHTMAPS && surf->styles[i] != 255; i++ )
surf->cached_light[i] = g_lightstylevalue[surf->styles[i]];
}

View File

@@ -1,5 +1,5 @@
/* /*
gl_rmath.c - renderer mathlib ref_math.c - renderer mathlib
Copyright (C) 2010 Uncle Mike Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@@ -13,8 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
*/ */
#include "r_local.h" #include "ref_common.h"
#include "xash3d_mathlib.h"
/* /*
======================================================================== ========================================================================
@@ -99,7 +98,27 @@ void Matrix4x4_CreateModelview( matrix4x4 out )
out[1][2] = 1.0f; out[1][2] = 1.0f;
} }
void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z ) void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] )
{
out[ 0] = in[0][0];
out[ 1] = in[1][0];
out[ 2] = in[2][0];
out[ 3] = in[3][0];
out[ 4] = in[0][1];
out[ 5] = in[1][1];
out[ 6] = in[2][1];
out[ 7] = in[3][1];
out[ 8] = in[0][2];
out[ 9] = in[1][2];
out[10] = in[2][2];
out[11] = in[3][2];
out[12] = in[0][3];
out[13] = in[1][3];
out[14] = in[2][3];
out[15] = in[3][3];
}
static void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z )
{ {
out[0][0] = 1.0f; out[0][0] = 1.0f;
out[0][1] = 0.0f; out[0][1] = 0.0f;
@@ -119,7 +138,7 @@ void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z )
out[3][3] = 1.0f; out[3][3] = 1.0f;
} }
void Matrix4x4_CreateRotate( matrix4x4 out, float angle, float x, float y, float z ) static void Matrix4x4_CreateRotate( matrix4x4 out, float angle, float x, float y, float z )
{ {
float len, c, s; float len, c, s;

27
ref/common/wscript Normal file
View File

@@ -0,0 +1,27 @@
#! /usr/bin/env python
# encoding: utf-8
def options(opt):
pass
def configure(conf):
pass
def build(bld):
use = ['engine_includes', 'sdk_includes', 'werror']
# FIXME: figure out why psvita needs it and how can we avoid it
if bld.env.DEST_OS == 'psvita':
bld.env.CFLAGS_cstlib.remove('-fno-PIC')
bld.env.CFLAGS += ['-fPIC']
else:
use += ['public']
bld.stlib(source = bld.path.ant_glob('*.c'),
target = 'ref_common',
includes = '.',
export_includes = '.',
defines = 'REF_DLL=1',
use = use,
subsystem = bld.env.MSVC_SUBSYSTEM
)

View File

@@ -578,7 +578,7 @@ static void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight )
if( !plight || !ent ) if( !plight || !ent )
return; return;
if( !RI.drawWorld || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT )) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT ))
{ {
plight->shadelight = 0; plight->shadelight = 0;
plight->ambientlight = 192; plight->ambientlight = 192;
@@ -684,7 +684,7 @@ static void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ ) for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{ {
const dlight_t *dl = &tr.dlights[lnum]; const dlight_t *dl = &gp_dlights[lnum];
if( dl->die < g_alias.time || !r_dynamic->value ) if( dl->die < g_alias.time || !r_dynamic->value )
continue; continue;
@@ -1126,7 +1126,7 @@ init current time for a given model
*/ */
static void R_AliasSetupTimings( void ) static void R_AliasSetupTimings( void )
{ {
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{ {
// synchronize with server time // synchronize with server time
g_alias.time = gp_cl->time; g_alias.time = gp_cl->time;

View File

@@ -61,7 +61,7 @@ void GL_BackendEndFrame( void )
{ {
mleaf_t *curleaf; mleaf_t *curleaf;
if( r_speeds->value <= 0 || !RI.drawWorld ) if( r_speeds->value <= 0 || !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return; return;
if( !RI.viewleaf ) if( !RI.viewleaf )
@@ -616,7 +616,7 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo
string basename; string basename;
int i = 1, flags, result; int i = 1, flags, result;
if( !RI.drawWorld || !WORLDMODEL ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || !WORLDMODEL )
return false; return false;
// make sure the specified size is valid // make sure the specified size is valid
@@ -633,7 +633,7 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo
r_side = Mem_Calloc( r_temppool, sizeof( rgbdata_t )); r_side = Mem_Calloc( r_temppool, sizeof( rgbdata_t ));
// use client vieworg // use client vieworg
if( !vieworg ) vieworg = RI.vieworg; if( !vieworg ) vieworg = RI.rvp.vieworigin;
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {

View File

@@ -98,7 +98,7 @@ static void R_BeamComputeNormal( const vec3_t vStartPos, const vec3_t vNextPos,
VectorSubtract( vStartPos, vNextPos, vTangentY ); VectorSubtract( vStartPos, vNextPos, vTangentY );
// vDirToBeam = vector from viewer origin to beam // vDirToBeam = vector from viewer origin to beam
VectorSubtract( vStartPos, RI.vieworg, vDirToBeam ); VectorSubtract( vStartPos, RI.rvp.vieworigin, vDirToBeam );
// get a vector that is perpendicular to us and perpendicular to the beam. // get a vector that is perpendicular to us and perpendicular to the beam.
// this is used to fatten the beam. // this is used to fatten the beam.
@@ -114,7 +114,7 @@ R_BeamCull
Cull the beam by bbox Cull the beam by bbox
============== ==============
*/ */
qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly ) static qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly )
{ {
vec3_t mins, maxs; vec3_t mins, maxs;
int i; int i;
@@ -151,28 +151,6 @@ qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly )
return true; return true;
} }
/*
================
CL_AddCustomBeam
Add the beam that encoded as custom entity
================
*/
void CL_AddCustomBeam( cl_entity_t *pEnvBeam )
{
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
{
gEngfuncs.Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
return;
}
if( pEnvBeam )
{
tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = pEnvBeam;
tr.draw_list->num_beam_entities++;
}
}
/* /*
============================================================== ==============================================================
@@ -1028,7 +1006,7 @@ static void R_BeamDraw( BEAM *pbeam, float frametime )
float flDistance; float flDistance;
// fade the beam if the player's not looking at the source // fade the beam if the player's not looking at the source
VectorSubtract( RI.vieworg, pbeam->source, localDir ); VectorSubtract( RI.rvp.vieworigin, pbeam->source, localDir );
flDot = DotProduct( delta, localDir ); flDot = DotProduct( delta, localDir );
VectorScale( delta, flDot, vecProjection ); VectorScale( delta, flDot, vecProjection );
VectorSubtract( localDir, vecProjection, tmp ); VectorSubtract( localDir, vecProjection, tmp );

View File

@@ -22,20 +22,7 @@ GNU General Public License for more details.
#include "gl4es/include/gl4esinit.h" #include "gl4es/include/gl4esinit.h"
#endif #endif
ref_api_t gEngfuncs;
ref_globals_t *gpGlobals;
ref_client_t *gp_cl;
ref_host_t *gp_host;
void _Mem_Free( void *data, const char *filename, int fileline )
{
gEngfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
static void R_ClearScreen( void ) static void R_ClearScreen( void )
{ {
@@ -132,7 +119,6 @@ static void Mod_UnloadTextures( model_t *mod )
Mod_BrushUnloadTextures( mod ); Mod_BrushUnloadTextures( mod );
break; break;
case mod_sprite: case mod_sprite:
Mod_SpriteUnloadTextures( mod->cache.data );
break; break;
default: default:
Assert( 0 ); Assert( 0 );
@@ -159,7 +145,7 @@ static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte
loaded = true; loaded = true;
break; break;
case mod_sprite: case mod_sprite:
Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo ); loaded = true;
break; break;
case mod_alias: case mod_alias:
Mod_LoadAliasModel( mod, buf, &loaded ); Mod_LoadAliasModel( mod, buf, &loaded );
@@ -228,7 +214,7 @@ static int GL_RefGetParm( int parm, int arg )
return glState.activeTMU; return glState.activeTMU;
case PARM_LIGHTSTYLEVALUE: case PARM_LIGHTSTYLEVALUE:
arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 ); arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 );
return tr.lightstylevalue[arg]; return g_lightstylevalue[arg];
case PARM_MAX_IMAGE_UNITS: case PARM_MAX_IMAGE_UNITS:
return GL_MaxTextureUnits(); return GL_MaxTextureUnits();
case PARM_REBUILD_GAMMA: case PARM_REBUILD_GAMMA:
@@ -258,6 +244,14 @@ static void R_GetDetailScaleForTexture( int texture, float *xScale, float *yScal
if( yScale ) *yScale = glt->yscale; if( yScale ) *yScale = glt->yscale;
} }
static void R_SetDetailScaleForTexture( int texture, float xScale, float yScale )
{
gl_texture_t *glt = R_GetTexture( texture );
glt->xscale = xScale;
glt->yscale = yScale;
}
static void R_GetExtraParmsForTexture( int texture, byte *red, byte *green, byte *blue, byte *density ) static void R_GetExtraParmsForTexture( int texture, byte *red, byte *green, byte *blue, byte *density )
{ {
gl_texture_t *glt = R_GetTexture( texture ); gl_texture_t *glt = R_GetTexture( texture );
@@ -325,11 +319,6 @@ static void R_ProcessEntData( qboolean allocate, cl_entity_t *entities, unsigned
gEngfuncs.drawFuncs->R_ProcessEntData( allocate ); gEngfuncs.drawFuncs->R_ProcessEntData( allocate );
} }
static void GAME_EXPORT R_Flush( unsigned int flags )
{
// stub
}
/* /*
============= =============
R_SetSkyCloudsTextures R_SetSkyCloudsTextures
@@ -383,11 +372,6 @@ static qboolean R_SetDisplayTransform( ref_screen_rotation_t rotate, int offset_
return ret; return ret;
} }
static void GAME_EXPORT VGUI_UploadTextureBlock( int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight )
{
pglTexSubImage2D( GL_TEXTURE_2D, 0, drawX, drawY, blockWidth, blockHeight, GL_RGBA, GL_UNSIGNED_BYTE, rgba );
}
static void GAME_EXPORT VGUI_SetupDrawing( qboolean rect ) static void GAME_EXPORT VGUI_SetupDrawing( qboolean rect )
{ {
pglEnable( GL_BLEND ); pglEnable( GL_BLEND );
@@ -427,7 +411,86 @@ static const char *R_GetConfigName( void )
return "opengl"; return "opengl";
} }
static const ref_interface_t gReffuncs = static void R_NewMap( void )
{
texture_t *tx;
int i;
tr.worldmodel = gp_cl->models[1];
R_ClearDecals(); // clear all level decals
R_StudioResetPlayerModels();
// clear out efrags in case the level hasn't been reloaded
for( i = 0; i < WORLDMODEL->numleafs; i++ )
WORLDMODEL->leafs[i+1].efrags = NULL;
glState.isFogEnabled = false;
tr.skytexturenum = -1;
pglDisable( GL_FOG );
// clearing texture chains
for( i = 0; i < WORLDMODEL->numtextures; i++ )
{
if( !WORLDMODEL->textures[i] )
continue;
tx = WORLDMODEL->textures[i];
if( !Q_strncmp( tx->name, "sky", 3 ) && tx->width == ( tx->height * 2 ))
tr.skytexturenum = i;
tx->texturechain = NULL;
}
GL_BuildLightmaps ();
R_ClearVBO();
if( R_HasEnabledVBO( ))
R_GenerateVBO();
R_ResetRipples();
if( gEngfuncs.drawFuncs->R_NewMap != NULL )
gEngfuncs.drawFuncs->R_NewMap();
}
static void R_FillRenderAPI( render_api_t *api )
{
api->GetExtraParmsForTexture = R_GetExtraParmsForTexture;
api->GetFrameTime = R_GetFrameTime;
api->R_SetCurrentEntity = R_SetCurrentEntity;
api->R_SetCurrentModel = R_SetCurrentModel;
api->GL_CreateTexture = GL_CreateTexture;
api->GL_LoadTextureArray = GL_LoadTextureArray;
api->GL_CreateTextureArray = GL_CreateTextureArray;
api->DrawSingleDecal = DrawSingleDecal;
api->R_DecalSetupVerts = R_DecalSetupVerts;
api->R_EntityRemoveDecals = R_EntityRemoveDecals;
api->GL_SelectTexture = GL_SelectTexture;
api->GL_LoadTextureMatrix = GL_LoadTexMatrixExt;
api->GL_TexMatrixIdentity = GL_LoadIdentityTexMatrix;
api->GL_CleanUpTextureUnits = GL_CleanUpTextureUnits;
api->GL_TexGen = GL_TexGen;
api->GL_TextureTarget = GL_TextureTarget;
api->GL_TexCoordArrayMode = GL_SetTexCoordArrayMode;
api->GL_UpdateTexSize = GL_UpdateTexSize;
api->GL_DrawParticles = CL_DrawParticlesExternal;
api->LightVec = R_LightVec;
api->StudioGetTexture = R_StudioGetTexture;
api->GL_GetProcAddress = R_GetProcAddress;
}
static void R_FillTriAPI( triangleapi_t *api )
{
api->TexCoord2f = TriTexCoord2f;
api->Fog = TriFog;
api->ScreenToWorld = R_ScreenToWorld;
api->GetMatrix = TriGetMatrix;
api->FogParams = TriFogParams;
}
const ref_interface_t gReffuncs =
{ {
R_Init, R_Init,
R_Shutdown, R_Shutdown,
@@ -452,9 +515,7 @@ static const ref_interface_t gReffuncs =
GL_SetRenderMode, GL_SetRenderMode,
R_AddEntity, R_AddEntity,
CL_AddCustomBeam,
R_ProcessEntData, R_ProcessEntData,
R_Flush,
R_ShowTextures, R_ShowTextures,
@@ -464,7 +525,6 @@ static const ref_interface_t gReffuncs =
R_SetupSky, R_SetupSky,
R_Set2DMode, R_Set2DMode,
R_DrawStretchRaw,
R_DrawStretchPic, R_DrawStretchPic,
CL_FillRGBA, CL_FillRGBA,
R_WorldToScreen, R_WorldToScreen,
@@ -481,14 +541,13 @@ static const ref_interface_t gReffuncs =
R_StudioEstimateFrame, R_StudioEstimateFrame,
R_StudioLerpMovement, R_StudioLerpMovement,
CL_InitStudioAPI, R_StudioFillAPI,
R_StudioSetDrawInterface,
R_SetSkyCloudsTextures, R_SetSkyCloudsTextures,
GL_SubdivideSurface, GL_SubdivideSurface,
CL_RunLightStyles, CL_RunLightStyles,
R_GetSpriteParms,
R_GetSpriteTexture,
Mod_ProcessRenderData, Mod_ProcessRenderData,
Mod_StudioLoadTextures, Mod_StudioLoadTextures,
@@ -496,47 +555,23 @@ static const ref_interface_t gReffuncs =
CL_DrawParticles, CL_DrawParticles,
CL_DrawTracers, CL_DrawTracers,
CL_DrawBeams, CL_DrawBeams,
R_BeamCull,
GL_RefGetParm, GL_RefGetParm,
R_GetDetailScaleForTexture, R_GetDetailScaleForTexture,
R_GetExtraParmsForTexture, R_SetDetailScaleForTexture,
R_GetFrameTime,
R_SetCurrentEntity,
R_SetCurrentModel,
GL_CreateTexture,
GL_FindTexture, GL_FindTexture,
GL_TextureName, GL_TextureName,
GL_TextureData, GL_TextureData,
GL_LoadTexture, GL_LoadTexture,
GL_CreateTexture,
GL_LoadTextureArray,
GL_CreateTextureArray,
GL_FreeTexture, GL_FreeTexture,
R_OverrideTextureSourceSize, R_OverrideTextureSourceSize,
DrawSingleDecal, GL_UpdateTexture,
R_DecalSetupVerts,
R_EntityRemoveDecals,
R_UploadStretchRaw,
GL_Bind, GL_Bind,
GL_SelectTexture,
GL_LoadTexMatrixExt,
GL_LoadIdentityTexMatrix,
GL_CleanUpTextureUnits,
GL_TexGen,
GL_TextureTarget,
GL_SetTexCoordArrayMode,
GL_UpdateTexSize,
NULL,
NULL,
CL_DrawParticlesExternal,
R_LightVec,
R_StudioGetTexture,
R_RenderFrame, R_RenderFrame,
Mod_SetOrthoBounds, Mod_SetOrthoBounds,
@@ -544,39 +579,19 @@ static const ref_interface_t gReffuncs =
Mod_GetCurrentVis, Mod_GetCurrentVis,
R_NewMap, R_NewMap,
R_ClearScene, R_ClearScene,
R_GetProcAddress,
TriRenderMode, TriRenderMode,
TriBegin, TriBegin,
TriEnd, TriEnd,
_TriColor4f, _TriColor4f,
_TriColor4ub, _TriColor4ub,
TriTexCoord2f,
TriVertex3fv, TriVertex3fv,
TriVertex3f, TriVertex3f,
TriFog,
R_ScreenToWorld,
TriGetMatrix,
TriFogParams,
TriCullFace, TriCullFace,
R_FillRenderAPI,
R_FillTriAPI,
VGUI_SetupDrawing, VGUI_SetupDrawing,
VGUI_UploadTextureBlock,
}; };
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals );
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals )
{
if( version != REF_API_VERSION )
return 0;
// fill in our callbacks
*funcs = gReffuncs;
gEngfuncs = *engfuncs;
gpGlobals = globals;
gp_cl = (ref_client_t *)ENGINE_GET_PARM( PARM_GET_CLIENT_PTR );
gp_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR );
return REF_API_VERSION;
}

View File

@@ -47,7 +47,7 @@ qboolean R_CullModel( const cl_entity_t *e, const vec3_t absmin, const vec3_t ab
if( ENGINE_GET_PARM( PARM_DEV_OVERVIEW )) if( ENGINE_GET_PARM( PARM_DEV_OVERVIEW ))
return true; return true;
if( RP_NORMALPASS() && !ENGINE_GET_PARM( PARM_THIRDPERSON ) && CL_IsViewEntityLocalPlayer()) if( !FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ) && !ENGINE_GET_PARM( PARM_THIRDPERSON ) && CL_IsViewEntityLocalPlayer())
return false; return false;
return true; return true;
@@ -85,7 +85,7 @@ int R_CullSurface( const msurface_t *surf, const gl_frustum_t *frustum, uint cli
float dist; float dist;
// can use normal.z for world (optimisation) // can use normal.z for world (optimisation)
if( RI.drawOrtho ) if( FBitSet( RI.rvp.flags, RF_DRAW_OVERVIEW ))
{ {
vec3_t orthonormal; vec3_t orthonormal;

View File

@@ -29,34 +29,6 @@ void R_GetTextureParms( int *w, int *h, int texnum )
if( h ) *h = glt->srcHeight; if( h ) *h = glt->srcHeight;
} }
/*
=============
R_GetSpriteParms
same as GetImageParms but used
for sprite models
=============
*/
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite )
{
mspriteframe_t *pFrame;
if( !pSprite || pSprite->type != mod_sprite ) return; // bad model ?
pFrame = R_GetSpriteFrame( pSprite, currentFrame, 0.0f );
if( frameWidth ) *frameWidth = pFrame->width;
if( frameHeight ) *frameHeight = pFrame->height;
if( numFrames ) *numFrames = pSprite->numframes;
}
int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
if( !m_pSpriteModel || m_pSpriteModel->type != mod_sprite || !m_pSpriteModel->cache.data )
return 0;
return R_GetSpriteFrame( m_pSpriteModel, frame, 0.0f )->gl_texturenum;
}
/* /*
============= =============
R_DrawStretchPic R_DrawStretchPic
@@ -83,120 +55,69 @@ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, f
/* /*
============= =============
R_DrawStretchRaw GL_UpdateTexture
============= =============
*/ */
void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) void GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt )
{ {
byte *raw = NULL; byte *raw = NULL;
gl_texture_t *tex; gl_texture_t *tex;
GLenum gl_format;
switch( fmt )
{
case PF_RGBA_32:
gl_format = GL_RGBA;
break;
case PF_BGRA_32:
gl_format = GL_BGRA;
break;
case PF_RGB_24:
gl_format = GL_RGB;
break;
case PF_BGR_24:
gl_format = GL_BGR;
break;
case PF_LUMINANCE:
gl_format = GL_LUMINANCE;
break;
default:
gEngfuncs.Con_DPrintf( S_ERROR "%s: unsupported pixel format %i\n", __func__, fmt );
return;
}
if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT )) if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT ))
{ {
int width = 1, height = 1;
// check the dimensions
width = NearestPOW( cols, true );
height = NearestPOW( rows, false );
if( cols != width || rows != height )
{
raw = GL_ResampleTexture( data, cols, rows, width, height, false );
cols = width;
rows = height;
}
}
else
{
raw = (byte *)data;
}
if( cols > glConfig.max_2d_texture_size )
gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, cols );
if( rows > glConfig.max_2d_texture_size )
gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, rows );
pglDisable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
tex = R_GetTexture( tr.cinTexture );
GL_Bind( XASH_TEXTURE0, tr.cinTexture );
if( cols == tex->width && rows == tex->height )
{
if( dirty )
{
pglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_BGRA, GL_UNSIGNED_BYTE, raw );
}
}
else
{
tex->size = cols * rows * 4;
tex->width = cols;
tex->height = rows;
if( dirty )
{
pglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw );
}
}
pglBegin( GL_QUADS );
pglTexCoord2f( 0, 0 );
pglVertex2f( x, y );
pglTexCoord2f( 1, 0 );
pglVertex2f( x + w, y );
pglTexCoord2f( 1, 1 );
pglVertex2f( x + w, y + h );
pglTexCoord2f( 0, 1 );
pglVertex2f( x, y + h );
pglEnd();
}
/*
=============
R_UploadStretchRaw
=============
*/
void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data )
{
byte *raw = NULL;
gl_texture_t *tex;
if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT ))
{
// check the dimensions
width = NearestPOW( width, true ); width = NearestPOW( width, true );
height = NearestPOW( height, false ); height = NearestPOW( height, false );
} }
else
{
width = bound( 128, width, glConfig.max_2d_texture_size );
height = bound( 128, height, glConfig.max_2d_texture_size );
}
if( cols != width || rows != height ) if( cols != width || rows != height )
{ {
raw = GL_ResampleTexture( data, cols, rows, width, height, false ); raw = GL_ResampleTexture( buffer, cols, rows, width, height, false );
cols = width; cols = width;
rows = height; rows = height;
} }
else else
{ raw = (byte *)buffer;
raw = (byte *)data;
}
if( cols > glConfig.max_2d_texture_size ) if( cols > glConfig.max_2d_texture_size )
gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, cols ); gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, cols );
if( rows > glConfig.max_2d_texture_size ) if( rows > glConfig.max_2d_texture_size )
gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, rows ); gEngfuncs.Host_Error( "%s: size %i exceeds hardware limits\n", __func__, rows );
tex = R_GetTexture( texture ); tex = R_GetTexture( texnum );
GL_Bind( GL_KEEP_UNIT, texture ); GL_Bind( GL_KEEP_UNIT, texnum );
tex->width = cols;
tex->height = rows; if( cols == tex->width && rows == tex->height )
pglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, gl_format, GL_UNSIGNED_BYTE, raw );
else
{
tex->width = cols;
tex->height = rows;
pglTexImage2D( GL_TEXTURE_2D, 0, tex->format, cols, rows, 0, gl_format, GL_UNSIGNED_BYTE, raw );
}
pglTexImage2D( GL_TEXTURE_2D, 0, tex->format, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw );
GL_ApplyTextureParams( tex ); GL_ApplyTextureParams( tex );
} }

View File

@@ -23,19 +23,6 @@ static gl_texture_t gl_textures[MAX_TEXTURES];
static gl_texture_t* gl_texturesHashTable[TEXTURES_HASH_SIZE]; static gl_texture_t* gl_texturesHashTable[TEXTURES_HASH_SIZE];
static uint gl_numTextures; static uint gl_numTextures;
static byte dottexture[8][8] =
{
{0,1,1,0,0,0,0,0},
{1,1,1,1,0,0,0,0},
{1,1,1,1,0,0,0,0},
{0,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
};
#define IsLightMap( tex ) ( FBitSet(( tex )->flags, TF_ATLAS_PAGE )) #define IsLightMap( tex ) ( FBitSet(( tex )->flags, TF_ATLAS_PAGE ))
/* /*
================= =================
@@ -691,97 +678,6 @@ static void GL_SetTextureFormat( gl_texture_t *tex, pixformat_t format, int chan
} }
} }
/*
=================
GL_ResampleTexture
Assume input buffer is RGBA
=================
*/
byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int outWidth, int outHeight, qboolean isNormalMap )
{
uint frac, fracStep;
uint *in = (uint *)source;
uint p1[0x1000], p2[0x1000];
byte *pix1, *pix2, *pix3, *pix4;
uint *out, *inRow1, *inRow2;
static byte *scaledImage = NULL; // pointer to a scaled image
vec3_t normal;
int i, x, y;
if( !source ) return NULL;
scaledImage = Mem_Realloc( r_temppool, scaledImage, outWidth * outHeight * 4 );
fracStep = inWidth * 0x10000 / outWidth;
out = (uint *)scaledImage;
frac = fracStep >> 2;
for( i = 0; i < outWidth; i++ )
{
p1[i] = 4 * (frac >> 16);
frac += fracStep;
}
frac = (fracStep >> 2) * 3;
for( i = 0; i < outWidth; i++ )
{
p2[i] = 4 * (frac >> 16);
frac += fracStep;
}
if( isNormalMap )
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f) * inHeight / outHeight);
inRow2 = in + inWidth * (int)(((float)y + 0.75f) * inHeight / outHeight);
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
normal[0] = MAKE_SIGNED( pix1[0] ) + MAKE_SIGNED( pix2[0] ) + MAKE_SIGNED( pix3[0] ) + MAKE_SIGNED( pix4[0] );
normal[1] = MAKE_SIGNED( pix1[1] ) + MAKE_SIGNED( pix2[1] ) + MAKE_SIGNED( pix3[1] ) + MAKE_SIGNED( pix4[1] );
normal[2] = MAKE_SIGNED( pix1[2] ) + MAKE_SIGNED( pix2[2] ) + MAKE_SIGNED( pix3[2] ) + MAKE_SIGNED( pix4[2] );
if( !VectorNormalizeLength( normal ))
VectorSet( normal, 0.5f, 0.5f, 1.0f );
((byte *)(out+x))[0] = 128 + (byte)(127.0f * normal[0]);
((byte *)(out+x))[1] = 128 + (byte)(127.0f * normal[1]);
((byte *)(out+x))[2] = 128 + (byte)(127.0f * normal[2]);
((byte *)(out+x))[3] = 255;
}
}
}
else
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f) * inHeight / outHeight);
inRow2 = in + inWidth * (int)(((float)y + 0.75f) * inHeight / outHeight);
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
((byte *)(out+x))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0]) >> 2;
((byte *)(out+x))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1]) >> 2;
((byte *)(out+x))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2]) >> 2;
((byte *)(out+x))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3]) >> 2;
}
}
}
return scaledImage;
}
/* /*
================= =================
GL_BoxFilter3x3 GL_BoxFilter3x3
@@ -1790,7 +1686,20 @@ int GL_CreateTexture( const char *name, int width, int height, const void *buffe
r_empty.size *= 6; r_empty.size *= 6;
} }
return GL_LoadTextureFromBuffer( name, &r_empty, flags, update ); int texnum = GL_LoadTextureFromBuffer( name, &r_empty, flags, update );
if( !Q_strcmp( name, REF_DEFAULT_TEXTURE ))
tr.defaultTexture = texnum;
else if( !Q_strcmp( name, REF_PARTICLE_TEXTURE ))
tr.particleTexture = texnum;
else if( !Q_strcmp( name, REF_WHITE_TEXTURE ))
tr.whiteTexture = texnum;
else if( !Q_strcmp( name, REF_GRAY_TEXTURE ))
tr.grayTexture = texnum;
else if( !Q_strcmp( name, REF_BLACK_TEXTURE ))
tr.blackTexture = texnum;
return texnum;
} }
/* /*
@@ -2003,70 +1912,6 @@ void R_InitDlightTexture( void )
tr.dlightTexture = GL_LoadTextureFromBuffer( "*dlight", &r_image, TF_NOMIPMAP|TF_CLAMP|TF_ATLAS_PAGE, update ); tr.dlightTexture = GL_LoadTextureFromBuffer( "*dlight", &r_image, TF_NOMIPMAP|TF_CLAMP|TF_ATLAS_PAGE, update );
} }
/*
==================
GL_CreateInternalTextures
==================
*/
static void GL_CreateInternalTextures( void )
{
int dx2, dy, d;
int x, y;
rgbdata_t *pic;
// emo-texture from quake1
pic = GL_FakeImage( 16, 16, 1, IMAGE_HAS_COLOR );
for( y = 0; y < 16; y++ )
{
for( x = 0; x < 16; x++ )
{
if(( y < 8 ) ^ ( x < 8 ))
((uint *)pic->buffer)[y*16+x] = 0xFFFF00FF;
else ((uint *)pic->buffer)[y*16+x] = 0xFF000000;
}
}
tr.defaultTexture = GL_LoadTextureInternal( REF_DEFAULT_TEXTURE, pic, TF_COLORMAP );
// particle texture from quake1
pic = GL_FakeImage( 8, 8, 1, IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA );
for( x = 0; x < 8; x++ )
{
for( y = 0; y < 8; y++ )
{
if( dottexture[x][y] )
pic->buffer[( y * 8 + x ) * 4 + 3] = 255;
else pic->buffer[( y * 8 + x ) * 4 + 3] = 0;
}
}
tr.particleTexture = GL_LoadTextureInternal( REF_PARTICLE_TEXTURE, pic, TF_CLAMP );
// white texture
pic = GL_FakeImage( 4, 4, 1, IMAGE_HAS_COLOR );
for( x = 0; x < 16; x++ )
((uint *)pic->buffer)[x] = 0xFFFFFFFF;
tr.whiteTexture = GL_LoadTextureInternal( REF_WHITE_TEXTURE, pic, TF_COLORMAP );
// gray texture
pic = GL_FakeImage( 4, 4, 1, IMAGE_HAS_COLOR );
for( x = 0; x < 16; x++ )
((uint *)pic->buffer)[x] = 0xFF7F7F7F;
tr.grayTexture = GL_LoadTextureInternal( REF_GRAY_TEXTURE, pic, TF_COLORMAP );
// black texture
pic = GL_FakeImage( 4, 4, 1, IMAGE_HAS_COLOR );
for( x = 0; x < 16; x++ )
((uint *)pic->buffer)[x] = 0xFF000000;
tr.blackTexture = GL_LoadTextureInternal( REF_BLACK_TEXTURE, pic, TF_COLORMAP );
// cinematic dummy
pic = GL_FakeImage( 640, 100, 1, IMAGE_HAS_COLOR );
tr.cinTexture = GL_LoadTextureInternal( "*cintexture", pic, TF_NOMIPMAP|TF_CLAMP );
}
/* /*
=============== ===============
R_TextureList_f R_TextureList_f
@@ -2299,7 +2144,6 @@ void R_InitImages( void )
// validate cvars // validate cvars
R_SetTextureParameters(); R_SetTextureParameters();
GL_CreateInternalTextures();
gEngfuncs.Cmd_AddCommand( "texturelist", R_TextureList_f, "display loaded textures list" ); gEngfuncs.Cmd_AddCommand( "texturelist", R_TextureList_f, "display loaded textures list" );
} }

View File

@@ -15,17 +15,12 @@ GNU General Public License for more details.
#ifndef GL_LOCAL_H #ifndef GL_LOCAL_H
#define GL_LOCAL_H #define GL_LOCAL_H
#include "ref_common.h"
#include "port.h" #include "port.h"
#include "xash3d_types.h" #include "xash3d_types.h"
#include "cvardef.h" #include "cvardef.h"
#include "const.h"
#include "com_model.h"
#include "cl_entity.h"
#include "render_api.h"
#include "protocol.h" #include "protocol.h"
#include "gl_frustum.h" #include "gl_frustum.h"
#include "ref_api.h"
#include "xash3d_mathlib.h"
#include "ref_params.h" #include "ref_params.h"
#include "enginefeatures.h" #include "enginefeatures.h"
#include "com_strings.h" #include "com_strings.h"
@@ -52,7 +47,6 @@ void VGL_ShimEndFrame( void );
#endif #endif
#endif #endif
#define Assert(x) if(!( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ )
#include <stdio.h> #include <stdio.h>
@@ -60,7 +54,6 @@ void VGL_ShimEndFrame( void );
#define LM_SAMPLE_SIZE 16 #define LM_SAMPLE_SIZE 16
extern poolhandle_t r_temppool;
#define BLOCK_SIZE tr.block_size // lightmap blocksize #define BLOCK_SIZE tr.block_size // lightmap blocksize
#define BLOCK_SIZE_DEFAULT 128 // for keep backward compatibility #define BLOCK_SIZE_DEFAULT 128 // for keep backward compatibility
@@ -77,17 +70,9 @@ extern poolhandle_t r_temppool;
#define SHADE_LAMBERT 1.4953241 #define SHADE_LAMBERT 1.4953241
#define DEFAULT_ALPHATEST 0.0f #define DEFAULT_ALPHATEST 0.0f
// refparams
#define RP_NONE 0
#define RP_ENVVIEW BIT( 0 ) // used for cubemapshot
#define RP_OLDVIEWLEAF BIT( 1 )
#define RP_CLIPPLANE BIT( 2 )
#define RP_NONVIEWERREF (RP_ENVVIEW)
#define R_ModelOpaque( rm ) ( rm == kRenderNormal ) #define R_ModelOpaque( rm ) ( rm == kRenderNormal )
#define R_StaticEntity( ent ) ( VectorIsNull( ent->origin ) && VectorIsNull( ent->angles )) #define R_StaticEntity( ent ) ( VectorIsNull( ent->origin ) && VectorIsNull( ent->angles ))
#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( gp_cl->playernum + 1 ) && e->player ) #define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( gp_cl->playernum + 1 ) && e->player )
#define RP_NORMALPASS() ( FBitSet( RI.params, RP_NONVIEWERREF ) == 0 )
#define CL_IsViewEntityLocalPlayer() ( gp_cl->viewentity == ( gp_cl->playernum + 1 )) #define CL_IsViewEntityLocalPlayer() ( gp_cl->viewentity == ( gp_cl->playernum + 1 ))
@@ -134,27 +119,16 @@ typedef struct gltexture_s
typedef struct typedef struct
{ {
int params; // rendering parameters ref_viewpass_t rvp;
qboolean drawWorld; // ignore world for drawing PlayerModel
qboolean isSkyVisible; // sky is visible
qboolean onlyClientDraw; // disabled by client request
qboolean drawOrtho; // draw world as orthogonal projection
float fov_x, fov_y; // current view fov
cl_entity_t *currententity; cl_entity_t *currententity;
model_t *currentmodel; model_t *currentmodel;
cl_entity_t *currentbeam; // same as above but for beams cl_entity_t *currentbeam; // same as above but for beams
int viewport[4];
gl_frustum_t frustum; gl_frustum_t frustum;
mleaf_t *viewleaf; mleaf_t *viewleaf;
mleaf_t *oldviewleaf; mleaf_t *oldviewleaf;
vec3_t pvsorigin;
vec3_t vieworg; // locked vieworigin
vec3_t viewangles;
vec3_t vforward; vec3_t vforward;
vec3_t vright; vec3_t vright;
vec3_t vup; vec3_t vup;
@@ -213,8 +187,6 @@ typedef struct
int lightmapTextures[MAX_LIGHTMAPS]; int lightmapTextures[MAX_LIGHTMAPS];
int dlightTexture; // custom dlight texture int dlightTexture; // custom dlight texture
int skyboxTextures[SKYBOX_MAX_SIDES]; // skybox sides int skyboxTextures[SKYBOX_MAX_SIDES]; // skybox sides
int cinTexture; // cinematic texture
int skytexturenum; // this not a gl_texturenum! int skytexturenum; // this not a gl_texturenum!
int skyboxbasenum; // start with 5800 int skyboxbasenum; // start with 5800
@@ -239,7 +211,6 @@ typedef struct
qboolean fFlipViewModel; qboolean fFlipViewModel;
byte visbytes[(MAX_MAP_LEAFS+7)/8]; // member custom PVS byte visbytes[(MAX_MAP_LEAFS+7)/8]; // member custom PVS
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
int block_size; // lightmap blocksize int block_size; // lightmap blocksize
double frametime; // special frametime for multipass rendering (will set to 0 on a nextview) double frametime; // special frametime for multipass rendering (will set to 0 on a nextview)
@@ -255,7 +226,6 @@ typedef struct
movevars_t *movevars; movevars_t *movevars;
color24 *palette; color24 *palette;
cl_entity_t *viewent; cl_entity_t *viewent;
dlight_t *dlights;
dlight_t *elights; dlight_t *elights;
byte *texgammatable; byte *texgammatable;
uint *lightgammatable; uint *lightgammatable;
@@ -324,7 +294,6 @@ void SCR_TimeRefresh_f( void );
// gl_beams.c // gl_beams.c
// //
void CL_DrawBeams( int fTrans, BEAM *active_beams ); void CL_DrawBeams( int fTrans, BEAM *active_beams );
qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly );
// //
// gl_cull.c // gl_cull.c
@@ -347,7 +316,7 @@ void R_ClearDecals( void );
// gl_draw.c // gl_draw.c
// //
void R_Set2DMode( qboolean enable ); void R_Set2DMode( qboolean enable );
void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ); void GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt );
// //
// gl_image.c // gl_image.c
@@ -359,7 +328,6 @@ gl_texture_t *R_GetTexture( unsigned int texnum );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags ); int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags );
int GL_LoadTextureArray( const char **names, int flags ); int GL_LoadTextureArray( const char **names, int flags );
int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update ); int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags ); int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags );
int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags ); int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags );
void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor ); void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor );
@@ -377,16 +345,6 @@ qboolean R_SearchForTextureReplacement( char *out, size_t size, const char *mode
void R_TextureReplacementReport( const char *modelname, int gl_texturenum, const char *foundpath ); void R_TextureReplacementReport( const char *modelname, int gl_texturenum, const char *foundpath );
void R_ShowTextures( void ); void R_ShowTextures( void );
//
// gl_rlight.c
//
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlights( void );
void R_GetLightSpot( vec3_t lightspot );
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
colorVec R_LightPoint( const vec3_t p0 );
// //
// gl_rmain.c // gl_rmain.c
// //
@@ -408,21 +366,6 @@ void R_DrawFog( void );
int CL_FxBlend( cl_entity_t *e ); int CL_FxBlend( cl_entity_t *e );
// //
// gl_rmath.c
//
void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] );
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z );
void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z );
void Matrix4x4_CreateProjection(matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar);
void Matrix4x4_CreateOrtho(matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar);
void Matrix4x4_CreateModelview( matrix4x4 out );
//
// gl_rmisc.c
//
void R_NewMap( void );
// //
// gl_rsurf.c // gl_rsurf.c
// //
@@ -434,7 +377,6 @@ void GL_SubdivideSurface( model_t *mod, msurface_t *fa );
void GL_SetupFogColorForSurfaces( void ); void GL_SetupFogColorForSurfaces( void );
void R_DrawAlphaTextureChains( void ); void R_DrawAlphaTextureChains( void );
void GL_RebuildLightmaps( void ); void GL_RebuildLightmaps( void );
void GL_InitRandomTable( void );
void GL_BuildLightmaps( void ); void GL_BuildLightmaps( void );
void GL_ResetFogColor( void ); void GL_ResetFogColor( void );
void R_GenerateVBO( void ); void R_GenerateVBO( void );
@@ -456,9 +398,6 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers );
// //
// gl_sprite.c // gl_sprite.c
// //
void R_SpriteInit( void );
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags );
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw );
void R_DrawSpriteModel( cl_entity_t *e ); void R_DrawSpriteModel( cl_entity_t *e );
// //
@@ -470,11 +409,11 @@ struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e );
int R_GetEntityRenderMode( cl_entity_t *ent ); int R_GetEntityRenderMode( cl_entity_t *ent );
void R_DrawStudioModel( cl_entity_t *e ); void R_DrawStudioModel( cl_entity_t *e );
player_info_t *pfnPlayerInfo( int index ); player_info_t *pfnPlayerInfo( int index );
void R_GatherPlayerLight( void );
float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time ); float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time );
void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles );
void R_StudioResetPlayerModels( void ); void R_StudioResetPlayerModels( void );
void CL_InitStudioAPI( void ); qboolean R_StudioFillAPI( struct engine_studio_api_s *api, struct r_studio_interface_s *pDefaultDraw );
void R_StudioSetDrawInterface( struct r_studio_interface_s *pDraw );
void Mod_StudioLoadTextures( model_t *mod, void *data ); void Mod_StudioLoadTextures( model_t *mod, void *data );
void Mod_StudioUnloadTextures( void *data ); void Mod_StudioUnloadTextures( void *data );
@@ -517,28 +456,23 @@ void R_RenderFrame( const struct ref_viewpass_s *vp );
void R_EndFrame( void ); void R_EndFrame( void );
void R_ClearScene( void ); void R_ClearScene( void );
void R_GetTextureParms( int *w, int *h, int texnum ); void R_GetTextureParms( int *w, int *h, int texnum );
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int curFrame, const struct model_s *pSprite );
void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty );
void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ); void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum );
qboolean R_SpeedsMessage( char *out, size_t size ); qboolean R_SpeedsMessage( char *out, size_t size );
qboolean R_CullBox( const vec3_t mins, const vec3_t maxs ); qboolean R_CullBox( const vec3_t mins, const vec3_t maxs );
int R_WorldToScreen( const vec3_t point, vec3_t screen ); int R_WorldToScreen( const vec3_t point, vec3_t screen );
void R_ScreenToWorld( const vec3_t screen, vec3_t point ); void R_ScreenToWorld( const vec3_t screen, vec3_t point );
qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType ); qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType );
void Mod_SpriteUnloadTextures( void *data );
void Mod_UnloadAliasModel( struct model_s *mod ); void Mod_UnloadAliasModel( struct model_s *mod );
void Mod_AliasUnloadTextures( void *data ); void Mod_AliasUnloadTextures( void *data );
void GL_SetRenderMode( int mode ); void GL_SetRenderMode( int mode );
void R_RunViewmodelEvents( void ); void R_RunViewmodelEvents( void );
void R_DrawViewModel( void ); void R_DrawViewModel( void );
int R_GetSpriteTexture( const struct model_s *m_pSpriteModel, int frame );
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, float scale ); void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, float scale );
void R_DecalRemoveAll( int texture ); void R_DecalRemoveAll( int texture );
int R_CreateDecalList( decallist_t *pList ); int R_CreateDecalList( decallist_t *pList );
void R_ClearAllDecals( void ); void R_ClearAllDecals( void );
byte *Mod_GetCurrentVis( void ); byte *Mod_GetCurrentVis( void );
void Mod_SetOrthoBounds( const float *mins, const float *maxs ); void Mod_SetOrthoBounds( const float *mins, const float *maxs );
void CL_AddCustomBeam( cl_entity_t *pEnvBeam );
// //
// gl_opengl.c // gl_opengl.c
@@ -698,13 +632,6 @@ extern glconfig_t glConfig;
extern glstate_t glState; extern glstate_t glState;
// move to engine // move to engine
extern glwstate_t glw_state; extern glwstate_t glw_state;
extern ref_api_t gEngfuncs;
extern ref_globals_t *gpGlobals;
extern ref_client_t *gp_cl;
extern ref_host_t *gp_host;
#define ENGINE_GET_PARM_ (*gEngfuncs.EngineGetParm)
#define ENGINE_GET_PARM( parm ) ENGINE_GET_PARM_( ( parm ), 0 )
// //
// helper funcs // helper funcs
@@ -794,7 +721,6 @@ extern convar_t gl_stencilbits;
extern convar_t gl_overbright; extern convar_t gl_overbright;
extern convar_t gl_fog; extern convar_t gl_fog;
extern convar_t r_lighting_extended;
extern convar_t r_lighting_ambient; extern convar_t r_lighting_ambient;
extern convar_t r_studio_lambert; extern convar_t r_studio_lambert;
extern convar_t r_detailtextures; extern convar_t r_detailtextures;
@@ -814,28 +740,16 @@ extern convar_t r_ripple;
extern convar_t r_ripple_updatetime; extern convar_t r_ripple_updatetime;
extern convar_t r_ripple_spawntime; extern convar_t r_ripple_spawntime;
extern convar_t r_large_lightmaps; extern convar_t r_large_lightmaps;
extern convar_t r_dlight_virtual_radius;
// //
// engine shared convars // engine shared convars
// //
DECLARE_ENGINE_SHARED_CVAR_LIST()
// //
// engine callbacks // engine callbacks
// //
#include "crtlib.h" #include "crtlib.h"
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) gEngfuncs._Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )
#endif // GL_LOCAL_H #endif // GL_LOCAL_H

View File

@@ -22,7 +22,6 @@ CVAR_DEFINE_AUTO( gl_msaa, "1", FCVAR_GLCONFIG, "enable or disable multisample a
CVAR_DEFINE_AUTO( gl_stencilbits, "8", FCVAR_GLCONFIG|FCVAR_READ_ONLY, "pixelformat stencil bits (0 - auto)" ); CVAR_DEFINE_AUTO( gl_stencilbits, "8", FCVAR_GLCONFIG|FCVAR_READ_ONLY, "pixelformat stencil bits (0 - auto)" );
CVAR_DEFINE_AUTO( gl_overbright, "1", FCVAR_GLCONFIG, "overbrights" ); CVAR_DEFINE_AUTO( gl_overbright, "1", FCVAR_GLCONFIG, "overbrights" );
CVAR_DEFINE_AUTO( gl_fog, "1", FCVAR_GLCONFIG, "allow for rendering fog using built-in OpenGL fog implementation" ); CVAR_DEFINE_AUTO( gl_fog, "1", FCVAR_GLCONFIG, "allow for rendering fog using built-in OpenGL fog implementation" );
CVAR_DEFINE_AUTO( r_lighting_extended, "1", FCVAR_GLCONFIG, "allow to get lighting from world and bmodels" );
CVAR_DEFINE_AUTO( r_lighting_ambient, "0.3", FCVAR_GLCONFIG, "map ambient lighting scale" ); CVAR_DEFINE_AUTO( r_lighting_ambient, "0.3", FCVAR_GLCONFIG, "map ambient lighting scale" );
CVAR_DEFINE_AUTO( r_detailtextures, "1", FCVAR_GLCONFIG, "enable detail textures support" ); CVAR_DEFINE_AUTO( r_detailtextures, "1", FCVAR_GLCONFIG, "enable detail textures support" );
CVAR_DEFINE_AUTO( r_novis, "0", 0, "ignore vis information (perfomance test)" ); CVAR_DEFINE_AUTO( r_novis, "0", 0, "ignore vis information (perfomance test)" );
@@ -39,11 +38,7 @@ CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water tex
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" ); CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" ); CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
CVAR_DEFINE_AUTO( r_large_lightmaps, "0", FCVAR_GLCONFIG|FCVAR_LATCH, "enable larger lightmap atlas textures (might break custom renderer mods)" ); CVAR_DEFINE_AUTO( r_large_lightmaps, "0", FCVAR_GLCONFIG|FCVAR_LATCH, "enable larger lightmap atlas textures (might break custom renderer mods)" );
CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount, should help against ugly cut off dlights on highly scaled textures" );
DEFINE_ENGINE_SHARED_CVAR_LIST()
poolhandle_t r_temppool;
gl_globals_t tr; gl_globals_t tr;
glconfig_t glConfig; glconfig_t glConfig;
@@ -1141,9 +1136,6 @@ GL_InitCommands
*/ */
static void GL_InitCommands( void ) static void GL_InitCommands( void )
{ {
RETRIEVE_ENGINE_SHARED_CVAR_LIST();
gEngfuncs.Cvar_RegisterVariable( &r_lighting_extended );
gEngfuncs.Cvar_RegisterVariable( &r_lighting_ambient ); gEngfuncs.Cvar_RegisterVariable( &r_lighting_ambient );
gEngfuncs.Cvar_RegisterVariable( &r_novis ); gEngfuncs.Cvar_RegisterVariable( &r_novis );
gEngfuncs.Cvar_RegisterVariable( &r_nocull ); gEngfuncs.Cvar_RegisterVariable( &r_nocull );
@@ -1162,7 +1154,6 @@ static void GL_InitCommands( void )
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode ); gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail ); gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
gEngfuncs.Cvar_RegisterVariable( &r_large_lightmaps ); gEngfuncs.Cvar_RegisterVariable( &r_large_lightmaps );
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );
gEngfuncs.Cvar_RegisterVariable( &gl_extensions ); gEngfuncs.Cvar_RegisterVariable( &gl_extensions );
gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest ); gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest );
@@ -1276,13 +1267,11 @@ qboolean R_Init( void )
tr.lightgammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LIGHTGAMMATABLE_PTR ); tr.lightgammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LIGHTGAMMATABLE_PTR );
tr.screengammatable = (uint *)ENGINE_GET_PARM( PARM_GET_SCREENGAMMATABLE_PTR ); tr.screengammatable = (uint *)ENGINE_GET_PARM( PARM_GET_SCREENGAMMATABLE_PTR );
tr.lineargammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LINEARGAMMATABLE_PTR ); tr.lineargammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LINEARGAMMATABLE_PTR );
tr.dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR ); tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
GL_SetDefaults(); GL_SetDefaults();
R_CheckVBO(); R_CheckVBO();
R_InitImages(); R_InitImages();
R_SpriteInit();
R_StudioInit(); R_StudioInit();
R_AliasInit(); R_AliasInit();
R_ClearDecals(); R_ClearDecals();

View File

@@ -101,7 +101,7 @@ static int R_TransEntityCompare( const void *a, const void *b )
{ {
VectorAverage( ent1->model->mins, ent1->model->maxs, org ); VectorAverage( ent1->model->mins, ent1->model->maxs, org );
VectorAdd( ent1->origin, org, org ); VectorAdd( ent1->origin, org, org );
VectorSubtract( RI.vieworg, org, vecLen ); VectorSubtract( RI.rvp.vieworigin, org, vecLen );
dist1 = DotProduct( vecLen, vecLen ); dist1 = DotProduct( vecLen, vecLen );
} }
else dist1 = 1000000000; else dist1 = 1000000000;
@@ -110,7 +110,7 @@ static int R_TransEntityCompare( const void *a, const void *b )
{ {
VectorAverage( ent2->model->mins, ent2->model->maxs, org ); VectorAverage( ent2->model->mins, ent2->model->maxs, org );
VectorAdd( ent2->origin, org, org ); VectorAdd( ent2->origin, org, org );
VectorSubtract( RI.vieworg, org, vecLen ); VectorSubtract( RI.rvp.vieworigin, org, vecLen );
dist2 = DotProduct( vecLen, vecLen ); dist2 = DotProduct( vecLen, vecLen );
} }
else dist2 = 1000000000; else dist2 = 1000000000;
@@ -243,9 +243,6 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
if( !r_drawentities->value ) if( !r_drawentities->value )
return false; // not allow to drawing return false; // not allow to drawing
if( !clent || !clent->model )
return false; // if set to invisible, skip
if( FBitSet( clent->curstate.effects, EF_NODRAW )) if( FBitSet( clent->curstate.effects, EF_NODRAW ))
return false; // done return false; // done
@@ -260,10 +257,22 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
case ET_TEMPENTITY: case ET_TEMPENTITY:
r_stats.c_active_tents_count++; r_stats.c_active_tents_count++;
break; break;
default: break;
} }
if( R_OpaqueEntity( clent )) if( type == ET_BEAM )
{
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
{
gEngfuncs.Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
return false;
}
tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = clent;
tr.draw_list->num_beam_entities++;
return true;
}
else if( R_OpaqueEntity( clent ))
{ {
// opaque // opaque
if( tr.draw_list->num_solid_entities >= MAX_VISIBLE_PACKET ) if( tr.draw_list->num_solid_entities >= MAX_VISIBLE_PACKET )
@@ -308,7 +317,7 @@ static void R_Clear( int bitMask )
pglClear( bits ); pglClear( bits );
// change ordering for overview // change ordering for overview
if( RI.drawOrtho ) if( FBitSet( RI.rvp.flags, RF_DRAW_OVERVIEW ))
{ {
gldepthmin = 1.0f; gldepthmin = 1.0f;
gldepthmax = 0.0f; gldepthmax = 0.0f;
@@ -331,7 +340,7 @@ R_GetFarClip
*/ */
static float R_GetFarClip( void ) static float R_GetFarClip( void )
{ {
if( WORLDMODEL && RI.drawWorld ) if( WORLDMODEL && FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return tr.movevars->zmax * 1.73f; return tr.movevars->zmax * 1.73f;
return 2048.0f; return 2048.0f;
} }
@@ -343,28 +352,26 @@ R_SetupFrustum
*/ */
void R_SetupFrustum( void ) void R_SetupFrustum( void )
{ {
const ref_overview_t *ov = gEngfuncs.GetOverviewParms();
if( RP_NORMALPASS() && FBitSet( gp_host->features, ENGINE_QUAKE_COMPATIBLE ) && ( ENGINE_GET_PARM( PARM_WATER_LEVEL ) >= 3 ))
{
RI.fov_x = atan( tan( DEG2RAD( RI.fov_x ) / 2 ) * ( 0.97f + sin( gp_cl->time * 1.5f ) * 0.03f )) * 2 / (M_PI_F / 180.0f);
RI.fov_y = atan( tan( DEG2RAD( RI.fov_y ) / 2 ) * ( 1.03f - sin( gp_cl->time * 1.5f ) * 0.03f )) * 2 / (M_PI_F / 180.0f);
}
// build the transformation matrix for the given view angles // build the transformation matrix for the given view angles
AngleVectors( RI.viewangles, RI.vforward, RI.vright, RI.vup ); AngleVectors( RI.rvp.viewangles, RI.vforward, RI.vright, RI.vup );
if( !r_lockfrustum.value ) if( !r_lockfrustum.value )
{ {
VectorCopy( RI.vieworg, RI.cullorigin ); VectorCopy( RI.rvp.vieworigin, RI.cullorigin );
VectorCopy( RI.vforward, RI.cull_vforward ); VectorCopy( RI.vforward, RI.cull_vforward );
VectorCopy( RI.vright, RI.cull_vright ); VectorCopy( RI.vright, RI.cull_vright );
VectorCopy( RI.vup, RI.cull_vup ); VectorCopy( RI.vup, RI.cull_vup );
} }
if( RI.drawOrtho ) if( FBitSet( RI.rvp.flags, RF_DRAW_OVERVIEW ))
{
const ref_overview_t *ov = gEngfuncs.GetOverviewParms();
GL_FrustumInitOrtho( &RI.frustum, ov->xLeft, ov->xRight, ov->yTop, ov->yBottom, ov->zNear, ov->zFar ); GL_FrustumInitOrtho( &RI.frustum, ov->xLeft, ov->xRight, ov->yTop, ov->yBottom, ov->zNear, ov->zFar );
else GL_FrustumInitProj( &RI.frustum, 0.0f, R_GetFarClip(), RI.fov_x, RI.fov_y ); // NOTE: we ignore nearplane here (mirrors only) }
else
{
GL_FrustumInitProj( &RI.frustum, 0.0f, R_GetFarClip(), RI.rvp.fov_x, RI.rvp.fov_y ); // NOTE: we ignore nearplane here (mirrors only)
}
} }
/* /*
@@ -376,7 +383,7 @@ static void R_SetupProjectionMatrix( matrix4x4 m )
{ {
GLfloat xMin, xMax, yMin, yMax, zNear, zFar; GLfloat xMin, xMax, yMin, yMax, zNear, zFar;
if( RI.drawOrtho ) if( FBitSet( RI.rvp.flags, RF_DRAW_OVERVIEW ))
{ {
const ref_overview_t *ov = gEngfuncs.GetOverviewParms(); const ref_overview_t *ov = gEngfuncs.GetOverviewParms();
Matrix4x4_CreateOrtho( m, ov->xLeft, ov->xRight, ov->yTop, ov->yBottom, ov->zNear, ov->zFar ); Matrix4x4_CreateOrtho( m, ov->xLeft, ov->xRight, ov->yTop, ov->yBottom, ov->zNear, ov->zFar );
@@ -388,10 +395,10 @@ static void R_SetupProjectionMatrix( matrix4x4 m )
zNear = 4.0f; zNear = 4.0f;
zFar = Q_max( 256.0f, RI.farClip ); zFar = Q_max( 256.0f, RI.farClip );
yMax = zNear * tan( RI.fov_y * M_PI_F / 360.0f ); yMax = zNear * tan( RI.rvp.fov_y * M_PI_F / 360.0f );
yMin = -yMax; yMin = -yMax;
xMax = zNear * tan( RI.fov_x * M_PI_F / 360.0f ); xMax = zNear * tan( RI.rvp.fov_x * M_PI_F / 360.0f );
xMin = -xMax; xMin = -xMax;
if( tr.rotation & 1 ) if( tr.rotation & 1 )
@@ -414,17 +421,17 @@ static void R_SetupModelviewMatrix( matrix4x4 m )
Matrix4x4_CreateModelview( m ); Matrix4x4_CreateModelview( m );
if( tr.rotation & 1 ) if( tr.rotation & 1 )
{ {
Matrix4x4_ConcatRotate( m, anglemod( -RI.viewangles[2] + 90 ), 1, 0, 0 ); Matrix4x4_ConcatRotate( m, anglemod( -RI.rvp.viewangles[2] + 90 ), 1, 0, 0 );
Matrix4x4_ConcatRotate( m, -RI.viewangles[0], 0, 1, 0 ); Matrix4x4_ConcatRotate( m, -RI.rvp.viewangles[0], 0, 1, 0 );
Matrix4x4_ConcatRotate( m, -RI.viewangles[1], 0, 0, 1 ); Matrix4x4_ConcatRotate( m, -RI.rvp.viewangles[1], 0, 0, 1 );
} }
else else
{ {
Matrix4x4_ConcatRotate( m, -RI.viewangles[2], 1, 0, 0 ); Matrix4x4_ConcatRotate( m, -RI.rvp.viewangles[2], 1, 0, 0 );
Matrix4x4_ConcatRotate( m, -RI.viewangles[0], 0, 1, 0 ); Matrix4x4_ConcatRotate( m, -RI.rvp.viewangles[0], 0, 1, 0 );
Matrix4x4_ConcatRotate( m, -RI.viewangles[1], 0, 0, 1 ); Matrix4x4_ConcatRotate( m, -RI.rvp.viewangles[1], 0, 0, 1 );
} }
Matrix4x4_ConcatTranslate( m, -RI.vieworg[0], -RI.vieworg[1], -RI.vieworg[2] ); Matrix4x4_ConcatTranslate( m, -RI.rvp.vieworigin[0], -RI.rvp.vieworigin[1], -RI.rvp.vieworigin[2] );
} }
/* /*
@@ -504,7 +511,7 @@ R_FindViewLeaf
void R_FindViewLeaf( void ) void R_FindViewLeaf( void )
{ {
RI.oldviewleaf = RI.viewleaf; RI.oldviewleaf = RI.viewleaf;
RI.viewleaf = gEngfuncs.Mod_PointInLeaf( RI.pvsorigin, WORLDMODEL->nodes ); RI.viewleaf = gEngfuncs.Mod_PointInLeaf( RI.rvp.vieworigin, WORLDMODEL->nodes, WORLDMODEL );
} }
/* /*
@@ -515,7 +522,7 @@ R_SetupFrame
static void R_SetupFrame( void ) static void R_SetupFrame( void )
{ {
// setup viewplane dist // setup viewplane dist
RI.viewplanedist = DotProduct( RI.vieworg, RI.vforward ); RI.viewplanedist = DotProduct( RI.rvp.vieworigin, RI.vforward );
// NOTE: this request is the fps-killer on some NVidia drivers // NOTE: this request is the fps-killer on some NVidia drivers
glState.isFogEnabled = pglIsEnabled( GL_FOG ); glState.isFogEnabled = pglIsEnabled( GL_FOG );
@@ -527,11 +534,8 @@ static void R_SetupFrame( void )
} }
// current viewleaf // current viewleaf
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{
RI.isSkyVisible = false; // unknown at this moment
R_FindViewLeaf(); R_FindViewLeaf();
}
} }
/* /*
@@ -548,15 +552,15 @@ void R_SetupGL( qboolean set_gl_state )
if( !set_gl_state ) return; if( !set_gl_state ) return;
if( RP_NORMALPASS( )) if( !FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
{ {
int x, x2, y, y2; int x, x2, y, y2;
// set up viewport (main, playersetup) // set up viewport (main, playersetup)
x = floor( RI.viewport[0] * gpGlobals->width / gpGlobals->width ); x = floor( RI.rvp.viewport[0] * gpGlobals->width / gpGlobals->width );
x2 = ceil(( RI.viewport[0] + RI.viewport[2] ) * gpGlobals->width / gpGlobals->width ); x2 = ceil(( RI.rvp.viewport[0] + RI.rvp.viewport[2] ) * gpGlobals->width / gpGlobals->width );
y = floor( gpGlobals->height - RI.viewport[1] * gpGlobals->height / gpGlobals->height ); y = floor( gpGlobals->height - RI.rvp.viewport[1] * gpGlobals->height / gpGlobals->height );
y2 = ceil( gpGlobals->height - ( RI.viewport[1] + RI.viewport[3] ) * gpGlobals->height / gpGlobals->height ); y2 = ceil( gpGlobals->height - ( RI.rvp.viewport[1] + RI.rvp.viewport[3] ) * gpGlobals->height / gpGlobals->height );
if( tr.rotation & 1 ) if( tr.rotation & 1 )
pglViewport( y2, x, y - y2, x2 - x ); pglViewport( y2, x, y - y2, x2 - x );
@@ -565,7 +569,7 @@ void R_SetupGL( qboolean set_gl_state )
else else
{ {
// envpass, mirrorpass // envpass, mirrorpass
pglViewport( RI.viewport[0], RI.viewport[1], RI.viewport[2], RI.viewport[3] ); pglViewport( RI.rvp.viewport[0], RI.rvp.viewport[1], RI.rvp.viewport[2], RI.rvp.viewport[3] );
} }
pglMatrixMode( GL_PROJECTION ); pglMatrixMode( GL_PROJECTION );
@@ -574,20 +578,6 @@ void R_SetupGL( qboolean set_gl_state )
pglMatrixMode( GL_MODELVIEW ); pglMatrixMode( GL_MODELVIEW );
GL_LoadMatrix( RI.worldviewMatrix ); GL_LoadMatrix( RI.worldviewMatrix );
if( FBitSet( RI.params, RP_CLIPPLANE ))
{
GLdouble clip[4];
mplane_t *p = &RI.clipPlane;
clip[0] = p->normal[0];
clip[1] = p->normal[1];
clip[2] = p->normal[2];
clip[3] = -p->dist;
pglClipPlane( GL_CLIP_PLANE0, clip );
pglEnable( GL_CLIP_PLANE0 );
}
GL_Cull( GL_FRONT ); GL_Cull( GL_FRONT );
pglDisable( GL_BLEND ); pglDisable( GL_BLEND );
@@ -595,17 +585,6 @@ void R_SetupGL( qboolean set_gl_state )
pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
} }
/*
=============
R_EndGL
=============
*/
static void R_EndGL( void )
{
if( RI.params & RP_CLIPPLANE )
pglDisable( GL_CLIP_PLANE0 );
}
/* /*
============= =============
R_RecursiveFindWaterTexture R_RecursiveFindWaterTexture
@@ -722,7 +701,7 @@ static void R_CheckFog( void )
RI.fogEnabled = false; RI.fogEnabled = false;
if( RI.onlyClientDraw || ENGINE_GET_PARM( PARM_WATER_LEVEL ) < 3 || !RI.drawWorld || !RI.viewleaf ) if( FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ) || ENGINE_GET_PARM( PARM_WATER_LEVEL ) < 3 || !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || !RI.viewleaf )
{ {
if( RI.cached_waterlevel == 3 ) if( RI.cached_waterlevel == 3 )
{ {
@@ -738,7 +717,7 @@ static void R_CheckFog( void )
return; return;
} }
ent = gEngfuncs.CL_GetWaterEntity( RI.vieworg ); ent = gEngfuncs.CL_GetWaterEntity( RI.rvp.vieworigin );
if( ent && ent->model && ent->model->type == mod_brush && ent->curstate.skin < 0 ) if( ent && ent->model && ent->model->type == mod_brush && ent->curstate.skin < 0 )
cnt = ent->curstate.skin; cnt = ent->curstate.skin;
else cnt = RI.viewleaf->contents; else cnt = RI.viewleaf->contents;
@@ -844,7 +823,7 @@ static void R_DrawEntitiesOnList( void )
GL_CheckForErrors(); GL_CheckForErrors();
// first draw solid entities // first draw solid entities
for( i = 0; i < tr.draw_list->num_solid_entities && !RI.onlyClientDraw; i++ ) for( i = 0; i < tr.draw_list->num_solid_entities && !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ); i++ )
{ {
RI.currententity = tr.draw_list->solid_entities[i]; RI.currententity = tr.draw_list->solid_entities[i];
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
@@ -876,7 +855,7 @@ static void R_DrawEntitiesOnList( void )
GL_CheckForErrors(); GL_CheckForErrors();
// draw sprites seperately, because of alpha blending // draw sprites seperately, because of alpha blending
for( i = 0; i < tr.draw_list->num_solid_entities && !RI.onlyClientDraw; i++ ) for( i = 0; i < tr.draw_list->num_solid_entities && !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ); i++ )
{ {
RI.currententity = tr.draw_list->solid_entities[i]; RI.currententity = tr.draw_list->solid_entities[i];
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
@@ -894,20 +873,20 @@ static void R_DrawEntitiesOnList( void )
GL_CheckForErrors(); GL_CheckForErrors();
if( !RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
{ {
gEngfuncs.CL_DrawEFX( tr.frametime, false ); gEngfuncs.CL_DrawEFX( tr.frametime, false );
} }
GL_CheckForErrors(); GL_CheckForErrors();
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
gEngfuncs.pfnDrawNormalTriangles(); gEngfuncs.pfnDrawNormalTriangles();
GL_CheckForErrors(); GL_CheckForErrors();
// then draw translucent entities // then draw translucent entities
for( i = 0; i < tr.draw_list->num_trans_entities && !RI.onlyClientDraw; i++ ) for( i = 0; i < tr.draw_list->num_trans_entities && !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ); i++ )
{ {
RI.currententity = tr.draw_list->trans_entities[i]; RI.currententity = tr.draw_list->trans_entities[i];
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
@@ -943,7 +922,7 @@ static void R_DrawEntitiesOnList( void )
GL_CheckForErrors(); GL_CheckForErrors();
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{ {
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
gEngfuncs.pfnDrawTransparentTriangles (); gEngfuncs.pfnDrawTransparentTriangles ();
@@ -951,7 +930,7 @@ static void R_DrawEntitiesOnList( void )
GL_CheckForErrors(); GL_CheckForErrors();
if( !RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
{ {
R_AllowFog( false ); R_AllowFog( false );
gEngfuncs.CL_DrawEFX( tr.frametime, true ); gEngfuncs.CL_DrawEFX( tr.frametime, true );
@@ -962,7 +941,7 @@ static void R_DrawEntitiesOnList( void )
pglDisable( GL_BLEND ); // Trinity Render issues pglDisable( GL_BLEND ); // Trinity Render issues
if( !RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
R_DrawViewModel(); R_DrawViewModel();
gEngfuncs.CL_ExtraUpdate(); gEngfuncs.CL_ExtraUpdate();
@@ -978,18 +957,18 @@ R_SetupRefParams must be called right before
*/ */
void R_RenderScene( void ) void R_RenderScene( void )
{ {
if( !WORLDMODEL && RI.drawWorld ) if( !WORLDMODEL && FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
gEngfuncs.Host_Error( "%s: NULL worldmodel\n", __func__ ); gEngfuncs.Host_Error( "%s: NULL worldmodel\n", __func__ );
// frametime is valid only for normal pass // frametime is valid only for normal pass
if( RP_NORMALPASS( )) if( !FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
tr.frametime = gp_cl->time - gp_cl->oldtime; tr.frametime = gp_cl->time - gp_cl->oldtime;
else tr.frametime = 0.0; else tr.frametime = 0.0;
// begin a new frame // begin a new frame
tr.framecount++; tr.framecount++;
R_PushDlights(); tr.dlightframecount = R_PushDlights( WORLDMODEL, tr.framecount );
R_SetupFrustum(); R_SetupFrustum();
R_SetupFrame(); R_SetupFrame();
@@ -998,7 +977,7 @@ void R_RenderScene( void )
R_MarkLeaves(); R_MarkLeaves();
R_DrawFog (); R_DrawFog ();
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
R_AnimateRipples(); R_AnimateRipples();
R_CheckGLFog(); R_CheckGLFog();
@@ -1010,8 +989,6 @@ void R_RenderScene( void )
R_DrawEntitiesOnList(); R_DrawEntitiesOnList();
R_DrawWaterSurfaces(); R_DrawWaterSurfaces();
R_EndGL();
} }
void R_GammaChanged( qboolean do_reset_gamma ) void R_GammaChanged( qboolean do_reset_gamma )
@@ -1100,28 +1077,9 @@ set initial params for renderer
*/ */
void R_SetupRefParams( const ref_viewpass_t *rvp ) void R_SetupRefParams( const ref_viewpass_t *rvp )
{ {
RI.params = RP_NONE; RI.rvp = *rvp;
RI.drawWorld = FBitSet( rvp->flags, RF_DRAW_WORLD );
RI.onlyClientDraw = FBitSet( rvp->flags, RF_ONLY_CLIENTDRAW );
RI.farClip = 0; RI.farClip = 0;
if( !FBitSet( rvp->flags, RF_DRAW_CUBEMAP ))
RI.drawOrtho = FBitSet( rvp->flags, RF_DRAW_OVERVIEW );
else RI.drawOrtho = false;
// setup viewport
RI.viewport[0] = rvp->viewport[0];
RI.viewport[1] = rvp->viewport[1];
RI.viewport[2] = rvp->viewport[2];
RI.viewport[3] = rvp->viewport[3];
// calc FOV
RI.fov_x = rvp->fov_x;
RI.fov_y = rvp->fov_y;
VectorCopy( rvp->vieworigin, RI.vieworg );
VectorCopy( rvp->viewangles, RI.viewangles );
VectorCopy( rvp->vieworigin, RI.pvsorigin );
} }
/* /*
@@ -1137,7 +1095,7 @@ void R_RenderFrame( const ref_viewpass_t *rvp )
// setup the initial render params // setup the initial render params
R_SetupRefParams( rvp ); R_SetupRefParams( rvp );
if( gl_finish.value && RI.drawWorld ) if( gl_finish.value && FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
pglFinish(); pglFinish();
// completely override rendering // completely override rendering
@@ -1147,7 +1105,7 @@ void R_RenderFrame( const ref_viewpass_t *rvp )
if( gEngfuncs.drawFuncs->GL_RenderFrame( rvp )) if( gEngfuncs.drawFuncs->GL_RenderFrame( rvp ))
{ {
R_GatherPlayerLight(); R_GatherPlayerLight( tr.viewent );
tr.realframecount++; tr.realframecount++;
tr.fResetVis = true; tr.fResetVis = true;
return; return;
@@ -1155,7 +1113,7 @@ void R_RenderFrame( const ref_viewpass_t *rvp )
} }
tr.fCustomRendering = false; tr.fCustomRendering = false;
if( !RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
R_RunViewmodelEvents(); R_RunViewmodelEvents();
tr.realframecount++; // right called after viewmodel events tr.realframecount++; // right called after viewmodel events
@@ -1237,7 +1195,7 @@ int CL_FxBlend( cl_entity_t *e )
blend = e->curstate.renderamt + 0x10 * sin( gp_cl->time * 8 + offset ); blend = e->curstate.renderamt + 0x10 * sin( gp_cl->time * 8 + offset );
break; break;
case kRenderFxFadeSlow: case kRenderFxFadeSlow:
if( RP_NORMALPASS( )) if( !FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
{ {
if( e->curstate.renderamt > 0 ) if( e->curstate.renderamt > 0 )
e->curstate.renderamt -= 1; e->curstate.renderamt -= 1;
@@ -1246,7 +1204,7 @@ int CL_FxBlend( cl_entity_t *e )
blend = e->curstate.renderamt; blend = e->curstate.renderamt;
break; break;
case kRenderFxFadeFast: case kRenderFxFadeFast:
if( RP_NORMALPASS( )) if( !FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
{ {
if( e->curstate.renderamt > 3 ) if( e->curstate.renderamt > 3 )
e->curstate.renderamt -= 4; e->curstate.renderamt -= 4;
@@ -1255,7 +1213,7 @@ int CL_FxBlend( cl_entity_t *e )
blend = e->curstate.renderamt; blend = e->curstate.renderamt;
break; break;
case kRenderFxSolidSlow: case kRenderFxSolidSlow:
if( RP_NORMALPASS( )) if( !FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
{ {
if( e->curstate.renderamt < 255 ) if( e->curstate.renderamt < 255 )
e->curstate.renderamt += 1; e->curstate.renderamt += 1;
@@ -1264,7 +1222,7 @@ int CL_FxBlend( cl_entity_t *e )
blend = e->curstate.renderamt; blend = e->curstate.renderamt;
break; break;
case kRenderFxSolidFast: case kRenderFxSolidFast:
if( RP_NORMALPASS( )) if( !FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
{ {
if( e->curstate.renderamt < 252 ) if( e->curstate.renderamt < 252 )
e->curstate.renderamt += 4; e->curstate.renderamt += 4;
@@ -1300,7 +1258,7 @@ int CL_FxBlend( cl_entity_t *e )
case kRenderFxHologram: case kRenderFxHologram:
case kRenderFxDistort: case kRenderFxDistort:
VectorCopy( e->origin, tmp ); VectorCopy( e->origin, tmp );
VectorSubtract( tmp, RI.vieworg, tmp ); VectorSubtract( tmp, RI.rvp.vieworigin, tmp );
dist = DotProduct( tmp, RI.vforward ); dist = DotProduct( tmp, RI.vforward );
// turn off distance fade // turn off distance fade

View File

@@ -1,189 +0,0 @@
/*
gl_rmath.c - renderer mathlib
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "gl_local.h"
#include "xash3d_mathlib.h"
/*
========================================================================
Matrix4x4 operations (private to renderer)
========================================================================
*/
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 )
{
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0] + in1[0][3] * in2[3][0];
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1] + in1[0][3] * in2[3][1];
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2] + in1[0][3] * in2[3][2];
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3] * in2[3][3];
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0] + in1[1][3] * in2[3][0];
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1] + in1[1][3] * in2[3][1];
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2] + in1[1][3] * in2[3][2];
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3] * in2[3][3];
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0] + in1[2][3] * in2[3][0];
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1] + in1[2][3] * in2[3][1];
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2] + in1[2][3] * in2[3][2];
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3] * in2[3][3];
out[3][0] = in1[3][0] * in2[0][0] + in1[3][1] * in2[1][0] + in1[3][2] * in2[2][0] + in1[3][3] * in2[3][0];
out[3][1] = in1[3][0] * in2[0][1] + in1[3][1] * in2[1][1] + in1[3][2] * in2[2][1] + in1[3][3] * in2[3][1];
out[3][2] = in1[3][0] * in2[0][2] + in1[3][1] * in2[1][2] + in1[3][2] * in2[2][2] + in1[3][3] * in2[3][2];
out[3][3] = in1[3][0] * in2[0][3] + in1[3][1] * in2[1][3] + in1[3][2] * in2[2][3] + in1[3][3] * in2[3][3];
}
/*
================
Matrix4x4_CreateProjection
NOTE: produce quake style world orientation
================
*/
void Matrix4x4_CreateProjection( matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar )
{
out[0][0] = ( 2.0f * zNear ) / ( xMax - xMin );
out[1][1] = ( 2.0f * zNear ) / ( yMax - yMin );
out[2][2] = -( zFar + zNear ) / ( zFar - zNear );
out[3][3] = out[0][1] = out[1][0] = out[3][0] = out[0][3] = out[3][1] = out[1][3] = 0.0f;
out[2][0] = 0.0f;
out[2][1] = 0.0f;
out[0][2] = ( xMax + xMin ) / ( xMax - xMin );
out[1][2] = ( yMax + yMin ) / ( yMax - yMin );
out[3][2] = -1.0f;
out[2][3] = -( 2.0f * zFar * zNear ) / ( zFar - zNear );
}
void Matrix4x4_CreateOrtho( matrix4x4 out, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar )
{
out[0][0] = 2.0f / (xRight - xLeft);
out[1][1] = 2.0f / (yTop - yBottom);
out[2][2] = -2.0f / (zFar - zNear);
out[3][3] = 1.0f;
out[0][1] = out[0][2] = out[1][0] = out[1][2] = out[3][0] = out[3][1] = out[3][2] = 0.0f;
out[2][0] = 0.0f;
out[2][1] = 0.0f;
out[0][3] = -(xRight + xLeft) / (xRight - xLeft);
out[1][3] = -(yTop + yBottom) / (yTop - yBottom);
out[2][3] = -(zFar + zNear) / (zFar - zNear);
}
/*
================
Matrix4x4_CreateModelview
NOTE: produce quake style world orientation
================
*/
void Matrix4x4_CreateModelview( matrix4x4 out )
{
out[0][0] = out[1][1] = out[2][2] = 0.0f;
out[3][0] = out[0][3] = 0.0f;
out[3][1] = out[1][3] = 0.0f;
out[3][2] = out[2][3] = 0.0f;
out[3][3] = 1.0f;
out[1][0] = out[0][2] = out[2][1] = 0.0f;
out[2][0] = out[0][1] = -1.0f;
out[1][2] = 1.0f;
}
void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] )
{
out[ 0] = in[0][0];
out[ 1] = in[1][0];
out[ 2] = in[2][0];
out[ 3] = in[3][0];
out[ 4] = in[0][1];
out[ 5] = in[1][1];
out[ 6] = in[2][1];
out[ 7] = in[3][1];
out[ 8] = in[0][2];
out[ 9] = in[1][2];
out[10] = in[2][2];
out[11] = in[3][2];
out[12] = in[0][3];
out[13] = in[1][3];
out[14] = in[2][3];
out[15] = in[3][3];
}
static void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z )
{
out[0][0] = 1.0f;
out[0][1] = 0.0f;
out[0][2] = 0.0f;
out[0][3] = x;
out[1][0] = 0.0f;
out[1][1] = 1.0f;
out[1][2] = 0.0f;
out[1][3] = y;
out[2][0] = 0.0f;
out[2][1] = 0.0f;
out[2][2] = 1.0f;
out[2][3] = z;
out[3][0] = 0.0f;
out[3][1] = 0.0f;
out[3][2] = 0.0f;
out[3][3] = 1.0f;
}
static void Matrix4x4_CreateRotate( matrix4x4 out, float angle, float x, float y, float z )
{
float len, c, s;
len = x * x + y * y + z * z;
if( len != 0.0f ) len = 1.0f / sqrt( len );
x *= len;
y *= len;
z *= len;
angle *= (-M_PI_F / 180.0f);
SinCos( angle, &s, &c );
out[0][0]=x * x + c * (1 - x * x);
out[0][1]=x * y * (1 - c) + z * s;
out[0][2]=z * x * (1 - c) - y * s;
out[0][3]=0.0f;
out[1][0]=x * y * (1 - c) - z * s;
out[1][1]=y * y + c * (1 - y * y);
out[1][2]=y * z * (1 - c) + x * s;
out[1][3]=0.0f;
out[2][0]=z * x * (1 - c) + y * s;
out[2][1]=y * z * (1 - c) - x * s;
out[2][2]=z * z + c * (1 - z * z);
out[2][3]=0.0f;
out[3][0]=0.0f;
out[3][1]=0.0f;
out[3][2]=0.0f;
out[3][3]=1.0f;
}
void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z )
{
matrix4x4 base, temp;
Matrix4x4_Copy( base, out );
Matrix4x4_CreateTranslate( temp, x, y, z );
Matrix4x4_Concat( out, base, temp );
}
void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z )
{
matrix4x4 base, temp;
Matrix4x4_Copy( base, out );
Matrix4x4_CreateRotate( temp, angle, x, y, z );
Matrix4x4_Concat( out, base, temp );
}

View File

@@ -1,161 +0,0 @@
/*
gl_rmisc.c - renderer misceallaneous
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "gl_local.h"
#include "shake.h"
#include "screenfade.h"
#include "cdll_int.h"
static void R_ParseDetailTextures( const char *filename )
{
byte *afile;
char *pfile;
string token, texname;
string detail_texname;
string detail_path;
float xScale, yScale;
texture_t *tex;
int i;
afile = gEngfuncs.fsapi->LoadFile( filename, NULL, false );
if( !afile ) return;
pfile = (char *)afile;
// format: 'texturename' 'detailtexture' 'xScale' 'yScale'
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
{
texname[0] = '\0';
detail_texname[0] = '\0';
// read texname
if( token[0] == '{' )
{
// NOTE: COM_ParseFile handled some symbols seperately
// this code will be fix it
pfile = COM_ParseFile( pfile, token, sizeof( token ));
Q_snprintf( texname, sizeof( texname ), "{%s", token );
}
else Q_strncpy( texname, token, sizeof( texname ));
// read detailtexture name
pfile = COM_ParseFile( pfile, token, sizeof( token ));
Q_strncpy( detail_texname, token, sizeof( detail_texname ));
// trying the scales or '{'
pfile = COM_ParseFile( pfile, token, sizeof( token ));
// read second part of detailtexture name
if( token[0] == '{' )
{
Q_strncat( detail_texname, token, sizeof( detail_texname ));
pfile = COM_ParseFile( pfile, token, sizeof( token )); // read scales
Q_strncat( detail_texname, token, sizeof( detail_texname ));
pfile = COM_ParseFile( pfile, token, sizeof( token )); // parse scales
}
Q_snprintf( detail_path, sizeof( detail_path ), "gfx/%s", detail_texname );
// read scales
xScale = Q_atof( token );
pfile = COM_ParseFile( pfile, token, sizeof( token ));
yScale = Q_atof( token );
if( xScale <= 0.0f || yScale <= 0.0f )
continue;
// search for existing texture and uploading detail texture
for( i = 0; i < WORLDMODEL->numtextures; i++ )
{
tex = WORLDMODEL->textures[i];
if( Q_stricmp( tex->name, texname ))
continue;
tex->dt_texturenum = GL_LoadTexture( detail_path, NULL, 0, TF_FORCE_COLOR|TF_NOFLIP_TGA );
// texture is loaded
if( tex->dt_texturenum )
{
gl_texture_t *glt;
glt = R_GetTexture( tex->gl_texturenum );
glt->xscale = xScale;
glt->yscale = yScale;
}
break;
}
}
Mem_Free( afile );
}
void R_NewMap( void )
{
texture_t *tx;
int i;
tr.worldmodel = gp_cl->models[1];
R_ClearDecals(); // clear all level decals
R_StudioResetPlayerModels();
// upload detailtextures
if( r_detailtextures.value )
{
string mapname, filepath;
Q_strncpy( mapname, WORLDMODEL->name, sizeof( mapname ));
COM_StripExtension( mapname );
Q_snprintf( filepath, sizeof( filepath ), "%s_detail.txt", mapname );
R_ParseDetailTextures( filepath );
}
// clear out efrags in case the level hasn't been reloaded
for( i = 0; i < WORLDMODEL->numleafs; i++ )
WORLDMODEL->leafs[i+1].efrags = NULL;
glState.isFogEnabled = false;
tr.skytexturenum = -1;
pglDisable( GL_FOG );
// clearing texture chains
for( i = 0; i < WORLDMODEL->numtextures; i++ )
{
if( !WORLDMODEL->textures[i] )
continue;
tx = WORLDMODEL->textures[i];
if( !Q_strncmp( tx->name, "sky", 3 ) && tx->width == ( tx->height * 2 ))
tr.skytexturenum = i;
tx->texturechain = NULL;
}
GL_BuildLightmaps ();
R_ClearVBO();
if( R_HasEnabledVBO( ))
R_GenerateVBO();
R_ResetRipples();
if( gEngfuncs.drawFuncs->R_NewMap != NULL )
gEngfuncs.drawFuncs->R_NewMap();
}

View File

@@ -73,9 +73,9 @@ void CL_DrawParticles( double frametime, particle_t *cl_active_particles, float
size = partsize; // get initial size of particle size = partsize; // get initial size of particle
// scale up to keep particles from disappearing // scale up to keep particles from disappearing
size += (p->org[0] - RI.vieworg[0]) * RI.cull_vforward[0]; size += (p->org[0] - RI.rvp.vieworigin[0]) * RI.cull_vforward[0];
size += (p->org[1] - RI.vieworg[1]) * RI.cull_vforward[1]; size += (p->org[1] - RI.rvp.vieworigin[1]) * RI.cull_vforward[1];
size += (p->org[2] - RI.vieworg[2]) * RI.cull_vforward[2]; size += (p->org[2] - RI.rvp.vieworigin[2]) * RI.cull_vforward[2];
if( size < 20.0f ) size = partsize; if( size < 20.0f ) size = partsize;
else size = partsize + size * 0.002f; else size = partsize + size * 0.002f;

View File

@@ -40,7 +40,6 @@ static vec2_t world_orthohalf;
static uint r_blocklights[BLOCK_SIZE_MAX*BLOCK_SIZE_MAX*3]; static uint r_blocklights[BLOCK_SIZE_MAX*BLOCK_SIZE_MAX*3];
static mextrasurf_t *fullbright_surfaces[MAX_TEXTURES]; static mextrasurf_t *fullbright_surfaces[MAX_TEXTURES];
static mextrasurf_t *detail_surfaces[MAX_TEXTURES]; static mextrasurf_t *detail_surfaces[MAX_TEXTURES];
static int rtable[MOD_FRAMES][MOD_FRAMES];
typedef struct typedef struct
{ {
@@ -576,7 +575,7 @@ static void R_AddDynamicLights( const msurface_t *surf )
if( !FBitSet( surf->dlightbits, BIT( lnum ))) if( !FBitSet( surf->dlightbits, BIT( lnum )))
continue; // not lit by this light continue; // not lit by this light
dl = &tr.dlights[lnum]; dl = &gp_dlights[lnum];
// transform light origin to local bmodel space // transform light origin to local bmodel space
if( !tr.modelviewIdentity ) if( !tr.modelviewIdentity )
@@ -638,21 +637,6 @@ static void R_AddDynamicLights( const msurface_t *surf )
} }
} }
/*
================
R_SetCacheState
================
*/
static void R_SetCacheState( msurface_t *surf )
{
int maps;
for( maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++ )
{
surf->cached_light[maps] = tr.lightstylevalue[surf->styles[maps]];
}
}
/* /*
============================================================================= =============================================================================
@@ -783,7 +767,7 @@ static void R_BuildLightMap( const msurface_t *surf, byte *dest, int stride, qbo
if( surf->styles[map] >= 255 ) if( surf->styles[map] >= 255 )
break; break;
scale = tr.lightstylevalue[surf->styles[map]]; scale = g_lightstylevalue[surf->styles[map]];
for( i = 0; i < size; i++ ) for( i = 0; i < size; i++ )
{ {
@@ -960,7 +944,7 @@ EmitWaterPolys
Does a water warp on the pre-fragmented glpoly_t chain Does a water warp on the pre-fragmented glpoly_t chain
============= =============
*/ */
void EmitWaterPolys( msurface_t *warp, qboolean reverse, qboolean ripples ) static void EmitWaterPolys( msurface_t *warp, qboolean reverse, qboolean ripples )
{ {
float *v, nv, waveHeight; float *v, nv, waveHeight;
float s, t, os, ot; float s, t, os, ot;
@@ -972,7 +956,7 @@ void EmitWaterPolys( msurface_t *warp, qboolean reverse, qboolean ripples )
if( !warp->polys ) return; if( !warp->polys ) return;
// set the current waveheight // set the current waveheight
if( warp->polys->verts[0][2] >= RI.vieworg[2] ) if( warp->polys->verts[0][2] >= RI.rvp.vieworigin[2] )
waveHeight = -RI.currententity->curstate.scale; waveHeight = -RI.currententity->curstate.scale;
else waveHeight = RI.currententity->curstate.scale; else waveHeight = RI.currententity->curstate.scale;
@@ -1398,7 +1382,7 @@ static qboolean R_CheckLightMap( msurface_t *fa )
// check for light styles // check for light styles
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ ) for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
{ {
if( tr.lightstylevalue[fa->styles[maps]] == fa->cached_light[maps] ) if( g_lightstylevalue[fa->styles[maps]] == fa->cached_light[maps] )
continue; continue;
const int style = fa->styles[maps]; const int style = fa->styles[maps];
@@ -1423,7 +1407,7 @@ static qboolean R_CheckLightMap( msurface_t *fa )
//Host_MapDesignError( "%s: bad surface extents: %d %d", __func__, fa->extents[0], fa->extents[1] ); //Host_MapDesignError( "%s: bad surface extents: %d %d", __func__, fa->extents[0], fa->extents[1] );
} }
R_SetCacheState( fa ); R_UpdateSurfaceCachedLight( fa );
#if XASH_WES #if XASH_WES
GL_Bind( XASH_TEXTURE1, tr.lightmapTextures[fa->lightmaptexturenum] ); GL_Bind( XASH_TEXTURE1, tr.lightmapTextures[fa->lightmaptexturenum] );
@@ -1626,7 +1610,7 @@ void R_DrawWaterSurfaces( void )
msurface_t *s; msurface_t *s;
texture_t *t; texture_t *t;
if( !RI.drawWorld || RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
return; return;
// non-transparent water is already drawed // non-transparent water is already drawed
@@ -1808,7 +1792,8 @@ void R_DrawBrushModel( cl_entity_t *e )
qboolean rotated; qboolean rotated;
qboolean allow_vbo = R_HasEnabledVBO(); qboolean allow_vbo = R_HasEnabledVBO();
if( !RI.drawWorld ) return; if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return;
model_t *clmodel = e->model; model_t *clmodel = e->model;
@@ -1858,20 +1843,7 @@ void R_DrawBrushModel( cl_entity_t *e )
e->visframe = tr.realframecount; // visible e->visframe = tr.realframecount; // visible
// calculate dynamic lighting for bmodel // calculate dynamic lighting for bmodel
for( int k = 0; k < MAX_DLIGHTS; k++ ) R_PushDlightsForBmodel( clmodel, tr.dlightframecount, RI.objectMatrix );
{
dlight_t *l = &tr.dlights[k];
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
continue;
VectorCopy( l->origin, oldorigin ); // save lightorigin
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1<<k, clmodel->nodes + clmodel->hulls[0].firstclipnode );
VectorCopy( oldorigin, l->origin ); // restore lightorigin
}
// setup the rendermode // setup the rendermode
R_SetRenderMode( e ); R_SetRenderMode( e );
@@ -3712,7 +3684,7 @@ void R_DrawWorld( void )
return; return;
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
if( !RI.drawWorld || RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
return; return;
VectorCopy( RI.cullorigin, tr.modelorg ); VectorCopy( RI.cullorigin, tr.modelorg );
@@ -3728,7 +3700,7 @@ void R_DrawWorld( void )
R_ClearSkyBox (); R_ClearSkyBox ();
start = gEngfuncs.pfnTime(); start = gEngfuncs.pfnTime();
if( RI.drawOrtho ) if( FBitSet( RI.rvp.flags, RF_DRAW_OVERVIEW ))
R_DrawWorldTopView( WORLDMODEL->nodes, RI.frustum.clipFlags ); R_DrawWorldTopView( WORLDMODEL->nodes, RI.frustum.clipFlags );
else R_RecursiveWorldNode( WORLDMODEL->nodes, RI.frustum.clipFlags ); else R_RecursiveWorldNode( WORLDMODEL->nodes, RI.frustum.clipFlags );
end = gEngfuncs.pfnTime(); end = gEngfuncs.pfnTime();
@@ -3777,7 +3749,8 @@ void R_MarkLeaves( void )
vec3_t test; vec3_t test;
int i; int i;
if( !RI.drawWorld ) return; if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return;
if( FBitSet( r_novis.flags, FCVAR_CHANGED ) || tr.fResetVis ) if( FBitSet( r_novis.flags, FCVAR_CHANGED ) || tr.fResetVis )
{ {
@@ -3787,17 +3760,17 @@ void R_MarkLeaves( void )
RI.viewleaf = NULL; RI.viewleaf = NULL;
} }
VectorCopy( RI.pvsorigin, test ); VectorCopy( RI.rvp.vieworigin, test );
if( RI.viewleaf != NULL ) if( RI.viewleaf != NULL )
{ {
// merge two leafs that can be a crossed-line contents // merge two leafs that can be a crossed-line contents
if( RI.viewleaf->contents == CONTENTS_EMPTY ) if( RI.viewleaf->contents == CONTENTS_EMPTY )
VectorSet( test, RI.pvsorigin[0], RI.pvsorigin[1], RI.pvsorigin[2] - 16.0f ); VectorSet( test, RI.rvp.vieworigin[0], RI.rvp.vieworigin[1], RI.rvp.vieworigin[2] - 16.0f );
else else
VectorSet( test, RI.pvsorigin[0], RI.pvsorigin[1], RI.pvsorigin[2] + 16.0f ); VectorSet( test, RI.rvp.vieworigin[0], RI.rvp.vieworigin[1], RI.rvp.vieworigin[2] + 16.0f );
leaf = gEngfuncs.Mod_PointInLeaf( test, WORLDMODEL->nodes ); leaf = gEngfuncs.Mod_PointInLeaf( test, WORLDMODEL->nodes, WORLDMODEL );
if(( leaf->contents != CONTENTS_SOLID ) && ( RI.viewleaf != leaf )) if(( leaf->contents != CONTENTS_SOLID ) && ( RI.viewleaf != leaf ))
force = true; force = true;
@@ -3813,10 +3786,10 @@ void R_MarkLeaves( void )
RI.oldviewleaf = RI.viewleaf; RI.oldviewleaf = RI.viewleaf;
tr.visframecount++; tr.visframecount++;
if( r_novis.value || RI.drawOrtho || !RI.viewleaf || !WORLDMODEL->visdata ) if( r_novis.value || FBitSet( RI.rvp.flags, RF_DRAW_OVERVIEW ) || !RI.viewleaf || !WORLDMODEL->visdata )
novis = true; novis = true;
gEngfuncs.R_FatPVS( RI.pvsorigin, r_pvs_radius->value, RI.visbytes, FBitSet( RI.params, RP_OLDVIEWLEAF ), novis ); gEngfuncs.R_FatPVS( RI.rvp.vieworigin, r_pvs_radius->value, RI.visbytes, false, novis );
if( force && !novis ) if( force && !novis )
gEngfuncs.R_FatPVS( test, r_pvs_radius->value, RI.visbytes, true, novis ); gEngfuncs.R_FatPVS( test, r_pvs_radius->value, RI.visbytes, true, novis );
@@ -3872,7 +3845,7 @@ static void GL_CreateSurfaceLightmap( msurface_t *surf, model_t *loadmodel )
base = gl_lms.lightmap_buffer; base = gl_lms.lightmap_buffer;
base += ( surf->light_t * BLOCK_SIZE + surf->light_s ) * 4; base += ( surf->light_t * BLOCK_SIZE + surf->light_s ) * 4;
R_SetCacheState( surf ); R_UpdateSurfaceCachedLight( surf );
R_BuildLightMap( surf, base, BLOCK_SIZE * 4, false ); R_BuildLightMap( surf, base, BLOCK_SIZE * 4, false );
} }
@@ -4008,17 +3981,3 @@ void GL_BuildLightmaps( void )
} }
} }
void GL_InitRandomTable( void )
{
int tu, tv;
for( tu = 0; tu < MOD_FRAMES; tu++ )
{
for( tv = 0; tv < MOD_FRAMES; tv++ )
{
rtable[tu][tv] = gEngfuncs.COM_RandomLong( 0, 0x7FFF );
}
}
gEngfuncs.COM_SetRandomSeed( 0 );
}

View File

@@ -21,329 +21,6 @@ GNU General Public License for more details.
#define GLARE_FALLOFF 19000.0f #define GLARE_FALLOFF 19000.0f
static char sprite_name[MAX_QPATH];
static char group_suffix[8];
static uint r_texFlags = 0;
static int sprite_version;
static float sprite_radius;
/*
====================
R_SpriteInit
====================
*/
void R_SpriteInit( void )
{
}
/*
====================
R_SpriteLoadFrame
upload a single frame
====================
*/
static const byte *R_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
{
dspriteframe_t pinframe;
mspriteframe_t *pspriteframe;
int gl_texturenum = 0;
char texname[128];
int bytes = 1;
memcpy( &pinframe, pin, sizeof( dspriteframe_t ));
if( sprite_version == SPRITE_VERSION_32 )
bytes = 4;
// build uinque frame name
if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite
{
Q_snprintf( texname, sizeof( texname ), "#HUD/%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
else
{
// partial HD-textures support
if( Mod_AllowMaterials( ))
{
if( R_SearchForTextureReplacement( texname, sizeof( texname ), sprite_name, "materials/%s/%s%i%i.tga", sprite_name, group_suffix, num / 10, num % 10 ))
{
gl_texturenum = GL_LoadTexture( texname, NULL, 0, r_texFlags );
R_TextureReplacementReport( sprite_name, gl_texturenum, texname );
}
}
if( gl_texturenum == 0 )
{
Q_snprintf( texname, sizeof( texname ), "#%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
}
// setup frame description
pspriteframe = Mem_Malloc( mod->mempool, sizeof( mspriteframe_t ));
pspriteframe->width = pinframe.width;
pspriteframe->height = pinframe.height;
pspriteframe->up = pinframe.origin[1];
pspriteframe->left = pinframe.origin[0];
pspriteframe->down = pinframe.origin[1] - pinframe.height;
pspriteframe->right = pinframe.width + pinframe.origin[0];
pspriteframe->gl_texturenum = gl_texturenum;
*ppframe = pspriteframe;
return (( const byte* )pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes );
}
/*
====================
R_SpriteLoadGroup
upload a group frames
====================
*/
static const byte *R_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
{
const dspritegroup_t *pingroup;
mspritegroup_t *pspritegroup;
const dspriteinterval_t *pin_intervals;
float *poutintervals;
int i, groupsize, numframes;
const void *ptemp;
pingroup = (const dspritegroup_t *)pin;
numframes = pingroup->numframes;
groupsize = sizeof( mspritegroup_t ) + (numframes - 1) * sizeof( pspritegroup->frames[0] );
pspritegroup = Mem_Calloc( mod->mempool, groupsize );
pspritegroup->numframes = numframes;
*ppframe = (mspriteframe_t *)pspritegroup;
pin_intervals = (const dspriteinterval_t *)(pingroup + 1);
poutintervals = Mem_Calloc( mod->mempool, numframes * sizeof( float ));
pspritegroup->intervals = poutintervals;
for( i = 0; i < numframes; i++ )
{
*poutintervals = pin_intervals->interval;
if( *poutintervals <= 0.0f )
*poutintervals = 1.0f; // set error value
poutintervals++;
pin_intervals++;
}
ptemp = (const void *)pin_intervals;
for( i = 0; i < numframes; i++ )
{
ptemp = R_SpriteLoadFrame( mod, ptemp, &pspritegroup->frames[i], framenum * 10 + i );
}
return ptemp;
}
/*
====================
Mod_LoadSpriteModel
load sprite model
====================
*/
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags )
{
const dsprite_t *pin;
const short *numi = NULL;
const byte *pframetype;
msprite_t *psprite;
int i;
pin = buffer;
psprite = mod->cache.data;
if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 )
numi = NULL;
else if( pin->version == SPRITE_VERSION_HL )
numi = (const short *)((const byte *)buffer + sizeof( dsprite_hl_t ));
r_texFlags = texFlags;
sprite_version = pin->version;
Q_strncpy( sprite_name, mod->name, sizeof( sprite_name ));
COM_StripExtension( sprite_name );
if( numi == NULL )
{
rgbdata_t *pal;
pal = gEngfuncs.FS_LoadImage( "#id.pal", (byte *)&i, 768 );
pframetype = ((const byte*)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else if( *numi <= 256 )
{
const byte *src = (const byte *)(numi+1);
rgbdata_t *pal;
size_t pal_bytes = *numi * 3;
// install palette
switch( psprite->texFormat )
{
case SPR_INDEXALPHA:
pal = gEngfuncs.FS_LoadImage( "#gradient.pal", src, pal_bytes );
break;
case SPR_ALPHTEST:
pal = gEngfuncs.FS_LoadImage( "#masked.pal", src, pal_bytes );
break;
default:
pal = gEngfuncs.FS_LoadImage( "#texgamma.pal", src, pal_bytes );
break;
}
pframetype = (const byte *)(src + pal_bytes);
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else
{
gEngfuncs.Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be less or equal than 256)\n", mod->name, *numi );
return;
}
if( mod->numframes < 1 )
return;
for( i = 0; i < mod->numframes; i++ )
{
frametype_t frametype;
dframetype_t dframetype;
memcpy( &dframetype, pframetype, sizeof( dframetype ));
frametype = dframetype.type;
psprite->frames[i].type = (spriteframetype_t)frametype;
switch( frametype )
{
case FRAME_SINGLE:
Q_strncpy( group_suffix, "frame", sizeof( group_suffix ));
pframetype = R_SpriteLoadFrame( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_GROUP:
Q_strncpy( group_suffix, "group", sizeof( group_suffix ));
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_ANGLED:
Q_strncpy( group_suffix, "angle", sizeof( group_suffix ));
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
}
if( pframetype == NULL ) break; // technically an error
}
if( loaded ) *loaded = true; // done
}
/*
====================
Mod_UnloadSpriteModel
release sprite model and frames
====================
*/
void Mod_SpriteUnloadTextures( void *data )
{
msprite_t *psprite = data;
int i;
if( !data )
return;
// release all textures
for( i = 0; i < psprite->numframes; i++ )
{
if( !psprite->frames[i].frameptr )
continue;
if( psprite->frames[i].type == SPR_SINGLE )
{
GL_FreeTexture( psprite->frames[i].frameptr->gl_texturenum );
}
else
{
mspritegroup_t *pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr;
int j;
for( j = 0; j < pspritegroup->numframes; j++ )
{
if( pspritegroup->frames[j] )
GL_FreeTexture( pspritegroup->frames[j]->gl_texturenum );
}
}
}
}
/*
================
R_GetSpriteFrame
assume pModel is valid
================
*/
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe = NULL;
float *pintervals, fullinterval;
int i, numframes;
float targettime;
Assert( pModel != NULL );
psprite = pModel->cache.data;
if( frame < 0 )
{
frame = 0;
}
else if( frame >= psprite->numframes )
{
if( frame > psprite->numframes )
gEngfuncs.Con_Printf( S_WARN "%s: no such frame %d (%s)\n", __func__, frame, pModel->name );
frame = psprite->numframes - 1;
}
if( psprite->frames[frame].type == SPR_SINGLE )
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if( psprite->frames[frame].type == SPR_GROUP )
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes-1];
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by zero
targettime = gp_cl->time - ((int)( gp_cl->time / fullinterval )) * fullinterval;
for( i = 0; i < (numframes - 1); i++ )
{
if( pintervals[i] > targettime )
break;
}
pspriteframe = pspritegroup->frames[i];
}
else if( psprite->frames[frame].type == FRAME_ANGLED )
{
int angleframe = (int)(Q_rint(( RI.viewangles[1] - yaw + 45.0f ) / 360 * 8) - 4) & 7;
// e.g. doom-style sprite monsters
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[angleframe];
}
return pspriteframe;
}
/* /*
================ ================
R_GetSpriteFrameInterpolant R_GetSpriteFrameInterpolant
@@ -464,7 +141,7 @@ static float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **old
{ {
// e.g. doom-style sprite monsters // e.g. doom-style sprite monsters
float yaw = ent->angles[YAW]; float yaw = ent->angles[YAW];
int angleframe = (int)(Q_rint(( RI.viewangles[1] - yaw + 45.0f ) / 360 * 8) - 4) & 7; int angleframe = (int)(Q_rint(( RI.rvp.viewangles[1] - yaw + 45.0f ) / 360 * 8) - 4) & 7;
if( m_fDoInterp ) if( m_fDoInterp )
{ {
@@ -533,8 +210,6 @@ static qboolean R_CullSpriteModel( cl_entity_t *e, vec3_t origin )
VectorScale( e->model->mins, scale, sprite_mins ); VectorScale( e->model->mins, scale, sprite_mins );
VectorScale( e->model->maxs, scale, sprite_maxs ); VectorScale( e->model->maxs, scale, sprite_maxs );
sprite_radius = RadiusFromBounds( sprite_mins, sprite_maxs );
VectorAdd( sprite_mins, origin, sprite_mins ); VectorAdd( sprite_mins, origin, sprite_mins );
VectorAdd( sprite_maxs, origin, sprite_maxs ); VectorAdd( sprite_maxs, origin, sprite_maxs );
@@ -554,12 +229,12 @@ static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, flo
vec3_t glowDist; vec3_t glowDist;
pmtrace_t *tr; pmtrace_t *tr;
VectorSubtract( origin, RI.vieworg, glowDist ); VectorSubtract( origin, RI.rvp.vieworigin, glowDist );
dist = VectorLength( glowDist ); dist = VectorLength( glowDist );
if( RP_NORMALPASS( )) if( !FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
{ {
tr = gEngfuncs.EV_VisTraceLine( RI.vieworg, origin, r_traceglow.value ? PM_GLASS_IGNORE : (PM_GLASS_IGNORE|PM_STUDIO_IGNORE)); tr = gEngfuncs.EV_VisTraceLine( RI.rvp.vieworigin, origin, r_traceglow.value ? PM_GLASS_IGNORE : (PM_GLASS_IGNORE|PM_STUDIO_IGNORE));
if(( 1.0f - tr->fraction ) * dist > 8.0f ) if(( 1.0f - tr->fraction ) * dist > 8.0f )
return 0.0f; return 0.0f;
@@ -591,9 +266,9 @@ static qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, float *pscale )
TriWorldToScreen( origin, v ); TriWorldToScreen( origin, v );
if( v[0] < RI.viewport[0] || v[0] > RI.viewport[0] + RI.viewport[2] ) if( v[0] < RI.rvp.viewport[0] || v[0] > RI.rvp.viewport[0] + RI.rvp.viewport[2] )
return true; // do scissor return true; // do scissor
if( v[1] < RI.viewport[1] || v[1] > RI.viewport[1] + RI.viewport[3] ) if( v[1] < RI.rvp.viewport[1] || v[1] > RI.rvp.viewport[1] + RI.rvp.viewport[3] )
return true; // do scissor return true; // do scissor
blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale ); blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale );
@@ -707,7 +382,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
vec3_t v_forward, v_right, v_up; vec3_t v_forward, v_right, v_up;
vec3_t origin, color, color2 = { 0.0f }; vec3_t origin, color, color2 = { 0.0f };
if( RI.params & RP_ENVVIEW ) if( FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
return; return;
model = e->model; model = e->model;
@@ -800,7 +475,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
if( R_SpriteAllowLerping( e, psprite )) if( R_SpriteAllowLerping( e, psprite ))
lerp = R_GetSpriteFrameInterpolant( e, &oldframe, &frame ); lerp = R_GetSpriteFrameInterpolant( e, &oldframe, &frame );
else frame = oldframe = R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] ); else frame = oldframe = gEngfuncs.R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );
type = psprite->type; type = psprite->type;
@@ -816,7 +491,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
VectorSubtract( origin, v_forward, origin ); VectorSubtract( origin, v_forward, origin );
break; break;
case SPR_FACING_UPRIGHT: case SPR_FACING_UPRIGHT:
VectorSet( v_right, origin[1] - RI.vieworg[1], -(origin[0] - RI.vieworg[0]), 0.0f ); VectorSet( v_right, origin[1] - RI.rvp.vieworigin[1], -(origin[0] - RI.rvp.vieworigin[0]), 0.0f );
VectorSet( v_up, 0.0f, 0.0f, 1.0f ); VectorSet( v_up, 0.0f, 0.0f, 1.0f );
VectorNormalize( v_right ); VectorNormalize( v_right );
break; break;

View File

@@ -167,7 +167,7 @@ init current time for a given model
*/ */
static void R_StudioSetupTimings( void ) static void R_StudioSetupTimings( void )
{ {
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{ {
// synchronize with server time // synchronize with server time
g_studio.time = gp_cl->time; g_studio.time = gp_cl->time;
@@ -369,23 +369,12 @@ pfnPlayerInfo
*/ */
player_info_t *pfnPlayerInfo( int index ) player_info_t *pfnPlayerInfo( int index )
{ {
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
index = -1; index = -1;
return gEngfuncs.pfnPlayerInfo( index ); return gEngfuncs.pfnPlayerInfo( index );
} }
/*
===============
pfnMod_ForName
===============
*/
static model_t *pfnMod_ForName( const char *model, int crash )
{
return gEngfuncs.Mod_ForName( model, crash, false );
}
/* /*
=============== ===============
pfnGetPlayerState pfnGetPlayerState
@@ -394,23 +383,12 @@ pfnGetPlayerState
*/ */
static entity_state_t *R_StudioGetPlayerState( int index ) static entity_state_t *R_StudioGetPlayerState( int index )
{ {
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return &RI.currententity->curstate; return &RI.currententity->curstate;
return gEngfuncs.pfnGetPlayerState( index ); return gEngfuncs.pfnGetPlayerState( index );
} }
/*
===============
pfnGetViewEntity
===============
*/
static cl_entity_t *pfnGetViewEntity( void )
{
return tr.viewent;
}
/* /*
=============== ===============
pfnGetEngineTimes pfnGetEngineTimes
@@ -432,23 +410,12 @@ pfnGetViewInfo
*/ */
static void pfnGetViewInfo( float *origin, float *upv, float *rightv, float *forwardv ) static void pfnGetViewInfo( float *origin, float *upv, float *rightv, float *forwardv )
{ {
if( origin ) VectorCopy( RI.vieworg, origin ); if( origin ) VectorCopy( RI.rvp.vieworigin, origin );
if( forwardv ) VectorCopy( RI.vforward, forwardv ); if( forwardv ) VectorCopy( RI.vforward, forwardv );
if( rightv ) VectorCopy( RI.vright, rightv ); if( rightv ) VectorCopy( RI.vright, rightv );
if( upv ) VectorCopy( RI.vup, upv ); if( upv ) VectorCopy( RI.vup, upv );
} }
/*
===============
R_GetChromeSprite
===============
*/
static model_t *R_GetChromeSprite( void )
{
return gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE );
}
/* /*
=============== ===============
pfnGetModelCounters pfnGetModelCounters
@@ -461,18 +428,6 @@ static void pfnGetModelCounters( int **s, int **a )
*a = &r_stats.c_studio_models_drawn; *a = &r_stats.c_studio_models_drawn;
} }
/*
===============
pfnGetAliasScale
===============
*/
static void pfnGetAliasScale( float *x, float *y )
{
if( x ) *x = 1.0f;
if( y ) *y = 1.0f;
}
/* /*
=============== ===============
pfnStudioGetBoneTransform pfnStudioGetBoneTransform
@@ -495,17 +450,6 @@ static float ****pfnStudioGetLightTransform( void )
return (float ****)g_studio.lighttransform; return (float ****)g_studio.lighttransform;
} }
/*
===============
pfnStudioGetAliasTransform
===============
*/
static float ***pfnStudioGetAliasTransform( void )
{
return NULL;
}
/* /*
=============== ===============
pfnStudioGetRotationMatrix pfnStudioGetRotationMatrix
@@ -1328,7 +1272,7 @@ static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
if( !plight || !ent || !ent->model ) if( !plight || !ent || !ent->model )
return; return;
if( !RI.drawWorld || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT )) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT ))
{ {
plight->shadelight = 0; plight->shadelight = 0;
plight->ambientlight = 192; plight->ambientlight = 192;
@@ -1441,7 +1385,7 @@ static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ ) for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{ {
dl = &tr.dlights[lnum]; dl = &gp_dlights[lnum];
if( dl->die < g_studio.time || !r_dynamic->value ) if( dl->die < g_studio.time || !r_dynamic->value )
continue; continue;
@@ -2662,7 +2606,7 @@ static model_t *R_StudioSetupPlayerModel( int index )
state = &g_studio.player_models[index]; state = &g_studio.player_models[index];
// g-cont: force for "dev-mode", non-local games and menu preview // g-cont: force for "dev-mode", non-local games and menu preview
if(( gpGlobals->developer || !ENGINE_GET_PARM( PARM_LOCAL_GAME ) || !RI.drawWorld ) && info->model[0] ) if(( gpGlobals->developer || !ENGINE_GET_PARM( PARM_LOCAL_GAME ) || !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) ) && info->model[0] )
{ {
if( Q_strcmp( state->name, info->model )) if( Q_strcmp( state->name, info->model ))
{ {
@@ -2914,19 +2858,7 @@ R_StudioSetChromeOrigin
*/ */
static void R_StudioSetChromeOrigin( void ) static void R_StudioSetChromeOrigin( void )
{ {
VectorCopy( RI.vieworg, g_studio.chrome_origin ); VectorCopy( RI.rvp.vieworigin, g_studio.chrome_origin );
}
/*
===============
pfnIsHardware
Xash3D is always works in hardware mode
===============
*/
static int pfnIsHardware( void )
{
return 1; // 0 is Software, 1 is OpenGL, 2 is Direct3D
} }
/* /*
@@ -3165,7 +3097,7 @@ static void R_StudioRenderModel( void )
R_StudioRenderFinal( ); R_StudioRenderFinal( );
R_StudioSetForceFaceFlags( STUDIO_NF_CHROME ); R_StudioSetForceFaceFlags( STUDIO_NF_CHROME );
TriSpriteTexture( R_GetChromeSprite(), 0 ); TriSpriteTexture( gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE ), 0 );
RI.currententity->curstate.renderfx = kRenderFxGlowShell; RI.currententity->curstate.renderfx = kRenderFxGlowShell;
R_StudioRenderFinal( ); R_StudioRenderFinal( );
@@ -3398,7 +3330,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer )
if( flags & STUDIO_RENDER ) if( flags & STUDIO_RENDER )
{ {
// change body if it's a menu entity // change body if it's a menu entity
if( cl_himodels->value && ( RI.currentmodel != RI.currententity->model || !RI.drawWorld )) if( cl_himodels->value && ( RI.currentmodel != RI.currententity->model || !FBitSet( RI.rvp.flags, RF_DRAW_WORLD )))
{ {
// show highest resolution multiplayer model // show highest resolution multiplayer model
RI.currententity->curstate.body = 255; RI.currententity->curstate.body = 255;
@@ -3554,7 +3486,7 @@ R_StudioDrawModelInternal
*/ */
static void R_StudioDrawModelInternal( cl_entity_t *e, int flags ) static void R_StudioDrawModelInternal( cl_entity_t *e, int flags )
{ {
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{ {
if( e->player ) if( e->player )
R_StudioDrawPlayer( flags, &e->curstate ); R_StudioDrawPlayer( flags, &e->curstate );
@@ -3589,7 +3521,7 @@ R_DrawStudioModel
*/ */
void R_DrawStudioModel( cl_entity_t *e ) void R_DrawStudioModel( cl_entity_t *e )
{ {
if( FBitSet( RI.params, RP_ENVVIEW )) if( FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ))
return; return;
R_StudioSetupTimings(); R_StudioSetupTimings();
@@ -3644,7 +3576,7 @@ void R_RunViewmodelEvents( void )
return; return;
// ignore in thirdperson, camera view or client is died // ignore in thirdperson, camera view or client is died
if( !RP_NORMALPASS() || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer()) if( FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ) || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer())
return; return;
RI.currententity = tr.viewent; RI.currententity = tr.viewent;
@@ -3662,20 +3594,6 @@ void R_RunViewmodelEvents( void )
R_StudioDrawModelInternal( RI.currententity, STUDIO_EVENTS ); R_StudioDrawModelInternal( RI.currententity, STUDIO_EVENTS );
} }
/*
=================
R_GatherPlayerLight
=================
*/
void R_GatherPlayerLight( void )
{
cl_entity_t *view = tr.viewent;
colorVec c;
c = R_LightPoint( view->origin );
gEngfuncs.SetLocalLightLevel( ( c.r + c.g + c.b ) / 3 );
}
/* /*
================= =================
R_DrawViewModel R_DrawViewModel
@@ -3685,7 +3603,7 @@ void R_DrawViewModel( void )
{ {
cl_entity_t *view = tr.viewent; cl_entity_t *view = tr.viewent;
R_GatherPlayerLight(); R_GatherPlayerLight( view );
if( r_drawviewmodel->value == 0 ) if( r_drawviewmodel->value == 0 )
return; return;
@@ -3694,7 +3612,7 @@ void R_DrawViewModel( void )
return; return;
// ignore in thirdperson, camera view or client is died // ignore in thirdperson, camera view or client is died
if( !RP_NORMALPASS() || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer()) if( FBitSet( RI.rvp.flags, RF_DRAW_CUBEMAP ) || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer())
return; return;
tr.blend = CL_FxBlend( view ) / 255.0f; tr.blend = CL_FxBlend( view ) / 255.0f;
@@ -3881,115 +3799,53 @@ void Mod_StudioUnloadTextures( void *data )
} }
} }
static model_t *pfnModelHandle( int modelindex ) qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefaultDraw )
{ {
if( modelindex < 0 || modelindex >= MAX_MODELS )
return NULL;
return CL_ModelHandle( modelindex );
}
static void *pfnMod_CacheCheck( struct cache_user_s *c )
{
return gEngfuncs.Mod_CacheCheck( c );
}
static void *pfnMod_StudioExtradata( model_t *mod )
{
return gEngfuncs.Mod_Extradata( mod_studio, mod );
}
static void pfnMod_LoadCacheFile( const char *path, struct cache_user_s *cu )
{
gEngfuncs.Mod_LoadCacheFile( path, cu );
}
static cvar_t *pfnGetCvarPointer( const char *name )
{
return (cvar_t*)gEngfuncs.pfnGetCvarPointer( name );
}
static void *pfnMod_Calloc( int number, size_t size )
{
return gEngfuncs.Mod_Calloc( number, size );
}
static engine_studio_api_t gStudioAPI =
{
pfnMod_Calloc,
pfnMod_CacheCheck,
pfnMod_LoadCacheFile,
pfnMod_ForName,
pfnMod_StudioExtradata,
pfnModelHandle,
pfnGetCurrentEntity,
pfnPlayerInfo,
R_StudioGetPlayerState,
pfnGetViewEntity,
pfnGetEngineTimes,
pfnGetCvarPointer,
pfnGetViewInfo,
R_GetChromeSprite,
pfnGetModelCounters,
pfnGetAliasScale,
pfnStudioGetBoneTransform,
pfnStudioGetLightTransform,
pfnStudioGetAliasTransform,
pfnStudioGetRotationMatrix,
R_StudioSetupModel,
R_StudioCheckBBox,
R_StudioDynamicLight,
R_StudioEntityLight,
R_StudioSetupLighting,
R_StudioDrawPoints,
R_StudioDrawHulls,
R_StudioDrawAbsBBox,
R_StudioDrawBones,
(void*)R_StudioSetupSkin,
R_StudioSetRemapColors,
R_StudioSetupPlayerModel,
R_StudioClientEvents,
R_StudioGetForceFaceFlags,
R_StudioSetForceFaceFlags,
(void*)R_StudioSetHeader,
R_StudioSetRenderModel,
R_StudioSetupRenderer,
R_StudioRestoreRenderer,
R_StudioSetChromeOrigin,
pfnIsHardware,
GL_StudioDrawShadow,
GL_StudioSetRenderMode,
R_StudioSetRenderamt,
R_StudioSetCullState,
R_StudioRenderShadow,
};
static r_studio_interface_t gStudioDraw =
{
STUDIO_INTERFACE_VERSION,
R_StudioDrawModel,
R_StudioDrawPlayer,
};
/*
===============
CL_InitStudioAPI
Initialize client studio
===============
*/
void CL_InitStudioAPI( void )
{
pStudioDraw = &gStudioDraw;
// trying to grab them from client.dll
cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" ); cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" );
// Xash will be used internal StudioModelRenderer api->GetCurrentEntity = pfnGetCurrentEntity;
if( gEngfuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI )) api->PlayerInfo = pfnPlayerInfo;
return; api->GetPlayerState = R_StudioGetPlayerState;
api->GetTimes = pfnGetEngineTimes;
api->GetViewInfo = pfnGetViewInfo;
api->GetModelCounters = pfnGetModelCounters;
api->StudioGetBoneTransform = pfnStudioGetBoneTransform;
api->StudioGetLightTransform = pfnStudioGetLightTransform;
api->StudioGetRotationMatrix = pfnStudioGetRotationMatrix;
api->StudioSetupModel = R_StudioSetupModel;
api->StudioCheckBBox = R_StudioCheckBBox;
api->StudioDynamicLight = R_StudioDynamicLight;
api->StudioEntityLight = R_StudioEntityLight;
api->StudioSetupLighting = R_StudioSetupLighting;
api->StudioDrawPoints = R_StudioDrawPoints;
api->StudioDrawHulls = R_StudioDrawHulls;
api->StudioDrawAbsBBox = R_StudioDrawAbsBBox;
api->StudioDrawBones = R_StudioDrawBones;
api->StudioSetupSkin = (void *)R_StudioSetupSkin;
api->StudioSetRemapColors = R_StudioSetRemapColors;
api->SetupPlayerModel = R_StudioSetupPlayerModel;
api->StudioClientEvents = R_StudioClientEvents;
api->GetForceFaceFlags = R_StudioGetForceFaceFlags;
api->SetForceFaceFlags = R_StudioSetForceFaceFlags;
api->StudioSetHeader = (void *)R_StudioSetHeader;
api->SetRenderModel = R_StudioSetRenderModel;
api->SetupRenderer = R_StudioSetupRenderer;
api->RestoreRenderer = R_StudioRestoreRenderer;
api->SetChromeOrigin = R_StudioSetChromeOrigin;
api->GL_StudioDrawShadow = GL_StudioDrawShadow;
api->GL_SetRenderMode = GL_StudioSetRenderMode;
api->StudioSetRenderamt = R_StudioSetRenderamt;
api->StudioSetCullState = R_StudioSetCullState;
api->StudioRenderShadow = R_StudioRenderShadow;
// NOTE: we always return true even if game interface was not correct pDefaultDraw->version = STUDIO_INTERFACE_VERSION;
// because we need Draw our StudioModels pDefaultDraw->StudioDrawModel = R_StudioDrawModel;
// just restore pointer to builtin function pDefaultDraw->StudioDrawPlayer = R_StudioDrawPlayer;
pStudioDraw = &gStudioDraw;
return true;
}
void R_StudioSetDrawInterface( r_studio_interface_t *pDraw )
{
pStudioDraw = pDraw;
} }

View File

@@ -226,10 +226,10 @@ int TriWorldToScreen( const float *world, float *screen )
retval = R_WorldToScreen( world, screen ); retval = R_WorldToScreen( world, screen );
screen[0] = 0.5f * screen[0] * (float)RI.viewport[2]; screen[0] = 0.5f * screen[0] * (float)RI.rvp.viewport[2];
screen[1] = -0.5f * screen[1] * (float)RI.viewport[3]; screen[1] = -0.5f * screen[1] * (float)RI.rvp.viewport[3];
screen[0] += 0.5f * (float)RI.viewport[2]; screen[0] += 0.5f * (float)RI.rvp.viewport[2];
screen[1] += 0.5f * (float)RI.viewport[3]; screen[1] += 0.5f * (float)RI.rvp.viewport[3];
return retval; return retval;
} }
@@ -245,7 +245,10 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
{ {
int gl_texturenum; int gl_texturenum;
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) == 0 ) if( !pSpriteModel || pSpriteModel->type != mod_sprite || !pSpriteModel->cache.data )
return 0;
if(( gl_texturenum = gEngfuncs.R_GetSpriteFrame( pSpriteModel, frame, 0.0f )->gl_texturenum ) == 0 )
return 0; return 0;
if( gl_texturenum <= 0 || gl_texturenum >= MAX_TEXTURES ) if( gl_texturenum <= 0 || gl_texturenum >= MAX_TEXTURES )

View File

@@ -339,10 +339,6 @@ R_DrawSkybox
*/ */
void R_DrawSkyBox( void ) void R_DrawSkyBox( void )
{ {
int i;
RI.isSkyVisible = true;
// don't fogging skybox (this fix old Half-Life bug) // don't fogging skybox (this fix old Half-Life bug)
if( !RI.fogSkybox ) R_AllowFog( false ); if( !RI.fogSkybox ) R_AllowFog( false );
@@ -353,7 +349,7 @@ void R_DrawSkyBox( void )
pglDisable( GL_ALPHA_TEST ); pglDisable( GL_ALPHA_TEST );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
for( i = 0; i < SKYBOX_MAX_SIDES; i++ ) for( int i = 0; i < SKYBOX_MAX_SIDES; i++ )
{ {
if( RI.skyMins[0][i] >= RI.skyMaxs[0][i] || RI.skyMins[1][i] >= RI.skyMaxs[1][i] ) if( RI.skyMins[0][i] >= RI.skyMaxs[0][i] || RI.skyMins[1][i] >= RI.skyMaxs[1][i] )
continue; continue;
@@ -421,7 +417,7 @@ static void R_CloudTexCoord( const vec3_t v, float speed, float *s, float *t )
speedscale = gp_cl->time * speed; speedscale = gp_cl->time * speed;
speedscale -= (int)speedscale & ~127; speedscale -= (int)speedscale & ~127;
VectorSubtract( v, RI.vieworg, dir ); VectorSubtract( v, RI.rvp.vieworigin, dir );
dir[2] *= 3.0f; // flatten the sphere dir[2] *= 3.0f; // flatten the sphere
length = VectorLength( dir ); length = VectorLength( dir );
@@ -533,16 +529,12 @@ Quake-style clouds
*/ */
void R_DrawClouds( void ) void R_DrawClouds( void )
{ {
int i;
RI.isSkyVisible = true;
if( RI.fogEnabled ) if( RI.fogEnabled )
pglFogf( GL_FOG_DENSITY, RI.fogDensity * 0.25f ); pglFogf( GL_FOG_DENSITY, RI.fogDensity * 0.25f );
pglDepthFunc( GL_GEQUAL ); pglDepthFunc( GL_GEQUAL );
pglDepthMask( GL_FALSE ); pglDepthMask( GL_FALSE );
for( i = 0; i < SKYBOX_MAX_SIDES; i++ ) for( int i = 0; i < SKYBOX_MAX_SIDES; i++ )
{ {
if( RI.skyMins[0][i] >= RI.skyMaxs[0][i] || RI.skyMins[1][i] >= RI.skyMaxs[1][i] ) if( RI.skyMins[0][i] >= RI.skyMaxs[0][i] || RI.skyMins[1][i] >= RI.skyMaxs[1][i] )
continue; continue;

View File

@@ -25,7 +25,7 @@ def configure(conf):
conf.check_cc(lib='log') conf.check_cc(lib='log')
def build(bld): def build(bld):
libs = [ 'engine_includes', 'werror' ] libs = [ 'ref_common', 'engine_includes', 'werror' ]
# on PSVita do not link any libraries that are already in the main executable, but add the includes target # on PSVita do not link any libraries that are already in the main executable, but add the includes target
if bld.env.DEST_OS == 'psvita': if bld.env.DEST_OS == 'psvita':
libs += [ 'sdk_includes', 'vgl_shim' ] libs += [ 'sdk_includes', 'vgl_shim' ]

View File

@@ -49,6 +49,37 @@ static void R_SimpleStubBool( qboolean unused )
; ;
} }
static qboolean R_StudioFillAPI( struct engine_studio_api_s *api, struct r_studio_interface_s *pDefaultDraw )
{
return false;
}
static void R_StudioSetDrawInterface( struct r_studio_interface_s *pDraw )
{
;
}
static void R_GetDetailScaleForTexture( int texture, float *xScale, float *yScale )
{
if( xScale ) *xScale = 1.0f;
if( yScale ) *yScale = 1.0f;
}
static void R_SetDetailScaleForTexture( int texture, float xScale, float yScale )
{
;
}
static void R_FillRenderAPI( render_api_t *api )
{
;
}
static void R_FillTriAPI( triangleapi_t *api )
{
;
}
static qboolean R_Init( void ) static qboolean R_Init( void )
{ {
gEngfuncs.R_Init_Video( REF_SOFTWARE ); gEngfuncs.R_Init_Video( REF_SOFTWARE );
@@ -75,11 +106,6 @@ static qboolean R_AddEntity( struct cl_entity_s *clent, int type )
return true; return true;
} }
static void CL_AddCustomBeam( cl_entity_t *pEnvBeam )
{
;
}
static void R_ProcessEntData( qboolean allocate, cl_entity_t *entities, unsigned int max_entities ) static void R_ProcessEntData( qboolean allocate, cl_entity_t *entities, unsigned int max_entities )
{ {
; ;
@@ -105,11 +131,6 @@ static void R_SetupSky( int *skytextures )
; ;
} }
static void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty )
{
;
}
static void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ) static void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum )
{ {
; ;
@@ -177,22 +198,6 @@ static void CL_RunLightStyles( lightstyle_t *ls )
} }
static void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite )
{
if( frameWidth )
*frameWidth = 0;
if( frameHeight )
*frameHeight = 0;
if( numFrames )
*numFrames = 0;
}
static int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
return 0;
}
static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buffer, size_t buffersize ) static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buffer, size_t buffersize )
{ {
@@ -219,11 +224,6 @@ static void CL_DrawBeams( int fTrans, BEAM *beams )
; ;
} }
static qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly )
{
return false;
}
static int RefGetParm( int parm, int arg ) static int RefGetParm( int parm, int arg )
{ {
return 0; return 0;
@@ -309,7 +309,7 @@ static void R_EntityRemoveDecals( struct model_s *mod )
; ;
} }
static void AVI_UploadRawFrame( int texture, int cols, int rows, int width, int height, const byte *data ) static void GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt )
{ {
; ;
} }
@@ -430,11 +430,6 @@ static void VGUI_SetupDrawing( qboolean rect )
; ;
} }
static void VGUI_UploadTextureBlock( int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight )
{
;
}
static const ref_interface_t gReffuncs = static const ref_interface_t gReffuncs =
{ {
.R_Init = R_Init, .R_Init = R_Init,
@@ -460,9 +455,7 @@ static const ref_interface_t gReffuncs =
.GL_SetRenderMode = R_SimpleStubInt, .GL_SetRenderMode = R_SimpleStubInt,
.R_AddEntity = R_AddEntity, .R_AddEntity = R_AddEntity,
.CL_AddCustomBeam = CL_AddCustomBeam,
.R_ProcessEntData = R_ProcessEntData, .R_ProcessEntData = R_ProcessEntData,
.R_Flush = R_SimpleStubUInt,
.R_ShowTextures = R_SimpleStub, .R_ShowTextures = R_SimpleStub,
@@ -472,7 +465,6 @@ static const ref_interface_t gReffuncs =
.R_SetupSky = R_SetupSky, .R_SetupSky = R_SetupSky,
.R_Set2DMode = R_SimpleStubBool, .R_Set2DMode = R_SimpleStubBool,
.R_DrawStretchRaw = R_DrawStretchRaw,
.R_DrawStretchPic = R_DrawStretchPic, .R_DrawStretchPic = R_DrawStretchPic,
.FillRGBA = FillRGBA, .FillRGBA = FillRGBA,
.WorldToScreen = WorldToScreen, .WorldToScreen = WorldToScreen,
@@ -489,14 +481,13 @@ static const ref_interface_t gReffuncs =
.R_StudioEstimateFrame = R_StudioEstimateFrame, .R_StudioEstimateFrame = R_StudioEstimateFrame,
.R_StudioLerpMovement = R_StudioLerpMovement, .R_StudioLerpMovement = R_StudioLerpMovement,
.CL_InitStudioAPI = R_SimpleStub, .R_StudioFillAPI = R_StudioFillAPI,
.R_StudioSetDrawInterface = R_StudioSetDrawInterface,
.R_SetSkyCloudsTextures = R_SetSkyCloudsTextures, .R_SetSkyCloudsTextures = R_SetSkyCloudsTextures,
.GL_SubdivideSurface = GL_SubdivideSurface, .GL_SubdivideSurface = GL_SubdivideSurface,
.CL_RunLightStyles = CL_RunLightStyles, .CL_RunLightStyles = CL_RunLightStyles,
.R_GetSpriteParms = R_GetSpriteParms,
.R_GetSpriteTexture = R_GetSpriteTexture,
.Mod_ProcessRenderData = Mod_ProcessRenderData, .Mod_ProcessRenderData = Mod_ProcessRenderData,
.Mod_StudioLoadTextures = Mod_StudioLoadTextures, .Mod_StudioLoadTextures = Mod_StudioLoadTextures,
@@ -504,47 +495,23 @@ static const ref_interface_t gReffuncs =
.CL_DrawParticles = CL_DrawParticles, .CL_DrawParticles = CL_DrawParticles,
.CL_DrawTracers = CL_DrawTracers, .CL_DrawTracers = CL_DrawTracers,
.CL_DrawBeams = CL_DrawBeams, .CL_DrawBeams = CL_DrawBeams,
.R_BeamCull = R_BeamCull,
.RefGetParm = RefGetParm, .RefGetParm = RefGetParm,
.GetDetailScaleForTexture = GetDetailScaleForTexture,
.GetExtraParmsForTexture = GetExtraParmsForTexture,
.GetFrameTime = GetFrameTime,
.R_SetCurrentEntity = R_SetCurrentEntity, .R_GetDetailScaleForTexture = R_GetDetailScaleForTexture,
.R_SetCurrentModel = R_SetCurrentModel, .R_SetDetailScaleForTexture = R_SetDetailScaleForTexture,
.GL_FindTexture = GL_FindTexture, .GL_CreateTexture = GL_CreateTexture,
.GL_TextureName = GL_TextureName, .GL_FindTexture = GL_FindTexture,
.GL_TextureData = GL_TextureData, .GL_TextureName = GL_TextureName,
.GL_LoadTexture = GL_LoadTexture, .GL_TextureData = GL_TextureData,
.GL_CreateTexture = GL_CreateTexture, .GL_LoadTexture = GL_LoadTexture,
.GL_LoadTextureArray = GL_LoadTextureArray, .GL_FreeTexture = R_SimpleStubUInt,
.GL_CreateTextureArray = GL_CreateTextureArray,
.GL_FreeTexture = R_SimpleStubUInt,
.R_OverrideTextureSourceSize = R_OverrideTextureSourceSize, .R_OverrideTextureSourceSize = R_OverrideTextureSourceSize,
.DrawSingleDecal = DrawSingleDecal, .GL_UpdateTexture = GL_UpdateTexture,
.R_DecalSetupVerts = R_DecalSetupVerts,
.R_EntityRemoveDecals = R_EntityRemoveDecals,
.AVI_UploadRawFrame = AVI_UploadRawFrame, .GL_Bind = GL_Bind,
.GL_Bind = GL_Bind,
.GL_SelectTexture = R_SimpleStubInt,
.GL_LoadTextureMatrix = GL_LoadTextureMatrix,
.GL_TexMatrixIdentity = R_SimpleStub,
.GL_CleanUpTextureUnits = R_SimpleStubInt,
.GL_TexGen = GL_TexGen,
.GL_TextureTarget = R_SimpleStubUInt,
.GL_TexCoordArrayMode = R_SimpleStubUInt,
.GL_UpdateTexSize = GL_UpdateTexSize,
.GL_Reserved0 = NULL,
.GL_Reserved1 = NULL,
.GL_DrawParticles = GL_DrawParticles,
.LightVec = LightVec,
.StudioGetTexture = StudioGetTexture,
.GL_RenderFrame = GL_RenderFrame, .GL_RenderFrame = GL_RenderFrame,
.GL_OrthoBounds = GL_OrthoBounds, .GL_OrthoBounds = GL_OrthoBounds,
@@ -552,24 +519,20 @@ static const ref_interface_t gReffuncs =
.Mod_GetCurrentVis = Mod_GetCurrentVis, .Mod_GetCurrentVis = Mod_GetCurrentVis,
.R_NewMap = R_SimpleStub, .R_NewMap = R_SimpleStub,
.R_ClearScene = R_SimpleStub, .R_ClearScene = R_SimpleStub,
.R_GetProcAddress = R_GetProcAddress,
.TriRenderMode = R_SimpleStubInt, .TriRenderMode = R_SimpleStubInt,
.Begin = R_SimpleStubInt, .Begin = R_SimpleStubInt,
.End = R_SimpleStub, .End = R_SimpleStub,
.Color4f = Color4f, .Color4f = Color4f,
.Color4ub = Color4ub, .Color4ub = Color4ub,
.TexCoord2f = TexCoord2f,
.Vertex3fv = Vertex3fv, .Vertex3fv = Vertex3fv,
.Vertex3f = Vertex3f, .Vertex3f = Vertex3f,
.Fog = Fog,
.ScreenToWorld = ScreenToWorld,
.GetMatrix = GetMatrix,
.FogParams = FogParams,
.CullFace = CullFace, .CullFace = CullFace,
.R_FillRenderAPI = R_FillRenderAPI,
.R_FillTriAPI = R_FillTriAPI,
.VGUI_SetupDrawing = VGUI_SetupDrawing, .VGUI_SetupDrawing = VGUI_SetupDrawing,
.VGUI_UploadTextureBlock = VGUI_UploadTextureBlock,
}; };
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals ); int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals );

View File

@@ -100,7 +100,7 @@ static void R_BeamComputeNormal( const vec3_t vStartPos, const vec3_t vNextPos,
VectorSubtract( vStartPos, vNextPos, vTangentY ); VectorSubtract( vStartPos, vNextPos, vTangentY );
// vDirToBeam = vector from viewer origin to beam // vDirToBeam = vector from viewer origin to beam
VectorSubtract( vStartPos, RI.vieworg, vDirToBeam ); VectorSubtract( vStartPos, RI.rvp.vieworigin, vDirToBeam );
// get a vector that is perpendicular to us and perpendicular to the beam. // get a vector that is perpendicular to us and perpendicular to the beam.
// this is used to fatten the beam. // this is used to fatten the beam.
@@ -116,35 +116,12 @@ R_BeamCull
Cull the beam by bbox Cull the beam by bbox
============== ==============
*/ */
qboolean GAME_EXPORT R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly ) static qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly )
{ {
// culling is undone in ref_soft // culling is undone in ref_soft
return false; return false;
} }
/*
================
CL_AddCustomBeam
Add the beam that encoded as custom entity
================
*/
void GAME_EXPORT CL_AddCustomBeam( cl_entity_t *pEnvBeam )
{
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
{
gEngfuncs.Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
return;
}
if( pEnvBeam )
{
tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = pEnvBeam;
tr.draw_list->num_beam_entities++;
}
}
/* /*
============================================================== ==============================================================
@@ -1023,7 +1000,7 @@ static void R_BeamDraw( BEAM *pbeam, float frametime )
float flDistance; float flDistance;
// fade the beam if the player's not looking at the source // fade the beam if the player's not looking at the source
VectorSubtract( RI.vieworg, pbeam->source, localDir ); VectorSubtract( RI.rvp.vieworigin, pbeam->source, localDir );
flDot = DotProduct( delta, localDir ); flDot = DotProduct( delta, localDir );
VectorScale( delta, flDot, vecProjection ); VectorScale( delta, flDot, vecProjection );
VectorSubtract( localDir, vecProjection, tmp ); VectorSubtract( localDir, vecProjection, tmp );

View File

@@ -643,14 +643,14 @@ R_RenderWorld
*/ */
void R_RenderWorld( void ) void R_RenderWorld( void )
{ {
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return; return;
// auto cycle the world frame for texture animation // auto cycle the world frame for texture animation
RI.currententity = CL_GetEntityByIndex( 0 ); RI.currententity = CL_GetEntityByIndex( 0 );
// RI.currententity->frame = (int)(gp_cl->time*2); // RI.currententity->frame = (int)(gp_cl->time*2);
VectorCopy( RI.vieworg, tr.modelorg ); VectorCopy( RI.rvp.vieworigin, tr.modelorg );
RI.currentmodel = WORLDMODEL; RI.currentmodel = WORLDMODEL;
r_pcurrentvertbase = RI.currentmodel->vertexes; r_pcurrentvertbase = RI.currentmodel->vertexes;

View File

@@ -15,24 +15,10 @@ GNU General Public License for more details.
#include "r_local.h" #include "r_local.h"
ref_api_t gEngfuncs;
ref_globals_t *gpGlobals;
ref_client_t *gp_cl;
ref_host_t *gp_host;
gl_globals_t tr; gl_globals_t tr;
ref_speeds_t r_stats; ref_speeds_t r_stats;
poolhandle_t r_temppool;
viddef_t vid; viddef_t vid;
void _Mem_Free( void *data, const char *filename, int fileline )
{
gEngfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
static void GAME_EXPORT R_ClearScreen( void ) static void GAME_EXPORT R_ClearScreen( void )
{ {
@@ -96,7 +82,6 @@ static void Mod_UnloadTextures( model_t *mod )
Mod_BrushUnloadTextures( mod ); Mod_BrushUnloadTextures( mod );
break; break;
case mod_sprite: case mod_sprite:
Mod_SpriteUnloadTextures( mod->cache.data );
break; break;
default: gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type ); default: gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type );
} }
@@ -122,7 +107,7 @@ static qboolean GAME_EXPORT Mod_ProcessRenderData( model_t *mod, qboolean create
loaded = true; loaded = true;
break; break;
case mod_sprite: case mod_sprite:
Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo ); loaded = true;
break; break;
default: default:
gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type ); gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type );
@@ -188,7 +173,7 @@ static int GL_RefGetParm( int parm, int arg )
return 0; // glState.activeTMU; return 0; // glState.activeTMU;
case PARM_LIGHTSTYLEVALUE: case PARM_LIGHTSTYLEVALUE:
arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 ); arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 );
return tr.lightstylevalue[arg]; return g_lightstylevalue[arg];
case PARM_MAX_IMAGE_UNITS: case PARM_MAX_IMAGE_UNITS:
return 0; // GL_MaxTextureUnits(); return 0; // GL_MaxTextureUnits();
case PARM_REBUILD_GAMMA: case PARM_REBUILD_GAMMA:
@@ -213,8 +198,13 @@ static void GAME_EXPORT R_GetDetailScaleForTexture( int texture, float *xScale,
{ {
// details are not implemented in ref_soft // details are not implemented in ref_soft
if( xScale ) *xScale = 0.0f; if( xScale ) *xScale = 1.0f;
if( yScale ) *yScale = 0.0f; if( yScale ) *yScale = 1.0f;
}
static void GAME_EXPORT R_SetDetailScaleForTexture( int texture, float xScale, float yScale )
{
// details are not implemented in ref_soft
} }
static void GAME_EXPORT R_GetExtraParmsForTexture( int texture, byte *red, byte *green, byte *blue, byte *density ) static void GAME_EXPORT R_GetExtraParmsForTexture( int texture, byte *red, byte *green, byte *blue, byte *density )
@@ -273,11 +263,6 @@ static void GAME_EXPORT R_ProcessEntData( qboolean allocate, cl_entity_t *entiti
tr.max_entities = max_entities; tr.max_entities = max_entities;
} }
static void GAME_EXPORT R_Flush( unsigned int flags )
{
// stub
}
// stubs // stubs
static void GAME_EXPORT GL_SetTexCoordArrayMode( uint mode ) static void GAME_EXPORT GL_SetTexCoordArrayMode( uint mode )
@@ -387,10 +372,6 @@ byte *GAME_EXPORT Mod_GetCurrentVis( void )
return NULL; return NULL;
} }
static void GAME_EXPORT VGUI_UploadTextureBlock( int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight )
{
}
static void GAME_EXPORT VGUI_SetupDrawing( qboolean rect ) static void GAME_EXPORT VGUI_SetupDrawing( qboolean rect )
{ {
} }
@@ -413,7 +394,42 @@ static void * GAME_EXPORT R_GetProcAddress( const char *name )
return gEngfuncs.GL_GetProcAddress( name ); return gEngfuncs.GL_GetProcAddress( name );
} }
static const ref_interface_t gReffuncs = static void R_FillRenderAPI( render_api_t *api )
{
api->GetExtraParmsForTexture = R_GetExtraParmsForTexture;
api->GetFrameTime = R_GetFrameTime;
api->R_SetCurrentEntity = R_SetCurrentEntity;
api->R_SetCurrentModel = R_SetCurrentModel;
api->GL_CreateTexture = GL_CreateTexture;
api->GL_LoadTextureArray = GL_LoadTextureArray;
api->GL_CreateTextureArray = GL_CreateTextureArray;
api->DrawSingleDecal = DrawSingleDecal;
api->R_DecalSetupVerts = R_DecalSetupVerts;
api->R_EntityRemoveDecals = R_EntityRemoveDecals;
api->GL_SelectTexture = GL_SelectTexture;
api->GL_LoadTextureMatrix = GL_LoadTexMatrixExt;
api->GL_TexMatrixIdentity = GL_LoadIdentityTexMatrix;
api->GL_CleanUpTextureUnits = GL_CleanUpTextureUnits;
api->GL_TexGen = GL_TexGen;
api->GL_TextureTarget = GL_TextureTarget;
api->GL_TexCoordArrayMode = GL_SetTexCoordArrayMode;
api->GL_UpdateTexSize = GL_UpdateTexSize;
api->GL_DrawParticles = CL_DrawParticlesExternal;
api->LightVec = R_LightVec;
api->StudioGetTexture = R_StudioGetTexture;
api->GL_GetProcAddress = R_GetProcAddress;
}
static void R_FillTriAPI( triangleapi_t *api )
{
api->TexCoord2f = TriTexCoord2f;
api->Fog = TriFog;
api->ScreenToWorld = R_ScreenToWorld;
api->GetMatrix = TriGetMatrix;
api->FogParams = TriFogParams;
}
const ref_interface_t gReffuncs =
{ {
R_Init, R_Init,
R_Shutdown, R_Shutdown,
@@ -438,9 +454,7 @@ static const ref_interface_t gReffuncs =
GL_SetRenderMode, GL_SetRenderMode,
R_AddEntity, R_AddEntity,
CL_AddCustomBeam,
R_ProcessEntData, R_ProcessEntData,
R_Flush,
R_ShowTextures, R_ShowTextures,
@@ -450,7 +464,6 @@ static const ref_interface_t gReffuncs =
R_SetupSky, R_SetupSky,
R_Set2DMode, R_Set2DMode,
R_DrawStretchRaw,
R_DrawStretchPic, R_DrawStretchPic,
CL_FillRGBA, CL_FillRGBA,
R_WorldToScreen, R_WorldToScreen,
@@ -467,14 +480,13 @@ static const ref_interface_t gReffuncs =
R_StudioEstimateFrame, R_StudioEstimateFrame,
R_StudioLerpMovement, R_StudioLerpMovement,
CL_InitStudioAPI, R_StudioFillAPI,
R_StudioSetDrawInterface,
R_SetSkyCloudsTextures, R_SetSkyCloudsTextures,
GL_SubdivideSurface, GL_SubdivideSurface,
CL_RunLightStyles, CL_RunLightStyles,
R_GetSpriteParms,
R_GetSpriteTexture,
Mod_ProcessRenderData, Mod_ProcessRenderData,
Mod_StudioLoadTextures, Mod_StudioLoadTextures,
@@ -482,47 +494,23 @@ static const ref_interface_t gReffuncs =
CL_DrawParticles, CL_DrawParticles,
CL_DrawTracers, CL_DrawTracers,
CL_DrawBeams, CL_DrawBeams,
R_BeamCull,
GL_RefGetParm, GL_RefGetParm,
R_GetDetailScaleForTexture, R_GetDetailScaleForTexture,
R_GetExtraParmsForTexture, R_SetDetailScaleForTexture,
R_GetFrameTime,
R_SetCurrentEntity,
R_SetCurrentModel,
GL_CreateTexture,
GL_FindTexture, GL_FindTexture,
GL_TextureName, GL_TextureName,
GL_TextureData, GL_TextureData,
GL_LoadTexture, GL_LoadTexture,
GL_CreateTexture,
GL_LoadTextureArray,
GL_CreateTextureArray,
GL_FreeTexture, GL_FreeTexture,
R_OverrideTextureSourceSize, R_OverrideTextureSourceSize,
DrawSingleDecal, GL_UpdateTexture,
R_DecalSetupVerts,
R_EntityRemoveDecals,
R_UploadStretchRaw,
GL_Bind, GL_Bind,
GL_SelectTexture,
GL_LoadTexMatrixExt,
GL_LoadIdentityTexMatrix,
GL_CleanUpTextureUnits,
GL_TexGen,
GL_TextureTarget,
GL_SetTexCoordArrayMode,
GL_UpdateTexSize,
NULL,
NULL,
CL_DrawParticlesExternal,
R_LightVec,
R_StudioGetTexture,
R_RenderFrame, R_RenderFrame,
Mod_SetOrthoBounds, Mod_SetOrthoBounds,
@@ -530,39 +518,19 @@ static const ref_interface_t gReffuncs =
Mod_GetCurrentVis, Mod_GetCurrentVis,
R_NewMap, R_NewMap,
R_ClearScene, R_ClearScene,
R_GetProcAddress,
TriRenderMode, TriRenderMode,
TriBegin, TriBegin,
TriEnd, TriEnd,
_TriColor4f, _TriColor4f,
_TriColor4ub, _TriColor4ub,
TriTexCoord2f,
TriVertex3fv, TriVertex3fv,
TriVertex3f, TriVertex3f,
TriFog,
R_ScreenToWorld,
TriGetMatrix,
TriFogParams,
TriCullFace, TriCullFace,
R_FillRenderAPI,
R_FillTriAPI,
VGUI_SetupDrawing, VGUI_SetupDrawing,
VGUI_UploadTextureBlock,
}; };
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals );
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals )
{
if( version != REF_API_VERSION )
return 0;
// fill in our callbacks
*funcs = gReffuncs;
gEngfuncs = *engfuncs;
gpGlobals = globals;
gp_cl = (ref_client_t *)ENGINE_GET_PARM( PARM_GET_CLIENT_PTR );
gp_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR );
return REF_API_VERSION;
}

View File

@@ -31,39 +31,6 @@ void R_GetTextureParms( int *w, int *h, int texnum )
*h = glt->srcHeight; *h = glt->srcHeight;
} }
/*
=============
R_GetSpriteParms
same as GetImageParms but used
for sprite models
=============
*/
void GAME_EXPORT R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite )
{
mspriteframe_t *pFrame;
if( !pSprite || pSprite->type != mod_sprite )
return; // bad model ?
pFrame = R_GetSpriteFrame( pSprite, currentFrame, 0.0f );
if( frameWidth )
*frameWidth = pFrame->width;
if( frameHeight )
*frameHeight = pFrame->height;
if( numFrames )
*numFrames = pSprite->numframes;
}
int GAME_EXPORT R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
if( !m_pSpriteModel || m_pSpriteModel->type != mod_sprite || !m_pSpriteModel->cache.data )
return 0;
return R_GetSpriteFrame( m_pSpriteModel, frame, 0.0f )->gl_texturenum;
}
/* /*
============= =============
Draw_StretchPicImplementation Draw_StretchPicImplementation
@@ -252,19 +219,10 @@ void Draw_Fill( int x, int y, int w, int h )
/* /*
============= =============
R_DrawStretchRaw GL_UpdateTexture
============= =============
*/ */
void GAME_EXPORT R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) void GAME_EXPORT GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt )
{
}
/*
=============
R_UploadStretchRaw
=============
*/
void GAME_EXPORT R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data )
{ {
} }

View File

@@ -877,7 +877,7 @@ static void D_TurbulentSurf( surf_t *s )
// TODO: store once at start of frame // TODO: store once at start of frame
RI.currententity = s->entity; // FIXME: make this passed in to RI.currententity = s->entity; // FIXME: make this passed in to
// R_RotateBmodel () // R_RotateBmodel ()
VectorSubtract( RI.vieworg, RI.currententity->origin, VectorSubtract( RI.rvp.vieworigin, RI.currententity->origin,
local_modelorg ); local_modelorg );
TransformVector( local_modelorg, transformed_modelorg ); TransformVector( local_modelorg, transformed_modelorg );
@@ -940,7 +940,7 @@ static void D_AlphaSurf( surf_t *s )
// TODO: store once at start of frame // TODO: store once at start of frame
RI.currententity = s->entity; // FIXME: make this passed in to RI.currententity = s->entity; // FIXME: make this passed in to
// R_RotateBmodel () // R_RotateBmodel ()
VectorSubtract( RI.vieworg, RI.currententity->origin, local_modelorg ); VectorSubtract( RI.rvp.vieworigin, RI.currententity->origin, local_modelorg );
TransformVector( local_modelorg, transformed_modelorg ); TransformVector( local_modelorg, transformed_modelorg );
R_RotateBmodel(); // FIXME: don't mess with the frustum, R_RotateBmodel(); // FIXME: don't mess with the frustum,
@@ -1021,7 +1021,7 @@ static void D_SolidSurf( surf_t *s )
// TODO: store once at start of frame // TODO: store once at start of frame
RI.currententity = s->entity; // FIXME: make this passed in to RI.currententity = s->entity; // FIXME: make this passed in to
// R_RotateBmodel () // R_RotateBmodel ()
VectorSubtract( RI.vieworg, RI.currententity->origin, local_modelorg ); VectorSubtract( RI.rvp.vieworigin, RI.currententity->origin, local_modelorg );
TransformVector( local_modelorg, transformed_modelorg ); TransformVector( local_modelorg, transformed_modelorg );
R_RotateBmodel(); // FIXME: don't mess with the frustum, R_RotateBmodel(); // FIXME: don't mess with the frustum,
@@ -1123,7 +1123,7 @@ void D_DrawSurfaces( void )
surf_t *s; surf_t *s;
// currententity = NULL; //&r_worldentity; // currententity = NULL; //&r_worldentity;
VectorSubtract( RI.vieworg, vec3_origin, tr.modelorg ); VectorSubtract( RI.rvp.vieworigin, vec3_origin, tr.modelorg );
TransformVector( tr.modelorg, transformed_modelorg ); TransformVector( tr.modelorg, transformed_modelorg );
VectorCopy( transformed_modelorg, world_transformed_modelorg ); VectorCopy( transformed_modelorg, world_transformed_modelorg );
@@ -1148,7 +1148,7 @@ void D_DrawSurfaces( void )
D_DrawflatSurfaces(); D_DrawflatSurfaces();
// RI.currententity = NULL; //&r_worldentity; // RI.currententity = NULL; //&r_worldentity;
VectorSubtract( RI.vieworg, vec3_origin, tr.modelorg ); VectorSubtract( RI.rvp.vieworigin, vec3_origin, tr.modelorg );
R_TransformFrustum(); R_TransformFrustum();
} }

View File

@@ -115,98 +115,6 @@ static void GL_SetTextureDimensions( image_t *tex, int width, int height, int de
tex->depth = Q_max( 1, depth ); tex->depth = Q_max( 1, depth );
} }
/*
=================
GL_ResampleTexture
Assume input buffer is RGBA
=================
*/
byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int outWidth, int outHeight, qboolean isNormalMap )
{
uint frac, fracStep;
uint *in = (uint *)source;
uint p1[0x1000], p2[0x1000];
byte *pix1, *pix2, *pix3, *pix4;
uint *out, *inRow1, *inRow2;
static byte *scaledImage = NULL; // pointer to a scaled image
vec3_t normal;
int i, x, y;
if( !source )
return NULL;
scaledImage = Mem_Realloc( r_temppool, scaledImage, outWidth * outHeight * 4 );
fracStep = inWidth * 0x10000 / outWidth;
out = (uint *)scaledImage;
frac = fracStep >> 2;
for( i = 0; i < outWidth; i++ )
{
p1[i] = 4 * ( frac >> 16 );
frac += fracStep;
}
frac = ( fracStep >> 2 ) * 3;
for( i = 0; i < outWidth; i++ )
{
p2[i] = 4 * ( frac >> 16 );
frac += fracStep;
}
if( isNormalMap )
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f ) * inHeight / outHeight );
inRow2 = in + inWidth * (int)(((float)y + 0.75f ) * inHeight / outHeight );
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
normal[0] = MAKE_SIGNED( pix1[0] ) + MAKE_SIGNED( pix2[0] ) + MAKE_SIGNED( pix3[0] ) + MAKE_SIGNED( pix4[0] );
normal[1] = MAKE_SIGNED( pix1[1] ) + MAKE_SIGNED( pix2[1] ) + MAKE_SIGNED( pix3[1] ) + MAKE_SIGNED( pix4[1] );
normal[2] = MAKE_SIGNED( pix1[2] ) + MAKE_SIGNED( pix2[2] ) + MAKE_SIGNED( pix3[2] ) + MAKE_SIGNED( pix4[2] );
if( !VectorNormalizeLength( normal ))
VectorSet( normal, 0.5f, 0.5f, 1.0f );
((byte *)( out + x ))[0] = 128 + (byte)( 127.0f * normal[0] );
((byte *)( out + x ))[1] = 128 + (byte)( 127.0f * normal[1] );
((byte *)( out + x ))[2] = 128 + (byte)( 127.0f * normal[2] );
((byte *)( out + x ))[3] = 255;
}
}
}
else
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f ) * inHeight / outHeight );
inRow2 = in + inWidth * (int)(((float)y + 0.75f ) * inHeight / outHeight );
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
((byte *)( out + x ))[0] = ( pix1[0] + pix2[0] + pix3[0] + pix4[0] ) >> 2;
((byte *)( out + x ))[1] = ( pix1[1] + pix2[1] + pix3[1] + pix4[1] ) >> 2;
((byte *)( out + x ))[2] = ( pix1[2] + pix2[2] + pix3[2] + pix4[2] ) >> 2;
((byte *)( out + x ))[3] = ( pix1[3] + pix2[3] + pix3[3] + pix4[3] ) >> 2;
}
}
}
return scaledImage;
}
/* /*
================= =================
GL_BuildMipMap GL_BuildMipMap
@@ -751,7 +659,20 @@ int GAME_EXPORT GL_CreateTexture( const char *name, int width, int height, const
return 0; return 0;
} }
return GL_LoadTextureInternal( name, &r_empty, flags ); int texnum = GL_LoadTextureInternal( name, &r_empty, flags );
if( !Q_strcmp( name, REF_DEFAULT_TEXTURE ))
tr.defaultTexture = texnum;
else if( !Q_strcmp( name, REF_PARTICLE_TEXTURE ))
tr.particleTexture = texnum;
else if( !Q_strcmp( name, REF_WHITE_TEXTURE ))
tr.whiteTexture = texnum;
else if( !Q_strcmp( name, REF_GRAY_TEXTURE ))
tr.grayTexture = texnum;
else if( !Q_strcmp( name, REF_BLACK_TEXTURE ))
tr.blackTexture = texnum;
return texnum;
} }
/* /*
@@ -930,74 +851,6 @@ void R_InitDlightTexture( void )
tr.dlightTexture = GL_LoadTextureInternal( "*dlight", &r_image, TF_NOMIPMAP | TF_CLAMP | TF_ATLAS_PAGE ); tr.dlightTexture = GL_LoadTextureInternal( "*dlight", &r_image, TF_NOMIPMAP | TF_CLAMP | TF_ATLAS_PAGE );
} }
/*
==================
GL_CreateInternalTextures
==================
*/
static void GL_CreateInternalTextures( void )
{
int dx2, dy, d;
int x, y;
rgbdata_t *pic;
// emo-texture from quake1
pic = GL_FakeImage( 16, 16, 1, IMAGE_HAS_COLOR );
for( y = 0; y < 16; y++ )
{
for( x = 0; x < 16; x++ )
{
if(( y < 8 ) ^ ( x < 8 ))
((uint *)pic->buffer )[y * 16 + x] = 0xFFFF00FF;
else
((uint *)pic->buffer )[y * 16 + x] = 0xFF000000;
}
}
tr.defaultTexture = GL_LoadTextureInternal( REF_DEFAULT_TEXTURE, pic, TF_COLORMAP );
// particle texture from quake1
pic = GL_FakeImage( 16, 16, 1, IMAGE_HAS_COLOR | IMAGE_HAS_ALPHA );
for( x = 0; x < 16; x++ )
{
dx2 = x - 8;
dx2 = dx2 * dx2;
for( y = 0; y < 16; y++ )
{
dy = y - 8;
d = 255 - 35 * sqrt( dx2 + dy * dy );
pic->buffer[( y * 16 + x ) * 4 + 3] = bound( 0, d, 255 );
}
}
tr.particleTexture = GL_LoadTextureInternal( "*particle", pic, TF_CLAMP );
// white texture
pic = GL_FakeImage( 4, 4, 1, IMAGE_HAS_COLOR );
for( x = 0; x < 16; x++ )
((uint *)pic->buffer )[x] = 0xFFFFFFFF;
tr.whiteTexture = GL_LoadTextureInternal( REF_WHITE_TEXTURE, pic, TF_COLORMAP );
// gray texture
pic = GL_FakeImage( 4, 4, 1, IMAGE_HAS_COLOR );
for( x = 0; x < 16; x++ )
((uint *)pic->buffer )[x] = 0xFF7F7F7F;
tr.grayTexture = GL_LoadTextureInternal( REF_GRAY_TEXTURE, pic, TF_COLORMAP );
// black texture
pic = GL_FakeImage( 4, 4, 1, IMAGE_HAS_COLOR );
for( x = 0; x < 16; x++ )
((uint *)pic->buffer )[x] = 0xFF000000;
tr.blackTexture = GL_LoadTextureInternal( REF_BLACK_TEXTURE, pic, TF_COLORMAP );
// cinematic dummy
pic = GL_FakeImage( 640, 100, 1, IMAGE_HAS_COLOR );
tr.cinTexture = GL_LoadTextureInternal( "*cintexture", pic, TF_NOMIPMAP | TF_CLAMP );
}
/* /*
=============== ===============
R_TextureList_f R_TextureList_f
@@ -1063,7 +916,6 @@ void R_InitImages( void )
r_numImages = 1; r_numImages = 1;
// validate cvars // validate cvars
GL_CreateInternalTextures();
gEngfuncs.Cmd_AddCommand( "texturelist", R_TextureList_f, "display loaded textures list" ); gEngfuncs.Cmd_AddCommand( "texturelist", R_TextureList_f, "display loaded textures list" );
} }

View File

@@ -1,463 +0,0 @@
/*
gl_rlight.c - dynamic and static lights
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "r_local.h"
#include "pm_local.h"
#include "studio.h"
#include "xash3d_mathlib.h"
#include "ref_params.h"
// unused, need refactor
unsigned blocklights[10240];
/*
=============================================================================
DYNAMIC LIGHTS
=============================================================================
*/
/*
==================
CL_RunLightStyles
==================
*/
void CL_RunLightStyles( lightstyle_t *ls )
{
int i;
float frametime = ( gp_cl->time - gp_cl->oldtime );
if( !WORLDMODEL )
return;
if( r_fullbright->value || !WORLDMODEL->lightdata )
{
for( i = 0; i < MAX_LIGHTSTYLES; i++ )
tr.lightstylevalue[i] = 256 * 256;
return;
}
// light animations
// 'm' is normal light, 'a' is no light, 'z' is double bright
for( i = 0; i < MAX_LIGHTSTYLES; i++ )
{
int k, flight, clight;
float l, lerpfrac, backlerp;
if( !gp_cl->paused && frametime <= 0.1f )
ls[i].time += frametime; // evaluate local time
if( !ls[i].length )
{
tr.lightstylevalue[i] = 256;
continue;
}
else if( ls[i].length == 1 )
{
// single length style so don't bother interpolating
tr.lightstylevalue[i] = ( ls[i].map[0] ) * 22;
continue;
}
flight = (int)Q_floor( ls[i].time * 10 );
if( !ls[i].interp || !cl_lightstyle_lerping->value )
{
tr.lightstylevalue[i] = ls[i].map[flight % ls[i].length] * 22;
continue;
}
clight = (int)Q_ceil( ls[i].time * 10 );
lerpfrac = ( ls[i].time * 10 ) - flight;
backlerp = 1.0f - lerpfrac;
// interpolate animating light
// frame just gone
k = ls[i].map[flight % ls[i].length];
l = (float)( k * 22.0f ) * backlerp;
// upcoming frame
k = ls[i].map[clight % ls[i].length];
l += (float)( k * 22.0f ) * lerpfrac;
tr.lightstylevalue[i] = (int)l;
}
}
/*
=============
R_MarkLights
=============
*/
void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
{
float dist;
msurface_t *surf;
int i;
int firstsurface, numsurfaces;
if( !node || node->contents < 0 )
return;
dist = PlaneDiff( light->origin, node->plane );
firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel );
if( dist > light->radius )
{
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
return;
}
if( dist < -light->radius )
{
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
return;
}
// mark the polygons
surf = RI.currentmodel->surfaces + firstsurface;
for( i = 0; i < numsurfaces; i++, surf++ )
{
if( !BoundsAndSphereIntersect( surf->info->mins, surf->info->maxs, light->origin, light->radius ))
continue; // no intersection
if( surf->dlightframe != tr.dlightframecount )
{
surf->dlightbits = 0;
surf->dlightframe = tr.dlightframecount;
}
surf->dlightbits |= bit;
}
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
}
/*
=============
R_PushDlights
=============
*/
void R_PushDlights( void )
{
int i;
tr.dlightframecount = tr.framecount;
RI.currententity = CL_GetEntityByIndex( 0 );
// no world -- no dlights
if( !RI.currententity )
return;
RI.currentmodel = RI.currententity->model;
for( i = 0; i < MAX_DLIGHTS; i++ )
{
dlight_t *l = &tr.dlights[i];
if( l->die < gp_cl->time || !l->radius )
continue;
R_MarkLights( l, 1 << i, RI.currentmodel->nodes );
}
}
/*
=======================================================================
AMBIENT LIGHTING
=======================================================================
*/
static vec3_t g_trace_lightspot;
static vec3_t g_trace_lightvec;
static float g_trace_fraction;
/*
=================
R_RecursiveLightPoint
=================
*/
static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, float p2f, colorVec *cv, const vec3_t start, const vec3_t end )
{
float front, back, frac, midf;
int i, map, side, size;
float ds, dt, s, t;
int sample_size;
color24 *lm, *dm;
mextrasurf_t *info;
msurface_t *surf;
matrix3x4 tbn;
vec3_t mid;
int firstsurface, numsurfaces;
// didn't hit anything
if( !node || node->contents < 0 )
{
cv->r = cv->g = cv->b = cv->a = 0;
return false;
}
firstsurface = node_firstsurface( node, model );
numsurfaces = node_numsurfaces( node, model );
// calculate mid point
front = PlaneDiff( start, node->plane );
back = PlaneDiff( end, node->plane );
side = front < 0;
if(( back < 0 ) == side )
return R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, p2f, cv, start, end );
frac = front / ( front - back );
VectorLerp( start, frac, end, mid );
midf = p1f + ( p2f - p1f ) * frac;
// co down front side
if( R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, midf, cv, start, mid ))
return true; // hit something
if(( back < 0 ) == side )
{
cv->r = cv->g = cv->b = cv->a = 0;
return false; // didn't hit anything
}
// check for impact on this node
surf = model->surfaces + firstsurface;
VectorCopy( mid, g_trace_lightspot );
for( i = 0; i < numsurfaces; i++, surf++ )
{
int smax, tmax;
info = surf->info;
if( FBitSet( surf->flags, SURF_DRAWTILED ))
continue; // no lightmaps
s = DotProduct( mid, info->lmvecs[0] ) + info->lmvecs[0][3];
t = DotProduct( mid, info->lmvecs[1] ) + info->lmvecs[1][3];
if( s < info->lightmapmins[0] || t < info->lightmapmins[1] )
continue;
ds = s - info->lightmapmins[0];
dt = t - info->lightmapmins[1];
if( ds > info->lightextents[0] || dt > info->lightextents[1] )
continue;
cv->r = cv->g = cv->b = cv->a = 0;
if( !surf->samples )
return true;
sample_size = gEngfuncs.Mod_SampleSizeForFace( surf );
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
ds /= sample_size;
dt /= sample_size;
lm = surf->samples + Q_rint( dt ) * smax + Q_rint( ds );
g_trace_fraction = midf;
size = smax * tmax;
dm = NULL;
if( surf->info->deluxemap )
{
vec3_t faceNormal;
if( FBitSet( surf->flags, SURF_PLANEBACK ))
VectorNegate( surf->plane->normal, faceNormal );
else
VectorCopy( surf->plane->normal, faceNormal );
// compute face TBN
#if 1
Vector4Set( tbn[0], surf->info->lmvecs[0][0], surf->info->lmvecs[0][1], surf->info->lmvecs[0][2], 0.0f );
Vector4Set( tbn[1], -surf->info->lmvecs[1][0], -surf->info->lmvecs[1][1], -surf->info->lmvecs[1][2], 0.0f );
Vector4Set( tbn[2], faceNormal[0], faceNormal[1], faceNormal[2], 0.0f );
#else
Vector4Set( tbn[0], surf->info->lmvecs[0][0], -surf->info->lmvecs[1][0], faceNormal[0], 0.0f );
Vector4Set( tbn[1], surf->info->lmvecs[0][1], -surf->info->lmvecs[1][1], faceNormal[1], 0.0f );
Vector4Set( tbn[2], surf->info->lmvecs[0][2], -surf->info->lmvecs[1][2], faceNormal[2], 0.0f );
#endif
VectorNormalize( tbn[0] );
VectorNormalize( tbn[1] );
VectorNormalize( tbn[2] );
dm = surf->info->deluxemap + Q_rint( dt ) * smax + Q_rint( ds );
}
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
{
uint scale = tr.lightstylevalue[surf->styles[map]];
cv->r += lm->r * scale;
cv->g += lm->g * scale;
cv->b += lm->b * scale;
lm += size; // skip to next lightmap
if( dm != NULL )
{
vec3_t srcNormal, lightNormal;
float f = ( 1.0f / 128.0f );
VectorSet( srcNormal, ((float)dm->r - 128.0f ) * f, ((float)dm->g - 128.0f ) * f, ((float)dm->b - 128.0f ) * f );
Matrix3x4_VectorIRotate( tbn, srcNormal, lightNormal ); // turn to world space
VectorScale( lightNormal, (float)scale * -1.0f, lightNormal ); // turn direction from light
VectorAdd( g_trace_lightvec, lightNormal, g_trace_lightvec );
dm += size; // skip to next deluxmap
}
}
return true;
}
// go down back side
return R_RecursiveLightPoint( model, node_child( node, !side, model ), midf, p2f, cv, mid, end );
}
/*
=================
R_LightVec
check bspmodels to get light from
=================
*/
static colorVec R_LightVecInternal( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
{
float last_fraction;
int i, maxEnts = 1;
colorVec light, cv;
if( lspot )
VectorClear( lspot );
if( lvec )
VectorClear( lvec );
if( WORLDMODEL && WORLDMODEL->lightdata )
{
light.r = light.g = light.b = light.a = 0;
last_fraction = 1.0f;
// get light from bmodels too
// if( CVAR_TO_BOOL( r_lighting_extended ))
maxEnts = MAX_PHYSENTS;
// check all the bsp-models
for( i = 0; i < maxEnts; i++ )
{
physent_t *pe = gEngfuncs.EV_GetPhysent( i );
vec3_t offset, start_l, end_l;
mnode_t *pnodes;
matrix4x4 matrix;
if( !pe )
break;
if( !pe->model || pe->model->type != mod_brush )
continue; // skip non-bsp models
pnodes = &pe->model->nodes[pe->model->hulls[0].firstclipnode];
VectorSubtract( pe->model->hulls[0].clip_mins, vec3_origin, offset );
VectorAdd( offset, pe->origin, offset );
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
// rotate start and end into the models frame of reference
if( !VectorIsNull( pe->angles ))
{
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
Matrix4x4_VectorITransform( matrix, start, start_l );
Matrix4x4_VectorITransform( matrix, end, end_l );
}
VectorClear( g_trace_lightspot );
VectorClear( g_trace_lightvec );
g_trace_fraction = 1.0f;
if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l ))
continue; // didn't hit anything
if( g_trace_fraction < last_fraction )
{
if( lspot )
VectorCopy( g_trace_lightspot, lspot );
if( lvec )
VectorNormalize2( g_trace_lightvec, lvec );
light.r = Q_min(( cv.r >> 8 ), 255 );
light.g = Q_min(( cv.g >> 8 ), 255 );
light.b = Q_min(( cv.b >> 8 ), 255 );
last_fraction = g_trace_fraction;
if(( light.r + light.g + light.b ) != 0 )
break; // we get light now
}
}
}
else
{
light.r = light.g = light.b = 255;
light.a = 0;
}
return light;
}
/*
=================
R_LightVec
check bspmodels to get light from
=================
*/
colorVec GAME_EXPORT R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
{
colorVec light = R_LightVecInternal( start, end, lspot, lvec );
// light.r = light.g = light.b = 255;
if( lspot != NULL && lvec != NULL ) // CVAR_TO_BOOL( r_lighting_extended ) &&
{
// trying to get light from ceiling (but ignore gradient analyze)
if(( light.r + light.g + light.b ) == 0 )
return R_LightVecInternal( end, start, lspot, lvec );
}
return light;
}
/*
=================
R_LightPoint
light from floor
=================
*/
colorVec GAME_EXPORT R_LightPoint( const vec3_t p0 )
{
vec3_t p1;
VectorSet( p1, p0[0], p0[1], p0[2] - 2048.0f );
return R_LightVec( p0, p1, NULL, NULL );
}

View File

@@ -15,16 +15,11 @@ GNU General Public License for more details.
#ifndef GL_LOCAL_H #ifndef GL_LOCAL_H
#define GL_LOCAL_H #define GL_LOCAL_H
#include "ref_common.h"
#include "port.h" #include "port.h"
#include "xash3d_types.h" #include "xash3d_types.h"
#include "cvardef.h" #include "cvardef.h"
#include "const.h"
#include "com_model.h"
#include "cl_entity.h"
#include "render_api.h"
#include "protocol.h" #include "protocol.h"
#include "ref_api.h"
#include "xash3d_mathlib.h"
#include "ref_params.h" #include "ref_params.h"
#include "enginefeatures.h" #include "enginefeatures.h"
#include "com_strings.h" #include "com_strings.h"
@@ -36,16 +31,13 @@ typedef struct mip_s mip_t;
typedef int fixed8_t; typedef int fixed8_t;
typedef int fixed16_t; typedef int fixed16_t;
#define ASSERT( x ) if( !( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ ) #define ASSERT( x ) Assert( x )
#define Assert( x ) if( !( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ )
#include <stdio.h> #include <stdio.h>
// make mod_ref.h? // make mod_ref.h?
#define LM_SAMPLE_SIZE 16 #define LM_SAMPLE_SIZE 16
extern poolhandle_t r_temppool;
#define BLOCK_SIZE tr.block_size // lightmap blocksize #define BLOCK_SIZE tr.block_size // lightmap blocksize
#define BLOCK_SIZE_DEFAULT 128 // for keep backward compatibility #define BLOCK_SIZE_DEFAULT 128 // for keep backward compatibility
#define BLOCK_SIZE_MAX 1024 #define BLOCK_SIZE_MAX 1024
@@ -69,17 +61,9 @@ extern poolhandle_t r_temppool;
#define SHADE_LAMBERT 1.4953241 #define SHADE_LAMBERT 1.4953241
#define DEFAULT_ALPHATEST 0.0f #define DEFAULT_ALPHATEST 0.0f
// refparams
#define RP_NONE 0
#define RP_ENVVIEW BIT( 0 ) // used for cubemapshot
#define RP_OLDVIEWLEAF BIT( 1 )
#define RP_CLIPPLANE BIT( 2 )
#define RP_NONVIEWERREF ( RP_ENVVIEW )
#define R_ModelOpaque( rm ) ( rm == kRenderNormal ) #define R_ModelOpaque( rm ) ( rm == kRenderNormal )
#define R_StaticEntity( ent ) ( VectorIsNull( ent->origin ) && VectorIsNull( ent->angles )) #define R_StaticEntity( ent ) ( VectorIsNull( ent->origin ) && VectorIsNull( ent->angles ))
#define RP_LOCALCLIENT( e ) (( e ) != NULL && ( e )->index == ( gp_cl->playernum + 1 ) && e->player ) #define RP_LOCALCLIENT( e ) (( e ) != NULL && ( e )->index == ( gp_cl->playernum + 1 ) && e->player )
#define RP_NORMALPASS() ( FBitSet( RI.params, RP_NONVIEWERREF ) == 0 )
#define CL_IsViewEntityLocalPlayer() ( gp_cl->viewentity == ( gp_cl->playernum + 1 )) #define CL_IsViewEntityLocalPlayer() ( gp_cl->viewentity == ( gp_cl->playernum + 1 ))
@@ -138,27 +122,16 @@ extern viddef_t vid;
typedef struct typedef struct
{ {
int params; // rendering parameters ref_viewpass_t rvp;
qboolean drawWorld; // ignore world for drawing PlayerModel
qboolean isSkyVisible; // sky is visible
qboolean onlyClientDraw; // disabled by client request
qboolean drawOrtho; // draw world as orthogonal projection
float fov_x, fov_y; // current view fov
cl_entity_t *currententity; cl_entity_t *currententity;
model_t *currentmodel; model_t *currentmodel;
cl_entity_t *currentbeam; // same as above but for beams cl_entity_t *currentbeam; // same as above but for beams
int viewport[4];
// gl_frustum_t frustum; // gl_frustum_t frustum;
mleaf_t *viewleaf; mleaf_t *viewleaf;
mleaf_t *oldviewleaf; mleaf_t *oldviewleaf;
vec3_t pvsorigin;
vec3_t vieworg; // locked vieworigin
vec3_t viewangles;
vec3_t vforward; vec3_t vforward;
vec3_t vright; vec3_t vright;
vec3_t vup; vec3_t vup;
@@ -232,7 +205,6 @@ typedef struct
int lightmapTextures[MAX_LIGHTMAPS]; int lightmapTextures[MAX_LIGHTMAPS];
int dlightTexture; // custom dlight texture int dlightTexture; // custom dlight texture
int skyboxTextures[6]; // skybox sides int skyboxTextures[6]; // skybox sides
int cinTexture; // cinematic texture
// entity lists // entity lists
draw_list_t draw_stack[MAX_DRAW_STACK]; draw_list_t draw_stack[MAX_DRAW_STACK];
@@ -259,7 +231,6 @@ typedef struct
int max_recursion; int max_recursion;
byte visbytes[( MAX_MAP_LEAFS + 7 ) / 8]; // member custom PVS byte visbytes[( MAX_MAP_LEAFS + 7 ) / 8]; // member custom PVS
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
int block_size; // lightmap blocksize int block_size; // lightmap blocksize
double frametime; // special frametime for multipass rendering (will set to 0 on a nextview) double frametime; // special frametime for multipass rendering (will set to 0 on a nextview)
@@ -278,7 +249,6 @@ typedef struct
color24 *palette; color24 *palette;
cl_entity_t *viewent; cl_entity_t *viewent;
lightstyle_t *lightstyles; lightstyle_t *lightstyles;
dlight_t *dlights;
dlight_t *elights; dlight_t *elights;
byte *texgammatable; byte *texgammatable;
uint *lightgammatable; uint *lightgammatable;
@@ -346,7 +316,6 @@ typedef struct image_s
// gl_beams.c // gl_beams.c
// //
void CL_DrawBeams( int fTrans, BEAM *active_beams ); void CL_DrawBeams( int fTrans, BEAM *active_beams );
qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly );
// //
// gl_decals.c // gl_decals.c
@@ -365,7 +334,7 @@ void GL_Bind( int tmu, unsigned int texnum );
// gl_draw.c // gl_draw.c
// //
void R_Set2DMode( qboolean enable ); void R_Set2DMode( qboolean enable );
void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ); // void GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt );
// gl_image.c // gl_image.c
// //
@@ -375,7 +344,6 @@ image_t *R_GetTexture( unsigned int texnum );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags ); int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags );
int GL_LoadTextureArray( const char **names, int flags ); int GL_LoadTextureArray( const char **names, int flags );
int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update ); int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags ); int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags );
int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags ); int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags );
void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor ); void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor );
@@ -389,17 +357,6 @@ void R_InitImages( void );
void R_ShutdownImages( void ); void R_ShutdownImages( void );
int R_TexMemory( void ); int R_TexMemory( void );
#if 1
//
// gl_rlight.c
//
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlights( void );
void R_GetLightSpot( vec3_t lightspot );
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
colorVec R_LightPoint( const vec3_t p0 );
#endif
// //
// gl_rmain.c // gl_rmain.c
// //
@@ -419,18 +376,6 @@ void R_PushScene( void );
void R_PopScene( void ); void R_PopScene( void );
void R_DrawFog( void ); void R_DrawFog( void );
//
// gl_rmath.c
//
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z );
void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z );
void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z );
void Matrix4x4_CreateRotate( matrix4x4 out, float angle, float x, float y, float z );
void Matrix4x4_CreateProjection( matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar );
void Matrix4x4_CreateOrtho( matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar );
void Matrix4x4_CreateModelview( matrix4x4 out );
// //
// gl_rpart.c // gl_rpart.c
// //
@@ -442,9 +387,6 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers );
// //
// gl_sprite.c // gl_sprite.c
// //
void R_SpriteInit( void );
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags );
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw );
void R_DrawSpriteModel( cl_entity_t *e ); void R_DrawSpriteModel( cl_entity_t *e );
// //
@@ -457,11 +399,11 @@ struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e );
int R_GetEntityRenderMode( cl_entity_t *ent ); int R_GetEntityRenderMode( cl_entity_t *ent );
void R_DrawStudioModel( cl_entity_t *e ); void R_DrawStudioModel( cl_entity_t *e );
player_info_t *pfnPlayerInfo( int index ); player_info_t *pfnPlayerInfo( int index );
void R_GatherPlayerLight( void );
float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time ); float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time );
void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles );
void R_StudioResetPlayerModels( void ); void R_StudioResetPlayerModels( void );
void CL_InitStudioAPI( void ); qboolean R_StudioFillAPI( struct engine_studio_api_s *api, struct r_studio_interface_s *pDefaultDraw );
void R_StudioSetDrawInterface( struct r_studio_interface_s *pDraw );
void Mod_StudioLoadTextures( model_t *mod, void *data ); void Mod_StudioLoadTextures( model_t *mod, void *data );
void Mod_StudioUnloadTextures( void *data ); void Mod_StudioUnloadTextures( void *data );
@@ -507,21 +449,17 @@ void R_RenderFrame( const struct ref_viewpass_s *vp );
void R_EndFrame( void ); void R_EndFrame( void );
void R_ClearScene( void ); void R_ClearScene( void );
void R_GetTextureParms( int *w, int *h, int texnum ); void R_GetTextureParms( int *w, int *h, int texnum );
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int curFrame, const struct model_s *pSprite );
void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty );
void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ); void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum );
qboolean R_SpeedsMessage( char *out, size_t size ); qboolean R_SpeedsMessage( char *out, size_t size );
qboolean R_CullBox( const vec3_t mins, const vec3_t maxs ); qboolean R_CullBox( const vec3_t mins, const vec3_t maxs );
int R_WorldToScreen( const vec3_t point, vec3_t screen ); int R_WorldToScreen( const vec3_t point, vec3_t screen );
void R_ScreenToWorld( const vec3_t screen, vec3_t point ); void R_ScreenToWorld( const vec3_t screen, vec3_t point );
qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType ); qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType );
void Mod_SpriteUnloadTextures( void *data );
void Mod_UnloadAliasModel( struct model_s *mod ); void Mod_UnloadAliasModel( struct model_s *mod );
void Mod_AliasUnloadTextures( void *data ); void Mod_AliasUnloadTextures( void *data );
void GL_SetRenderMode( int mode ); void GL_SetRenderMode( int mode );
void R_RunViewmodelEvents( void ); void R_RunViewmodelEvents( void );
void R_DrawViewModel( void ); void R_DrawViewModel( void );
int R_GetSpriteTexture( const struct model_s *m_pSpriteModel, int frame );
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, float scale ); void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, float scale );
void R_DecalRemoveAll( int texture ); void R_DecalRemoveAll( int texture );
int R_CreateDecalList( decallist_t *pList ); int R_CreateDecalList( decallist_t *pList );
@@ -529,7 +467,6 @@ void R_ClearAllDecals( void );
byte *Mod_GetCurrentVis( void ); byte *Mod_GetCurrentVis( void );
void Mod_SetOrthoBounds( const float *mins, const float *maxs ); void Mod_SetOrthoBounds( const float *mins, const float *maxs );
void R_NewMap( void ); void R_NewMap( void );
void CL_AddCustomBeam( cl_entity_t *pEnvBeam );
// //
// gl_triapi.c // gl_triapi.c
@@ -552,15 +489,7 @@ void TriFogParams( float flDensity, int iFogSkybox );
void TriCullFace( TRICULLSTYLE mode ); void TriCullFace( TRICULLSTYLE mode );
void TriBrightness( float brightness ); void TriBrightness( float brightness );
#define ENGINE_GET_PARM_ ( *gEngfuncs.EngineGetParm )
#define ENGINE_GET_PARM( parm ) ENGINE_GET_PARM_(( parm ), 0 )
extern ref_api_t gEngfuncs;
extern ref_globals_t *gpGlobals;
extern ref_client_t *gp_cl;
extern ref_host_t *gp_host;
DECLARE_ENGINE_SHARED_CVAR_LIST()
// //
// helper funcs // helper funcs
@@ -1099,7 +1028,6 @@ void R_ScanEdges( void );
// //
// r_surf.c // r_surf.c
// //
void GL_InitRandomTable( void );
void D_FlushCaches( void ); void D_FlushCaches( void );
// //
@@ -1147,16 +1075,6 @@ void R_SetUpWorldTransform( void );
// //
#include "crtlib.h" #include "crtlib.h"
#include "crclib.h" #include "crclib.h"
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) gEngfuncs._Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )
#endif // GL_LOCAL_H #endif // GL_LOCAL_H

View File

@@ -71,7 +71,6 @@ CVAR_DEFINE_AUTO( sw_texfilt, "0", FCVAR_GLCONFIG, "texture dither" );
static CVAR_DEFINE_AUTO( r_novis, "0", 0, "" ); static CVAR_DEFINE_AUTO( r_novis, "0", 0, "" );
DEFINE_ENGINE_SHARED_CVAR_LIST()
int r_viewcluster, r_oldviewcluster; int r_viewcluster, r_oldviewcluster;
@@ -173,7 +172,7 @@ static int R_TransEntityCompare( const cl_entity_t **a, const cl_entity_t **b )
{ {
VectorAverage( ent1->model->mins, ent1->model->maxs, org ); VectorAverage( ent1->model->mins, ent1->model->maxs, org );
VectorAdd( ent1->origin, org, org ); VectorAdd( ent1->origin, org, org );
VectorSubtract( RI.vieworg, org, vecLen ); VectorSubtract( RI.rvp.vieworigin, org, vecLen );
dist1 = DotProduct( vecLen, vecLen ); dist1 = DotProduct( vecLen, vecLen );
} }
else else
@@ -183,7 +182,7 @@ static int R_TransEntityCompare( const cl_entity_t **a, const cl_entity_t **b )
{ {
VectorAverage( ent2->model->mins, ent2->model->maxs, org ); VectorAverage( ent2->model->mins, ent2->model->maxs, org );
VectorAdd( ent2->origin, org, org ); VectorAdd( ent2->origin, org, org );
VectorSubtract( RI.vieworg, org, vecLen ); VectorSubtract( RI.rvp.vieworigin, org, vecLen );
dist2 = DotProduct( vecLen, vecLen ); dist2 = DotProduct( vecLen, vecLen );
} }
else else
@@ -319,9 +318,6 @@ qboolean GAME_EXPORT R_AddEntity( struct cl_entity_s *clent, int type )
if( !r_drawentities->value ) if( !r_drawentities->value )
return false; // not allow to drawing return false; // not allow to drawing
if( !clent || !clent->model )
return false; // if set to invisible, skip
if( FBitSet( clent->curstate.effects, EF_NODRAW )) if( FBitSet( clent->curstate.effects, EF_NODRAW ))
return false; // done return false; // done
@@ -331,7 +327,20 @@ qboolean GAME_EXPORT R_AddEntity( struct cl_entity_s *clent, int type )
if( type == ET_FRAGMENTED ) if( type == ET_FRAGMENTED )
r_stats.c_client_ents++; r_stats.c_client_ents++;
if( R_OpaqueEntity( clent )) if( type == ET_BEAM )
{
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
{
gEngfuncs.Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
return false;
}
tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = clent;
tr.draw_list->num_beam_entities++;
return true;
}
else if( R_OpaqueEntity( clent ))
{ {
if( clent->model->type == mod_brush ) if( clent->model->type == mod_brush )
{ {
@@ -370,7 +379,7 @@ R_GetFarClip
*/ */
static float R_GetFarClip( void ) static float R_GetFarClip( void )
{ {
if( WORLDMODEL && RI.drawWorld ) if( WORLDMODEL && FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return tr.movevars->zmax * 1.73f; return tr.movevars->zmax * 1.73f;
return 2048.0f; return 2048.0f;
} }
@@ -383,10 +392,10 @@ R_SetupFrustum
void R_SetupFrustum( void ) void R_SetupFrustum( void )
{ {
// build the transformation matrix for the given view angles // build the transformation matrix for the given view angles
AngleVectors( RI.viewangles, RI.vforward, RI.vright, RI.vup ); AngleVectors( RI.rvp.viewangles, RI.vforward, RI.vright, RI.vup );
{ {
VectorCopy( RI.vieworg, RI.cullorigin ); VectorCopy( RI.rvp.vieworigin, RI.cullorigin );
VectorCopy( RI.vforward, RI.cull_vforward ); VectorCopy( RI.vforward, RI.cull_vforward );
VectorCopy( RI.vright, RI.cull_vright ); VectorCopy( RI.vright, RI.cull_vright );
VectorCopy( RI.vup, RI.cull_vup ); VectorCopy( RI.vup, RI.cull_vup );
@@ -402,22 +411,15 @@ static void R_SetupProjectionMatrix( matrix4x4 m )
{ {
float xMin, xMax, yMin, yMax, zNear, zFar; float xMin, xMax, yMin, yMax, zNear, zFar;
if( RI.drawOrtho )
{
const ref_overview_t *ov = gEngfuncs.GetOverviewParms();
Matrix4x4_CreateOrtho( m, ov->xLeft, ov->xRight, ov->yTop, ov->yBottom, ov->zNear, ov->zFar );
return;
}
RI.farClip = R_GetFarClip(); RI.farClip = R_GetFarClip();
zNear = 4.0f; zNear = 4.0f;
zFar = Q_max( 256.0f, RI.farClip ); zFar = Q_max( 256.0f, RI.farClip );
yMax = zNear * tan( RI.fov_y * M_PI_F / 360.0f ); yMax = zNear * tan( RI.rvp.fov_y * M_PI_F / 360.0f );
yMin = -yMax; yMin = -yMax;
xMax = zNear * tan( RI.fov_x * M_PI_F / 360.0f ); xMax = zNear * tan( RI.rvp.fov_x * M_PI_F / 360.0f );
xMin = -xMax; xMin = -xMax;
Matrix4x4_CreateProjection( m, xMax, xMin, yMax, yMin, zNear, zFar ); Matrix4x4_CreateProjection( m, xMax, xMin, yMax, yMin, zNear, zFar );
@@ -431,10 +433,10 @@ R_SetupModelviewMatrix
static void R_SetupModelviewMatrix( matrix4x4 m ) static void R_SetupModelviewMatrix( matrix4x4 m )
{ {
Matrix4x4_CreateModelview( m ); Matrix4x4_CreateModelview( m );
Matrix4x4_ConcatRotate( m, -RI.viewangles[2], 1, 0, 0 ); Matrix4x4_ConcatRotate( m, -RI.rvp.viewangles[2], 1, 0, 0 );
Matrix4x4_ConcatRotate( m, -RI.viewangles[0], 0, 1, 0 ); Matrix4x4_ConcatRotate( m, -RI.rvp.viewangles[0], 0, 1, 0 );
Matrix4x4_ConcatRotate( m, -RI.viewangles[1], 0, 0, 1 ); Matrix4x4_ConcatRotate( m, -RI.rvp.viewangles[1], 0, 0, 1 );
Matrix4x4_ConcatTranslate( m, -RI.vieworg[0], -RI.vieworg[1], -RI.vieworg[2] ); Matrix4x4_ConcatTranslate( m, -RI.rvp.vieworigin[0], -RI.rvp.vieworigin[1], -RI.rvp.vieworigin[2] );
} }
/* /*
@@ -472,7 +474,7 @@ R_FindViewLeaf
void R_FindViewLeaf( void ) void R_FindViewLeaf( void )
{ {
RI.oldviewleaf = RI.viewleaf; RI.oldviewleaf = RI.viewleaf;
RI.viewleaf = gEngfuncs.Mod_PointInLeaf( RI.pvsorigin, WORLDMODEL->nodes ); RI.viewleaf = gEngfuncs.Mod_PointInLeaf( RI.rvp.vieworigin, WORLDMODEL->nodes, WORLDMODEL );
} }
/* /*
@@ -483,7 +485,7 @@ R_SetupFrame
static void R_SetupFrame( void ) static void R_SetupFrame( void )
{ {
// setup viewplane dist // setup viewplane dist
RI.viewplanedist = DotProduct( RI.vieworg, RI.vforward ); RI.viewplanedist = DotProduct( RI.rvp.vieworigin, RI.vforward );
// if( !gl_nosort->value ) // if( !gl_nosort->value )
{ {
@@ -492,11 +494,8 @@ static void R_SetupFrame( void )
} }
// current viewleaf // current viewleaf
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{
RI.isSkyVisible = false; // unknown at this moment
R_FindViewLeaf(); R_FindViewLeaf();
}
// setup twice until globals fully refactored // setup twice until globals fully refactored
R_SetupFrameQ(); R_SetupFrameQ();
@@ -518,7 +517,7 @@ static void R_DrawEntitiesOnList( void )
d_pdrawspans = R_PolysetFillSpans8; d_pdrawspans = R_PolysetFillSpans8;
GL_SetRenderMode( kRenderNormal ); GL_SetRenderMode( kRenderNormal );
// first draw solid entities // first draw solid entities
for( i = 0; i < tr.draw_list->num_solid_entities && !RI.onlyClientDraw; i++ ) for( i = 0; i < tr.draw_list->num_solid_entities && !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ); i++ )
{ {
RI.currententity = tr.draw_list->solid_entities[i]; RI.currententity = tr.draw_list->solid_entities[i];
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
@@ -546,7 +545,7 @@ static void R_DrawEntitiesOnList( void )
R_SetUpWorldTransform(); R_SetUpWorldTransform();
// draw sprites seperately, because of alpha blending // draw sprites seperately, because of alpha blending
for( i = 0; i < tr.draw_list->num_solid_entities && !RI.onlyClientDraw; i++ ) for( i = 0; i < tr.draw_list->num_solid_entities && !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ); i++ )
{ {
RI.currententity = tr.draw_list->solid_entities[i]; RI.currententity = tr.draw_list->solid_entities[i];
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
@@ -562,17 +561,17 @@ static void R_DrawEntitiesOnList( void )
} }
} }
if( !RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
{ {
gEngfuncs.CL_DrawEFX( tr.frametime, false ); gEngfuncs.CL_DrawEFX( tr.frametime, false );
} }
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
gEngfuncs.pfnDrawNormalTriangles(); gEngfuncs.pfnDrawNormalTriangles();
d_pdrawspans = R_PolysetDrawSpans8_33; d_pdrawspans = R_PolysetDrawSpans8_33;
// then draw translucent entities // then draw translucent entities
for( i = 0; i < tr.draw_list->num_trans_entities && !RI.onlyClientDraw; i++ ) for( i = 0; i < tr.draw_list->num_trans_entities && !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ); i++ )
{ {
RI.currententity = tr.draw_list->trans_entities[i]; RI.currententity = tr.draw_list->trans_entities[i];
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
@@ -610,12 +609,10 @@ static void R_DrawEntitiesOnList( void )
} }
} }
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{
gEngfuncs.pfnDrawTransparentTriangles(); gEngfuncs.pfnDrawTransparentTriangles();
}
if( !RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
{ {
R_AllowFog( false ); R_AllowFog( false );
gEngfuncs.CL_DrawEFX( tr.frametime, true ); gEngfuncs.CL_DrawEFX( tr.frametime, true );
@@ -624,7 +621,7 @@ static void R_DrawEntitiesOnList( void )
GL_SetRenderMode( kRenderNormal ); GL_SetRenderMode( kRenderNormal );
R_SetUpWorldTransform(); R_SetUpWorldTransform();
if( !RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
R_DrawViewModel(); R_DrawViewModel();
gEngfuncs.CL_ExtraUpdate(); gEngfuncs.CL_ExtraUpdate();
@@ -795,7 +792,7 @@ static void R_DrawBEntitiesOnList( void )
VectorCopy( tr.modelorg, oldorigin ); VectorCopy( tr.modelorg, oldorigin );
insubmodel = true; insubmodel = true;
for( i = 0; i < tr.draw_list->num_edge_entities && !RI.onlyClientDraw; i++ ) for( i = 0; i < tr.draw_list->num_edge_entities && !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ); i++ )
{ {
int k; int k;
RI.currententity = tr.draw_list->edge_entities[i]; RI.currententity = tr.draw_list->edge_entities[i];
@@ -823,7 +820,7 @@ static void R_DrawBEntitiesOnList( void )
continue; // no part in a visible leaf continue; // no part in a visible leaf
VectorCopy( RI.currententity->origin, r_entorigin ); VectorCopy( RI.currententity->origin, r_entorigin );
VectorSubtract( RI.vieworg, r_entorigin, tr.modelorg ); VectorSubtract( RI.rvp.vieworigin, r_entorigin, tr.modelorg );
// VectorSubtract (r_origin, RI.currententity->origin, modelorg); // VectorSubtract (r_origin, RI.currententity->origin, modelorg);
r_pcurrentvertbase = RI.currentmodel->vertexes; r_pcurrentvertbase = RI.currentmodel->vertexes;
@@ -831,21 +828,8 @@ static void R_DrawBEntitiesOnList( void )
R_RotateBmodel(); R_RotateBmodel();
// calculate dynamic lighting for bmodel // calculate dynamic lighting for bmodel
for( k = 0; k < MAX_DLIGHTS; k++ ) Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
{ R_PushDlightsForBmodel( RI.currentmodel, tr.dlightframecount, RI.objectMatrix );
dlight_t *l = &tr.dlights[k];
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
continue;
VectorCopy( l->origin, oldorigin ); // save lightorigin
Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1 << k, RI.currentmodel->nodes + RI.currentmodel->hulls[0].firstclipnode );
VectorCopy( oldorigin, l->origin ); // restore lightorigin
}
RI.currententity->topnode = topnode; RI.currententity->topnode = topnode;
if( topnode->contents >= 0 ) if( topnode->contents >= 0 )
@@ -894,7 +878,7 @@ void R_DrawBrushModel( cl_entity_t *pent )
surf_t lsurfs[NUMSTACKSURFACES surf_t lsurfs[NUMSTACKSURFACES
+ (( CACHE_SIZE - 1 ) / sizeof( surf_t )) + 1]; + (( CACHE_SIZE - 1 ) / sizeof( surf_t )) + 1];
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return; return;
if( auxedges ) if( auxedges )
@@ -948,7 +932,7 @@ void R_DrawBrushModel( cl_entity_t *pent )
alphaspans = true; alphaspans = true;
VectorCopy( RI.currententity->origin, r_entorigin ); VectorCopy( RI.currententity->origin, r_entorigin );
VectorSubtract( RI.vieworg, r_entorigin, tr.modelorg ); VectorSubtract( RI.rvp.vieworigin, r_entorigin, tr.modelorg );
// VectorSubtract (r_origin, RI.currententity->origin, modelorg); // VectorSubtract (r_origin, RI.currententity->origin, modelorg);
r_pcurrentvertbase = RI.currentmodel->vertexes; r_pcurrentvertbase = RI.currentmodel->vertexes;
@@ -956,22 +940,9 @@ void R_DrawBrushModel( cl_entity_t *pent )
R_RotateBmodel(); R_RotateBmodel();
// calculate dynamic lighting for bmodel // calculate dynamic lighting for bmodel
for( k = 0; k < MAX_DLIGHTS; k++ ) Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
{ R_PushDlightsForBmodel( RI.currentmodel, tr.dlightframecount, RI.objectMatrix );
dlight_t *l = &tr.dlights[k]; tr.modelviewIdentity = false;
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
continue;
VectorCopy( l->origin, oldorigin ); // save lightorigin
Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
tr.modelviewIdentity = false;
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1 << k, RI.currentmodel->nodes + RI.currentmodel->hulls[0].firstclipnode );
VectorCopy( oldorigin, l->origin ); // restore lightorigin*/
}
RI.currententity->topnode = topnode; RI.currententity->topnode = topnode;
if( topnode->contents >= 0 ) if( topnode->contents >= 0 )
@@ -1015,7 +986,7 @@ static void R_EdgeDrawing( void )
surf_t lsurfs[NUMSTACKSURFACES surf_t lsurfs[NUMSTACKSURFACES
+ (( CACHE_SIZE - 1 ) / sizeof( surf_t )) + 1]; + (( CACHE_SIZE - 1 ) / sizeof( surf_t )) + 1];
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return; return;
if( auxedges ) if( auxedges )
@@ -1070,7 +1041,7 @@ static void R_MarkLeaves( void )
tr.visframecount++; tr.visframecount++;
r_oldviewcluster = r_viewcluster; r_oldviewcluster = r_viewcluster;
gEngfuncs.R_FatPVS( RI.pvsorigin, r_pvs_radius->value, RI.visbytes, FBitSet( RI.params, RP_OLDVIEWLEAF ), false ); gEngfuncs.R_FatPVS( RI.rvp.vieworigin, r_pvs_radius->value, RI.visbytes, false, false );
vis = RI.visbytes; vis = RI.visbytes;
for( i = 0; i < WORLDMODEL->numleafs; i++ ) for( i = 0; i < WORLDMODEL->numleafs; i++ )
@@ -1099,14 +1070,11 @@ R_SetupRefParams must be called right before
*/ */
void GAME_EXPORT R_RenderScene( void ) void GAME_EXPORT R_RenderScene( void )
{ {
if( !WORLDMODEL && RI.drawWorld ) if( !WORLDMODEL && FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
gEngfuncs.Host_Error( "%s: NULL worldmodel\n", __func__ ); gEngfuncs.Host_Error( "%s: NULL worldmodel\n", __func__ );
// frametime is valid only for normal pass // frametime is valid only for normal pass
if( RP_NORMALPASS( )) tr.frametime = gp_cl->time - gp_cl->oldtime;
tr.frametime = gp_cl->time - gp_cl->oldtime;
else
tr.frametime = 0.0;
// begin a new frame // begin a new frame
tr.framecount++; tr.framecount++;
@@ -1121,7 +1089,7 @@ void GAME_EXPORT R_RenderScene( void )
R_SetupFrustum(); R_SetupFrustum();
R_SetupFrame(); R_SetupFrame();
R_PushDlights(); tr.dlightframecount = R_PushDlights( WORLDMODEL, tr.framecount );
R_SetupModelviewMatrix( RI.worldviewMatrix ); R_SetupModelviewMatrix( RI.worldviewMatrix );
R_SetupProjectionMatrix( RI.projectionMatrix ); R_SetupProjectionMatrix( RI.projectionMatrix );
@@ -1177,28 +1145,7 @@ set initial params for renderer
*/ */
void R_SetupRefParams( const ref_viewpass_t *rvp ) void R_SetupRefParams( const ref_viewpass_t *rvp )
{ {
RI.params = RP_NONE; RI.rvp = *rvp;
RI.drawWorld = FBitSet( rvp->flags, RF_DRAW_WORLD );
RI.onlyClientDraw = FBitSet( rvp->flags, RF_ONLY_CLIENTDRAW );
if( !FBitSet( rvp->flags, RF_DRAW_CUBEMAP ))
RI.drawOrtho = FBitSet( rvp->flags, RF_DRAW_OVERVIEW );
else
RI.drawOrtho = false;
// setup viewport
RI.viewport[0] = rvp->viewport[0];
RI.viewport[1] = rvp->viewport[1];
RI.viewport[2] = rvp->viewport[2];
RI.viewport[3] = rvp->viewport[3];
// calc FOV
RI.fov_x = rvp->fov_x;
RI.fov_y = rvp->fov_y;
VectorCopy( rvp->vieworigin, RI.vieworg );
VectorCopy( rvp->viewangles, RI.viewangles );
VectorCopy( rvp->vieworigin, RI.pvsorigin );
} }
/* /*
@@ -1225,7 +1172,7 @@ void GAME_EXPORT R_RenderFrame( const ref_viewpass_t *rvp )
if( gEngfuncs.drawFuncs->GL_RenderFrame( rvp )) if( gEngfuncs.drawFuncs->GL_RenderFrame( rvp ))
{ {
// R_GatherPlayerLight(); // R_GatherPlayerLight( tr.viewent );
tr.realframecount++; tr.realframecount++;
tr.fResetVis = true; tr.fResetVis = true;
return; return;
@@ -1233,7 +1180,7 @@ void GAME_EXPORT R_RenderFrame( const ref_viewpass_t *rvp )
} }
tr.fCustomRendering = false; tr.fCustomRendering = false;
if( !RI.onlyClientDraw ) if( !FBitSet( RI.rvp.flags, RF_ONLY_CLIENTDRAW ))
R_RunViewmodelEvents(); R_RunViewmodelEvents();
tr.realframecount++; // right called after viewmodel events tr.realframecount++; // right called after viewmodel events
@@ -1397,9 +1344,6 @@ qboolean GAME_EXPORT R_Init( void )
{ {
qboolean glblit = false; qboolean glblit = false;
RETRIEVE_ENGINE_SHARED_CVAR_LIST();
gEngfuncs.Cvar_RegisterVariable( &sw_clearcolor ); gEngfuncs.Cvar_RegisterVariable( &sw_clearcolor );
gEngfuncs.Cvar_RegisterVariable( &sw_drawflat ); gEngfuncs.Cvar_RegisterVariable( &sw_drawflat );
gEngfuncs.Cvar_RegisterVariable( &sw_draworder ); gEngfuncs.Cvar_RegisterVariable( &sw_draworder );
@@ -1444,8 +1388,7 @@ qboolean GAME_EXPORT R_Init( void )
tr.lightgammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LIGHTGAMMATABLE_PTR ); tr.lightgammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LIGHTGAMMATABLE_PTR );
tr.screengammatable = (uint *)ENGINE_GET_PARM( PARM_GET_SCREENGAMMATABLE_PTR ); tr.screengammatable = (uint *)ENGINE_GET_PARM( PARM_GET_SCREENGAMMATABLE_PTR );
tr.lineargammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LINEARGAMMATABLE_PTR ); tr.lineargammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LINEARGAMMATABLE_PTR );
tr.dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR ); tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
if( !R_InitBlit( glblit )) if( !R_InitBlit( glblit ))
{ {
@@ -1462,7 +1405,6 @@ qboolean GAME_EXPORT R_Init( void )
qfrustum.view_clipplanes[1].leftedge = qfrustum.view_clipplanes[2].leftedge = qfrustum.view_clipplanes[3].leftedge = false; qfrustum.view_clipplanes[1].leftedge = qfrustum.view_clipplanes[2].leftedge = qfrustum.view_clipplanes[3].leftedge = false;
qfrustum.view_clipplanes[0].rightedge = qfrustum.view_clipplanes[2].rightedge = qfrustum.view_clipplanes[3].rightedge = false; qfrustum.view_clipplanes[0].rightedge = qfrustum.view_clipplanes[2].rightedge = qfrustum.view_clipplanes[3].rightedge = false;
R_StudioInit(); R_StudioInit();
R_SpriteInit();
R_InitTurb(); R_InitTurb();
GL_InitRandomTable(); GL_InitRandomTable();
@@ -1504,43 +1446,31 @@ int CL_FxBlend( cl_entity_t *e )
blend = e->curstate.renderamt + 0x10 * sin( gp_cl->time * 8 + offset ); blend = e->curstate.renderamt + 0x10 * sin( gp_cl->time * 8 + offset );
break; break;
case kRenderFxFadeSlow: case kRenderFxFadeSlow:
if( RP_NORMALPASS( )) if( e->curstate.renderamt > 0 )
{ e->curstate.renderamt -= 1;
if( e->curstate.renderamt > 0 ) else
e->curstate.renderamt -= 1; e->curstate.renderamt = 0;
else
e->curstate.renderamt = 0;
}
blend = e->curstate.renderamt; blend = e->curstate.renderamt;
break; break;
case kRenderFxFadeFast: case kRenderFxFadeFast:
if( RP_NORMALPASS( )) if( e->curstate.renderamt > 3 )
{ e->curstate.renderamt -= 4;
if( e->curstate.renderamt > 3 ) else
e->curstate.renderamt -= 4; e->curstate.renderamt = 0;
else
e->curstate.renderamt = 0;
}
blend = e->curstate.renderamt; blend = e->curstate.renderamt;
break; break;
case kRenderFxSolidSlow: case kRenderFxSolidSlow:
if( RP_NORMALPASS( )) if( e->curstate.renderamt < 255 )
{ e->curstate.renderamt += 1;
if( e->curstate.renderamt < 255 ) else
e->curstate.renderamt += 1; e->curstate.renderamt = 255;
else
e->curstate.renderamt = 255;
}
blend = e->curstate.renderamt; blend = e->curstate.renderamt;
break; break;
case kRenderFxSolidFast: case kRenderFxSolidFast:
if( RP_NORMALPASS( )) if( e->curstate.renderamt < 252 )
{ e->curstate.renderamt += 4;
if( e->curstate.renderamt < 252 ) else
e->curstate.renderamt += 4; e->curstate.renderamt = 255;
else
e->curstate.renderamt = 255;
}
blend = e->curstate.renderamt; blend = e->curstate.renderamt;
break; break;
case kRenderFxStrobeSlow: case kRenderFxStrobeSlow:
@@ -1581,7 +1511,7 @@ int CL_FxBlend( cl_entity_t *e )
case kRenderFxHologram: case kRenderFxHologram:
case kRenderFxDistort: case kRenderFxDistort:
VectorCopy( e->origin, tmp ); VectorCopy( e->origin, tmp );
VectorSubtract( tmp, RI.vieworg, tmp ); VectorSubtract( tmp, RI.rvp.vieworigin, tmp );
dist = DotProduct( tmp, RI.vforward ); dist = DotProduct( tmp, RI.vforward );
// turn off distance fade // turn off distance fade

View File

@@ -87,10 +87,8 @@ void D_ViewChanged( void )
/* /*
** clear Z-buffer and color-buffers if we're doing the gallery ** clear Z-buffer and color-buffers if we're doing the gallery
*/ */
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{
memset( d_pzbuffer, 0xff, vid.width * vid.height * sizeof( d_pzbuffer[0] )); memset( d_pzbuffer, 0xff, vid.width * vid.height * sizeof( d_pzbuffer[0] ));
}
D_Patch(); D_Patch();
} }
@@ -184,8 +182,8 @@ static void R_ViewChanged( vrect_t *vr )
RI.vrect = *vr; RI.vrect = *vr;
horizontalFieldOfView = 2 * tan((float)RI.fov_x / 360.0f * M_PI_F ); horizontalFieldOfView = 2 * tan((float)RI.rvp.fov_x / 360.0f * M_PI_F );
verticalFieldOfView = 2 * tan((float)RI.fov_y / 360.0f * M_PI_F ); verticalFieldOfView = 2 * tan((float)RI.rvp.fov_y / 360.0f * M_PI_F );
RI.fvrectx = (float)RI.vrect.x; RI.fvrectx = (float)RI.vrect.x;
RI.fvrectx_adj = (float)RI.vrect.x - 0.5f; RI.fvrectx_adj = (float)RI.vrect.x - 0.5f;
@@ -288,14 +286,14 @@ void R_SetupFrameQ( void )
// build the transformation matrix for the given view angles // build the transformation matrix for the given view angles
VectorCopy( RI.vieworg, tr.modelorg ); VectorCopy( RI.rvp.vieworigin, tr.modelorg );
// AngleVectors (RI.viewangles, RI.vforward, RI.vright, RI.vup); // AngleVectors (RI.rvp.viewangles, RI.vforward, RI.vright, RI.vup);
// current viewleaf // current viewleaf
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{ {
RI.viewleaf = gEngfuncs.Mod_PointInLeaf( RI.vieworg, WORLDMODEL->nodes ); RI.viewleaf = gEngfuncs.Mod_PointInLeaf( RI.rvp.vieworigin, WORLDMODEL->nodes, WORLDMODEL );
r_viewcluster = RI.viewleaf->cluster; r_viewcluster = RI.viewleaf->cluster;
} }
@@ -307,10 +305,10 @@ void R_SetupFrameQ( void )
vrect.y = 0;//r_newrefdef.y; vrect.y = 0;//r_newrefdef.y;
vrect.width = gpGlobals->width; vrect.width = gpGlobals->width;
vrect.height = gpGlobals->height;*/ vrect.height = gpGlobals->height;*/
vrect.x = RI.viewport[0]; vrect.x = RI.rvp.viewport[0];
vrect.y = RI.viewport[1]; vrect.y = RI.rvp.viewport[1];
vrect.width = RI.viewport[2]; vrect.width = RI.rvp.viewport[2];
vrect.height = RI.viewport[3]; vrect.height = RI.rvp.viewport[3];
d_viewbuffer = (void *)vid.buffer; d_viewbuffer = (void *)vid.buffer;
r_screenwidth = vid.rowbytes; r_screenwidth = vid.rowbytes;

View File

@@ -72,9 +72,9 @@ void GAME_EXPORT CL_DrawParticles( double frametime, particle_t *cl_active_parti
size = partsize; // get initial size of particle size = partsize; // get initial size of particle
// scale up to keep particles from disappearing // scale up to keep particles from disappearing
size += ( p->org[0] - RI.vieworg[0] ) * RI.cull_vforward[0]; size += ( p->org[0] - RI.rvp.vieworigin[0] ) * RI.cull_vforward[0];
size += ( p->org[1] - RI.vieworg[1] ) * RI.cull_vforward[1]; size += ( p->org[1] - RI.rvp.vieworigin[1] ) * RI.cull_vforward[1];
size += ( p->org[2] - RI.vieworg[2] ) * RI.cull_vforward[2]; size += ( p->org[2] - RI.rvp.vieworigin[2] ) * RI.cull_vforward[2];
if( size < 20.0f ) if( size < 20.0f )
size = partsize; size = partsize;

View File

@@ -21,317 +21,6 @@ GNU General Public License for more details.
#define GLARE_FALLOFF 19000.0f #define GLARE_FALLOFF 19000.0f
static char sprite_name[MAX_QPATH];
static char group_suffix[8];
static uint r_texFlags = 0;
static int sprite_version;
static float sprite_radius;
/*
====================
R_SpriteInit
====================
*/
void R_SpriteInit( void )
{
}
/*
====================
R_SpriteLoadFrame
upload a single frame
====================
*/
static const byte *R_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
{
dspriteframe_t pinframe;
mspriteframe_t *pspriteframe;
int gl_texturenum = 0;
char texname[128];
int bytes = 1;
memcpy( &pinframe, pin, sizeof( dspriteframe_t ));
if( sprite_version == SPRITE_VERSION_32 )
bytes = 4;
// build uinque frame name
if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite
{
Q_snprintf( texname, sizeof( texname ), "#HUD/%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
else
{
Q_snprintf( texname, sizeof( texname ), "#%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
// setup frame description
pspriteframe = Mem_Malloc( mod->mempool, sizeof( mspriteframe_t ));
pspriteframe->width = pinframe.width;
pspriteframe->height = pinframe.height;
pspriteframe->up = pinframe.origin[1];
pspriteframe->left = pinframe.origin[0];
pspriteframe->down = pinframe.origin[1] - pinframe.height;
pspriteframe->right = pinframe.width + pinframe.origin[0];
pspriteframe->gl_texturenum = gl_texturenum;
*ppframe = pspriteframe;
return (const byte *)((const byte *)pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes );
}
/*
====================
R_SpriteLoadGroup
upload a group frames
====================
*/
static const void *R_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
{
const dspritegroup_t *pingroup;
mspritegroup_t *pspritegroup;
const dspriteinterval_t *pin_intervals;
float *poutintervals;
int i, groupsize, numframes;
const void *ptemp;
pingroup = (const dspritegroup_t *)pin;
numframes = pingroup->numframes;
groupsize = sizeof( mspritegroup_t ) + ( numframes - 1 ) * sizeof( pspritegroup->frames[0] );
pspritegroup = Mem_Calloc( mod->mempool, groupsize );
pspritegroup->numframes = numframes;
*ppframe = (mspriteframe_t *)pspritegroup;
pin_intervals = (const dspriteinterval_t *)( pingroup + 1 );
poutintervals = Mem_Calloc( mod->mempool, numframes * sizeof( float ));
pspritegroup->intervals = poutintervals;
for( i = 0; i < numframes; i++ )
{
*poutintervals = pin_intervals->interval;
if( *poutintervals <= 0.0f )
*poutintervals = 1.0f; // set error value
poutintervals++;
pin_intervals++;
}
ptemp = (const void *)pin_intervals;
for( i = 0; i < numframes; i++ )
{
ptemp = R_SpriteLoadFrame( mod, ptemp, &pspritegroup->frames[i], framenum * 10 + i );
}
return ptemp;
}
/*
====================
Mod_LoadSpriteModel
load sprite model
====================
*/
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags )
{
const dsprite_t *pin;
const short *numi = NULL;
const byte *pframetype;
msprite_t *psprite;
int i;
pin = buffer;
psprite = mod->cache.data;
if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 )
numi = NULL;
else if( pin->version == SPRITE_VERSION_HL )
numi = (const short *)((const byte *)buffer + sizeof( dsprite_hl_t ));
r_texFlags = texFlags;
sprite_version = pin->version;
Q_strncpy( sprite_name, mod->name, sizeof( sprite_name ));
COM_StripExtension( sprite_name );
if( numi == NULL )
{
rgbdata_t *pal;
pal = gEngfuncs.FS_LoadImage( "#id.pal", (byte *)&i, 768 );
pframetype = ((const byte *)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else if( *numi <= 256 )
{
const byte *src = (const byte *)(numi+1);
rgbdata_t *pal;
size_t pal_bytes = *numi * 3;
// install palette
switch( psprite->texFormat )
{
case SPR_INDEXALPHA:
pal = gEngfuncs.FS_LoadImage( "#gradient.pal", src, pal_bytes );
break;
case SPR_ALPHTEST:
pal = gEngfuncs.FS_LoadImage( "#masked.pal", src, pal_bytes );
break;
default:
pal = gEngfuncs.FS_LoadImage( "#texgamma.pal", src, pal_bytes );
break;
}
pframetype = (const byte *)(src + pal_bytes);
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else
{
gEngfuncs.Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be less or equal than 256)\n", mod->name, *numi );
return;
}
if( mod->numframes < 1 )
return;
for( i = 0; i < mod->numframes; i++ )
{
frametype_t frametype;
dframetype_t dframetype;
memcpy( &dframetype, pframetype, sizeof( dframetype ));
frametype = dframetype.type;
psprite->frames[i].type = (spriteframetype_t)frametype;
switch( frametype )
{
case FRAME_SINGLE:
Q_strncpy( group_suffix, "frame", sizeof( group_suffix ));
pframetype = R_SpriteLoadFrame( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_GROUP:
Q_strncpy( group_suffix, "group", sizeof( group_suffix ));
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_ANGLED:
Q_strncpy( group_suffix, "angle", sizeof( group_suffix ));
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
}
if( pframetype == NULL )
break; // technically an error
}
if( loaded )
*loaded = true; // done
}
/*
====================
Mod_UnloadSpriteModel
release sprite model and frames
====================
*/
void Mod_SpriteUnloadTextures( void *data )
{
msprite_t *psprite = data;
int i;
if( !data )
return;
// release all textures
for( i = 0; i < psprite->numframes; i++ )
{
if( !psprite->frames[i].frameptr )
continue;
if( psprite->frames[i].type == SPR_SINGLE )
{
GL_FreeTexture( psprite->frames[i].frameptr->gl_texturenum );
}
else
{
mspritegroup_t *pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr;
int j;
for( j = 0; j < pspritegroup->numframes; j++ )
{
if( pspritegroup->frames[j] )
GL_FreeTexture( pspritegroup->frames[j]->gl_texturenum );
}
}
}
}
/*
================
R_GetSpriteFrame
assume pModel is valid
================
*/
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe = NULL;
float *pintervals, fullinterval;
int i, numframes;
float targettime;
Assert( pModel != NULL );
psprite = pModel->cache.data;
if( frame < 0 )
{
frame = 0;
}
else if( frame >= psprite->numframes )
{
if( frame > psprite->numframes )
gEngfuncs.Con_Printf( S_WARN "%s: no such frame %d (%s)\n", __func__, frame, pModel->name );
frame = psprite->numframes - 1;
}
if( psprite->frames[frame].type == SPR_SINGLE )
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if( psprite->frames[frame].type == SPR_GROUP )
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by zero
targettime = gp_cl->time - ((int)( gp_cl->time / fullinterval )) * fullinterval;
for( i = 0; i < ( numframes - 1 ); i++ )
{
if( pintervals[i] > targettime )
break;
}
pspriteframe = pspritegroup->frames[i];
}
else if( psprite->frames[frame].type == FRAME_ANGLED )
{
int angleframe = (int)( Q_rint(( RI.viewangles[1] - yaw + 45.0f ) / 360 * 8 ) - 4 ) & 7;
// e.g. doom-style sprite monsters
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[angleframe];
}
return pspriteframe;
}
/* /*
================ ================
R_CullSpriteModel R_CullSpriteModel
@@ -354,8 +43,6 @@ static qboolean R_CullSpriteModel( cl_entity_t *e, vec3_t origin )
VectorScale( e->model->mins, scale, sprite_mins ); VectorScale( e->model->mins, scale, sprite_mins );
VectorScale( e->model->maxs, scale, sprite_maxs ); VectorScale( e->model->maxs, scale, sprite_maxs );
sprite_radius = RadiusFromBounds( sprite_mins, sprite_maxs );
VectorAdd( sprite_mins, origin, sprite_mins ); VectorAdd( sprite_mins, origin, sprite_mins );
VectorAdd( sprite_maxs, origin, sprite_maxs ); VectorAdd( sprite_maxs, origin, sprite_maxs );
@@ -371,20 +58,15 @@ Set sprite brightness factor
*/ */
static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, float *pscale ) static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, float *pscale )
{ {
float dist, brightness; float dist, brightness;
vec3_t glowDist; vec3_t glowDist;
pmtrace_t *tr;
VectorSubtract( origin, RI.vieworg, glowDist ); VectorSubtract( origin, RI.rvp.vieworigin, glowDist );
dist = VectorLength( glowDist ); dist = VectorLength( glowDist );
if( RP_NORMALPASS( )) pmtrace_t *tr = gEngfuncs.EV_VisTraceLine( RI.rvp.vieworigin, origin, r_traceglow.value ? PM_GLASS_IGNORE : ( PM_GLASS_IGNORE | PM_STUDIO_IGNORE ));
{ if(( 1.0f - tr->fraction ) * dist > 8.0f )
tr = gEngfuncs.EV_VisTraceLine( RI.vieworg, origin, r_traceglow.value ? PM_GLASS_IGNORE : ( PM_GLASS_IGNORE | PM_STUDIO_IGNORE )); return 0.0f;
if(( 1.0f - tr->fraction ) * dist > 8.0f )
return 0.0f;
}
if( renderfx == kRenderFxNoDissipation ) if( renderfx == kRenderFxNoDissipation )
return 1.0f; return 1.0f;
@@ -412,9 +94,9 @@ static qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, float *pscale )
TriWorldToScreen( origin, v ); TriWorldToScreen( origin, v );
if( v[0] < RI.viewport[0] || v[0] > RI.viewport[0] + RI.viewport[2] ) if( v[0] < RI.rvp.viewport[0] || v[0] > RI.rvp.viewport[0] + RI.rvp.viewport[2] )
return true; // do scissor return true; // do scissor
if( v[1] < RI.viewport[1] || v[1] > RI.viewport[1] + RI.viewport[3] ) if( v[1] < RI.rvp.viewport[1] || v[1] > RI.rvp.viewport[1] + RI.rvp.viewport[3] )
return true; // do scissor return true; // do scissor
blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale ); blend = R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, pscale );
@@ -482,9 +164,6 @@ void R_DrawSpriteModel( cl_entity_t *e )
vec3_t v_forward, v_right, v_up; vec3_t v_forward, v_right, v_up;
vec3_t origin, color; vec3_t origin, color;
if( RI.params & RP_ENVVIEW )
return;
model = e->model; model = e->model;
psprite = (msprite_t *)model->cache.data; psprite = (msprite_t *)model->cache.data;
VectorCopy( e->origin, origin ); // set render origin VectorCopy( e->origin, origin ); // set render origin
@@ -536,7 +215,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
color[2] = 1.0f; color[2] = 1.0f;
} }
frame = R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] ); frame = gEngfuncs.R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );
type = psprite->type; type = psprite->type;
@@ -552,7 +231,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
VectorSubtract( origin, v_forward, origin ); VectorSubtract( origin, v_forward, origin );
break; break;
case SPR_FACING_UPRIGHT: case SPR_FACING_UPRIGHT:
VectorSet( v_right, origin[1] - RI.vieworg[1], -( origin[0] - RI.vieworg[0] ), 0.0f ); VectorSet( v_right, origin[1] - RI.rvp.vieworigin[1], -( origin[0] - RI.rvp.vieworigin[0] ), 0.0f );
VectorSet( v_up, 0.0f, 0.0f, 1.0f ); VectorSet( v_up, 0.0f, 0.0f, 1.0f );
VectorNormalize( v_right ); VectorNormalize( v_right );
break; break;

View File

@@ -147,7 +147,7 @@ init current time for a given model
*/ */
static void R_StudioSetupTimings( void ) static void R_StudioSetupTimings( void )
{ {
if( RI.drawWorld ) if( FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{ {
// synchronize with server time // synchronize with server time
g_studio.time = gp_cl->time; g_studio.time = gp_cl->time;
@@ -353,23 +353,12 @@ pfnPlayerInfo
*/ */
player_info_t *pfnPlayerInfo( int index ) player_info_t *pfnPlayerInfo( int index )
{ {
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
index = -1; index = -1;
return gEngfuncs.pfnPlayerInfo( index ); return gEngfuncs.pfnPlayerInfo( index );
} }
/*
===============
pfnMod_ForName
===============
*/
static model_t *pfnMod_ForName( const char *model, int crash )
{
return gEngfuncs.Mod_ForName( model, crash, false );
}
/* /*
=============== ===============
pfnGetPlayerState pfnGetPlayerState
@@ -378,23 +367,12 @@ pfnGetPlayerState
*/ */
static entity_state_t *R_StudioGetPlayerState( int index ) static entity_state_t *R_StudioGetPlayerState( int index )
{ {
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
return &RI.currententity->curstate; return &RI.currententity->curstate;
return gEngfuncs.pfnGetPlayerState( index ); return gEngfuncs.pfnGetPlayerState( index );
} }
/*
===============
pfnGetViewEntity
===============
*/
static cl_entity_t *pfnGetViewEntity( void )
{
return tr.viewent;
}
/* /*
=============== ===============
pfnGetEngineTimes pfnGetEngineTimes
@@ -420,7 +398,7 @@ pfnGetViewInfo
static void pfnGetViewInfo( float *origin, float *upv, float *rightv, float *forwardv ) static void pfnGetViewInfo( float *origin, float *upv, float *rightv, float *forwardv )
{ {
if( origin ) if( origin )
VectorCopy( RI.vieworg, origin ); VectorCopy( RI.rvp.vieworigin, origin );
if( forwardv ) if( forwardv )
VectorCopy( RI.vforward, forwardv ); VectorCopy( RI.vforward, forwardv );
if( rightv ) if( rightv )
@@ -429,17 +407,6 @@ static void pfnGetViewInfo( float *origin, float *upv, float *rightv, float *for
VectorCopy( RI.vup, upv ); VectorCopy( RI.vup, upv );
} }
/*
===============
R_GetChromeSprite
===============
*/
static model_t *R_GetChromeSprite( void )
{
return gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE );
}
/* /*
=============== ===============
pfnGetModelCounters pfnGetModelCounters
@@ -452,20 +419,6 @@ static void pfnGetModelCounters( int **s, int **a )
*a = &r_stats.c_studio_models_drawn; *a = &r_stats.c_studio_models_drawn;
} }
/*
===============
pfnGetAliasScale
===============
*/
static void pfnGetAliasScale( float *x, float *y )
{
if( x )
*x = 1.0f;
if( y )
*y = 1.0f;
}
/* /*
=============== ===============
pfnStudioGetBoneTransform pfnStudioGetBoneTransform
@@ -488,17 +441,6 @@ static float ****pfnStudioGetLightTransform( void )
return (float ****)g_studio.lighttransform; return (float ****)g_studio.lighttransform;
} }
/*
===============
pfnStudioGetAliasTransform
===============
*/
static float ***pfnStudioGetAliasTransform( void )
{
return NULL;
}
/* /*
=============== ===============
pfnStudioGetRotationMatrix pfnStudioGetRotationMatrix
@@ -1352,7 +1294,7 @@ static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
if( !plight || !ent || !ent->model ) if( !plight || !ent || !ent->model )
return; return;
if( !RI.drawWorld || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT )) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ) || r_fullbright->value || FBitSet( ent->curstate.effects, EF_FULLBRIGHT ))
{ {
plight->shadelight = 0; plight->shadelight = 0;
plight->ambientlight = 192; plight->ambientlight = 192;
@@ -1467,7 +1409,7 @@ static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ ) for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{ {
dl = &tr.dlights[lnum]; dl = &gp_dlights[lnum];
if( dl->die < g_studio.time || !r_dynamic->value ) if( dl->die < g_studio.time || !r_dynamic->value )
continue; continue;
@@ -2333,7 +2275,7 @@ static model_t *R_StudioSetupPlayerModel( int index )
state = &g_studio.player_models[index]; state = &g_studio.player_models[index];
// g-cont: force for "dev-mode", non-local games and menu preview // g-cont: force for "dev-mode", non-local games and menu preview
if(( gpGlobals->developer || !ENGINE_GET_PARM( PARM_LOCAL_GAME ) || !RI.drawWorld ) && info->model[0] ) if(( gpGlobals->developer || !ENGINE_GET_PARM( PARM_LOCAL_GAME ) || !FBitSet( RI.rvp.flags, RF_DRAW_WORLD )) && info->model[0] )
{ {
if( Q_strcmp( state->name, info->model )) if( Q_strcmp( state->name, info->model ))
{ {
@@ -2572,19 +2514,7 @@ R_StudioSetChromeOrigin
*/ */
static void R_StudioSetChromeOrigin( void ) static void R_StudioSetChromeOrigin( void )
{ {
VectorCopy( RI.vieworg, g_studio.chrome_origin ); VectorCopy( RI.rvp.vieworigin, g_studio.chrome_origin );
}
/*
===============
pfnIsHardware
Xash3D is always works in hardware mode
===============
*/
static int pfnIsHardware( void )
{
return 1; // 0 is Software, 1 is OpenGL, 2 is Direct3D
} }
/* /*
@@ -2683,7 +2613,7 @@ static void R_StudioRenderModel( void )
R_StudioRenderFinal( ); R_StudioRenderFinal( );
R_StudioSetForceFaceFlags( STUDIO_NF_CHROME ); R_StudioSetForceFaceFlags( STUDIO_NF_CHROME );
TriSpriteTexture( R_GetChromeSprite(), 0 ); TriSpriteTexture( gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE ), 0 );
RI.currententity->curstate.renderfx = kRenderFxGlowShell; RI.currententity->curstate.renderfx = kRenderFxGlowShell;
R_StudioRenderFinal( ); R_StudioRenderFinal( );
@@ -2926,7 +2856,7 @@ static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer )
if( flags & STUDIO_RENDER ) if( flags & STUDIO_RENDER )
{ {
// change body if it's a menu entity // change body if it's a menu entity
if( cl_himodels->value && ( RI.currentmodel != RI.currententity->model || !RI.drawWorld )) if( cl_himodels->value && ( RI.currentmodel != RI.currententity->model || !FBitSet( RI.rvp.flags, RF_DRAW_WORLD )))
{ {
// show highest resolution multiplayer model // show highest resolution multiplayer model
RI.currententity->curstate.body = 255; RI.currententity->curstate.body = 255;
@@ -3087,7 +3017,7 @@ R_StudioDrawModelInternal
*/ */
static void R_StudioDrawModelInternal( cl_entity_t *e, int flags ) static void R_StudioDrawModelInternal( cl_entity_t *e, int flags )
{ {
if( !RI.drawWorld ) if( !FBitSet( RI.rvp.flags, RF_DRAW_WORLD ))
{ {
if( e->player ) if( e->player )
R_StudioDrawPlayer( flags, &e->curstate ); R_StudioDrawPlayer( flags, &e->curstate );
@@ -3124,9 +3054,6 @@ R_DrawStudioModel
*/ */
void R_DrawStudioModel( cl_entity_t *e ) void R_DrawStudioModel( cl_entity_t *e )
{ {
if( FBitSet( RI.params, RP_ENVVIEW ))
return;
R_StudioSetupTimings(); R_StudioSetupTimings();
if( e->player ) if( e->player )
@@ -3180,7 +3107,7 @@ void R_RunViewmodelEvents( void )
return; return;
// ignore in thirdperson, camera view or client is died // ignore in thirdperson, camera view or client is died
if( !RP_NORMALPASS() || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer()) if( ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer())
return; return;
RI.currententity = tr.viewent; RI.currententity = tr.viewent;
@@ -3198,20 +3125,6 @@ void R_RunViewmodelEvents( void )
R_StudioDrawModelInternal( RI.currententity, STUDIO_EVENTS ); R_StudioDrawModelInternal( RI.currententity, STUDIO_EVENTS );
} }
/*
=================
R_GatherPlayerLight
=================
*/
void R_GatherPlayerLight( void )
{
cl_entity_t *view = tr.viewent;
colorVec c;
c = R_LightPoint( view->origin );
gEngfuncs.SetLocalLightLevel(( c.r + c.g + c.b ) / 3 );
}
/* /*
================= =================
R_DrawViewModel R_DrawViewModel
@@ -3221,7 +3134,7 @@ void R_DrawViewModel( void )
{ {
cl_entity_t *view = tr.viewent; cl_entity_t *view = tr.viewent;
R_GatherPlayerLight(); R_GatherPlayerLight( view );
if( r_drawviewmodel->value == 0 ) if( r_drawviewmodel->value == 0 )
return; return;
@@ -3230,7 +3143,7 @@ void R_DrawViewModel( void )
return; return;
// ignore in thirdperson, camera view or client is died // ignore in thirdperson, camera view or client is died
if( !RP_NORMALPASS() || ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer()) if( ENGINE_GET_PARM( PARM_LOCAL_HEALTH ) <= 0 || !CL_IsViewEntityLocalPlayer())
return; return;
tr.blend = CL_FxBlend( view ) / 255.0f; tr.blend = CL_FxBlend( view ) / 255.0f;
@@ -3418,113 +3331,53 @@ void Mod_StudioUnloadTextures( void *data )
} }
} }
static model_t *pfnModelHandle( int modelindex ) qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefaultDraw )
{ {
return CL_ModelHandle( modelindex );
}
static void *pfnMod_CacheCheck( struct cache_user_s *c )
{
return gEngfuncs.Mod_CacheCheck( c );
}
static void *pfnMod_StudioExtradata( model_t *mod )
{
return gEngfuncs.Mod_Extradata( mod_studio, mod );
}
static void pfnMod_LoadCacheFile( const char *path, struct cache_user_s *cu )
{
gEngfuncs.Mod_LoadCacheFile( path, cu );
}
static cvar_t *pfnGetCvarPointer( const char *name )
{
return (cvar_t *)gEngfuncs.pfnGetCvarPointer( name );
}
static void *pfnMod_Calloc( int number, size_t size )
{
return gEngfuncs.Mod_Calloc( number, size );
}
static engine_studio_api_t gStudioAPI =
{
pfnMod_Calloc,
pfnMod_CacheCheck,
pfnMod_LoadCacheFile,
pfnMod_ForName,
pfnMod_StudioExtradata,
pfnModelHandle,
pfnGetCurrentEntity,
pfnPlayerInfo,
R_StudioGetPlayerState,
pfnGetViewEntity,
pfnGetEngineTimes,
pfnGetCvarPointer,
pfnGetViewInfo,
R_GetChromeSprite,
pfnGetModelCounters,
pfnGetAliasScale,
pfnStudioGetBoneTransform,
pfnStudioGetLightTransform,
pfnStudioGetAliasTransform,
pfnStudioGetRotationMatrix,
R_StudioSetupModel,
R_StudioCheckBBox,
R_StudioDynamicLight,
R_StudioEntityLight,
R_StudioSetupLighting,
R_StudioDrawPoints,
R_StudioDrawHulls,
R_StudioDrawAbsBBox,
R_StudioDrawBones,
(void *)R_StudioSetupSkin,
R_StudioSetRemapColors,
R_StudioSetupPlayerModel,
R_StudioClientEvents,
R_StudioGetForceFaceFlags,
R_StudioSetForceFaceFlags,
(void *)R_StudioSetHeader,
R_StudioSetRenderModel,
R_StudioSetupRenderer,
R_StudioRestoreRenderer,
R_StudioSetChromeOrigin,
pfnIsHardware,
GL_StudioDrawShadow,
GL_StudioSetRenderMode,
R_StudioSetRenderamt,
R_StudioSetCullState,
R_StudioRenderShadow,
};
static r_studio_interface_t gStudioDraw =
{
STUDIO_INTERFACE_VERSION,
R_StudioDrawModel,
R_StudioDrawPlayer,
};
/*
===============
CL_InitStudioAPI
Initialize client studio
===============
*/
void GAME_EXPORT CL_InitStudioAPI( void )
{
pStudioDraw = &gStudioDraw;
// trying to grab them from client.dll
cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" ); cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" );
// Xash will be used internal StudioModelRenderer api->GetCurrentEntity = pfnGetCurrentEntity;
if( gEngfuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI )) api->PlayerInfo = pfnPlayerInfo;
return; api->GetPlayerState = R_StudioGetPlayerState;
api->GetTimes = pfnGetEngineTimes;
api->GetViewInfo = pfnGetViewInfo;
api->GetModelCounters = pfnGetModelCounters;
api->StudioGetBoneTransform = pfnStudioGetBoneTransform;
api->StudioGetLightTransform = pfnStudioGetLightTransform;
api->StudioGetRotationMatrix = pfnStudioGetRotationMatrix;
api->StudioSetupModel = R_StudioSetupModel;
api->StudioCheckBBox = R_StudioCheckBBox;
api->StudioDynamicLight = R_StudioDynamicLight;
api->StudioEntityLight = R_StudioEntityLight;
api->StudioSetupLighting = R_StudioSetupLighting;
api->StudioDrawPoints = R_StudioDrawPoints;
api->StudioDrawHulls = R_StudioDrawHulls;
api->StudioDrawAbsBBox = R_StudioDrawAbsBBox;
api->StudioDrawBones = R_StudioDrawBones;
api->StudioSetupSkin = (void *)R_StudioSetupSkin;
api->StudioSetRemapColors = R_StudioSetRemapColors;
api->SetupPlayerModel = R_StudioSetupPlayerModel;
api->StudioClientEvents = R_StudioClientEvents;
api->GetForceFaceFlags = R_StudioGetForceFaceFlags;
api->SetForceFaceFlags = R_StudioSetForceFaceFlags;
api->StudioSetHeader = (void *)R_StudioSetHeader;
api->SetRenderModel = R_StudioSetRenderModel;
api->SetupRenderer = R_StudioSetupRenderer;
api->RestoreRenderer = R_StudioRestoreRenderer;
api->SetChromeOrigin = R_StudioSetChromeOrigin;
api->GL_StudioDrawShadow = GL_StudioDrawShadow;
api->GL_SetRenderMode = GL_StudioSetRenderMode;
api->StudioSetRenderamt = R_StudioSetRenderamt;
api->StudioSetCullState = R_StudioSetCullState;
api->StudioRenderShadow = R_StudioRenderShadow;
// NOTE: we always return true even if game interface was not correct pDefaultDraw->version = STUDIO_INTERFACE_VERSION;
// because we need Draw our StudioModels pDefaultDraw->StudioDrawModel = R_StudioDrawModel;
// just restore pointer to builtin function pDefaultDraw->StudioDrawPlayer = R_StudioDrawPlayer;
pStudioDraw = &gStudioDraw;
return true;
}
void R_StudioSetDrawInterface( r_studio_interface_t *pDraw )
{
pStudioDraw = pDraw;
} }

View File

@@ -53,7 +53,7 @@ static void (*surfmiptable[4])( void ) = {
}; };
// void R_BuildLightMap (void); // void R_BuildLightMap (void);
extern unsigned blocklights[10240]; // allow some very large lightmaps static unsigned blocklights[10240]; // allow some very large lightmaps
static float surfscale; static float surfscale;
static qboolean r_cache_thrash; // set if surface cache is thrashing static qboolean r_cache_thrash; // set if surface cache is thrashing
@@ -62,7 +62,6 @@ static int sc_size;
surfcache_t *sc_rover; surfcache_t *sc_rover;
static surfcache_t *sc_base; static surfcache_t *sc_base;
static int rtable[MOD_FRAMES][MOD_FRAMES];
static void R_BuildLightMap( void ); static void R_BuildLightMap( void );
/* /*
@@ -108,7 +107,7 @@ static void R_AddDynamicLights( const msurface_t *surf )
if( !FBitSet( surf->dlightbits, BIT( lnum ))) if( !FBitSet( surf->dlightbits, BIT( lnum )))
continue; // not lit by this light continue; // not lit by this light
dl = &tr.dlights[lnum]; dl = &gp_dlights[lnum];
// transform light origin to local bmodel space // transform light origin to local bmodel space
if( !tr.modelviewIdentity ) if( !tr.modelviewIdentity )
@@ -209,7 +208,7 @@ static void R_BuildLightMap( void )
if( surf->styles[map] >= 255 ) if( surf->styles[map] >= 255 )
break; break;
scale = tr.lightstylevalue[surf->styles[map]]; scale = g_lightstylevalue[surf->styles[map]];
for( i = 0; i < size; i++ ) for( i = 0; i < size; i++ )
blocklights[i] += ( lm[i].r + lm[i].g + lm[i].b ) * scale; blocklights[i] += ( lm[i].r + lm[i].g + lm[i].b ) * scale;
@@ -238,20 +237,6 @@ static void R_BuildLightMap( void )
} }
} }
void GL_InitRandomTable( void )
{
int tu, tv;
for( tu = 0; tu < MOD_FRAMES; tu++ )
{
for( tv = 0; tv < MOD_FRAMES; tv++ )
{
rtable[tu][tv] = gEngfuncs.COM_RandomLong( 0, 0x7FFF );
}
}
gEngfuncs.COM_SetRandomSeed( 0 );
}
/* /*
=============== ===============
@@ -1118,7 +1103,7 @@ surfcache_t *D_CacheSurface( msurface_t *surface, int miplevel )
// check for lightmap modification // check for lightmap modification
for( maps = 0; maps < MAXLIGHTMAPS && surface->styles[maps] != 255; maps++ ) for( maps = 0; maps < MAXLIGHTMAPS && surface->styles[maps] != 255; maps++ )
{ {
if( tr.lightstylevalue[surface->styles[maps]] != surface->cached_light[maps] ) if( g_lightstylevalue[surface->styles[maps]] != surface->cached_light[maps] )
{ {
surface->dlightframe = tr.framecount; surface->dlightframe = tr.framecount;
} }
@@ -1188,10 +1173,7 @@ surfcache_t *D_CacheSurface( msurface_t *surface, int miplevel )
cache->lightadj[1] = r_drawsurf.lightadj[1]; cache->lightadj[1] = r_drawsurf.lightadj[1];
cache->lightadj[2] = r_drawsurf.lightadj[2]; cache->lightadj[2] = r_drawsurf.lightadj[2];
cache->lightadj[3] = r_drawsurf.lightadj[3]; cache->lightadj[3] = r_drawsurf.lightadj[3];
for( maps = 0; maps < MAXLIGHTMAPS && surface->styles[maps] != 255; maps++ ) R_UpdateSurfaceCachedLight( surface );
{
surface->cached_light[maps] = tr.lightstylevalue[surface->styles[maps]];
}
// //
// draw and light the surface texture // draw and light the surface texture
// //

View File

@@ -78,9 +78,9 @@ void R_SetUpWorldTransform( void )
aliasoldworldtransform[i][0] = aliasworldtransform[i][2] = s_alias_up[i]; aliasoldworldtransform[i][0] = aliasworldtransform[i][2] = s_alias_up[i];
} }
aliasworldtransform[0][3] = -RI.vieworg[0]; aliasworldtransform[0][3] = -RI.rvp.vieworigin[0];
aliasworldtransform[1][3] = -RI.vieworg[1]; aliasworldtransform[1][3] = -RI.rvp.vieworigin[1];
aliasworldtransform[2][3] = -RI.vieworg[2]; aliasworldtransform[2][3] = -RI.rvp.vieworigin[2];
// aliasoldworldtransform[0][3] = RI.currententity->oldorigin[0]-r_origin[0]; // aliasoldworldtransform[0][3] = RI.currententity->oldorigin[0]-r_origin[0];
// aliasoldworldtransform[1][3] = RI.currententity->oldorigin[1]-r_origin[1]; // aliasoldworldtransform[1][3] = RI.currententity->oldorigin[1]-r_origin[1];

View File

@@ -286,7 +286,10 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
{ {
int gl_texturenum; int gl_texturenum;
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) == 0 ) if( !pSpriteModel || pSpriteModel->type != mod_sprite || !pSpriteModel->cache.data )
return 0;
if(( gl_texturenum = gEngfuncs.R_GetSpriteFrame( pSpriteModel, frame, 0.0f )->gl_texturenum ) == 0 )
return 0; return 0;
if( gl_texturenum <= 0 || gl_texturenum >= MAX_TEXTURES ) if( gl_texturenum <= 0 || gl_texturenum >= MAX_TEXTURES )

View File

@@ -14,7 +14,7 @@ def configure(conf):
return return
def build(bld): def build(bld):
libs = [ 'engine_includes', 'werror' ] libs = [ 'ref_common', 'engine_includes', 'werror' ]
# on PSVita do not link any libraries that are already in the main executable, but add the includes target # on PSVita do not link any libraries that are already in the main executable, but add the includes target
if bld.env.DEST_OS == 'psvita': if bld.env.DEST_OS == 'psvita':
libs += [ 'sdk_includes' ] libs += [ 'sdk_includes' ]

View File

@@ -9,7 +9,8 @@ cd "$GITHUB_WORKSPACE" || die
cp -vr /Library/Frameworks/SDL2.framework ./build cp -vr /Library/Frameworks/SDL2.framework ./build
pushd hlsdk || die pushd hlsdk || die
cmake -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DGAMEDIR=$(realpath ../build/ios) -DCMAKE_BUILD_TYPE=Debug -B build -S . mkdir -p ../build/ios/libs || die
cmake -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$(realpath ../build/ios/libs) -DCMAKE_BUILD_TYPE=Debug -B build -S .
cmake --build build --target install || die cmake --build build --target install || die
popd || die popd || die

View File

@@ -91,6 +91,7 @@ SUBDIRS = [
Subproject('3rdparty/nanogl', lambda x: x.env.CLIENT and x.env.NANOGL), Subproject('3rdparty/nanogl', lambda x: x.env.CLIENT and x.env.NANOGL),
Subproject('3rdparty/gl-wes-v2', lambda x: x.env.CLIENT and x.env.GLWES), Subproject('3rdparty/gl-wes-v2', lambda x: x.env.CLIENT and x.env.GLWES),
Subproject('3rdparty/gl4es', lambda x: x.env.CLIENT and x.env.GL4ES), Subproject('3rdparty/gl4es', lambda x: x.env.CLIENT and x.env.GL4ES),
Subproject('ref/common', lambda x: x.env.CLIENT),
Subproject('ref/gl', lambda x: x.env.CLIENT and (x.env.GL or x.env.NANOGL or x.env.GLWES or x.env.GL4ES or x.env.GLES3COMPAT)), Subproject('ref/gl', lambda x: x.env.CLIENT and (x.env.GL or x.env.NANOGL or x.env.GLWES or x.env.GL4ES or x.env.GLES3COMPAT)),
Subproject('ref/soft', lambda x: x.env.CLIENT and x.env.SOFT), Subproject('ref/soft', lambda x: x.env.CLIENT and x.env.SOFT),
Subproject('ref/null', lambda x: x.env.CLIENT and x.env.NULL), Subproject('ref/null', lambda x: x.env.CLIENT and x.env.NULL),