diff --git a/common/backends.h b/common/backends.h index bd0d7769..f95a551f 100644 --- a/common/backends.h +++ b/common/backends.h @@ -18,6 +18,7 @@ GNU General Public License for more details. #define BACKENDS_H // video backends (XASH_VIDEO) +#define VIDEO_DONTCARE -1 // a special mode for ref_dll #define VIDEO_NULL 0 #define VIDEO_SDL 1 #define VIDEO_ANDROID 2 diff --git a/common/defaults.h b/common/defaults.h index 0df60a07..da4d07b2 100644 --- a/common/defaults.h +++ b/common/defaults.h @@ -95,7 +95,11 @@ SETUP BACKENDS DEFINITIONS // fallback to NULL // #ifndef XASH_VIDEO - #define XASH_VIDEO VIDEO_NULL + #ifdef REF_DLL + #define XASH_VIDEO VIDEO_DONTCARE + #else + #define XASH_VIDEO VIDEO_NULL + #endif #endif #ifndef XASH_SOUND diff --git a/common/port.h b/common/port.h index 79ef55eb..174b5bc6 100644 --- a/common/port.h +++ b/common/port.h @@ -78,6 +78,7 @@ GNU General Public License for more details. #define __stdcall #define _inline static inline + #define FORCEINLINE inline __attribute__((always_inline)) #define O_BINARY 0 // O_BINARY is Windows extension #define O_TEXT 0 // O_TEXT is Windows extension @@ -113,6 +114,9 @@ GNU General Public License for more details. #else // WIN32 #ifdef __MINGW32__ #define _inline static inline + #define FORCEINLINE inline __attribute__((always_inline)) + #else + #define FORCEINLINE __forceinline #endif #define strcasecmp _stricmp diff --git a/common/ref_api.h b/common/ref_api.h index 586925dd..3be645ba 100644 --- a/common/ref_api.h +++ b/common/ref_api.h @@ -15,6 +15,8 @@ GNU General Public License for more details. #pragma once #ifndef REF_API #define REF_API + +#include #include "com_image.h" #include "vgui_api.h" #include "render_api.h" @@ -24,6 +26,7 @@ GNU General Public License for more details. #include "com_model.h" #include "studio.h" #include "r_efx.h" +#include "cvar.h" #define REF_API_VERSION 1 @@ -41,11 +44,28 @@ GNU General Public License for more details. #define VID_MAPSHOT 3 // special case for overview layer #define VID_SNAPSHOT 4 // save screenshot into root dir and no gamma correction +// model flags (stored in model_t->flags) +#define MODEL_CONVEYOR BIT( 0 ) +#define MODEL_HAS_ORIGIN BIT( 1 ) +#define MODEL_LIQUID BIT( 2 ) // model has only point hull +#define MODEL_TRANSPARENT BIT( 3 ) // have transparent surfaces +#define MODEL_COLORED_LIGHTING BIT( 4 ) // lightmaps stored as RGB +#define MODEL_WORLD BIT( 29 ) // it's a worldmodel +#define MODEL_CLIENT BIT( 30 ) // client sprite + +// goes into world.flags +#define FWORLD_SKYSPHERE BIT( 0 ) +#define FWORLD_CUSTOM_SKYBOX BIT( 1 ) +#define FWORLD_WATERALPHA BIT( 2 ) +#define FWORLD_HAS_DELUXEMAP BIT( 3 ) typedef struct ref_globals_s { qboolean developer; + float time; // cl.time + float oldtime; // cl.oldtime + // viewport width and height int width; int height; @@ -87,10 +107,107 @@ enum ref_shared_texture_e REF_ALPHASKY_TEXTURE, }; +struct con_nprint_s; + typedef struct ref_api_s { - // TriApi helper - int (*TriGetRenderMode)( void ); + qboolean (*CL_IsDevOverviewMode)( void ); + qboolean (*CL_IsThirdPersonMode)( void ); + qboolean (*Host_IsQuakeCompatible)( void ); + int (*GetPlayerIndex)( void ); // cl.playernum + 1 + int (*GetViewEntIndex)( void ); // cl.viewentity + + // cvar handlers + convar_t *(*pfnRegisterVariable)( const char *szName, const char *szValue, int flags, const char *description ); + convar_t *(*pfnGetCvarPointer)( const char *name ); + float (*pfnGetCvarFloat)( const char *szName ); + const char *(*pfnGetCvarString)( const char *szName ); + + // command handlers + int (*Cmd_AddCommand)( const char *cmd_name, void (*function)(void), const char *description ); + int (*Cmd_RemoveCommand)( const char *cmd_name ); + int (*Cmd_Argc)( void ); + const char *(*Cmd_Argv)( int arg ); + + // cbuf + void (*Cbuf_AddText)( const char *commands ); + void (*Cbuf_InsertText)( const char *commands ); + void (*Cbuf_Execute)( void ); + + // logging + void (*Con_VPrintf)( const char *fmt, va_list args ); + void (*Con_Printf)( const char *fmt, ... ); + void (*Con_DPrintf)( const char *fmt, ... ); + void (*Con_NPrintf)( int pos, const char *fmt, ... ); + void (*Con_NXPrintf)( struct con_nprint_s *info, const char *fmt, ... ); + + // entity management + struct cl_entity_s *(*GetLocalPlayer)( void ); + struct cl_entity_s *(*GetViewModel)( void ); + struct cl_entity_s *(*GetEntityByIndex)( int idx ); + int (*pfnNumberOfEntities)( void ); + struct cl_entity_s *(*R_BeamGetEntity)( int index ); + + // brushes + int (*Mod_SampleSizeForFace)( struct msurface_s *surf ); + qboolean (*Mod_BoxVisible)( const vec3_t mins, const vec3_t maxs, const byte *visbits ); + struct world_static_s *(*GetWorld)( void ); // returns &world + + // studio models + void (*R_StudioSlerpBones)( int numbones, vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s ); + void (*R_StudioCalcBoneQuaternion)( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, vec4_t q ); + void (*R_StudioCalcBonePosition)( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, vec3_t adj, vec3_t pos ); + void *(*R_StudioGetAnim)( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc ); + + // efx + void (*CL_DrawEFX)( float time, qboolean fTrans ); + void (*R_FreeDeadParticles)( particle_t **ppparticles ); + + // model management + model_t *(*Mod_ForName)( const char *name, qboolean crash, qboolean trackCRC ); + void *(*Mod_Extradata)( int type, model_t *model ); + struct model_s *(*pfnGetModelByIndex)( int index ); // CL_ModelHandle + + // trace + struct pmtrace_s *(*PM_TraceLine)( float *start, float *end, int flags, int usehull, int ignore_pe ); + struct pmtrace_s *(*EV_VisTraceLine )( float *start, float *end, int flags ); + struct pmtrace_t (*CL_TraceLine)( vec3_t start, vec3_t end, int flags ); + + struct movevars_s *(*pfnGetMoveVars)( void ); + + // utils + void (*CL_ExtraUpdate)( void ); + uint (*COM_HashKey)( const char *strings, uint hashSize ); + void (*Host_Error)( const char *fmt, ... ); + int (*CL_FxBlend)( cl_entity_t *e ); + float (*COM_RandomFloat)( float rmin, float rmax ); + int (*COM_RandomLong)( int rmin, int rmax ); + struct screenfade_s *(*GetScreenFade)( void ); + struct client_textmessage_s *(*pfnTextMessageGet)( const char *pName ); + void (*GetPredictedOrigin)( vec3_t v ); + + // memory + byte *(*_Mem_AllocPool)( const char *name, const char *filename, int fileline ); + void (*_Mem_FreePool)( byte **poolptr, const char *filename, int fileline ); + void *(*_Mem_Alloc)( byte *poolptr, size_t size, qboolean clear, const char *filename, int fileline ); + void *(*_Mem_Realloc)( byte *poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ); + void (*_Mem_Free)( void *data, const char *filename, int fileline ); + + // library management + void *(*COM_LoadLibrary)( const char *name ); + void (*COM_FreeLibrary)( void *handle ); + void *(*COM_GetProcAddress)( void *handle, const char *name ); + + // filesystem + int (*FS_FileExists)( const char *filename, int gamedironly ); + + // GL + int (*GL_SetAttribute)( int attr, int value ); + int (*GL_GetAttribute)( int attr ); + int (*GL_CreateContext)( void ); // TODO + void (*GL_DestroyContext)( ); + void *(*GL_GetProcAddress)( const char *name ); + } ref_api_t; struct mip_s; @@ -134,9 +251,7 @@ typedef struct ref_interface_s void (*R_IncrementSpeedsCounter)( int counterType ); // texture management - const byte *(*GL_TextureData)( unsigned int texnum ); - const char *(*R_GetTextureName)( int idx ); - const byte *(*R_GetTextureOriginalBuffer)( int idx ); // not always available + const byte *(*R_GetTextureOriginalBuffer)( unsigned int idx ); // not always available int (*GL_LoadTextureFromBuffer)( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update ); int (*R_GetBuiltinTexture)( enum ref_shared_texture_e type ); void (*R_FreeSharedTexture)( enum ref_shared_texture_e type ); @@ -148,7 +263,7 @@ typedef struct ref_interface_s 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_DrawTileClear)( int x, int y, int w, int h ); + void (*R_DrawTileClear)( int texnum, int x, int y, int w, int h ); void (*FillRGBA)( float x, float y, float w, float h, int r, int g, int b, int a ); // in screen space void (*FillRGBABlend)( float x, float y, float w, float h, int r, int g, int b, int a ); // in screen space diff --git a/common/xash3d_types.h b/common/xash3d_types.h index b13a3153..04ea8f79 100644 --- a/common/xash3d_types.h +++ b/common/xash3d_types.h @@ -2,6 +2,12 @@ #ifndef XASH_TYPES_H #define XASH_TYPES_H +#ifdef _WIN32 +#include +#else // _WIN32 +#include +#endif // _WIN32 + typedef unsigned char byte; typedef int sound_t; typedef float vec_t; @@ -121,5 +127,6 @@ typedef struct dll_info_s void *link; // hinstance of loading library } dll_info_t; +typedef void (*setpair_t)( const char *key, const char *value, void *buffer, void *numpairs ); #endif // XASH_TYPES_H diff --git a/engine/client/cl_efx.c b/engine/client/cl_efx.c index 94378c75..2538e9f7 100644 --- a/engine/client/cl_efx.c +++ b/engine/client/cl_efx.c @@ -2070,7 +2070,6 @@ void CL_ReadPointFile_f( void ) else Con_Printf( "map %s has no leaks!\n", clgame.mapname ); } - void CL_FreeDeadBeams() { BEAM *pBeam, *pNext, *pPrev = NULL; diff --git a/engine/client/cl_remap.c b/engine/client/cl_remap.c index dec5815c..deeb9de2 100644 --- a/engine/client/cl_remap.c +++ b/engine/client/cl_remap.c @@ -110,7 +110,7 @@ void CL_DuplicateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomco // save off the real texture index index = ptexture->index; - name = ref.dllFuncs.R_GetTextureName( index ); + name = RefRenderAPI->GL_TextureName( index ); Q_snprintf( texname, sizeof( texname ), "#%i_%s", refState.currententity->curstate.number, name + 1 ); // search for pixels @@ -153,7 +153,7 @@ void CL_UpdateStudioTexture( mstudiotexture_t *ptexture, int topcolor, int botto byte *raw, *pal; // save off the real texture index - origtexname = ref.dllFuncs.R_GetTextureName( ptexture->index ); + origtexname = RefRenderAPI->GL_TextureName( ptexture->index ); // build name of original texture Q_strncpy( mdlname, refState.currentmodel->name, sizeof( mdlname )); diff --git a/engine/client/cl_render.c b/engine/client/cl_render.c new file mode 100644 index 00000000..999aefdb --- /dev/null +++ b/engine/client/cl_render.c @@ -0,0 +1,197 @@ +/* +cl_render.c - RenderAPI loader & implementation +Copyright (C) 2019 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. +*/ + +#ifndef XASH_DEDICATED + +#include "common.h" +#include "client.h" +#include "library.h" + +static int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis ) +{ + return Mod_FatPVS( org, radius, visbuffer, world.visbytes, merge, fullvis ); +} + +static lightstyle_t *CL_GetLightStyle( int number ) +{ + Assert( number >= 0 && number < MAX_LIGHTSTYLES ); + return &cl.lightstyles[number]; +} + +static const ref_overview_t *GL_GetOverviewParms( void ) +{ + return &clgame.overView; +} + +static void *R_Mem_Alloc( size_t cb, const char *filename, const int fileline ) +{ + return _Mem_Alloc( cls.mempool, cb, true, filename, fileline ); +} + +static void R_Mem_Free( void *mem, const char *filename, const int fileline ) +{ + if( !mem ) return; + _Mem_Free( mem, filename, fileline ); +} + +/* +========= +pfnGetFilesList + +========= +*/ +static char **pfnGetFilesList( const char *pattern, int *numFiles, int gamedironly ) +{ + static search_t *t = NULL; + + if( t ) Mem_Free( t ); // release prev search + + t = FS_Search( pattern, true, gamedironly ); + + if( !t ) + { + if( numFiles ) *numFiles = 0; + return NULL; + } + + if( numFiles ) *numFiles = t->numfilenames; + return t->filenames; +} + +static uint pfnFileBufferCRC32( const void *buffer, const int length ) +{ + uint modelCRC = 0; + + if( !buffer || length <= 0 ) + return modelCRC; + + CRC32_Init( &modelCRC ); + CRC32_ProcessBuffer( &modelCRC, buffer, length ); + return CRC32_Final( modelCRC ); +} + +/* +============= +CL_GenericHandle + +============= +*/ +const char *CL_GenericHandle( int fileindex ) +{ + if( fileindex < 0 || fileindex >= MAX_CUSTOM ) + return 0; + return cl.files_precache[fileindex]; +} + +static render_api_t gRenderAPI = +{ + NULL, // GL_RenderGetParm, + NULL, // R_GetDetailScaleForTexture, + NULL, // R_GetExtraParmsForTexture, + CL_GetLightStyle, + CL_GetDynamicLight, + CL_GetEntityLight, + LightToTexGamma, + NULL, // R_GetFrameTime, + NULL, // R_SetCurrentEntity, + NULL, // R_SetCurrentModel, + R_FatPVS, + NULL, // R_StoreEfrags, + NULL, // GL_FindTexture, + NULL, // GL_TextureName, + NULL, // GL_TextureData, + NULL, // GL_LoadTexture, + NULL, // GL_CreateTexture, + NULL, // GL_LoadTextureArray, + NULL, // GL_CreateTextureArray, + NULL, // GL_FreeTexture, + NULL, // DrawSingleDecal, + NULL, // R_DecalSetupVerts, + NULL, // R_EntityRemoveDecals, + (void*)AVI_LoadVideo, + (void*)AVI_GetVideoInfo, + (void*)AVI_GetVideoFrameNumber, + (void*)AVI_GetVideoFrame, + NULL, // R_UploadStretchRaw, + (void*)AVI_FreeVideo, + (void*)AVI_IsActive, + S_StreamAviSamples, + NULL, + NULL, + NULL, // GL_Bind, + NULL, // GL_SelectTexture, + NULL, // GL_LoadTexMatrixExt, + NULL, // GL_LoadIdentityTexMatrix, + NULL, // GL_CleanUpTextureUnits, + NULL, // GL_TexGen, + NULL, // GL_TextureTarget, + NULL, // GL_SetTexCoordArrayMode, + NULL, // GL_GetProcAddress, + NULL, // GL_UpdateTexSize, + NULL, + NULL, + NULL, // CL_DrawParticlesExternal, + NULL, // R_EnvShot, + pfnSPR_LoadExt, + NULL, // R_LightVec, + NULL, // R_StudioGetTexture, + GL_GetOverviewParms, + CL_GenericHandle, + NULL, + NULL, + R_Mem_Alloc, + R_Mem_Free, + pfnGetFilesList, + pfnFileBufferCRC32, + COM_CompareFileTime, + Host_Error, + (void*)CL_ModelHandle, + pfnTime, + Cvar_Set, + S_FadeMusicVolume, + COM_SetRandomSeed, +}; + +/* +=============== +R_InitRenderAPI + +Initialize client external rendering +=============== +*/ +qboolean R_InitRenderAPI( void ) +{ + // make sure what render functions is cleared + memset( &clgame.drawFuncs, 0, sizeof( clgame.drawFuncs )); + + if( clgame.dllFuncs.pfnGetRenderInterface ) + { + if( clgame.dllFuncs.pfnGetRenderInterface( CL_RENDER_INTERFACE_VERSION, &gRenderAPI, &clgame.drawFuncs )) + { + Con_Reportf( "CL_LoadProgs: ^2initailized extended RenderAPI ^7ver. %i\n", CL_RENDER_INTERFACE_VERSION ); + return true; + } + + // make sure what render functions is cleared + memset( &clgame.drawFuncs, 0, sizeof( clgame.drawFuncs )); + + return false; // just tell user about problems + } + + // render interface is missed + return true; +} + +#endif // XASH_DEDICATED diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 31b22770..2a0f9e76 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -418,7 +418,7 @@ void SCR_TileClear( void ) { // clear above view screen i = clear.y2 < top-1 ? clear.y2 : top - 1; - ref.dllFuncs.R_DrawTileClear( clear.x1, clear.y1, clear.x2 - clear.x1 + 1, i - clear.y1 + 1 ); + ref.dllFuncs.R_DrawTileClear( cls.tileImage, clear.x1, clear.y1, clear.x2 - clear.x1 + 1, i - clear.y1 + 1 ); clear.y1 = top; } @@ -426,7 +426,7 @@ void SCR_TileClear( void ) { // clear below view screen i = clear.y1 > bottom + 1 ? clear.y1 : bottom + 1; - ref.dllFuncs.R_DrawTileClear( clear.x1, i, clear.x2 - clear.x1 + 1, clear.y2 - i + 1 ); + ref.dllFuncs.R_DrawTileClear( cls.tileImage, clear.x1, i, clear.x2 - clear.x1 + 1, clear.y2 - i + 1 ); clear.y2 = bottom; } @@ -434,7 +434,7 @@ void SCR_TileClear( void ) { // clear left of view screen i = clear.x2 < left - 1 ? clear.x2 : left - 1; - ref.dllFuncs.R_DrawTileClear( clear.x1, clear.y1, i - clear.x1 + 1, clear.y2 - clear.y1 + 1 ); + ref.dllFuncs.R_DrawTileClear( cls.tileImage, clear.x1, clear.y1, i - clear.x1 + 1, clear.y2 - clear.y1 + 1 ); clear.x1 = left; } @@ -442,7 +442,7 @@ void SCR_TileClear( void ) { // clear left of view screen i = clear.x1 > right + 1 ? clear.x1 : right + 1; - ref.dllFuncs.R_DrawTileClear( i, clear.y1, clear.x2 - i + 1, clear.y2 - clear.y1 + 1 ); + ref.dllFuncs.R_DrawTileClear( cls.tileImage, i, clear.y1, clear.x2 - i + 1, clear.y2 - clear.y1 + 1 ); clear.x2 = right; } } diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 1806ddc8..8526f6f6 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -2722,6 +2722,18 @@ void CL_DecayLights( void ) } } +dlight_t *CL_GetDynamicLight( int number ) +{ + Assert( number >= 0 && number < MAX_DLIGHTS ); + return &cl_dlights[number]; +} + +dlight_t *CL_GetEntityLight( int number ) +{ + Assert( number >= 0 && number < MAX_ELIGHTS ); + return &cl_elights[number]; +} + /* ================ CL_UpdateFlashlight diff --git a/engine/client/client.h b/engine/client/client.h index 8b40ea13..73df82e9 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -713,6 +713,8 @@ extern convar_t *m_ignore; void CL_SetLightstyle( int style, const char* s, float f ); void CL_RunLightStyles( void ); void CL_DecayLights( void ); +dlight_t *CL_GetDynamicLight( int number ); +dlight_t *CL_GetEntityLight( int number ); //================================================= @@ -974,7 +976,6 @@ void CL_WeaponAnim( int iAnim, int body ); void CL_ClearEffects( void ); void CL_ClearEfrags( void ); void CL_TestLights( void ); -void CL_DrawParticlesExternal( const ref_viewpass_t *rvp, qboolean trans_pass, float frametime ); void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale ); void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags ); void CL_PlayerDecal( int playerIndex, int textureIndex, int entityIndex, float *pos ); diff --git a/engine/client/ref_common.c b/engine/client/ref_common.c index fc5af332..e93c4def 100644 --- a/engine/client/ref_common.c +++ b/engine/client/ref_common.c @@ -132,7 +132,7 @@ static qboolean R_LoadProgs( const char *name ) return false; } - refState.developer = host.allow_console; + refState.developer = host_developer.value; if( !ref.dllFuncs.R_Init( true ) ) { diff --git a/engine/client/vid_common.h b/engine/client/vid_common.h index 9134e63d..89602af9 100644 --- a/engine/client/vid_common.h +++ b/engine/client/vid_common.h @@ -4,16 +4,6 @@ #define FCONTEXT_CORE_PROFILE BIT( 0 ) #define FCONTEXT_DEBUG_ARB BIT( 1 ) -#if 0 -#define GL_CheckForErrors() GL_CheckForErrors_( __FILE__, __LINE__ ) -void GL_CheckForErrors_( const char *filename, const int fileline ); -const char *GL_ErrorString( int err ); -void GL_UpdateSwapInterval( void ); -qboolean GL_Support( int r_ext ); -int GL_MaxTextureUnits( void ); -void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cvarname, int r_ext ); -void GL_SetExtension( int r_ext, int enable ); -#endif typedef struct vidmode_s { diff --git a/engine/common/common.c b/engine/common/common.c index 2c09cf18..65fd4016 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -767,12 +767,14 @@ COM_CheckString ============= */ +#if 0 int COM_CheckString( const char *string ) { if( !string || !*string ) return 0; return 1; } +#endif /* ============= diff --git a/engine/common/common.h b/engine/common/common.h index 8057515d..8faadc3b 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -84,9 +84,6 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc #define HACKS_RELATED_HLMODS // some HL-mods works differently under Xash and can't be fixed without some hacks at least at current time - -typedef void (*setpair_t)( const char *key, const char *value, void *buffer, void *numpairs ); - typedef struct { int numfilenames; @@ -510,7 +507,7 @@ void COM_NormalizeAngles( vec3_t angles ); int COM_FileSize( const char *filename ); void COM_FixSlashes( char *pname ); void COM_FreeFile( void *buffer ); -int COM_CheckString( const char *string ); +#define COM_CheckString( string ) ( ( !string || !*string ) ? 0 : 1 ) int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCompare ); search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ); file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly ); diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 84bba470..d4ea1e7a 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -19,6 +19,7 @@ GNU General Public License for more details. #include "common.h" #include "edict.h" #include "eiface.h" +#include "ref_api.h" #define LM_SAMPLE_SIZE 16 #define LM_SAMPLE_EXTRASIZE 8 @@ -35,22 +36,6 @@ GNU General Public License for more details. #define WORLD_INDEX (1) // world index is always 1 -// model flags (stored in model_t->flags) -#define MODEL_CONVEYOR BIT( 0 ) -#define MODEL_HAS_ORIGIN BIT( 1 ) -#define MODEL_LIQUID BIT( 2 ) // model has only point hull -#define MODEL_TRANSPARENT BIT( 3 ) // have transparent surfaces -#define MODEL_COLORED_LIGHTING BIT( 4 ) // lightmaps stored as RGB - -#define MODEL_WORLD BIT( 29 ) // it's a worldmodel -#define MODEL_CLIENT BIT( 30 ) // client sprite - -// goes into world.flags -#define FWORLD_SKYSPHERE BIT( 0 ) -#define FWORLD_CUSTOM_SKYBOX BIT( 1 ) -#define FWORLD_WATERALPHA BIT( 2 ) -#define FWORLD_HAS_DELUXEMAP BIT( 3 ) - typedef struct consistency_s { const char *filename; @@ -103,7 +88,7 @@ typedef struct int cull; } sortedface_t; -typedef struct +typedef struct world_static_s { qboolean loading; // true if worldmodel is loading int flags; // misc flags diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index be97503d..ade07dd1 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -2005,7 +2005,7 @@ const char* pfnGetModelName( int modelindex ) static const byte *GL_TextureData( unsigned int texnum ) { - return ref.dllFuncs.GL_TextureData( texnum ); + return RefRenderAPI->GL_TextureData( texnum ); } static server_physics_api_t gPhysicsAPI = diff --git a/ref_gl/gl_alias.c b/ref_gl/gl_alias.c index 7127daa0..b6ee1b58 100644 --- a/ref_gl/gl_alias.c +++ b/ref_gl/gl_alias.c @@ -484,7 +484,7 @@ void *Mod_LoadSingleSkin( daliasskintype_t *pskintype, int skinnum, int size ) Q_snprintf( name, sizeof( name ), "%s:frame%i", loadmodel->name, skinnum ); Q_snprintf( lumaname, sizeof( lumaname ), "%s:luma%i", loadmodel->name, skinnum ); Q_snprintf( checkname, sizeof( checkname ), "%s_%i.tga", loadmodel->name, skinnum ); - if( !FS_FileExists( checkname, false ) || ( pic = FS_LoadImage( checkname, NULL, 0 )) == NULL ) + if( !gEngfuncs.FS_FileExists( checkname, false ) || ( pic = FS_LoadImage( checkname, NULL, 0 )) == NULL ) pic = Mod_CreateSkinData( loadmodel, (byte *)(pskintype + 1), m_pAliasHeader->skinwidth, m_pAliasHeader->skinheight ); m_pAliasHeader->gl_texturenum[skinnum][0] = @@ -1270,7 +1270,7 @@ static void R_AliasDrawAbsBBox( cl_entity_t *e, const vec3_t absmin, const vec3_ int i; // looks ugly, skip - if( r_drawentities->value != 5 || e == &clgame.viewent ) + if( r_drawentities->value != 5 || e == gEngfuncs.GetViewModel() ) return; // compute a full bounding box @@ -1346,7 +1346,7 @@ static void R_AliasSetupTimings( void ) if( RI.drawWorld ) { // synchronize with server time - g_alias.time = cl.time; + g_alias.time = gpGlobals->time; } else { diff --git a/ref_gl/gl_backend.c b/ref_gl/gl_backend.c index 0c3c1b9d..bf302002 100644 --- a/ref_gl/gl_backend.c +++ b/ref_gl/gl_backend.c @@ -105,7 +105,7 @@ void GL_BackendEndFrame( void ) break; case 4: Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i static entities\n%3i normal entities\n%3i server entities", - r_numStatics, r_numEntities - r_numStatics, pfnNumberOfEntities( )); + r_numStatics, r_numEntities - r_numStatics, gEngfuncs.pfnNumberOfEntities( )); break; case 5: Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i tempents\n%3i viewbeams\n%3i particles", diff --git a/ref_gl/gl_beams.c b/ref_gl/gl_beams.c index 60e2ea1e..2c0b7a07 100644 --- a/ref_gl/gl_beams.c +++ b/ref_gl/gl_beams.c @@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ +#include "common.h" #include "gl_local.h" #include "r_efx.h" #include "event_flags.h" @@ -140,7 +141,7 @@ qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly ) } // check bbox - if( Mod_BoxVisible( mins, maxs, Mod_GetCurrentVis( ))) + if( gEngfuncs.Mod_BoxVisible( mins, maxs, Mod_GetCurrentVis( ))) { if( pvsOnly || !R_CullBox( mins, maxs )) { @@ -583,7 +584,7 @@ void R_DrawBeamFollow( BEAM *pbeam, float frametime ) vec3_t last1, last2, tmp, screen; vec3_t delta, screenLast, normal; - R_FreeDeadParticles( &pbeam->particles ); + gEngfuncs.R_FreeDeadParticles( &pbeam->particles ); particles = pbeam->particles; pnew = NULL; @@ -613,7 +614,7 @@ void R_DrawBeamFollow( BEAM *pbeam, float frametime ) if( pnew ) { VectorCopy( pbeam->source, pnew->org ); - pnew->die = cl.time + pbeam->amplitude; + pnew->die = gpGlobals->time + pbeam->amplitude; VectorClear( pnew->vel ); pnew->next = particles; @@ -660,7 +661,7 @@ void R_DrawBeamFollow( BEAM *pbeam, float frametime ) VectorMA( delta, -pbeam->width, normal, last2 ); div = 1.0 / pbeam->amplitude; - fraction = ( pbeam->die - cl.time ) * div; + fraction = ( pbeam->die - gpGlobals->time ) * div; vLast = 0.0; vStep = 1.0; @@ -693,7 +694,7 @@ void R_DrawBeamFollow( BEAM *pbeam, float frametime ) if( particles->next != NULL ) { - fraction = (particles->die - cl.time) * div; + fraction = (particles->die - gpGlobals->time) * div; } else { @@ -778,7 +779,7 @@ void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitude, floa return; // is that box in PVS && frustum? - if( !Mod_BoxVisible( screen, tmp, Mod_GetCurrentVis( )) || R_CullBox( screen, tmp )) + if( !gEngfuncs.Mod_BoxVisible( screen, tmp, Mod_GetCurrentVis( )) || R_CullBox( screen, tmp )) { return; } @@ -844,23 +845,6 @@ void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitude, floa } } -/// export from engine... -/* -============== -R_BeamGetEntity - -extract entity number from index -handle user entities -============== -*/ -static cl_entity_t *R_BeamGetEntity( int index ) -{ - if( index < 0 ) - return clgame.dllFuncs.pfnGetUserEntity( BEAMENT_ENTITY( -index )); - return CL_GetEntityByIndex( BEAMENT_ENTITY( index )); -} - - /* ============== R_BeamComputePoint @@ -873,7 +857,7 @@ static qboolean R_BeamComputePoint( int beamEnt, vec3_t pt ) cl_entity_t *ent; int attach; - ent = R_BeamGetEntity( beamEnt ); + ent = gEngfuncs.R_BeamGetEntity( beamEnt ); if( beamEnt < 0 ) attach = BEAMENT_ATTACHMENT( -beamEnt ); @@ -889,8 +873,12 @@ static qboolean R_BeamComputePoint( int beamEnt, vec3_t pt ) // get attachment if( attach > 0 ) VectorCopy( ent->attachment[attach - 1], pt ); - else if(( ent->index - 1 ) == cl.playernum ) - VectorCopy( cl.simorg, pt ); + else if( ent->index == gEngfuncs.GetPlayerIndex() ) + { + vec3_t simorg; + gEngfuncs.GetPredictedOrigin( simorg ); + VectorCopy( simorg, pt ); + } else VectorCopy( ent->origin, pt ); return true; @@ -907,7 +895,7 @@ qboolean R_BeamRecomputeEndpoints( BEAM *pbeam ) { if( FBitSet( pbeam->flags, FBEAM_STARTENTITY )) { - cl_entity_t *start = R_BeamGetEntity( pbeam->startEntity ); + cl_entity_t *start = gEngfuncs.R_BeamGetEntity( pbeam->startEntity ); if( R_BeamComputePoint( pbeam->startEntity, pbeam->source )) { @@ -923,7 +911,7 @@ qboolean R_BeamRecomputeEndpoints( BEAM *pbeam ) if( FBitSet( pbeam->flags, FBEAM_ENDENTITY )) { - cl_entity_t *end = R_BeamGetEntity( pbeam->endEntity ); + cl_entity_t *end = gEngfuncs.R_BeamGetEntity( pbeam->endEntity ); if( R_BeamComputePoint( pbeam->endEntity, pbeam->target )) { @@ -934,7 +922,7 @@ qboolean R_BeamRecomputeEndpoints( BEAM *pbeam ) else if( !FBitSet( pbeam->flags, FBEAM_FOREVER )) { ClearBits( pbeam->flags, FBEAM_ENDENTITY ); - pbeam->die = cl.time; + pbeam->die = gpGlobals->time; return false; } else @@ -967,7 +955,7 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) if( !model || model->type != mod_sprite ) { pbeam->flags &= ~FBEAM_ISACTIVE; // force to ignore - pbeam->die = cl.time; + pbeam->die = gpGlobals->time; return; } @@ -1025,7 +1013,7 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) if( pbeam->flags & ( FBEAM_FADEIN|FBEAM_FADEOUT )) { // update life cycle - pbeam->t = pbeam->freq + ( pbeam->die - cl.time ); + pbeam->t = pbeam->freq + ( pbeam->die - gpGlobals->time ); if( pbeam->t != 0.0f ) pbeam->t = 1.0f - pbeam->freq / pbeam->t; } @@ -1073,7 +1061,7 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) TriRenderMode( FBitSet( pbeam->flags, FBEAM_SOLID ) ? kRenderNormal : kRenderTransAdd ); - if( !TriSpriteTexture( model, (int)(pbeam->frame + pbeam->frameRate * cl.time) % pbeam->frameCount )) + if( !TriSpriteTexture( model, (int)(pbeam->frame + pbeam->frameRate * gpGlobals->time) % pbeam->frameCount )) { ClearBits( pbeam->flags, FBEAM_ISACTIVE ); return; @@ -1084,9 +1072,9 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) cl_entity_t *pStart; // XASH SPECIFIC: get brightness from head entity - pStart = R_BeamGetEntity( pbeam->startEntity ); + pStart = gEngfuncs.R_BeamGetEntity( pbeam->startEntity ); if( pStart && pStart->curstate.rendermode != kRenderNormal ) - pbeam->brightness = CL_FxBlend( pStart ) / 255.0f; + pbeam->brightness = gEngfuncs.CL_FxBlend( pStart ) / 255.0f; } if( FBitSet( pbeam->flags, FBEAM_FADEIN )) @@ -1178,8 +1166,8 @@ static void R_BeamSetup( BEAM *pbeam, vec3_t start, vec3_t end, int modelIndex, VectorCopy( end, pbeam->target ); VectorSubtract( end, start, pbeam->delta ); - pbeam->freq = speed * cl.time; - pbeam->die = life + cl.time; + pbeam->freq = speed * gpGlobals->time; + pbeam->die = life + gpGlobals->time; pbeam->amplitude = amplitude; pbeam->brightness = brightness; pbeam->width = width; @@ -1206,7 +1194,7 @@ void R_BeamDrawCustomEntity( cl_entity_t *ent ) { BEAM beam; float amp = ent->curstate.body / 100.0f; - float blend = CL_FxBlend( ent ) / 255.0f; + float blend = gEngfuncs.CL_FxBlend( ent ) / 255.0f; float r, g, b; int beamFlags; @@ -1313,7 +1301,7 @@ void CL_DrawBeams(int fTrans , BEAM *active_beams ) if( !fTrans && !FBitSet( pBeam->flags, FBEAM_SOLID )) continue; - R_BeamDraw( pBeam, cl.time - cl.oldtime ); + R_BeamDraw( pBeam, gpGlobals->time - gpGlobals->oldtime ); } pglShadeModel( GL_FLAT ); diff --git a/ref_gl/gl_context.c b/ref_gl/gl_context.c index c84b7d03..d39670d3 100644 --- a/ref_gl/gl_context.c +++ b/ref_gl/gl_context.c @@ -13,478 +13,42 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ +#include "common.h" #include "gl_local.h" #include "gl_export.h" -#define GL_CALL( x ) #x, (void**)&p##x -static dllfunc_t opengl_110funcs[] = -{ - { GL_CALL( glClearColor ) }, - { GL_CALL( glClear ) }, - { GL_CALL( glAlphaFunc ) }, - { GL_CALL( glBlendFunc ) }, - { GL_CALL( glCullFace ) }, - { GL_CALL( glDrawBuffer ) }, - { GL_CALL( glReadBuffer ) }, - { GL_CALL( glAccum ) }, - { GL_CALL( glEnable ) }, - { GL_CALL( glDisable ) }, - { GL_CALL( glEnableClientState ) }, - { GL_CALL( glDisableClientState ) }, - { GL_CALL( glGetBooleanv ) }, - { GL_CALL( glGetDoublev ) }, - { GL_CALL( glGetFloatv ) }, - { GL_CALL( glGetIntegerv ) }, - { GL_CALL( glGetError ) }, - { GL_CALL( glGetString ) }, - { GL_CALL( glFinish ) }, - { GL_CALL( glFlush ) }, - { GL_CALL( glClearDepth ) }, - { GL_CALL( glDepthFunc ) }, - { GL_CALL( glDepthMask ) }, - { GL_CALL( glDepthRange ) }, - { GL_CALL( glFrontFace ) }, - { GL_CALL( glDrawElements ) }, - { GL_CALL( glDrawArrays ) }, - { GL_CALL( glColorMask ) }, - { GL_CALL( glIndexPointer ) }, - { GL_CALL( glVertexPointer ) }, - { GL_CALL( glNormalPointer ) }, - { GL_CALL( glColorPointer ) }, - { GL_CALL( glTexCoordPointer ) }, - { GL_CALL( glArrayElement ) }, - { GL_CALL( glColor3f ) }, - { GL_CALL( glColor3fv ) }, - { GL_CALL( glColor4f ) }, - { GL_CALL( glColor4fv ) }, - { GL_CALL( glColor3ub ) }, - { GL_CALL( glColor4ub ) }, - { GL_CALL( glColor4ubv ) }, - { GL_CALL( glTexCoord1f ) }, - { GL_CALL( glTexCoord2f ) }, - { GL_CALL( glTexCoord3f ) }, - { GL_CALL( glTexCoord4f ) }, - { GL_CALL( glTexCoord1fv ) }, - { GL_CALL( glTexCoord2fv ) }, - { GL_CALL( glTexCoord3fv ) }, - { GL_CALL( glTexCoord4fv ) }, - { GL_CALL( glTexGenf ) }, - { GL_CALL( glTexGenfv ) }, - { GL_CALL( glTexGeni ) }, - { GL_CALL( glVertex2f ) }, - { GL_CALL( glVertex3f ) }, - { GL_CALL( glVertex3fv ) }, - { GL_CALL( glNormal3f ) }, - { GL_CALL( glNormal3fv ) }, - { GL_CALL( glBegin ) }, - { GL_CALL( glEnd ) }, - { GL_CALL( glLineWidth ) }, - { GL_CALL( glPointSize ) }, - { GL_CALL( glMatrixMode ) }, - { GL_CALL( glOrtho ) }, - { GL_CALL( glRasterPos2f ) }, - { GL_CALL( glFrustum ) }, - { GL_CALL( glViewport ) }, - { GL_CALL( glPushMatrix ) }, - { GL_CALL( glPopMatrix ) }, - { GL_CALL( glPushAttrib ) }, - { GL_CALL( glPopAttrib ) }, - { GL_CALL( glLoadIdentity ) }, - { GL_CALL( glLoadMatrixd ) }, - { GL_CALL( glLoadMatrixf ) }, - { GL_CALL( glMultMatrixd ) }, - { GL_CALL( glMultMatrixf ) }, - { GL_CALL( glRotated ) }, - { GL_CALL( glRotatef ) }, - { GL_CALL( glScaled ) }, - { GL_CALL( glScalef ) }, - { GL_CALL( glTranslated ) }, - { GL_CALL( glTranslatef ) }, - { GL_CALL( glReadPixels ) }, - { GL_CALL( glDrawPixels ) }, - { GL_CALL( glStencilFunc ) }, - { GL_CALL( glStencilMask ) }, - { GL_CALL( glStencilOp ) }, - { GL_CALL( glClearStencil ) }, - { GL_CALL( glIsEnabled ) }, - { GL_CALL( glIsList ) }, - { GL_CALL( glIsTexture ) }, - { GL_CALL( glTexEnvf ) }, - { GL_CALL( glTexEnvfv ) }, - { GL_CALL( glTexEnvi ) }, - { GL_CALL( glTexParameterf ) }, - { GL_CALL( glTexParameterfv ) }, - { GL_CALL( glTexParameteri ) }, - { GL_CALL( glHint ) }, - { GL_CALL( glPixelStoref ) }, - { GL_CALL( glPixelStorei ) }, - { GL_CALL( glGenTextures ) }, - { GL_CALL( glDeleteTextures ) }, - { GL_CALL( glBindTexture ) }, - { GL_CALL( glTexImage1D ) }, - { GL_CALL( glTexImage2D ) }, - { GL_CALL( glTexSubImage1D ) }, - { GL_CALL( glTexSubImage2D ) }, - { GL_CALL( glCopyTexImage1D ) }, - { GL_CALL( glCopyTexImage2D ) }, - { GL_CALL( glCopyTexSubImage1D ) }, - { GL_CALL( glCopyTexSubImage2D ) }, - { GL_CALL( glScissor ) }, - { GL_CALL( glGetTexImage ) }, - { GL_CALL( glGetTexEnviv ) }, - { GL_CALL( glPolygonOffset ) }, - { GL_CALL( glPolygonMode ) }, - { GL_CALL( glPolygonStipple ) }, - { GL_CALL( glClipPlane ) }, - { GL_CALL( glGetClipPlane ) }, - { GL_CALL( glShadeModel ) }, - { GL_CALL( glGetTexLevelParameteriv ) }, - { GL_CALL( glGetTexLevelParameterfv ) }, - { GL_CALL( glFogfv ) }, - { GL_CALL( glFogf ) }, - { GL_CALL( glFogi ) }, - { NULL , NULL } -}; - -static dllfunc_t debugoutputfuncs[] = -{ - { GL_CALL( glDebugMessageControlARB ) }, - { GL_CALL( glDebugMessageInsertARB ) }, - { GL_CALL( glDebugMessageCallbackARB ) }, - { GL_CALL( glGetDebugMessageLogARB ) }, - { NULL , NULL } -}; - -static dllfunc_t multitexturefuncs[] = -{ - { GL_CALL( glMultiTexCoord1f ) }, - { GL_CALL( glMultiTexCoord2f ) }, - { GL_CALL( glMultiTexCoord3f ) }, - { GL_CALL( glMultiTexCoord4f ) }, - { GL_CALL( glActiveTexture ) }, - { GL_CALL( glActiveTextureARB ) }, - { GL_CALL( glClientActiveTexture ) }, - { GL_CALL( glClientActiveTextureARB ) }, - { NULL , NULL } -}; - -static dllfunc_t texture3dextfuncs[] = -{ - { GL_CALL( glTexImage3D ) }, - { GL_CALL( glTexSubImage3D ) }, - { GL_CALL( glCopyTexSubImage3D ) }, - { NULL , NULL } -}; - -static dllfunc_t texturecompressionfuncs[] = -{ - { GL_CALL( glCompressedTexImage3DARB ) }, - { GL_CALL( glCompressedTexImage2DARB ) }, - { GL_CALL( glCompressedTexImage1DARB ) }, - { GL_CALL( glCompressedTexSubImage3DARB ) }, - { GL_CALL( glCompressedTexSubImage2DARB ) }, - { GL_CALL( glCompressedTexSubImage1DARB ) }, - { GL_CALL( glGetCompressedTexImage ) }, - { NULL , NULL } -}; - -static dllfunc_t vbofuncs[] = -{ - { GL_CALL( glBindBufferARB ) }, - { GL_CALL( glDeleteBuffersARB ) }, - { GL_CALL( glGenBuffersARB ) }, - { GL_CALL( glIsBufferARB ) }, - { GL_CALL( glMapBufferARB ) }, - { GL_CALL( glUnmapBufferARB ) }, // , - { GL_CALL( glBufferDataARB ) }, - { GL_CALL( glBufferSubDataARB ) }, - { NULL, NULL} -}; +ref_api_t gEngfuncs; +ref_globals_t *gpGlobals; /* -======================== -DebugCallback +============ +Con_Printf -For ARB_debug_output -======================== +engine callback wrapper +============ */ -static void APIENTRY GL_DebugOutput( GLuint source, GLuint type, GLuint id, GLuint severity, GLint length, const GLcharARB *message, GLvoid *userParam ) +void Con_Printf( const char *fmt, ... ) { - switch( type ) - { - case GL_DEBUG_TYPE_ERROR_ARB: - Con_Printf( S_OPENGL_ERROR "%s\n", message ); - break; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: - Con_Printf( S_OPENGL_WARN "%s\n", message ); - break; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: - Con_Printf( S_OPENGL_WARN "%s\n", message ); - break; - case GL_DEBUG_TYPE_PORTABILITY_ARB: - if( host_developer.value < DEV_EXTENDED ) - return; - Con_Printf( S_OPENGL_WARN "%s\n", message ); - break; - case GL_DEBUG_TYPE_PERFORMANCE_ARB: - Con_Printf( S_OPENGL_NOTE "%s\n", message ); - break; - case GL_DEBUG_TYPE_OTHER_ARB: - default: Con_Printf( S_OPENGL_NOTE "%s\n", message ); - break; - } + va_list args; + va_start( args, fmt ); + gEngfuncs.Con_VPrintf( fmt, args ); + va_end( args ); } -#ifdef XASH_GLES -void GL_InitExtensionsGLES( void ) +ref_interface_t gReffuncs = { - // intialize wrapper type -#ifdef XASH_NANOGL - glConfig.context = CONTEXT_TYPE_GLES_1_X; - glConfig.wrapper = GLES_WRAPPER_NANOGL; -#elif defined( XASH_WES ) - glConfig.context = CONTEXT_TYPE_GLES_2_X; - glConfig.wrapper = GLES_WRAPPER_WES; -#endif - - glConfig.hardware_type = GLHW_GENERIC; - - // initalize until base opengl functions loaded - GL_SetExtension( GL_DRAW_RANGEELEMENTS_EXT, true ); - GL_SetExtension( GL_ARB_MULTITEXTURE, true ); - pglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texture_units ); - glConfig.max_texture_coords = glConfig.max_texture_units = 4; - - GL_SetExtension( GL_ENV_COMBINE_EXT, true ); - GL_SetExtension( GL_DOT3_ARB_EXT, true ); - GL_SetExtension( GL_TEXTURE_3D_EXT, false ); - GL_SetExtension( GL_SGIS_MIPMAPS_EXT, true ); // gles specs - GL_SetExtension( GL_ARB_VERTEX_BUFFER_OBJECT_EXT, true ); // gles specs - - // hardware cubemaps - GL_CheckExtension( "GL_OES_texture_cube_map", NULL, "gl_texture_cubemap", GL_TEXTURECUBEMAP_EXT ); - - if( GL_Support( GL_TEXTURECUBEMAP_EXT )) - pglGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig.max_cubemap_size ); - - GL_SetExtension( GL_ARB_SEAMLESS_CUBEMAP, false ); - - GL_SetExtension( GL_EXT_POINTPARAMETERS, false ); - GL_CheckExtension( "GL_OES_texture_npot", NULL, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT ); - - GL_SetExtension( GL_TEXTURE_COMPRESSION_EXT, false ); - GL_SetExtension( GL_CUSTOM_VERTEX_ARRAY_EXT, false ); - GL_SetExtension( GL_CLAMPTOEDGE_EXT, true ); // by gles1 specs - GL_SetExtension( GL_ANISOTROPY_EXT, false ); - GL_SetExtension( GL_TEXTURE_LODBIAS, false ); - GL_SetExtension( GL_CLAMP_TEXBORDER_EXT, false ); - GL_SetExtension( GL_BLEND_MINMAX_EXT, false ); - GL_SetExtension( GL_BLEND_SUBTRACT_EXT, false ); - GL_SetExtension( GL_SEPARATESTENCIL_EXT, false ); - GL_SetExtension( GL_STENCILTWOSIDE_EXT, false ); - GL_SetExtension( GL_TEXTURE_ENV_ADD_EXT,false ); - GL_SetExtension( GL_SHADER_OBJECTS_EXT, false ); - GL_SetExtension( GL_SHADER_GLSL100_EXT, false ); - GL_SetExtension( GL_VERTEX_SHADER_EXT,false ); - GL_SetExtension( GL_FRAGMENT_SHADER_EXT, false ); - GL_SetExtension( GL_SHADOW_EXT, false ); - GL_SetExtension( GL_ARB_DEPTH_FLOAT_EXT, false ); - GL_SetExtension( GL_OCCLUSION_QUERIES_EXT,false ); - GL_CheckExtension( "GL_OES_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE ); - - glConfig.texRectangle = glConfig.max_2d_rectangle_size = 0; // no rectangle - - Cvar_FullSet( "gl_allow_mirrors", "0", CVAR_READ_ONLY); // No support for GLES - -} -#else -void GL_InitExtensionsBigGL() -{ - // intialize wrapper type - glConfig.context = CONTEXT_TYPE_GL; - glConfig.wrapper = GLES_WRAPPER_NONE; - - if( Q_stristr( glConfig.renderer_string, "geforce" )) - glConfig.hardware_type = GLHW_NVIDIA; - else if( Q_stristr( glConfig.renderer_string, "quadro fx" )) - glConfig.hardware_type = GLHW_NVIDIA; - else if( Q_stristr(glConfig.renderer_string, "rv770" )) - glConfig.hardware_type = GLHW_RADEON; - else if( Q_stristr(glConfig.renderer_string, "radeon hd" )) - glConfig.hardware_type = GLHW_RADEON; - else if( Q_stristr( glConfig.renderer_string, "eah4850" ) || Q_stristr( glConfig.renderer_string, "eah4870" )) - glConfig.hardware_type = GLHW_RADEON; - else if( Q_stristr( glConfig.renderer_string, "radeon" )) - glConfig.hardware_type = GLHW_RADEON; - else if( Q_stristr( glConfig.renderer_string, "intel" )) - glConfig.hardware_type = GLHW_INTEL; - else glConfig.hardware_type = GLHW_GENERIC; - - // multitexture - glConfig.max_texture_units = glConfig.max_texture_coords = glConfig.max_teximage_units = 1; - GL_CheckExtension( "GL_ARB_multitexture", multitexturefuncs, "gl_arb_multitexture", GL_ARB_MULTITEXTURE ); - - if( GL_Support( GL_ARB_MULTITEXTURE )) - { - pglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texture_units ); - } - - if( glConfig.max_texture_units == 1 ) - GL_SetExtension( GL_ARB_MULTITEXTURE, false ); - // 3d texture support - GL_CheckExtension( "GL_EXT_texture3D", texture3dextfuncs, "gl_texture_3d", GL_TEXTURE_3D_EXT ); - - if( GL_Support( GL_TEXTURE_3D_EXT )) - { - pglGetIntegerv( GL_MAX_3D_TEXTURE_SIZE, &glConfig.max_3d_texture_size ); - - if( glConfig.max_3d_texture_size < 32 ) - { - GL_SetExtension( GL_TEXTURE_3D_EXT, false ); - Con_Printf( S_ERROR "GL_EXT_texture3D reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n" ); - } - } - - // 2d texture array support - GL_CheckExtension( "GL_EXT_texture_array", texture3dextfuncs, "gl_texture_2d_array", GL_TEXTURE_ARRAY_EXT ); - - if( GL_Support( GL_TEXTURE_ARRAY_EXT )) - pglGetIntegerv( GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &glConfig.max_2d_texture_layers ); - - // cubemaps support - GL_CheckExtension( "GL_ARB_texture_cube_map", NULL, "gl_texture_cubemap", GL_TEXTURE_CUBEMAP_EXT ); - - if( GL_Support( GL_TEXTURE_CUBEMAP_EXT )) - { - pglGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig.max_cubemap_size ); - - // check for seamless cubemaps too - GL_CheckExtension( "GL_ARB_seamless_cube_map", NULL, "gl_texture_cubemap_seamless", GL_ARB_SEAMLESS_CUBEMAP ); - } - - GL_CheckExtension( "GL_ARB_texture_non_power_of_two", NULL, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT ); - GL_CheckExtension( "GL_ARB_texture_compression", texturecompressionfuncs, "gl_dds_hardware_support", GL_TEXTURE_COMPRESSION_EXT ); - GL_CheckExtension( "GL_EXT_texture_edge_clamp", NULL, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT ); - if( !GL_Support( GL_CLAMPTOEDGE_EXT )) - GL_CheckExtension( "GL_SGIS_texture_edge_clamp", NULL, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT ); - - glConfig.max_texture_anisotropy = 0.0f; - GL_CheckExtension( "GL_EXT_texture_filter_anisotropic", NULL, "gl_ext_anisotropic_filter", GL_ANISOTROPY_EXT ); - if( GL_Support( GL_ANISOTROPY_EXT )) - pglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.max_texture_anisotropy ); - -#ifdef _WIN32 // Win32 only drivers? - // g-cont. because lodbias it too glitchy on Intel's cards - if( glConfig.hardware_type != GLHW_INTEL ) -#endif - GL_CheckExtension( "GL_EXT_texture_lod_bias", NULL, "gl_texture_mipmap_biasing", GL_TEXTURE_LOD_BIAS ); - - if( GL_Support( GL_TEXTURE_LOD_BIAS )) - pglGetFloatv( GL_MAX_TEXTURE_LOD_BIAS_EXT, &glConfig.max_texture_lod_bias ); - - GL_CheckExtension( "GL_ARB_texture_border_clamp", NULL, "gl_ext_texborder_clamp", GL_CLAMP_TEXBORDER_EXT ); - GL_CheckExtension( "GL_ARB_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE ); - GL_CheckExtension( "GL_ARB_texture_float", NULL, "gl_arb_texture_float", GL_ARB_TEXTURE_FLOAT_EXT ); - GL_CheckExtension( "GL_ARB_depth_buffer_float", NULL, "gl_arb_depth_float", GL_ARB_DEPTH_FLOAT_EXT ); - GL_CheckExtension( "GL_EXT_gpu_shader4", NULL, NULL, GL_EXT_GPU_SHADER4 ); // don't confuse users - GL_CheckExtension( "GL_ARB_shading_language_100", NULL, "gl_glslprogram", GL_SHADER_GLSL100_EXT ); - GL_CheckExtension( "GL_ARB_vertex_buffer_object", vbofuncs, "gl_vertex_buffer_object", GL_ARB_VERTEX_BUFFER_OBJECT_EXT ); - - // rectangle textures support - GL_CheckExtension( "GL_ARB_texture_rectangle", NULL, "gl_texture_rectangle", GL_TEXTURE_2D_RECT_EXT ); - - // this won't work without extended context - if( glw_state.extended ) - GL_CheckExtension( "GL_ARB_debug_output", debugoutputfuncs, "gl_debug_output", GL_DEBUG_OUTPUT ); - - if( GL_Support( GL_SHADER_GLSL100_EXT )) - { - pglGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &glConfig.max_texture_coords ); - pglGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &glConfig.max_teximage_units ); - - // check for hardware skinning - pglGetIntegerv( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig.max_vertex_uniforms ); - pglGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig.max_vertex_attribs ); - -#ifdef _WIN32 // Win32 only drivers? - if( glConfig.hardware_type == GLHW_RADEON && glConfig.max_vertex_uniforms > 512 ) - glConfig.max_vertex_uniforms /= 4; // radeon returns not correct info -#endif - } - else - { - // just get from multitexturing - glConfig.max_texture_coords = glConfig.max_teximage_units = glConfig.max_texture_units; - } - - pglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.max_2d_texture_size ); - if( glConfig.max_2d_texture_size <= 0 ) glConfig.max_2d_texture_size = 256; - - if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) - pglGetIntegerv( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &glConfig.max_2d_rectangle_size ); - -#ifndef XASH_GL_STATIC - // enable gldebug if allowed - if( GL_Support( GL_DEBUG_OUTPUT )) - { - if( host_developer.value ) - { - Con_Reportf( "Installing GL_DebugOutput...\n"); - pglDebugMessageCallbackARB( GL_DebugOutput, NULL ); - - // force everything to happen in the main thread instead of in a separate driver thread - pglEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB ); - } - - // enable all the low priority messages - pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); - } -#endif -} -#endif +}; -void GL_InitExtensions( void ) +int GAME_EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals ) { - // initialize gl extensions - GL_CheckExtension( "OpenGL 1.1.0", opengl_110funcs, NULL, GL_OPENGL_110 ); - - // get our various GL strings - glConfig.vendor_string = pglGetString( GL_VENDOR ); - glConfig.renderer_string = pglGetString( GL_RENDERER ); - glConfig.version_string = pglGetString( GL_VERSION ); - glConfig.extensions_string = pglGetString( GL_EXTENSIONS ); - Con_Reportf( "^3Video^7: %s\n", glConfig.renderer_string ); + if( version != REF_API_VERSION ) + return 0; -#ifdef XASH_GLES - GL_InitExtensionsGLES(); -#else - GL_InitExtensionsBigGL(); -#endif + // fill in our callbacks + memcpy( funcs, &gReffuncs, sizeof( ref_interface_t )); + memcpy( &gEngfuncs, engfuncs, sizeof( ref_api_t )); + gpGlobals = globals; - if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) - pglGetIntegerv( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &glConfig.max_2d_rectangle_size ); - - Cvar_Get( "gl_max_size", va( "%i", glConfig.max_2d_texture_size ), 0, "opengl texture max dims" ); - Cvar_Set( "gl_anisotropy", va( "%f", bound( 0, gl_texture_anisotropy->value, glConfig.max_texture_anisotropy ))); - - if( GL_Support( GL_TEXTURE_COMPRESSION_EXT )) - Image_AddCmdFlags( IL_DDS_HARDWARE ); - - // MCD has buffering issues -#ifdef _WIN32 - if( Q_strstr( glConfig.renderer_string, "gdi" )) - Cvar_SetValue( "gl_finish", 1 ); -#endif - - tr.framecount = tr.visframecount = 1; - glw_state.initialized = true; + return REF_API_VERSION; } - -void GL_ClearExtensions( void ) -{ - // now all extensions are disabled - memset( glConfig.extension, 0, sizeof( glConfig.extension )); - glw_state.initialized = false; -} - diff --git a/ref_gl/gl_cull.c b/ref_gl/gl_cull.c index be6bec1b..559693c4 100644 --- a/ref_gl/gl_cull.c +++ b/ref_gl/gl_cull.c @@ -54,19 +54,19 @@ R_CullModel */ int R_CullModel( cl_entity_t *e, const vec3_t absmin, const vec3_t absmax ) { - if( e == &clgame.viewent ) + if( e == gEngfuncs.GetViewModel() ) { - if( CL_IsDevOverviewMode( )) + if( gEngfuncs.CL_IsDevOverviewMode( )) return 1; - if( RP_NORMALPASS() && !cl.local.thirdperson && cl.viewentity == ( cl.playernum + 1 )) + if( RP_NORMALPASS() && !gEngfuncs.CL_IsThirdPersonMode() && CL_IsViewEntityLocalPlayer()) return 0; return 1; } // local client can't view himself if camera or thirdperson is not active - if( RP_LOCALCLIENT( e ) && !cl.local.thirdperson && cl.viewentity == ( cl.playernum + 1 )) + if( RP_LOCALCLIENT( e ) && !gEngfuncs.CL_IsThirdPersonMode() && CL_IsViewEntityLocalPlayer()) return 1; if( R_CullBox( absmin, absmax )) @@ -93,7 +93,7 @@ int R_CullSurface( msurface_t *surf, gl_frustum_t *frustum, uint clipflags ) return CULL_VISIBLE; // world surfaces can be culled by vis frame too - if( RI.currententity == clgame.entities && surf->visframe != tr.framecount ) + if( RI.currententity == gEngfuncs.GetEntityByIndex( 0 ) && surf->visframe != tr.framecount ) return CULL_VISFRAME; // only static ents can be culled by frustum @@ -108,7 +108,7 @@ int R_CullSurface( msurface_t *surf, gl_frustum_t *frustum, uint clipflags ) { vec3_t orthonormal; - if( e == clgame.entities ) orthonormal[2] = surf->plane->normal[2]; + if( e == gEngfuncs.GetEntityByIndex( 0 ) ) orthonormal[2] = surf->plane->normal[2]; else Matrix4x4_VectorRotate( RI.objectMatrix, surf->plane->normal, orthonormal ); dist = orthonormal[2]; } diff --git a/ref_gl/gl_dbghulls.c b/ref_gl/gl_dbghulls.c index 729b333b..53b0ae48 100644 --- a/ref_gl/gl_dbghulls.c +++ b/ref_gl/gl_dbghulls.c @@ -15,6 +15,7 @@ GNU General Public License for more details. #include "gl_local.h" +#include "mod_local.h" #define list_entry( ptr, type, member ) \ ((type *)((char *)(ptr) - (size_t)(&((type *)0)->member))) @@ -27,7 +28,7 @@ GNU General Public License for more details. void R_DrawWorldHull( void ) { - hull_model_t *hull = &WORLDMODEL->hull_models[0]; + hull_model_t *hull = &WORLD->hull_models[0]; winding_t *poly; int i; @@ -67,10 +68,10 @@ void R_DrawModelHull( void ) return; i = atoi( RI.currentmodel->name + 1 ); - if( i < 1 || i >= WORLDMODEL->num_hull_models ) + if( i < 1 || i >= WORLD->num_hull_models ) return; - hull = &WORLDMODEL->hull_models[i]; + hull = &WORLD->hull_models[i]; pglPolygonOffset( 1.0f, 2.0 ); pglEnable( GL_POLYGON_OFFSET_FILL ); diff --git a/ref_gl/gl_decals.c b/ref_gl/gl_decals.c index 9638e7cd..81462189 100644 --- a/ref_gl/gl_decals.c +++ b/ref_gl/gl_decals.c @@ -398,7 +398,7 @@ static void R_DecalVertsLight( float *v, msurface_t *surf, int vertCount ) float sample_size; int j; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); tex = surf->texinfo; for( j = 0; j < vertCount; j++, v += VERTEXSIZE ) diff --git a/ref_gl/gl_draw.c b/ref_gl/gl_draw.c index cd455380..952fd4c6 100644 --- a/ref_gl/gl_draw.c +++ b/ref_gl/gl_draw.c @@ -89,16 +89,16 @@ This repeats a 64*64 tile graphic to fill the screen around a sized down refresh window. ============= */ -void R_DrawTileClear( int x, int y, int w, int h ) +void R_DrawTileClear( int texnum, int x, int y, int w, int h ) { float tw, th; gl_texture_t *glt; GL_SetRenderMode( kRenderNormal ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); - GL_Bind( XASH_TEXTURE0, cls.tileImage ); + GL_Bind( XASH_TEXTURE0, texnum ); - glt = R_GetTexture( cls.tileImage ); + glt = R_GetTexture( texnum ); tw = glt->srcWidth; th = glt->srcHeight; diff --git a/ref_gl/gl_frustum.c b/ref_gl/gl_frustum.c index 64c56118..aa1c0a5d 100644 --- a/ref_gl/gl_frustum.c +++ b/ref_gl/gl_frustum.c @@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ +#include "common.h" #include "gl_local.h" #include "mathlib.h" diff --git a/ref_gl/gl_image.c b/ref_gl/gl_image.c index a2b97553..443d6aa1 100644 --- a/ref_gl/gl_image.c +++ b/ref_gl/gl_image.c @@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ +#include "common.h" #include "gl_local.h" #define TEXTURES_HASH_SIZE (MAX_TEXTURES >> 2) @@ -877,7 +878,7 @@ byte *GL_ApplyFilter( const byte *source, int width, int height ) byte *out = (byte *)source; int i; - if( Host_IsQuakeCompatible() || glConfig.max_multisamples > 1 ) + if( gEngfuncs.Host_IsQuakeCompatible() || glConfig.max_multisamples > 1 ) return in; for( i = 0; source && i < width * height; i++, in += 4 ) diff --git a/ref_gl/gl_local.h b/ref_gl/gl_local.h index 3755989b..97068cc7 100644 --- a/ref_gl/gl_local.h +++ b/ref_gl/gl_local.h @@ -32,56 +32,28 @@ GNU General Public License for more details. #include "enginefeatures.h" #include "com_strings.h" #include "pm_movevars.h" -typedef cvar_t convar_t; -#include -#define Con_Reportf printf -#define Con_Printf printf -#define Con_DPrintf printf void CL_DrawEFX(double, double); void *CL_ModelHandle(int); void *GL_GetProcAddress(char *); void GL_CheckForErrors(); void CL_ExtraUpdate(); -void Cbuf_AddText(char*); void Cbuf_Execute(); -int COM_HashKey(char*,int); extern convar_t cvstub; #define Cvar_Get(...) &cvstub -#define Cvar_FindVar(...) &cvstub #define Cvar_SetValue(...) #define Cmd_AddCommand(...) #define Cmd_RemoveCommand(...) #define FS_FreeImage(...) #define Host_Error(...) -#define ASSERT(x) -#define Q_strcpy(...) -#define Q_strncpy(...) -#define Q_strncat(...) -#define Q_strnat(...) -#define Q_snprintf(...) -#define Q_strcmp(...) 1 -#define Q_stricmp(...) 1 -#define Q_strncmp(...) 1 -#define Q_strnicmp(...) 1 -#define Q_strlen(...) 1 -#define Assert(x) -#define va(...) ((const char*)NULL) - -void *FS_LoadImage(char *, void *, int); -void *FS_CopyImage(void *); -void *Mem_Calloc(void*, int); -void *Mem_Malloc(void*, int); - -void *Mem_Realloc(void*,void*, int); - #define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) convar_t cv = { cvname, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc } #define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) convar_t cv = { #cv, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc } #define CVAR_TO_BOOL( x ) ((x) && ((x)->value != 0.0f) ? true : false ) -#define WORLDMODEL ((model_t*)NULL) -#define MOVEVARS ((movevars_t*)NULL) +#define WORLD (gEngfuncs.GetWorld()) +#define WORLDMODEL (gEngfuncs.pfnGetModelByIndex( 1 )) +#define MOVEVARS (gEngfuncs.pfnGetMoveVars()) extern byte *r_temppool; @@ -110,9 +82,11 @@ extern byte *r_temppool; #define RP_NONVIEWERREF (RP_ENVVIEW) #define R_ModelOpaque( rm ) ( rm == kRenderNormal ) #define R_StaticEntity( ent ) ( VectorIsNull( ent->origin ) && VectorIsNull( ent->angles )) -#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( cl.playernum + 1 ) && e->player ) +#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == gEngfuncs.GetPlayerIndex() && e->player ) #define RP_NORMALPASS() ( FBitSet( RI.params, RP_NONVIEWERREF ) == 0 ) +#define CL_IsViewEntityLocalPlayer() ( gEngfuncs.GetViewEntIndex() == gEngfuncs.GetPlayerIndex() ) + #define CULL_VISIBLE 0 // not culled #define CULL_BACKSIDE 1 // backside of transparent wall #define CULL_FRUSTUM 2 // culled by frustum @@ -352,7 +326,7 @@ void R_ClearDecals( void ); // gl_draw.c // void R_Set2DMode( qboolean enable ); -void R_DrawTileClear( int x, int y, int w, int h ); +void R_DrawTileClear( int texnum, int x, int y, int w, int h ); void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ); // @@ -565,6 +539,30 @@ byte *Mod_GetCurrentVis( void ); void Mod_SetOrthoBounds( float *mins, float *maxs ); void R_NewMap( void ); +// +// gl_opengl.c +// +#define GL_CheckForErrors() GL_CheckForErrors_( __FILE__, __LINE__ ) +void GL_CheckForErrors_( const char *filename, const int fileline ); +const char *GL_ErrorString( int err ); +void GL_UpdateSwapInterval( void ); +qboolean GL_Support( int r_ext ); +int GL_MaxTextureUnits( void ); +void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cvarname, int r_ext ); +void GL_SetExtension( int r_ext, int enable ); + +// +// gl_triapi.c +// +void TriBegin( int mode ); +void TriEnd( void ); +void TriTexCoord2f( float u, float v ); +void TriVertex3fv( const float *v ); +void TriVertex3f( float x, float y, float z ); +int TriWorldToScreen( float *world, float *screen ); +int TriSpriteTexture( model_t *pSpriteModel, int frame ); + + /* ======================================================================= @@ -687,6 +685,8 @@ extern glconfig_t glConfig; extern glstate_t glState; // move to engine //extern glwstate_t glw_state; +extern ref_api_t gEngfuncs; +extern ref_globals_t *gpGlobals; // // renderer cvars @@ -736,4 +736,55 @@ extern convar_t *vid_brightness; extern convar_t *vid_gamma; extern convar_t *vid_highdpi; -#endif//GL_LOCAL_H +// +// engine shared convars +// +extern convar_t *v_dark; + +// +// engine callbacks +// +#include "crtlib.h" + +FORCEINLINE float COM_RandomFloat( float rmin, float rmax ) +{ + return gEngfuncs.COM_RandomFloat( rmin, rmax ); +} + +FORCEINLINE int COM_RandomLong( int rmin, int rmax ) +{ + return gEngfuncs.COM_RandomLong( rmin, rmax ); +} + +FORCEINLINE uint COM_HashKey( const char *str, uint hashSize ) +{ + return gEngfuncs.COM_HashKey( str, hashSize ); +} + +FORCEINLINE byte *_Mem_AllocPool( const char *name, const char *filename, int fileline ) +{ + return gEngfuncs._Mem_AllocPool( name, filename, fileline ); +} + +FORCEINLINE void _Mem_FreePool( byte **poolptr, const char *filename, int fileline ) +{ + gEngfuncs._Mem_FreePool( poolptr, filename, fileline ); +} + +FORCEINLINE void *_Mem_Alloc( byte *poolptr, size_t size, qboolean clear, const char *filename, int fileline ) +{ + return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline ); +} + + +FORCEINLINE void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ) +{ + return gEngfuncs._Mem_Realloc( poolptr, memptr, size, clear, filename, fileline ); +} + +FORCEINLINE void _Mem_Free( void *data, const char *filename, int fileline ) +{ + gEngfuncs._Mem_Free( data, filename, fileline ); +} + +#endif // GL_LOCAL_H diff --git a/ref_gl/gl_opengl.c b/ref_gl/gl_opengl.c index 89539f54..06a0df52 100644 --- a/ref_gl/gl_opengl.c +++ b/ref_gl/gl_opengl.c @@ -48,6 +48,225 @@ glconfig_t glConfig; glstate_t glState; glwstate_t glw_state; +#define GL_CALL( x ) #x, (void**)&p##x +static dllfunc_t opengl_110funcs[] = +{ + { GL_CALL( glClearColor ) }, + { GL_CALL( glClear ) }, + { GL_CALL( glAlphaFunc ) }, + { GL_CALL( glBlendFunc ) }, + { GL_CALL( glCullFace ) }, + { GL_CALL( glDrawBuffer ) }, + { GL_CALL( glReadBuffer ) }, + { GL_CALL( glAccum ) }, + { GL_CALL( glEnable ) }, + { GL_CALL( glDisable ) }, + { GL_CALL( glEnableClientState ) }, + { GL_CALL( glDisableClientState ) }, + { GL_CALL( glGetBooleanv ) }, + { GL_CALL( glGetDoublev ) }, + { GL_CALL( glGetFloatv ) }, + { GL_CALL( glGetIntegerv ) }, + { GL_CALL( glGetError ) }, + { GL_CALL( glGetString ) }, + { GL_CALL( glFinish ) }, + { GL_CALL( glFlush ) }, + { GL_CALL( glClearDepth ) }, + { GL_CALL( glDepthFunc ) }, + { GL_CALL( glDepthMask ) }, + { GL_CALL( glDepthRange ) }, + { GL_CALL( glFrontFace ) }, + { GL_CALL( glDrawElements ) }, + { GL_CALL( glDrawArrays ) }, + { GL_CALL( glColorMask ) }, + { GL_CALL( glIndexPointer ) }, + { GL_CALL( glVertexPointer ) }, + { GL_CALL( glNormalPointer ) }, + { GL_CALL( glColorPointer ) }, + { GL_CALL( glTexCoordPointer ) }, + { GL_CALL( glArrayElement ) }, + { GL_CALL( glColor3f ) }, + { GL_CALL( glColor3fv ) }, + { GL_CALL( glColor4f ) }, + { GL_CALL( glColor4fv ) }, + { GL_CALL( glColor3ub ) }, + { GL_CALL( glColor4ub ) }, + { GL_CALL( glColor4ubv ) }, + { GL_CALL( glTexCoord1f ) }, + { GL_CALL( glTexCoord2f ) }, + { GL_CALL( glTexCoord3f ) }, + { GL_CALL( glTexCoord4f ) }, + { GL_CALL( glTexCoord1fv ) }, + { GL_CALL( glTexCoord2fv ) }, + { GL_CALL( glTexCoord3fv ) }, + { GL_CALL( glTexCoord4fv ) }, + { GL_CALL( glTexGenf ) }, + { GL_CALL( glTexGenfv ) }, + { GL_CALL( glTexGeni ) }, + { GL_CALL( glVertex2f ) }, + { GL_CALL( glVertex3f ) }, + { GL_CALL( glVertex3fv ) }, + { GL_CALL( glNormal3f ) }, + { GL_CALL( glNormal3fv ) }, + { GL_CALL( glBegin ) }, + { GL_CALL( glEnd ) }, + { GL_CALL( glLineWidth ) }, + { GL_CALL( glPointSize ) }, + { GL_CALL( glMatrixMode ) }, + { GL_CALL( glOrtho ) }, + { GL_CALL( glRasterPos2f ) }, + { GL_CALL( glFrustum ) }, + { GL_CALL( glViewport ) }, + { GL_CALL( glPushMatrix ) }, + { GL_CALL( glPopMatrix ) }, + { GL_CALL( glPushAttrib ) }, + { GL_CALL( glPopAttrib ) }, + { GL_CALL( glLoadIdentity ) }, + { GL_CALL( glLoadMatrixd ) }, + { GL_CALL( glLoadMatrixf ) }, + { GL_CALL( glMultMatrixd ) }, + { GL_CALL( glMultMatrixf ) }, + { GL_CALL( glRotated ) }, + { GL_CALL( glRotatef ) }, + { GL_CALL( glScaled ) }, + { GL_CALL( glScalef ) }, + { GL_CALL( glTranslated ) }, + { GL_CALL( glTranslatef ) }, + { GL_CALL( glReadPixels ) }, + { GL_CALL( glDrawPixels ) }, + { GL_CALL( glStencilFunc ) }, + { GL_CALL( glStencilMask ) }, + { GL_CALL( glStencilOp ) }, + { GL_CALL( glClearStencil ) }, + { GL_CALL( glIsEnabled ) }, + { GL_CALL( glIsList ) }, + { GL_CALL( glIsTexture ) }, + { GL_CALL( glTexEnvf ) }, + { GL_CALL( glTexEnvfv ) }, + { GL_CALL( glTexEnvi ) }, + { GL_CALL( glTexParameterf ) }, + { GL_CALL( glTexParameterfv ) }, + { GL_CALL( glTexParameteri ) }, + { GL_CALL( glHint ) }, + { GL_CALL( glPixelStoref ) }, + { GL_CALL( glPixelStorei ) }, + { GL_CALL( glGenTextures ) }, + { GL_CALL( glDeleteTextures ) }, + { GL_CALL( glBindTexture ) }, + { GL_CALL( glTexImage1D ) }, + { GL_CALL( glTexImage2D ) }, + { GL_CALL( glTexSubImage1D ) }, + { GL_CALL( glTexSubImage2D ) }, + { GL_CALL( glCopyTexImage1D ) }, + { GL_CALL( glCopyTexImage2D ) }, + { GL_CALL( glCopyTexSubImage1D ) }, + { GL_CALL( glCopyTexSubImage2D ) }, + { GL_CALL( glScissor ) }, + { GL_CALL( glGetTexImage ) }, + { GL_CALL( glGetTexEnviv ) }, + { GL_CALL( glPolygonOffset ) }, + { GL_CALL( glPolygonMode ) }, + { GL_CALL( glPolygonStipple ) }, + { GL_CALL( glClipPlane ) }, + { GL_CALL( glGetClipPlane ) }, + { GL_CALL( glShadeModel ) }, + { GL_CALL( glGetTexLevelParameteriv ) }, + { GL_CALL( glGetTexLevelParameterfv ) }, + { GL_CALL( glFogfv ) }, + { GL_CALL( glFogf ) }, + { GL_CALL( glFogi ) }, + { NULL , NULL } +}; + +static dllfunc_t debugoutputfuncs[] = +{ + { GL_CALL( glDebugMessageControlARB ) }, + { GL_CALL( glDebugMessageInsertARB ) }, + { GL_CALL( glDebugMessageCallbackARB ) }, + { GL_CALL( glGetDebugMessageLogARB ) }, + { NULL , NULL } +}; + +static dllfunc_t multitexturefuncs[] = +{ + { GL_CALL( glMultiTexCoord1f ) }, + { GL_CALL( glMultiTexCoord2f ) }, + { GL_CALL( glMultiTexCoord3f ) }, + { GL_CALL( glMultiTexCoord4f ) }, + { GL_CALL( glActiveTexture ) }, + { GL_CALL( glActiveTextureARB ) }, + { GL_CALL( glClientActiveTexture ) }, + { GL_CALL( glClientActiveTextureARB ) }, + { NULL , NULL } +}; + +static dllfunc_t texture3dextfuncs[] = +{ + { GL_CALL( glTexImage3D ) }, + { GL_CALL( glTexSubImage3D ) }, + { GL_CALL( glCopyTexSubImage3D ) }, + { NULL , NULL } +}; + +static dllfunc_t texturecompressionfuncs[] = +{ + { GL_CALL( glCompressedTexImage3DARB ) }, + { GL_CALL( glCompressedTexImage2DARB ) }, + { GL_CALL( glCompressedTexImage1DARB ) }, + { GL_CALL( glCompressedTexSubImage3DARB ) }, + { GL_CALL( glCompressedTexSubImage2DARB ) }, + { GL_CALL( glCompressedTexSubImage1DARB ) }, + { GL_CALL( glGetCompressedTexImage ) }, + { NULL , NULL } +}; + +static dllfunc_t vbofuncs[] = +{ + { GL_CALL( glBindBufferARB ) }, + { GL_CALL( glDeleteBuffersARB ) }, + { GL_CALL( glGenBuffersARB ) }, + { GL_CALL( glIsBufferARB ) }, + { GL_CALL( glMapBufferARB ) }, + { GL_CALL( glUnmapBufferARB ) }, // , + { GL_CALL( glBufferDataARB ) }, + { GL_CALL( glBufferSubDataARB ) }, + { NULL, NULL} +}; + +/* +======================== +DebugCallback + +For ARB_debug_output +======================== +*/ +static void APIENTRY GL_DebugOutput( GLuint source, GLuint type, GLuint id, GLuint severity, GLint length, const GLcharARB *message, GLvoid *userParam ) +{ + switch( type ) + { + case GL_DEBUG_TYPE_ERROR_ARB: + Con_Printf( S_OPENGL_ERROR "%s\n", message ); + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: + Con_Printf( S_OPENGL_WARN "%s\n", message ); + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: + Con_Printf( S_OPENGL_WARN "%s\n", message ); + break; + case GL_DEBUG_TYPE_PORTABILITY_ARB: + if( gpGlobals->developer < DEV_EXTENDED ) + return; + Con_Printf( S_OPENGL_WARN "%s\n", message ); + break; + case GL_DEBUG_TYPE_PERFORMANCE_ARB: + Con_Printf( S_OPENGL_NOTE "%s\n", message ); + break; + case GL_DEBUG_TYPE_OTHER_ARB: + default: Con_Printf( S_OPENGL_NOTE "%s\n", message ); + break; + } +} + /* ================= GL_SetExtension @@ -265,6 +484,259 @@ void R_RenderInfo_f( void ) glConfig.alpha_bits, glConfig.depth_bits, glConfig.stencil_bits ); } +#ifdef XASH_GLES +void GL_InitExtensionsGLES( void ) +{ + // intialize wrapper type +#ifdef XASH_NANOGL + glConfig.context = CONTEXT_TYPE_GLES_1_X; + glConfig.wrapper = GLES_WRAPPER_NANOGL; +#elif defined( XASH_WES ) + glConfig.context = CONTEXT_TYPE_GLES_2_X; + glConfig.wrapper = GLES_WRAPPER_WES; +#endif + + glConfig.hardware_type = GLHW_GENERIC; + + // initalize until base opengl functions loaded + GL_SetExtension( GL_DRAW_RANGEELEMENTS_EXT, true ); + GL_SetExtension( GL_ARB_MULTITEXTURE, true ); + pglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texture_units ); + glConfig.max_texture_coords = glConfig.max_texture_units = 4; + + GL_SetExtension( GL_ENV_COMBINE_EXT, true ); + GL_SetExtension( GL_DOT3_ARB_EXT, true ); + GL_SetExtension( GL_TEXTURE_3D_EXT, false ); + GL_SetExtension( GL_SGIS_MIPMAPS_EXT, true ); // gles specs + GL_SetExtension( GL_ARB_VERTEX_BUFFER_OBJECT_EXT, true ); // gles specs + + // hardware cubemaps + GL_CheckExtension( "GL_OES_texture_cube_map", NULL, "gl_texture_cubemap", GL_TEXTURECUBEMAP_EXT ); + + if( GL_Support( GL_TEXTURECUBEMAP_EXT )) + pglGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig.max_cubemap_size ); + + GL_SetExtension( GL_ARB_SEAMLESS_CUBEMAP, false ); + + GL_SetExtension( GL_EXT_POINTPARAMETERS, false ); + GL_CheckExtension( "GL_OES_texture_npot", NULL, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT ); + + GL_SetExtension( GL_TEXTURE_COMPRESSION_EXT, false ); + GL_SetExtension( GL_CUSTOM_VERTEX_ARRAY_EXT, false ); + GL_SetExtension( GL_CLAMPTOEDGE_EXT, true ); // by gles1 specs + GL_SetExtension( GL_ANISOTROPY_EXT, false ); + GL_SetExtension( GL_TEXTURE_LODBIAS, false ); + GL_SetExtension( GL_CLAMP_TEXBORDER_EXT, false ); + GL_SetExtension( GL_BLEND_MINMAX_EXT, false ); + GL_SetExtension( GL_BLEND_SUBTRACT_EXT, false ); + GL_SetExtension( GL_SEPARATESTENCIL_EXT, false ); + GL_SetExtension( GL_STENCILTWOSIDE_EXT, false ); + GL_SetExtension( GL_TEXTURE_ENV_ADD_EXT,false ); + GL_SetExtension( GL_SHADER_OBJECTS_EXT, false ); + GL_SetExtension( GL_SHADER_GLSL100_EXT, false ); + GL_SetExtension( GL_VERTEX_SHADER_EXT,false ); + GL_SetExtension( GL_FRAGMENT_SHADER_EXT, false ); + GL_SetExtension( GL_SHADOW_EXT, false ); + GL_SetExtension( GL_ARB_DEPTH_FLOAT_EXT, false ); + GL_SetExtension( GL_OCCLUSION_QUERIES_EXT,false ); + GL_CheckExtension( "GL_OES_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE ); + + glConfig.texRectangle = glConfig.max_2d_rectangle_size = 0; // no rectangle + + Cvar_FullSet( "gl_allow_mirrors", "0", CVAR_READ_ONLY); // No support for GLES + +} +#else +void GL_InitExtensionsBigGL() +{ + // intialize wrapper type + glConfig.context = CONTEXT_TYPE_GL; + glConfig.wrapper = GLES_WRAPPER_NONE; + + if( Q_stristr( glConfig.renderer_string, "geforce" )) + glConfig.hardware_type = GLHW_NVIDIA; + else if( Q_stristr( glConfig.renderer_string, "quadro fx" )) + glConfig.hardware_type = GLHW_NVIDIA; + else if( Q_stristr(glConfig.renderer_string, "rv770" )) + glConfig.hardware_type = GLHW_RADEON; + else if( Q_stristr(glConfig.renderer_string, "radeon hd" )) + glConfig.hardware_type = GLHW_RADEON; + else if( Q_stristr( glConfig.renderer_string, "eah4850" ) || Q_stristr( glConfig.renderer_string, "eah4870" )) + glConfig.hardware_type = GLHW_RADEON; + else if( Q_stristr( glConfig.renderer_string, "radeon" )) + glConfig.hardware_type = GLHW_RADEON; + else if( Q_stristr( glConfig.renderer_string, "intel" )) + glConfig.hardware_type = GLHW_INTEL; + else glConfig.hardware_type = GLHW_GENERIC; + + // multitexture + glConfig.max_texture_units = glConfig.max_texture_coords = glConfig.max_teximage_units = 1; + GL_CheckExtension( "GL_ARB_multitexture", multitexturefuncs, "gl_arb_multitexture", GL_ARB_MULTITEXTURE ); + + if( GL_Support( GL_ARB_MULTITEXTURE )) + { + pglGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.max_texture_units ); + } + + if( glConfig.max_texture_units == 1 ) + GL_SetExtension( GL_ARB_MULTITEXTURE, false ); + + // 3d texture support + GL_CheckExtension( "GL_EXT_texture3D", texture3dextfuncs, "gl_texture_3d", GL_TEXTURE_3D_EXT ); + + if( GL_Support( GL_TEXTURE_3D_EXT )) + { + pglGetIntegerv( GL_MAX_3D_TEXTURE_SIZE, &glConfig.max_3d_texture_size ); + + if( glConfig.max_3d_texture_size < 32 ) + { + GL_SetExtension( GL_TEXTURE_3D_EXT, false ); + Con_Printf( S_ERROR "GL_EXT_texture3D reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n" ); + } + } + + // 2d texture array support + GL_CheckExtension( "GL_EXT_texture_array", texture3dextfuncs, "gl_texture_2d_array", GL_TEXTURE_ARRAY_EXT ); + + if( GL_Support( GL_TEXTURE_ARRAY_EXT )) + pglGetIntegerv( GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &glConfig.max_2d_texture_layers ); + + // cubemaps support + GL_CheckExtension( "GL_ARB_texture_cube_map", NULL, "gl_texture_cubemap", GL_TEXTURE_CUBEMAP_EXT ); + + if( GL_Support( GL_TEXTURE_CUBEMAP_EXT )) + { + pglGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig.max_cubemap_size ); + + // check for seamless cubemaps too + GL_CheckExtension( "GL_ARB_seamless_cube_map", NULL, "gl_texture_cubemap_seamless", GL_ARB_SEAMLESS_CUBEMAP ); + } + + GL_CheckExtension( "GL_ARB_texture_non_power_of_two", NULL, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT ); + GL_CheckExtension( "GL_ARB_texture_compression", texturecompressionfuncs, "gl_dds_hardware_support", GL_TEXTURE_COMPRESSION_EXT ); + GL_CheckExtension( "GL_EXT_texture_edge_clamp", NULL, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT ); + if( !GL_Support( GL_CLAMPTOEDGE_EXT )) + GL_CheckExtension( "GL_SGIS_texture_edge_clamp", NULL, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT ); + + glConfig.max_texture_anisotropy = 0.0f; + GL_CheckExtension( "GL_EXT_texture_filter_anisotropic", NULL, "gl_ext_anisotropic_filter", GL_ANISOTROPY_EXT ); + if( GL_Support( GL_ANISOTROPY_EXT )) + pglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.max_texture_anisotropy ); + +#ifdef _WIN32 // Win32 only drivers? + // g-cont. because lodbias it too glitchy on Intel's cards + if( glConfig.hardware_type != GLHW_INTEL ) +#endif + GL_CheckExtension( "GL_EXT_texture_lod_bias", NULL, "gl_texture_mipmap_biasing", GL_TEXTURE_LOD_BIAS ); + + if( GL_Support( GL_TEXTURE_LOD_BIAS )) + pglGetFloatv( GL_MAX_TEXTURE_LOD_BIAS_EXT, &glConfig.max_texture_lod_bias ); + + GL_CheckExtension( "GL_ARB_texture_border_clamp", NULL, "gl_ext_texborder_clamp", GL_CLAMP_TEXBORDER_EXT ); + GL_CheckExtension( "GL_ARB_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE ); + GL_CheckExtension( "GL_ARB_texture_float", NULL, "gl_arb_texture_float", GL_ARB_TEXTURE_FLOAT_EXT ); + GL_CheckExtension( "GL_ARB_depth_buffer_float", NULL, "gl_arb_depth_float", GL_ARB_DEPTH_FLOAT_EXT ); + GL_CheckExtension( "GL_EXT_gpu_shader4", NULL, NULL, GL_EXT_GPU_SHADER4 ); // don't confuse users + GL_CheckExtension( "GL_ARB_shading_language_100", NULL, "gl_glslprogram", GL_SHADER_GLSL100_EXT ); + GL_CheckExtension( "GL_ARB_vertex_buffer_object", vbofuncs, "gl_vertex_buffer_object", GL_ARB_VERTEX_BUFFER_OBJECT_EXT ); + + // rectangle textures support + GL_CheckExtension( "GL_ARB_texture_rectangle", NULL, "gl_texture_rectangle", GL_TEXTURE_2D_RECT_EXT ); + + // this won't work without extended context + if( glw_state.extended ) + GL_CheckExtension( "GL_ARB_debug_output", debugoutputfuncs, "gl_debug_output", GL_DEBUG_OUTPUT ); + + if( GL_Support( GL_SHADER_GLSL100_EXT )) + { + pglGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &glConfig.max_texture_coords ); + pglGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &glConfig.max_teximage_units ); + + // check for hardware skinning + pglGetIntegerv( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig.max_vertex_uniforms ); + pglGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig.max_vertex_attribs ); + +#ifdef _WIN32 // Win32 only drivers? + if( glConfig.hardware_type == GLHW_RADEON && glConfig.max_vertex_uniforms > 512 ) + glConfig.max_vertex_uniforms /= 4; // radeon returns not correct info +#endif + } + else + { + // just get from multitexturing + glConfig.max_texture_coords = glConfig.max_teximage_units = glConfig.max_texture_units; + } + + pglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.max_2d_texture_size ); + if( glConfig.max_2d_texture_size <= 0 ) glConfig.max_2d_texture_size = 256; + + if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) + pglGetIntegerv( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &glConfig.max_2d_rectangle_size ); + +#ifndef XASH_GL_STATIC + // enable gldebug if allowed + if( GL_Support( GL_DEBUG_OUTPUT )) + { + if( host_developer.value ) + { + Con_Reportf( "Installing GL_DebugOutput...\n"); + pglDebugMessageCallbackARB( GL_DebugOutput, NULL ); + + // force everything to happen in the main thread instead of in a separate driver thread + pglEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB ); + } + + // enable all the low priority messages + pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); + } +#endif +} +#endif + +void GL_InitExtensions( void ) +{ + // initialize gl extensions + GL_CheckExtension( "OpenGL 1.1.0", opengl_110funcs, NULL, GL_OPENGL_110 ); + + // get our various GL strings + glConfig.vendor_string = pglGetString( GL_VENDOR ); + glConfig.renderer_string = pglGetString( GL_RENDERER ); + glConfig.version_string = pglGetString( GL_VERSION ); + glConfig.extensions_string = pglGetString( GL_EXTENSIONS ); + Con_Reportf( "^3Video^7: %s\n", glConfig.renderer_string ); + +#ifdef XASH_GLES + GL_InitExtensionsGLES(); +#else + GL_InitExtensionsBigGL(); +#endif + + if( GL_Support( GL_TEXTURE_2D_RECT_EXT )) + pglGetIntegerv( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &glConfig.max_2d_rectangle_size ); + + Cvar_Get( "gl_max_size", va( "%i", glConfig.max_2d_texture_size ), 0, "opengl texture max dims" ); + Cvar_Set( "gl_anisotropy", va( "%f", bound( 0, gl_texture_anisotropy->value, glConfig.max_texture_anisotropy ))); + + if( GL_Support( GL_TEXTURE_COMPRESSION_EXT )) + Image_AddCmdFlags( IL_DDS_HARDWARE ); + + // MCD has buffering issues +#ifdef _WIN32 + if( Q_strstr( glConfig.renderer_string, "gdi" )) + Cvar_SetValue( "gl_finish", 1 ); +#endif + + tr.framecount = tr.visframecount = 1; + glw_state.initialized = true; +} + +void GL_ClearExtensions( void ) +{ + // now all extensions are disabled + memset( glConfig.extension, 0, sizeof( glConfig.extension )); + glw_state.initialized = false; +} + //======================================================================= /* diff --git a/ref_gl/gl_rlight.c b/ref_gl/gl_rlight.c index 0c451397..889553bf 100644 --- a/ref_gl/gl_rlight.c +++ b/ref_gl/gl_rlight.c @@ -35,7 +35,7 @@ void CL_RunLightStyles( void ) { int i, k, flight, clight; float l, lerpfrac, backlerp; - float frametime = (cl.time - cl.oldtime); + float frametime = (gpGlobals->time - gpGlobals->oldtime); float scale; lightstyle_t *ls; @@ -151,12 +151,12 @@ void R_PushDlights( void ) tr.dlightframecount = tr.framecount; l = cl_dlights; - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; for( i = 0; i < MAX_DLIGHTS; i++, l++ ) { - if( l->die < cl.time || !l->radius ) + if( l->die < gpGlobals->time || !l->radius ) continue; if( GL_FrustumCullSphere( &RI.frustum, l->origin, l->radius, 15 )) @@ -178,7 +178,7 @@ int R_CountDlights( void ) for( i = 0, l = cl_dlights; i < MAX_DLIGHTS; i++, l++ ) { - if( l->die < cl.time || !l->radius ) + if( l->die < gpGlobals->time || !l->radius ) continue; numDlights++; @@ -297,7 +297,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, if( !surf->samples ) return true; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = (info->lightextents[0] / sample_size) + 1; tmax = (info->lightextents[1] / sample_size) + 1; ds /= sample_size; diff --git a/ref_gl/gl_rmain.c b/ref_gl/gl_rmain.c index 873d5310..25e9fd49 100644 --- a/ref_gl/gl_rmain.c +++ b/ref_gl/gl_rmain.c @@ -241,7 +241,7 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type ) if( FBitSet( clent->curstate.effects, EF_NODRAW )) return false; // done - if( !R_ModelOpaque( clent->curstate.rendermode ) && CL_FxBlend( clent ) <= 0 ) + if( !R_ModelOpaque( clent->curstate.rendermode ) && gEngfuncs.CL_FxBlend( clent ) <= 0 ) return true; // invisible if( type == ET_FRAGMENTED ) @@ -331,8 +331,8 @@ void R_SetupFrustum( void ) if( RP_NORMALPASS() && ( cl.local.waterlevel >= 3 )) { - RI.fov_x = atan( tan( DEG2RAD( RI.fov_x ) / 2 ) * ( 0.97 + sin( cl.time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); - RI.fov_y = atan( tan( DEG2RAD( RI.fov_y ) / 2 ) * ( 1.03 - sin( cl.time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); + RI.fov_x = atan( tan( DEG2RAD( RI.fov_x ) / 2 ) * ( 0.97 + sin( gpGlobals->time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); + RI.fov_y = atan( tan( DEG2RAD( RI.fov_y ) / 2 ) * ( 1.03 - sin( gpGlobals->time * 1.5 ) * 0.03 )) * 2 / (M_PI / 180.0); } // build the transformation matrix for the given view angles @@ -421,7 +421,7 @@ void R_RotateForEntity( cl_entity_t *e ) { float scale = 1.0f; - if( e == clgame.entities ) + if( e == gEngfuncs.GetEntityByIndex( 0 ) ) { R_LoadIdentity(); return; @@ -447,7 +447,7 @@ void R_TranslateForEntity( cl_entity_t *e ) { float scale = 1.0f; - if( e == clgame.entities ) + if( e == gEngfuncs.GetEntityByIndex( 0 ) ) { R_LoadIdentity(); return; @@ -656,7 +656,7 @@ static void R_CheckFog( void ) int i, cnt, count; // quake global fog - if( Host_IsQuakeCompatible( )) + if( gEngfuncs.Host_IsQuakeCompatible( )) { if( !MOVEVARS->fog_settings ) { @@ -779,7 +779,7 @@ void R_DrawFog( void ) if( !RI.fogEnabled ) return; pglEnable( GL_FOG ); - if( Host_IsQuakeCompatible( )) + if( gEngfuncs.Host_IsQuakeCompatible( )) pglFogi( GL_FOG_MODE, GL_EXP2 ); else pglFogi( GL_FOG_MODE, GL_EXP ); pglFogf( GL_FOG_DENSITY, RI.fogDensity ); @@ -851,7 +851,7 @@ void R_DrawEntitiesOnList( void ) GL_CheckForErrors(); if( !RI.onlyClientDraw ) - { + { CL_DrawEFX( tr.frametime, false ); } @@ -870,7 +870,7 @@ void R_DrawEntitiesOnList( void ) // handle studiomodels with custom rendermodes on texture if( RI.currententity->curstate.rendermode != kRenderNormal ) - tr.blend = CL_FxBlend( RI.currententity ) / 255.0f; + tr.blend = gEngfuncs.CL_FxBlend( RI.currententity ) / 255.0f; else tr.blend = 1.0f; // draw as solid but sorted by distance if( tr.blend <= 0.0f ) continue; @@ -939,7 +939,7 @@ void R_RenderScene( void ) // frametime is valid only for normal pass if( RP_NORMALPASS( )) - tr.frametime = cl.time - cl.oldtime; + tr.frametime = gpGlobals->time - gpGlobals->oldtime; else tr.frametime = 0.0; // begin a new frame @@ -1261,7 +1261,7 @@ static int GL_RenderGetParm( int parm, int arg ) return (host.type == HOST_DEDICATED); case PARM_SURF_SAMPLESIZE: if( arg >= 0 && arg < WORLDMODEL->numsurfaces ) - return Mod_SampleSizeForFace( &WORLDMODEL->surfaces[arg] ); + return gEngfuncs.Mod_SampleSizeForFace( &WORLDMODEL->surfaces[arg] ); return LM_SAMPLE_SIZE; case PARM_GL_CONTEXT_TYPE: return glConfig.context; @@ -1348,188 +1348,6 @@ static void R_SetCurrentModel( model_t *mod ) RI.currentmodel = mod; } -// to engine? -#if 0 - -static int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis ) -{ - return Mod_FatPVS( org, radius, visbuffer, WORLDMODEL->visbytes, merge, fullvis ); -} - -static lightstyle_t *CL_GetLightStyle( int number ) -{ - Assert( number >= 0 && number < MAX_LIGHTSTYLES ); - return &cl.lightstyles[number]; -} - -static dlight_t *CL_GetDynamicLight( int number ) -{ - Assert( number >= 0 && number < MAX_DLIGHTS ); - return &cl_dlights[number]; -} - -static dlight_t *CL_GetEntityLight( int number ) -{ - Assert( number >= 0 && number < MAX_ELIGHTS ); - return &cl_elights[number]; -} - -static float R_GetFrameTime( void ) -{ - return tr.frametime; -} - -static const char *GL_TextureName( unsigned int texnum ) -{ - return R_GetTexture( texnum )->name; -} - -const byte *GL_TextureData( unsigned int texnum ) -{ - rgbdata_t *pic = R_GetTexture( texnum )->original; - - if( pic != NULL ) - return pic->buffer; - return NULL; -} - -static const ref_overview_t *GL_GetOverviewParms( void ) -{ - return &clgame.overView; -} - -static void *R_Mem_Alloc( size_t cb, const char *filename, const int fileline ) -{ - return _Mem_Alloc( cls.mempool, cb, true, filename, fileline ); -} - -static void R_Mem_Free( void *mem, const char *filename, const int fileline ) -{ - if( !mem ) return; - _Mem_Free( mem, filename, fileline ); -} - -/* -========= -pfnGetFilesList - -========= -*/ -static char **pfnGetFilesList( const char *pattern, int *numFiles, int gamedironly ) -{ - static search_t *t = NULL; - - if( t ) Mem_Free( t ); // release prev search - - t = FS_Search( pattern, true, gamedironly ); - - if( !t ) - { - if( numFiles ) *numFiles = 0; - return NULL; - } - - if( numFiles ) *numFiles = t->numfilenames; - return t->filenames; -} - -static uint pfnFileBufferCRC32( const void *buffer, const int length ) -{ - uint modelCRC = 0; - - if( !buffer || length <= 0 ) - return modelCRC; - - CRC32_Init( &modelCRC ); - CRC32_ProcessBuffer( &modelCRC, buffer, length ); - return CRC32_Final( modelCRC ); -} - -/* -============= -CL_GenericHandle - -============= -*/ -const char *CL_GenericHandle( int fileindex ) -{ - if( fileindex < 0 || fileindex >= MAX_CUSTOM ) - return 0; - return cl.files_precache[fileindex]; -} -#endif - -static render_api_t gRenderAPI = -{ -#if 0 - GL_RenderGetParm, - R_GetDetailScaleForTexture, - R_GetExtraParmsForTexture, - CL_GetLightStyle, - CL_GetDynamicLight, - CL_GetEntityLight, - LightToTexGamma, - R_GetFrameTime, - R_SetCurrentEntity, - R_SetCurrentModel, - R_FatPVS, - R_StoreEfrags, - GL_FindTexture, - GL_TextureName, - GL_TextureData, - GL_LoadTexture, - GL_CreateTexture, - GL_LoadTextureArray, - GL_CreateTextureArray, - GL_FreeTexture, - DrawSingleDecal, - R_DecalSetupVerts, - R_EntityRemoveDecals, - (void*)AVI_LoadVideo, - (void*)AVI_GetVideoInfo, - (void*)AVI_GetVideoFrameNumber, - (void*)AVI_GetVideoFrame, - R_UploadStretchRaw, - (void*)AVI_FreeVideo, - (void*)AVI_IsActive, - S_StreamAviSamples, - NULL, - NULL, - GL_Bind, - GL_SelectTexture, - GL_LoadTexMatrixExt, - GL_LoadIdentityTexMatrix, - GL_CleanUpTextureUnits, - GL_TexGen, - GL_TextureTarget, - GL_SetTexCoordArrayMode, - GL_GetProcAddress, - GL_UpdateTexSize, - NULL, - NULL, - CL_DrawParticlesExternal, - R_EnvShot, - pfnSPR_LoadExt, - R_LightVec, - R_StudioGetTexture, - GL_GetOverviewParms, - CL_GenericHandle, - NULL, - NULL, - R_Mem_Alloc, - R_Mem_Free, - pfnGetFilesList, - pfnFileBufferCRC32, - COM_CompareFileTime, - Host_Error, - (void*)CL_ModelHandle, - pfnTime, - Cvar_Set, - S_FadeMusicVolume, - COM_SetRandomSeed, -#endif -}; - /* =============== R_InitRenderAPI diff --git a/ref_gl/gl_rmisc.c b/ref_gl/gl_rmisc.c index b0b64168..efdeb97f 100644 --- a/ref_gl/gl_rmisc.c +++ b/ref_gl/gl_rmisc.c @@ -16,6 +16,8 @@ GNU General Public License for more details. #include "gl_local.h" #include "mod_local.h" #include "shake.h" +#include "screenfade.h" +#include "cdll_int.h" static void R_ParseDetailTextures( const char *filename ) { @@ -123,12 +125,12 @@ void R_NewMap( void ) if( CVAR_TO_BOOL( v_dark )) { - screenfade_t *sf = &clgame.fade; + screenfade_t *sf = gEngfuncs.GetScreenFade(); float fadetime = 5.0f; client_textmessage_t *title; - title = CL_TextMessageGet( "GAMETITLE" ); - if( Host_IsQuakeCompatible( )) + title = gEngfuncs.pfnTextMessageGet( "GAMETITLE" ); + if( gEngfuncs.Host_IsQuakeCompatible( )) fadetime = 1.0f; if( title ) @@ -143,7 +145,7 @@ void R_NewMap( void ) sf->fader = sf->fadeg = sf->fadeb = 0; sf->fadealpha = 255; sf->fadeSpeed = (float)sf->fadealpha / sf->fadeReset; - sf->fadeReset += cl.time; + sf->fadeReset += gpGlobals->time; sf->fadeEnd += sf->fadeReset; Cvar_SetValue( "v_dark", 0.0f ); diff --git a/ref_gl/gl_rpart.c b/ref_gl/gl_rpart.c index d6b4b106..10620d68 100644 --- a/ref_gl/gl_rpart.c +++ b/ref_gl/gl_rpart.c @@ -79,7 +79,7 @@ void CL_DrawParticles( double frametime, particle_t *cl_active_particles ) p->color = bound( 0, p->color, 255 ); pColor = &clgame.palette[p->color]; - alpha = 255 * (p->die - cl.time) * 16.0f; + alpha = 255 * (p->die - gpGlobals->time) * 16.0f; if( alpha > 255 || p->type == pt_static ) alpha = 255; @@ -258,7 +258,7 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers ) for( p = cl_active_tracers; p; p = p->next ) { - atten = (p->die - cl.time); + atten = (p->die - gpGlobals->time); if( atten > 0.1f ) atten = 0.1f; VectorScale( p->vel, ( p->ramp * atten ), delta ); @@ -317,7 +317,7 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers ) p->vel[1] *= scale; p->vel[2] -= gravity; - p->packedColor = 255 * (p->die - cl.time) * 2; + p->packedColor = 255 * (p->die - gpGlobals->time) * 2; if( p->packedColor > 255 ) p->packedColor = 255; } else if( p->type == pt_slowgrav ) diff --git a/ref_gl/gl_rsurf.c b/ref_gl/gl_rsurf.c index 1f42418c..3c92ca11 100644 --- a/ref_gl/gl_rsurf.c +++ b/ref_gl/gl_rsurf.c @@ -92,7 +92,7 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts if( numverts > ( SUBDIVIDE_SIZE - 4 )) Host_Error( "Mod_SubdividePolygon: too many vertexes on face ( %i )\n", numverts ); - sample_size = Mod_SampleSizeForFace( warpface ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( warpface ); BoundPoly( numverts, verts, mins, maxs ); for( i = 0; i < 3; i++ ) @@ -293,7 +293,7 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) glt->srcHeight = tex->height; } - sample_size = Mod_SampleSizeForFace( fa ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( fa ); // reconstruct the polygon pedges = mod->edges; @@ -425,7 +425,7 @@ texture_t *R_TextureAnim( texture_t *b ) speed = 10; else speed = 20; - reletive = (int)(cl.time * speed) % base->anim_total; + reletive = (int)(gpGlobals->time * speed) % base->anim_total; } @@ -479,7 +479,7 @@ texture_t *R_TextureAnimation( msurface_t *s ) speed = 10; else speed = 20; - reletive = (int)(cl.time * speed) % base->anim_total; + reletive = (int)(gpGlobals->time * speed) % base->anim_total; } count = 0; @@ -516,7 +516,7 @@ void R_AddDynamicLights( msurface_t *surf ) // no dlighted surfaces here if( !R_CountSurfaceDlights( surf )) return; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = (info->lightextents[0] / sample_size) + 1; tmax = (info->lightextents[1] / sample_size) + 1; tex = surf->texinfo; @@ -722,7 +722,7 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean mextrasurf_t *info = surf->info; color24 *lm; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; size = smax * tmax; @@ -791,7 +791,7 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale ) float flRate, flAngle; gl_texture_t *texture; - if( Host_IsQuakeCompatible() && RI.currententity == clgame.entities ) + if( gEngfuncs.Host_IsQuakeCompatible() && RI.currententity == gEngfuncs.GetEntityByIndex( 0 ) ) { // same as doom speed flConveyorSpeed = -35.0f; @@ -807,8 +807,8 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale ) flAngle = ( flConveyorSpeed >= 0 ) ? 180 : 0; SinCos( flAngle * ( M_PI / 180.0f ), &sy, &cy ); - sOffset = cl.time * cy * flRate; - tOffset = cl.time * sy * flRate; + sOffset = gpGlobals->time * cy * flRate; + tOffset = gpGlobals->time * sy * flRate; // make sure that we are positive if( sOffset < 0.0f ) sOffset += 1.0f + -(int)sOffset; @@ -955,7 +955,7 @@ void R_BlendLightmaps( void ) mextrasurf_t *info = surf->info; byte *base; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -1221,7 +1221,7 @@ dynamic: int sample_size; int smax, tmax; - sample_size = Mod_SampleSizeForFace( fa ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( fa ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -1267,7 +1267,7 @@ void R_DrawTextureChains( void ) GL_SetupFogColorForSurfaces(); // restore worldmodel - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; if( FBitSet( WORLDMODEL->flags, FWORLD_SKYSPHERE ) && !FBitSet( WORLDMODEL->flags, FWORLD_CUSTOM_SKYBOX )) @@ -1301,11 +1301,11 @@ void R_DrawTextureChains( void ) if(( s->flags & SURF_DRAWTURB ) && MOVEVARS->wateralpha < 1.0f ) continue; // draw translucent water later - if( Host_IsQuakeCompatible() && FBitSet( s->flags, SURF_TRANSPARENT )) + if( gEngfuncs.Host_IsQuakeCompatible() && FBitSet( s->flags, SURF_TRANSPARENT )) { draw_alpha_surfaces = true; continue; // draw transparent surfaces later - } + } for( ; s != NULL; s = s->texturechain ) R_RenderBrushPoly( s, CULL_VISIBLE ); @@ -1341,7 +1341,7 @@ void R_DrawAlphaTextureChains( void ) GL_SetupFogColorForSurfaces(); // restore worldmodel - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; RI.currententity->curstate.rendermode = kRenderTransAlpha; draw_alpha_surfaces = false; @@ -1386,7 +1386,7 @@ void R_DrawWaterSurfaces( void ) return; // restore worldmodel - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; // go back to the world matrix @@ -1481,7 +1481,7 @@ void R_SetRenderMode( cl_entity_t *e ) case kRenderTransAlpha: pglEnable( GL_ALPHA_TEST ); pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - if( Host_IsQuakeCompatible( )) + if( gEngfuncs.Host_IsQuakeCompatible( )) { pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglColor4f( 1.0f, 1.0f, 1.0f, tr.blend ); @@ -1556,7 +1556,7 @@ void R_DrawBrushModel( cl_entity_t *e ) if( rotated ) R_RotateForEntity( e ); else R_TranslateForEntity( e ); - if( Host_IsQuakeCompatible() && FBitSet( clmodel->flags, MODEL_TRANSPARENT )) + if( gEngfuncs.Host_IsQuakeCompatible() && FBitSet( clmodel->flags, MODEL_TRANSPARENT )) e->curstate.rendermode = kRenderTransAlpha; e->visframe = tr.realframecount; // visible @@ -1567,7 +1567,7 @@ void R_DrawBrushModel( cl_entity_t *e ) // calculate dynamic lighting for bmodel for( k = 0, l = cl_dlights; k < MAX_DLIGHTS; k++, l++ ) { - if( l->die < cl.time || !l->radius ) + if( l->die < gpGlobals->time || !l->radius ) continue; VectorCopy( l->origin, oldorigin ); // save lightorigin @@ -1589,7 +1589,7 @@ void R_DrawBrushModel( cl_entity_t *e ) for( i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ ) { - if( FBitSet( psurf->flags, SURF_DRAWTURB ) && !Host_IsQuakeCompatible( )) + if( FBitSet( psurf->flags, SURF_DRAWTURB ) && !gEngfuncs.Host_IsQuakeCompatible( )) { if( psurf->plane->type != PLANE_Z && !FBitSet( e->curstate.effects, EF_WATERSIDES )) continue; @@ -2312,7 +2312,7 @@ static void R_DrawLightmappedVBO( vboarray_t *vbo, vbotexture_t *vbotex, texture int sample_size; info = surf->info; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -2912,7 +2912,7 @@ static qboolean R_CheckLightMap( msurface_t *fa ) mextrasurf_t *info; info = fa->info; - sample_size = Mod_SampleSizeForFace( fa ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( fa ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; @@ -3302,7 +3302,7 @@ void R_DrawWorld( void ) // paranoia issues: when gl_renderer is "0" we need have something valid for currententity // to prevent crashing until HeadShield drawing. - RI.currententity = clgame.entities; + RI.currententity = gEngfuncs.GetEntityByIndex( 0 ); RI.currentmodel = RI.currententity->model; if( !RI.drawWorld || RI.onlyClientDraw ) @@ -3452,7 +3452,7 @@ void GL_CreateSurfaceLightmap( msurface_t *surf ) if( FBitSet( surf->flags, SURF_DRAWTILED )) return; - sample_size = Mod_SampleSizeForFace( surf ); + sample_size = gEngfuncs.Mod_SampleSizeForFace( surf ); smax = ( info->lightextents[0] / sample_size ) + 1; tmax = ( info->lightextents[1] / sample_size ) + 1; diff --git a/ref_gl/gl_sprite.c b/ref_gl/gl_sprite.c index 7a3431dc..606324a9 100644 --- a/ref_gl/gl_sprite.c +++ b/ref_gl/gl_sprite.c @@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ +#include "common.h" #include "gl_local.h" #include "pm_local.h" #include "sprite.h" @@ -493,7 +494,7 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw ) else if( frame >= psprite->numframes ) { if( frame > psprite->numframes ) - Con_Reportf( S_WARN "R_GetSpriteFrame: no such frame %d (%s)\n", frame, pModel->name ); + Con_Printf( S_WARN "R_GetSpriteFrame: no such frame %d (%s)\n", frame, pModel->name ); frame = psprite->numframes - 1; } @@ -510,7 +511,7 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw ) // 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; + targettime = gpGlobals->time - ((int)( gpGlobals->time / fullinterval )) * fullinterval; for( i = 0; i < (numframes - 1); i++ ) { @@ -574,25 +575,25 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, // this can be happens when rendering switched between single and angled frames // or change model on replace delta-entity ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 1.0f; } - if( ent->latched.sequencetime < cl.time ) + if( ent->latched.sequencetime < gpGlobals->time ) { if( frame != ent->latched.prevblending[1] ) { ent->latched.prevblending[0] = ent->latched.prevblending[1]; ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } - else lerpFrac = (cl.time - ent->latched.sequencetime) * 11.0f; + else lerpFrac = (gpGlobals->time - ent->latched.sequencetime) * 11.0f; } else { ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } } @@ -606,7 +607,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, { // reset interpolation on change model ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } @@ -621,7 +622,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, numframes = pspritegroup->numframes; fullinterval = pintervals[numframes-1]; jinterval = pintervals[1] - pintervals[0]; - time = cl.time; + time = gpGlobals->time; jtime = 0.0f; // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values @@ -660,25 +661,25 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe, // this can be happens when rendering switched between single and angled frames // or change model on replace delta-entity ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 1.0f; } - if( ent->latched.sequencetime < cl.time ) + if( ent->latched.sequencetime < gpGlobals->time ) { if( frame != ent->latched.prevblending[1] ) { ent->latched.prevblending[0] = ent->latched.prevblending[1]; ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } - else lerpFrac = (cl.time - ent->latched.sequencetime) * ent->curstate.framerate; + else lerpFrac = (gpGlobals->time - ent->latched.sequencetime) * ent->curstate.framerate; } else { ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; - ent->latched.sequencetime = cl.time; + ent->latched.sequencetime = gpGlobals->time; lerpFrac = 0.0f; } } @@ -746,7 +747,7 @@ static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, flo if( RP_NORMALPASS( )) { - tr = CL_VisTraceLine( RI.vieworg, origin, r_traceglow->value ? PM_GLASS_IGNORE : (PM_GLASS_IGNORE|PM_STUDIO_IGNORE)); + tr = gEngfuncs.EV_VisTraceLine( RI.vieworg, origin, r_traceglow->value ? PM_GLASS_IGNORE : (PM_GLASS_IGNORE|PM_STUDIO_IGNORE)); if(( 1.0f - tr->fraction ) * dist > 8.0f ) return 0.0f; diff --git a/ref_gl/gl_studio.c b/ref_gl/gl_studio.c index c0bc6c25..14b3a5c2 100644 --- a/ref_gl/gl_studio.c +++ b/ref_gl/gl_studio.c @@ -164,8 +164,8 @@ static void R_StudioSetupTimings( void ) if( RI.drawWorld ) { // synchronize with server time - g_studio.time = cl.time; - g_studio.frametime = cl.time - cl.oldtime; + g_studio.time = gpGlobals->time; + g_studio.frametime = gpGlobals->time - gpGlobals->oldtime; } else { @@ -186,7 +186,7 @@ static qboolean R_AllowFlipViewModel( cl_entity_t *e ) { if( cl_righthand && cl_righthand->value > 0 ) { - if( e == &clgame.viewent ) + if( e == gEngfuncs.GetViewModel() ) return true; } @@ -379,7 +379,7 @@ pfnMod_ForName */ static model_t *pfnMod_ForName( const char *model, int crash ) { - return Mod_ForName( model, crash, false ); + return gEngfuncs.Mod_ForName( model, crash, false ); } /* @@ -407,7 +407,7 @@ pfnGetViewEntity */ static cl_entity_t *pfnGetViewEntity( void ) { - return &clgame.viewent; + return gEngfuncs.GetViewModel(); } /* @@ -419,8 +419,8 @@ pfnGetEngineTimes static void pfnGetEngineTimes( int *framecount, double *current, double *old ) { if( framecount ) *framecount = tr.realframecount; - if( current ) *current = cl.time; - if( old ) *old = cl.oldtime; + if( current ) *current = gpGlobals->time; + if( old ) *old = gpGlobals->oldtime; } /* @@ -681,7 +681,7 @@ float CL_GetSequenceDuration( cl_entity_t *ent, int sequence ) if( ent->model != NULL && ent->model->type == mod_studio ) { - pstudiohdr = (studiohdr_t *)Mod_StudioExtradata( ent->model ); + pstudiohdr = (studiohdr_t *)gEngfuncs.Mod_Extradata( mod_studio, ent->model ); if( pstudiohdr ) { @@ -844,8 +844,8 @@ void R_StudioCalcRotations( cl_entity_t *e, float pos[][3], vec4_t *q, mstudiose for( i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++ ) { - R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] ); - R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] ); + gEngfuncs.R_StudioCalcBoneQuaternion( frame, s, pbone, panim, adj, q[i] ); + gEngfuncs.R_StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] ); } if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f; @@ -877,7 +877,7 @@ void R_StudioMergeBones( cl_entity_t *e, model_t *m_pSubModel ) f = R_StudioEstimateFrame( e, pseqdesc ); - panim = R_StudioGetAnim( m_pStudioHeader, m_pSubModel, pseqdesc ); + panim = gEngfuncs.R_StudioGetAnim( m_pStudioHeader, m_pSubModel, pseqdesc ); R_StudioCalcRotations( e, pos, q, pseqdesc, panim, f ); pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); @@ -943,7 +943,7 @@ void R_StudioSetupBones( cl_entity_t *e ) f = R_StudioEstimateFrame( e, pseqdesc ); - panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); + panim = gEngfuncs.R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); R_StudioCalcRotations( e, pos, q, pseqdesc, panim, f ); if( pseqdesc->numblends > 1 ) @@ -957,7 +957,7 @@ void R_StudioSetupBones( cl_entity_t *e ) dadt = R_StudioEstimateInterpolant( e ); s = (e->curstate.blending[0] * dadt + e->latched.prevblending[0] * (1.0f - dadt)) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q2, pos2, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q2, pos2, s ); if( pseqdesc->numblends == 4 ) { @@ -968,10 +968,10 @@ void R_StudioSetupBones( cl_entity_t *e ) R_StudioCalcRotations( e, pos4, q4, pseqdesc, panim, f ); s = (e->curstate.blending[0] * dadt + e->latched.prevblending[0] * (1.0f - dadt)) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q3, pos3, q4, pos4, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q3, pos3, q4, pos4, s ); s = (e->curstate.blending[1] * dadt + e->latched.prevblending[1] * (1.0f - dadt)) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q3, pos3, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q3, pos3, s ); } } @@ -983,7 +983,7 @@ void R_StudioSetupBones( cl_entity_t *e ) float s; pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->latched.prevsequence; - panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); + panim = gEngfuncs.R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); // clip prevframe R_StudioCalcRotations( e, pos1b, q1b, pseqdesc, panim, e->latched.prevframe ); @@ -994,7 +994,7 @@ void R_StudioSetupBones( cl_entity_t *e ) R_StudioCalcRotations( e, pos2, q2, pseqdesc, panim, e->latched.prevframe ); s = (e->latched.prevseqblending[0]) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q1b, pos1b, q2, pos2, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q1b, pos1b, q2, pos2, s ); if( pseqdesc->numblends == 4 ) { @@ -1005,15 +1005,15 @@ void R_StudioSetupBones( cl_entity_t *e ) R_StudioCalcRotations( e, pos4, q4, pseqdesc, panim, e->latched.prevframe ); s = (e->latched.prevseqblending[0]) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q3, pos3, q4, pos4, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q3, pos3, q4, pos4, s ); s = (e->latched.prevseqblending[1]) / 255.0f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q1b, pos1b, q3, pos3, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q1b, pos1b, q3, pos3, s ); } } s = 1.0f - ( g_studio.time - e->latched.sequencetime ) / 0.2f; - R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q1b, pos1b, s ); + gEngfuncs.R_StudioSlerpBones( m_pStudioHeader->numbones, q, pos, q1b, pos1b, s ); } else { @@ -1033,7 +1033,7 @@ void R_StudioSetupBones( cl_entity_t *e ) pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pPlayerInfo->gaitsequence; - panim = R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); + panim = gEngfuncs.R_StudioGetAnim( m_pStudioHeader, RI.currentmodel, pseqdesc ); R_StudioCalcRotations( e, pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe ); for( i = 0; i < m_pStudioHeader->numbones; i++ ) @@ -1824,7 +1824,7 @@ void R_StudioSetRenderamt( int iRenderamt ) if( !RI.currententity ) return; RI.currententity->curstate.renderamt = iRenderamt; - tr.blend = CL_FxBlend( RI.currententity ) / 255.0f; + tr.blend = gEngfuncs.CL_FxBlend( RI.currententity ) / 255.0f; } /* @@ -2251,7 +2251,7 @@ static void R_StudioDrawAbsBBox( void ) int i; // looks ugly, skip - if( RI.currententity == &clgame.viewent ) + if( RI.currententity == gEngfuncs.GetViewModel() ) return; if( !R_StudioComputeBBox( p )) @@ -2431,7 +2431,7 @@ static model_t *R_StudioSetupPlayerModel( int index ) Q_snprintf( state->modelname, sizeof( state->modelname ), "models/player/%s/%s.mdl", info->model, info->model ); - if( FS_FileExists( state->modelname, false )) + if( gEngfuncs.FS_FileExists( state->modelname, false )) state->model = Mod_ForName( state->modelname, false, true ); else state->model = NULL; @@ -2531,7 +2531,7 @@ static void R_StudioClientEvents( void ) ClearBits( e->curstate.effects, EF_MUZZLEFLASH ); VectorCopy( e->attachment[0], el->origin ); - el->die = cl.time + 0.05f; + el->die = gpGlobals->time + 0.05f; el->color.r = 255; el->color.g = 192; el->color.b = 64; @@ -3362,6 +3362,7 @@ R_RunViewmodelEvents void R_RunViewmodelEvents( void ) { int i; + vec3_t simorg; if( r_drawviewmodel->value == 0 ) return; @@ -3370,18 +3371,19 @@ void R_RunViewmodelEvents( void ) return; // ignore in thirdperson, camera view or client is died - if( !RP_NORMALPASS() || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 )) + if( !RP_NORMALPASS() || cl.local.health <= 0 || !CL_IsViewEntityLocalPlayer()) return; - RI.currententity = &clgame.viewent; + RI.currententity = gEngfuncs.GetViewModel(); if( !RI.currententity->model || RI.currententity->model->type != mod_studio ) return; R_StudioSetupTimings(); + gEngfuncs.GetPredictedOrigin( simorg ); for( i = 0; i < 4; i++ ) - VectorCopy( cl.simorg, RI.currententity->attachment[i] ); + VectorCopy( simorg, RI.currententity->attachment[i] ); RI.currentmodel = RI.currententity->model; R_StudioDrawModelInternal( RI.currententity, STUDIO_EVENTS ); @@ -3394,7 +3396,7 @@ R_GatherPlayerLight */ void R_GatherPlayerLight( void ) { - cl_entity_t *view = &clgame.viewent; + cl_entity_t *view = gEngfuncs.GetViewModel(); colorVec c; tr.ignore_lightgamma = true; @@ -3410,7 +3412,7 @@ R_DrawViewModel */ void R_DrawViewModel( void ) { - cl_entity_t *view = &clgame.viewent; + cl_entity_t *view = gEngfuncs.GetViewModel(); R_GatherPlayerLight(); @@ -3421,10 +3423,10 @@ void R_DrawViewModel( void ) return; // ignore in thirdperson, camera view or client is died - if( !RP_NORMALPASS() || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 )) + if( !RP_NORMALPASS() || cl.local.health <= 0 || !CL_IsViewEntityLocalPlayer()) return; - tr.blend = CL_FxBlend( view ) / 255.0f; + tr.blend = gEngfuncs.CL_FxBlend( view ) / 255.0f; if( !R_ModelOpaque( view->curstate.rendermode ) && tr.blend <= 0.0f ) return; // invisible ? diff --git a/ref_gl/gl_triapi.c b/ref_gl/gl_triapi.c index 7b68cd3f..a3ddc2f9 100644 --- a/ref_gl/gl_triapi.c +++ b/ref_gl/gl_triapi.c @@ -113,28 +113,6 @@ void TriEnd( void ) pglEnd( ); } -/* -============= -_TriColor4f - -============= -*/ -void _TriColor4f( float r, float g, float b, float a ) -{ - pglColor4f( r, g, b, a ); -} - -/* -============= -_TriColor4ub - -============= -*/ -void _TriColor4ub( byte r, byte g, byte b, byte a ) -{ - pglColor4ub( r, g, b, a ); -} - /* ============= TriColor4f @@ -143,14 +121,7 @@ TriColor4f */ void TriColor4f( float r, float g, float b, float a ) { - if( engine.TriGetRenderMode() == kRenderTransAlpha ) - RefTriAPI->Color4ub( r * 255.9f, g * 255.9f, b * 255.9f, a * 255.0f ); - else RefTriAPI->Color4f( r * a, g * a, b * a, 1.0 ); - - clgame.ds.triRGBA[0] = r; - clgame.ds.triRGBA[1] = g; - clgame.ds.triRGBA[2] = b; - clgame.ds.triRGBA[3] = a; + pglColor4f( r, g, b, a ); } /* @@ -161,12 +132,7 @@ TriColor4ub */ void TriColor4ub( byte r, byte g, byte b, byte a ) { - clgame.ds.triRGBA[0] = r * (1.0f / 255.0f); - clgame.ds.triRGBA[1] = g * (1.0f / 255.0f); - clgame.ds.triRGBA[2] = b * (1.0f / 255.0f); - clgame.ds.triRGBA[3] = a * (1.0f / 255.0f); - - pglColor4f( clgame.ds.triRGBA[0], clgame.ds.triRGBA[1], clgame.ds.triRGBA[2], 1.0f ); + pglColor4ub( r, g, b, a ); } /* @@ -317,7 +283,7 @@ TriCullFace ============= */ -void _TriCullFace( TRICULLSTYLE mode ) +void TriCullFace( TRICULLSTYLE mode ) { int glMode; diff --git a/ref_gl/gl_warp.c b/ref_gl/gl_warp.c index c0b8542e..c3b3214c 100644 --- a/ref_gl/gl_warp.c +++ b/ref_gl/gl_warp.c @@ -79,7 +79,7 @@ static int CheckSkybox( const char *name ) { // build side name sidename = va( "%s%s.%s", name, r_skyBoxSuffix[j], skybox_ext[i] ); - if( FS_FileExists( sidename, false )) + if( gEngfuncs.FS_FileExists( sidename, false )) num_checked_sides++; } @@ -91,7 +91,7 @@ static int CheckSkybox( const char *name ) { // build side name sidename = va( "%s_%s.%s", name, r_skyBoxSuffix[j], skybox_ext[i] ); - if( FS_FileExists( sidename, false )) + if( gEngfuncs.FS_FileExists( sidename, false )) num_checked_sides++; } @@ -502,7 +502,7 @@ void R_CloudTexCoord( vec3_t v, float speed, float *s, float *t ) float length, speedscale; vec3_t dir; - speedscale = cl.time * speed; + speedscale = gpGlobals->time * speed; speedscale -= (int)speedscale & ~127; VectorSubtract( v, RI.vieworg, dir ); @@ -787,8 +787,8 @@ void EmitWaterPolys( msurface_t *warp, qboolean reverse ) { if( waveHeight ) { - nv = r_turbsin[(int)(cl.time * 160.0f + v[1] + v[0]) & 255] + 8.0f; - nv = (r_turbsin[(int)(v[0] * 5.0f + cl.time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv; + nv = r_turbsin[(int)(gpGlobals->time * 160.0f + v[1] + v[0]) & 255] + 8.0f; + nv = (r_turbsin[(int)(v[0] * 5.0f + gpGlobals->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv; nv = nv * waveHeight + v[2]; } else nv = v[2]; @@ -796,10 +796,10 @@ void EmitWaterPolys( msurface_t *warp, qboolean reverse ) os = v[3]; ot = v[4]; - s = os + r_turbsin[(int)((ot * 0.125f + cl.time) * TURBSCALE) & 255]; + s = os + r_turbsin[(int)((ot * 0.125f + gpGlobals->time) * TURBSCALE) & 255]; s *= ( 1.0f / SUBDIVIDE_SIZE ); - t = ot + r_turbsin[(int)((os * 0.125f + cl.time) * TURBSCALE) & 255]; + t = ot + r_turbsin[(int)((os * 0.125f + gpGlobals->time) * TURBSCALE) & 255]; t *= ( 1.0f / SUBDIVIDE_SIZE ); pglTexCoord2f( s, t ); diff --git a/ref_gl/wscript b/ref_gl/wscript index f06c5b90..b91061a1 100644 --- a/ref_gl/wscript +++ b/ref_gl/wscript @@ -20,6 +20,8 @@ def configure(conf): if conf.options.SUPPORT_BSP2_FORMAT: conf.env.append_unique('DEFINES', 'SUPPORT_BSP2_FORMAT') + conf.env.append_unique('DEFINES', 'REF_DLL') + def build(bld): if bld.env.DEDICATED: return @@ -41,7 +43,7 @@ def build(bld): '../pm_shared' ] bld.shlib( - source = source, + source = source, target = name, features = 'c', includes = includes,