forked from fte/fteqw
1
0
Fork 0

xonotic: fix 'sticky walls' issue when spectating.

xonotic: fix jumppads not working while onground.
attempt to parse meag's protocol changes, in case we get a .qwd from ezquake. does not report them to servers at this time.
added cl_fullpitch cvar. only affects nq servers that lack serverinfo.
support dds/ktx-based cubemaps, including for skyboxes.
recognise multiple new compressed texture formats - bc1-7, etc1+2+eac,.astc. Addeded to supporting drivers/apis.
software decoder for etc2,bc4+bc5 textures, so they can be considered universal (but with fallbacks).
software decoder for bc1-bc3 textures, but disabled due to lingering patent paranoia.
report heartbeats once, by default.
r_viewmodel_fov support for vk+d3d9+d3d11 renderers.
fix depth projection differences with various renderers (min dist is now consistent).
added some code to announce when cl_delay_packets changes.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5188 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2017-12-28 16:24:50 +00:00
parent 6d9c3f5df0
commit 845bb231ca
55 changed files with 11191 additions and 9563 deletions

View File

@ -407,19 +407,34 @@ void CLQW_ParseDelta (entity_state_t *from, entity_state_t *to, int bits)
to->effects = (to->effects&0xff00)|MSG_ReadByte();
if (bits & U_ORIGIN1)
{
if (cls.ezprotocolextensions1 & EZPEXT1_FLOATENTCOORDS)
to->origin[0] = MSG_ReadCoordFloat ();
else
to->origin[0] = MSG_ReadCoord ();
}
if (bits & U_ANGLE1)
to->angles[0] = MSG_ReadAngle ();
if (bits & U_ORIGIN2)
{
if (cls.ezprotocolextensions1 & EZPEXT1_FLOATENTCOORDS)
to->origin[1] = MSG_ReadCoordFloat ();
else
to->origin[1] = MSG_ReadCoord ();
}
if (bits & U_ANGLE2)
to->angles[1] = MSG_ReadAngle ();
if (bits & U_ORIGIN3)
{
if (cls.ezprotocolextensions1 & EZPEXT1_FLOATENTCOORDS)
to->origin[1] = MSG_ReadCoordFloat ();
else
to->origin[2] = MSG_ReadCoord ();
}
if (bits & U_ANGLE3)
to->angles[2] = MSG_ReadAngle ();
@ -4420,7 +4435,7 @@ void CL_MVDUpdateSpectator(void)
}
void CL_ParsePlayerinfo (void)
void CLQW_ParsePlayerinfo (void)
{
float msec;
unsigned int flags;
@ -4571,9 +4586,18 @@ void CL_ParsePlayerinfo (void)
state->flags = flags;
state->messagenum = cl.parsecount;
if (cls.ezprotocolextensions1 & EZPEXT1_FLOATENTCOORDS)
{
org[0] = MSG_ReadCoordFloat ();
org[1] = MSG_ReadCoordFloat ();
org[2] = MSG_ReadCoordFloat ();
}
else
{
org[0] = MSG_ReadCoord ();
org[1] = MSG_ReadCoord ();
org[2] = MSG_ReadCoord ();
}
VectorCopy(org, state->origin);

View File

@ -64,6 +64,7 @@ cvar_t cl_nopext = CVARF("cl_nopext", "0", CVAR_ARCHIVE);
cvar_t cl_pext_mask = CVAR("cl_pext_mask", "0xffffffff");
cvar_t cl_nolerp = CVARD("cl_nolerp", "0", "Disables interpolation. If set, missiles/monsters will be show exactly what was last received, which will be jerky. Does not affect players. A value of 2 means 'interpolate only in single-player/coop'.");
cvar_t cl_nolerp_netquake = CVARD("cl_nolerp_netquake", "0", "Disables interpolation when connected to an NQ server. Does affect players, even the local player. You probably don't want to set this.");
cvar_t cl_fullpitch_nq = CVARAFD("cl_fullpitch", "0", "pq_fullpitch", CVAR_SEMICHEAT, "When set, attempts to unlimit the default view pitch. Note that some servers will screw over your angles if you use this, resulting in terrible gameplay, while some may merely clamp your angle serverside. This is also considered a cheat in quakeworld, so this will not function there. For the equivelent in quakeworld, use serverinfo minpitch+maxpitch instead, which applies to all players fairly.");
cvar_t *hud_tracking_show;
cvar_t *hud_miniscores_show;
extern cvar_t net_compress;
@ -417,6 +418,7 @@ void CL_ConnectToDarkPlaces(char *challenge, netadr_t *adr)
char data[2048];
cls.fteprotocolextensions = 0;
cls.fteprotocolextensions2 = 0;
cls.ezprotocolextensions1 = 0;
cls.resendinfo = false;
@ -2157,10 +2159,10 @@ void CL_CheckServerInfo(void)
// Initialize cl.maxpitch & cl.minpitch
if (cls.protocol == CP_QUAKEWORLD || cls.protocol == CP_NETQUAKE)
{
s = (cls.z_ext & Z_EXT_PITCHLIMITS) ? Info_ValueForKey (cl.serverinfo, "maxpitch") : "";
cl.maxpitch = *s ? Q_atof(s) : 80.0f;
s = (cls.z_ext & Z_EXT_PITCHLIMITS) ? Info_ValueForKey (cl.serverinfo, "minpitch") : "";
cl.minpitch = *s ? Q_atof(s) : -70.0f;
s = Info_ValueForKey (cl.serverinfo, "maxpitch");
cl.maxpitch = *s ? Q_atof(s) : ((cl_fullpitch_nq.ival && !cl.haveserverinfo)?90.0f:80.0f);
s = Info_ValueForKey (cl.serverinfo, "minpitch");
cl.minpitch = *s ? Q_atof(s) : ((cl_fullpitch_nq.ival && !cl.haveserverinfo)?-90.0f:-70.0f);
if (cls.protocol == CP_NETQUAKE)
{ //proquake likes spamming us with fixangles
@ -3477,6 +3479,7 @@ void CLNQ_ConnectionlessPacket(void)
cls.fteprotocolextensions = connectinfo.fteext1;
cls.fteprotocolextensions2 = connectinfo.fteext2;
cls.ezprotocolextensions1 = 0;
Netchan_Setup (NS_CLIENT, &cls.netchan, &net_from, connectinfo.qport);
CL_ParseEstablished();
cls.netchan.isnqprotocol = true;
@ -4221,6 +4224,9 @@ void CL_Init (void)
Cvar_Register (&cl_nolerp, "Item effects");
Cvar_Register (&cl_nolerp_netquake, "Item effects");
#ifdef NQPROT
Cvar_Register (&cl_fullpitch_nq, "Cheats");
#endif
Cvar_Register (&r_drawflame, "Item effects");

View File

@ -3013,8 +3013,9 @@ static void CLQW_ParseServerData (void)
// parse protocol version number
// allow 2.2 and 2.29 demos to play
#ifdef PROTOCOL_VERSION_FTE
cls.fteprotocolextensions=0;
cls.fteprotocolextensions2=0;
cls.fteprotocolextensions = 0;
cls.fteprotocolextensions2 = 0;
cls.ezprotocolextensions1 = 0;
for(;;)
{
protover = MSG_ReadLong ();
@ -3028,6 +3029,11 @@ static void CLQW_ParseServerData (void)
cls.fteprotocolextensions2 = MSG_ReadLong();
continue;
}
if (protover == PROTOCOL_VERSION_EZQUAKE1)
{
cls.ezprotocolextensions1 = MSG_ReadLong();
continue;
}
if (protover == PROTOCOL_VERSION_VARLENGTH)
{
int ident;
@ -3059,9 +3065,11 @@ static void CLQW_ParseServerData (void)
Host_EndGame ("Server returned version %i, not %i\n", protover, PROTOCOL_VERSION_QW);
#endif
if (cls.fteprotocolextensions2||cls.fteprotocolextensions)
if (developer.ival || cl_shownet.ival)
{
if (cls.fteprotocolextensions2||cls.fteprotocolextensions)
Con_TPrintf ("Using FTE extensions 0x%x%08x\n", cls.fteprotocolextensions2, cls.fteprotocolextensions);
}
if (cls.fteprotocolextensions & PEXT_FLOATCOORDS)
{
@ -3313,6 +3321,7 @@ static void CLQ2_ParseServerData (void)
cls.netchan.netprim.anglesize = 1;
cls.fteprotocolextensions = 0;
cls.fteprotocolextensions2 = 0;
cls.ezprotocolextensions1 = 0;
cls.demohadkeyframe = true; //assume that it did, so this stuff all gets recorded.
Con_DPrintf ("Serverdata packet %s.\n", cls.demoplayback?"read":"received");
@ -3479,6 +3488,7 @@ static void CLNQ_ParseProtoVersion(void)
cls.fteprotocolextensions = 0;
cls.fteprotocolextensions2 = 0;
cls.ezprotocolextensions1 = 0;
for(;;)
{
protover = MSG_ReadLong ();
@ -6713,6 +6723,8 @@ void CLQW_ParseServerMessage (void)
else
{
inframe_t *inf = &cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK];
if (cls.ezprotocolextensions1 & EZPEXT1_SETANGLEREASON)
MSG_ReadByte(); //0=unknown, 1=tele, 2=spawn
for (i=0 ; i<3 ; i++)
ang[i] = MSG_ReadAngle();
if (!CSQC_Parse_SetAngles(destsplit, ang, false))
@ -6963,7 +6975,7 @@ void CLQW_ParseServerMessage (void)
break;
case svc_playerinfo:
CL_ParsePlayerinfo ();
CLQW_ParsePlayerinfo ();
break;
case svc_nails:

View File

@ -2698,11 +2698,11 @@ static void SCR_ScreenShot_Mega_f(void)
}
if (!fbwidth)
fbwidth = sh_config.texture_maxsize;
fbwidth = bound(1, fbwidth, sh_config.texture_maxsize);
fbwidth = sh_config.texture2d_maxsize;
fbwidth = bound(1, fbwidth, sh_config.texture2d_maxsize);
if (!fbheight)
fbheight = (fbwidth * 3)/4;
fbheight = bound(1, fbheight, sh_config.texture_maxsize);
fbheight = bound(1, fbheight, sh_config.texture2d_maxsize);
if (strstr (screenyname, "..") || strchr(screenyname, ':') || *screenyname == '.' || *screenyname == '/')
screenyname = "";
@ -2799,8 +2799,8 @@ static void SCR_ScreenShot_VR_f(void)
if (width <= 2)
width = 2048;
if (width > sh_config.texture_maxsize)
width = sh_config.texture_maxsize;
if (width > sh_config.texture2d_maxsize)
width = sh_config.texture2d_maxsize;
height = width/2;
if (step <= 0)
step = 5;

View File

@ -278,7 +278,7 @@ sfx_t *cl_sfx_ric2;
sfx_t *cl_sfx_ric3;
sfx_t *cl_sfx_r_exp3;
cvar_t cl_expsprite = CVARFD("cl_expsprite", "0", CVAR_ARCHIVE, "Display a central sprite in explosion effects. QuakeWorld typically does so, NQ mods should not (which is problematic when played with the qw protocol).");
cvar_t cl_expsprite = CVARFD("cl_expsprite", "1", CVAR_ARCHIVE, "Display a central sprite in explosion effects. QuakeWorld typically does so, NQ mods should not (which is problematic when played with the qw protocol).");
cvar_t r_explosionlight = CVARFC("r_explosionlight", "1", CVAR_ARCHIVE, Cvar_Limiter_ZeroToOne_Callback);
cvar_t cl_truelightning = CVARF("cl_truelightning", "0", CVAR_SEMICHEAT);
cvar_t cl_beam_trace = CVAR("cl_beam_trace", "0");

View File

@ -442,6 +442,7 @@ typedef struct
#ifdef PROTOCOLEXTENSIONS
unsigned int fteprotocolextensions;
unsigned int fteprotocolextensions2;
unsigned int ezprotocolextensions1;
#endif
unsigned int z_ext;
@ -953,8 +954,16 @@ extern unsigned int cl_enemybottomcolor;
//FPD values
//(commented out ones are ones that we don't support)
#define FPD_NO_FORCE_SKIN 256
#define FPD_NO_FORCE_COLOR 512
//#define FPD_NO_SAY_MACROS (1 << 0)
//#define FPD_NO_TIMERS (1 << 1)
//#define FPD_NO_SOUNDTRIGGERS (1 << 2)
#define FPD_NO_FAKE_LAG (1 << 3)
#define FPD_ANOUNCE_FAKE_LAG (1 << 4)
//#define FPD_HIDE_ENEMY_VICINITY (1 << 5)
//#define FPD_NO_SPEC_CHAT (1 << 6)
//#define FPD_HIDE_X_Y_MACRO (1 << 7)
#define FPD_NO_FORCE_SKIN (1 << 8)
#define FPD_NO_FORCE_COLOR (1 << 9)
#define FPD_LIMIT_PITCH (1 << 14) //limit scripted pitch changes
#define FPD_LIMIT_YAW (1 << 15) //limit scripted yaw changes
@ -1336,7 +1345,7 @@ void CLQW_ParsePacketEntities (qboolean delta);
void CLFTE_ParseEntities (void);
void CLFTE_ParseBaseline(entity_state_t *es, qboolean numberisimportant);
void CL_SetSolidEntities (void);
void CL_ParsePlayerinfo (void);
void CLQW_ParsePlayerinfo (void);
void CL_ParseClientPersist(void);
//these last ones are needed for csqc handling of engine-bound ents.
void CL_ClearEntityLists(void);

File diff suppressed because it is too large Load Diff

View File

@ -736,6 +736,7 @@ const char *presetexec[] =
"seta r_part_classic_square 0;"
"seta r_part_classic_expgrav 10;"
"seta r_part_classic_opaque 0;"
"seta cl_expsprite 1;"
"seta r_stains 0;"
"seta r_drawflat 1;"
"seta r_lightmap 0;"

View File

@ -303,22 +303,74 @@ struct pendingtextureinfo
PTI_ARGB4444, //16bit format (d3d)
PTI_RGBA5551, //16bit alpha format (gl).
PTI_ARGB1555, //16bit alpha format (d3d).
PTI_RGB8, //24bit packed format. generally not supported
PTI_LUMINANCE8_ALPHA8, //16bit format.
//floating point formats
PTI_RGBA16F,
PTI_RGBA32F,
//small formats.
PTI_R8,
PTI_RG8,
//(desktop) compressed formats
PTI_S3RGB1,
PTI_S3RGBA1,
PTI_S3RGBA3,
PTI_S3RGBA5,
//(mobile) compressed formats
PTI_RG8, //might be useful for normalmaps
PTI_R8_SIGNED,
PTI_RG8_SIGNED, //might be useful for normalmaps
//(desktop/tegra) compressed formats
PTI_BC1_RGB,
PTI_BC1_RGB_SRGB,
PTI_BC1_RGBA,
PTI_BC1_RGBA_SRGB,
PTI_BC2_RGBA,
PTI_BC2_RGBA_SRGB,
PTI_BC3_RGBA, //maybe add a bc3 normalmapswizzle type for d3d9?
PTI_BC3_RGBA_SRGB,
PTI_BC4_R8,
PTI_BC4_R8_SIGNED,
PTI_BC5_RG8, //useful for normalmaps
PTI_BC5_RG8_SIGNED, //useful for normalmaps
PTI_BC6_RGBF, //unsigned (half) floats!
PTI_BC6_RGBF_SIGNED, //signed (half) floats!
PTI_BC7_RGBA, //multimode compression, using as many bits as bc2/bc3
PTI_BC7_RGBA_SRGB,
//(mobile/intel) compressed formats
PTI_ETC1_RGB8, //limited form
PTI_ETC2_RGB8, //extended form
PTI_ETC2_RGB8A1,
PTI_ETC2_RGB8A8,
PTI_ETC2_RGB8_SRGB,
PTI_ETC2_RGB8A1_SRGB,
PTI_ETC2_RGB8A8_SRGB,
PTI_EAC_R11, //no idea what this might be used for, whatever
PTI_EAC_R11_SIGNED, //no idea what this might be used for, whatever
PTI_EAC_RG11, //useful for normalmaps (calculate blue)
PTI_EAC_RG11_SIGNED, //useful for normalmaps (calculate blue)
//astc... zomg
PTI_ASTC_4X4,
PTI_ASTC_4X4_SRGB,
PTI_ASTC_5X4,
PTI_ASTC_5X4_SRGB,
PTI_ASTC_5X5,
PTI_ASTC_5X5_SRGB,
PTI_ASTC_6X5,
PTI_ASTC_6X5_SRGB,
PTI_ASTC_6X6,
PTI_ASTC_6X6_SRGB,
PTI_ASTC_8X5,
PTI_ASTC_8X5_SRGB,
PTI_ASTC_8X6,
PTI_ASTC_8X6_SRGB,
PTI_ASTC_10X5,
PTI_ASTC_10X5_SRGB,
PTI_ASTC_10X6,
PTI_ASTC_10X6_SRGB,
PTI_ASTC_8X8,
PTI_ASTC_8X8_SRGB,
PTI_ASTC_10X8,
PTI_ASTC_10X8_SRGB,
PTI_ASTC_10X10,
PTI_ASTC_10X10_SRGB,
PTI_ASTC_12X10,
PTI_ASTC_12X10_SRGB,
PTI_ASTC_12X12,
PTI_ASTC_12X12_SRGB,
//weird specialcase mess to take advantage of webgl so we don't need redundant bloat where we're already strugging with potential heap limits
PTI_WHOLEFILE,
//depth formats
@ -328,6 +380,7 @@ struct pendingtextureinfo
PTI_DEPTH24_8,
PTI_MAX,
} encoding; //0
void *extrafree;
int mipcount;
struct
{
@ -336,8 +389,7 @@ struct pendingtextureinfo
int width;
int height;
qboolean needfree;
} mip[32];
void *extrafree;
} mip[72]; //enough for a 4096 cubemap. or a really smegging big 2d texture...
};
//small context for easy vbo creation.

View File

@ -76,6 +76,7 @@ typedef struct {
cvar_t cv;
char *comment;
qboolean announced; //when set, hide when sv_reportheartbeats 2
qboolean needsresolve; //set any time the cvar is modified
qboolean resolving; //set any time the cvar is modified
netadr_t adr[MAX_MASTER_ADDRESSES];
@ -245,7 +246,11 @@ void SV_Master_SingleHeartbeat(net_masterlist_t *master)
}
if (sv_reportheartbeats.value)
{
if (sv_reportheartbeats.ival != 2 || !master->announced)
Con_TPrintf ("Sending heartbeat to %s (%s)\n", NET_AdrToString (adr, sizeof(adr), na), master->cv.string);
master->announced = true;
}
NET_SendPacket (NS_SERVER, strlen(string), string, na);
}
@ -255,7 +260,11 @@ void SV_Master_SingleHeartbeat(net_masterlist_t *master)
if (svs.gametype == GT_QUAKE2 && sv_listen_qw.value) //set listen to 1 to allow qw connections, 2 to allow nq connections too.
{
if (sv_reportheartbeats.value)
{
if (sv_reportheartbeats.ival != 2 || !master->announced)
Con_TPrintf ("Sending heartbeat to %s (%s)\n", NET_AdrToString (adr, sizeof(adr), na), master->cv.string);
master->announced = true;
}
{
char *str = "\377\377\377\377heartbeat\n%s";
@ -269,7 +278,11 @@ void SV_Master_SingleHeartbeat(net_masterlist_t *master)
if (sv_listen_dp.value || sv_listen_nq.value) //set listen to 1 to allow qw connections, 2 to allow nq connections too.
{
if (sv_reportheartbeats.value)
{
if (sv_reportheartbeats.ival != 2 || !master->announced)
Con_TPrintf ("Sending heartbeat to %s (%s)\n", NET_AdrToString (adr, sizeof(adr), na), master->cv.string);
master->announced = true;
}
{
//darkplaces here refers to the master server protocol, rather than the game protocol

View File

@ -395,7 +395,7 @@ void R2D_Init(void)
atlas.shader = NULL;
atlas.data = NULL;
atlas.dirty = false;
Mod_LightmapAllocInit(&atlas.allocation, false, min(512, sh_config.texture_maxsize), min(512, sh_config.texture_maxsize), 0);
Mod_LightmapAllocInit(&atlas.allocation, false, min(512, sh_config.texture2d_maxsize), min(512, sh_config.texture2d_maxsize), 0);
}
mpic_t *R2D_SafeCachePic (const char *path)
@ -1161,7 +1161,12 @@ void R2D_Console_Resize(void)
}
if (!cwidth && !cheight)
{
if (vid.dpi_y)
cheight = (480 * 96) / vid.dpi_y;
else
cheight = 480;
}
if (cheight && !cwidth && vid.rotpixelheight)
cwidth = (cheight*vid.rotpixelwidth)/vid.rotpixelheight;
if (cwidth && !cheight && vid.rotpixelwidth)

View File

@ -448,6 +448,7 @@ void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, in
void Image_Purge(void); //purge any textures which are not needed any more (releases memory, but doesn't give null pointers).
void Image_Init(void);
void Image_Shutdown(void);
void Image_BlockSizeForEncoding(unsigned int encoding, unsigned int *blockbytes, unsigned int *blockwidth, unsigned int *blockheight);
image_t *Image_LoadTexture (const char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags);

View File

@ -224,7 +224,7 @@ cvar_t scr_conspeed = CVAR ("scr_conspeed", "2000");
// 10 - 170
cvar_t scr_fov = CVARFCD("fov", "90", CVAR_ARCHIVE, SCR_Fov_Callback,
"field of vision, 1-170 degrees, standard fov is 90, nquake defaults to 108.");
cvar_t scr_fov_viewmodel = CVARFCD("r_viewmodel_fov", "", CVAR_ARCHIVE, SCR_Fov_Callback,
cvar_t scr_fov_viewmodel = CVARFD("r_viewmodel_fov", "", CVAR_ARCHIVE,
"field of vision, 1-170 degrees, standard fov is 90, nquake defaults to 108.");
cvar_t scr_printspeed = CVAR ("scr_printspeed", "16");
cvar_t scr_showpause = CVAR ("showpause", "1");
@ -377,7 +377,6 @@ cvar_t gl_overbright_all = CVARF ("gl_overbright_all", "0",
cvar_t gl_picmip = CVARFD ("gl_picmip", "0", CVAR_ARCHIVE, "Reduce world/model texture sizes by some exponential factor.");
cvar_t gl_picmip2d = CVARFD ("gl_picmip2d", "0", CVAR_ARCHIVE, "Reduce hud/menu texture sizes by some exponential factor.");
cvar_t gl_nohwblend = CVARD ("gl_nohwblend","1", "If 1, don't use hardware gamma ramps for transient effects that change each frame (does not affect long-term effects like holding quad or underwater tints).");
cvar_t gl_savecompressedtex = CVARD ("gl_savecompressedtex", "0", "Write out a copy of textures in a compressed format. The driver will do the compression on the fly, thus this setting is likely inferior to software which does not care so much about compression times.");
//cvar_t gl_schematics = CVARD ("gl_schematics", "0", "Gimmick rendering mode that draws the length of various world edges.");
cvar_t gl_skyboxdist = CVARD ("gl_skyboxdist", "0", "The distance of the skybox. If 0, the engine will determine it based upon the far clip plane distance."); //0 = guess.
cvar_t gl_smoothcrosshair = CVAR ("gl_smoothcrosshair", "1");
@ -518,7 +517,6 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_picmip2d, GLRENDEREROPTIONS);
Cvar_Register (&r_shaderblobs, GLRENDEREROPTIONS);
Cvar_Register (&gl_savecompressedtex, GLRENDEREROPTIONS);
Cvar_Register (&gl_compress, GLRENDEREROPTIONS);
// Cvar_Register (&gl_detail, GRAPHICALNICETIES);
// Cvar_Register (&gl_detailscale, GRAPHICALNICETIES);
@ -1370,8 +1368,8 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
pmove.numphysent = 0;
pmove.physents[0].model = NULL;
vid.dpi_x = 0;
vid.dpi_y = 0;
vid.dpi_x = 96;
vid.dpi_y = 96;
#ifndef CLIENTONLY
sv.world.lastcheckpvs = NULL;
@ -2693,56 +2691,60 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
float scale;
int i;
float mvp[16];
mplane_t *p;
if (r_novis.ival & 4)
return;
Matrix4_Multiply(projmat, viewmat, mvp);
r_refdef.frustum_numplanes = 0;
for (i = 0; i < 4; i++)
{
//each of the four side planes
p = &r_refdef.frustum[r_refdef.frustum_numplanes++];
if (i & 1)
{
r_refdef.frustum[i].normal[0] = mvp[3] + mvp[0+i/2];
r_refdef.frustum[i].normal[1] = mvp[7] + mvp[4+i/2];
r_refdef.frustum[i].normal[2] = mvp[11] + mvp[8+i/2];
r_refdef.frustum[i].dist = mvp[15] + mvp[12+i/2];
p->normal[0] = mvp[3] + mvp[0+i/2];
p->normal[1] = mvp[7] + mvp[4+i/2];
p->normal[2] = mvp[11] + mvp[8+i/2];
p->dist = mvp[15] + mvp[12+i/2];
}
else
{
r_refdef.frustum[i].normal[0] = mvp[3] - mvp[0+i/2];
r_refdef.frustum[i].normal[1] = mvp[7] - mvp[4+i/2];
r_refdef.frustum[i].normal[2] = mvp[11] - mvp[8+i/2];
r_refdef.frustum[i].dist = mvp[15] - mvp[12+i/2];
p->normal[0] = mvp[3] - mvp[0+i/2];
p->normal[1] = mvp[7] - mvp[4+i/2];
p->normal[2] = mvp[11] - mvp[8+i/2];
p->dist = mvp[15] - mvp[12+i/2];
}
scale = 1/sqrt(DotProduct(r_refdef.frustum[i].normal, r_refdef.frustum[i].normal));
r_refdef.frustum[i].normal[0] *= scale;
r_refdef.frustum[i].normal[1] *= scale;
r_refdef.frustum[i].normal[2] *= scale;
r_refdef.frustum[i].dist *= -scale;
scale = 1/sqrt(DotProduct(p->normal, p->normal));
p->normal[0] *= scale;
p->normal[1] *= scale;
p->normal[2] *= scale;
p->dist *= -scale;
r_refdef.frustum[i].type = PLANE_ANYZ;
r_refdef.frustum[i].signbits = SignbitsForPlane (&r_refdef.frustum[i]);
p->type = PLANE_ANYZ;
p->signbits = SignbitsForPlane (p);
}
r_refdef.frustum_numplanes = 4;
//the near clip plane.
p = &r_refdef.frustum[r_refdef.frustum_numplanes++];
r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] = mvp[3] - mvp[2];
r_refdef.frustum[r_refdef.frustum_numplanes].normal[1] = mvp[7] - mvp[6];
r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] = mvp[11] - mvp[10];
r_refdef.frustum[r_refdef.frustum_numplanes].dist = mvp[15] - mvp[14];
p->normal[0] = mvp[3] - mvp[2];
p->normal[1] = mvp[7] - mvp[6];
p->normal[2] = mvp[11] - mvp[10];
p->dist = mvp[15] - mvp[14];
scale = 1/sqrt(DotProduct(r_refdef.frustum[r_refdef.frustum_numplanes].normal, r_refdef.frustum[r_refdef.frustum_numplanes].normal));
r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] *= scale;
r_refdef.frustum[r_refdef.frustum_numplanes].normal[1] *= scale;
r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] *= scale;
r_refdef.frustum[r_refdef.frustum_numplanes].dist *= -scale;
scale = 1/sqrt(DotProduct(p->normal, p->normal));
p->normal[0] *= scale;
p->normal[1] *= scale;
p->normal[2] *= scale;
p->dist *= -scale;
r_refdef.frustum[r_refdef.frustum_numplanes].type = PLANE_ANYZ;
r_refdef.frustum[r_refdef.frustum_numplanes].signbits = SignbitsForPlane (&r_refdef.frustum[4]);
r_refdef.frustum_numplanes++;
p->type = PLANE_ANYZ;
p->signbits = SignbitsForPlane (p);
r_refdef.frustum_numworldplanes = r_refdef.frustum_numplanes;
@ -2773,21 +2775,21 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
culldist = culldist / (-r_refdef.globalfog.density);
//anything drawn beyond this point is fully obscured by fog
r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] = mvp[3] - mvp[2];
r_refdef.frustum[r_refdef.frustum_numplanes].normal[1] = mvp[7] - mvp[6];
r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] = mvp[11] - mvp[10];
r_refdef.frustum[r_refdef.frustum_numplanes].dist = mvp[15] - mvp[14];
p = &r_refdef.frustum[r_refdef.frustum_numplanes++];
p->normal[0] = mvp[3] - mvp[2];
p->normal[1] = mvp[7] - mvp[6];
p->normal[2] = mvp[11] - mvp[10];
p->dist = mvp[15] - mvp[14];
scale = 1/sqrt(DotProduct(r_refdef.frustum[r_refdef.frustum_numplanes].normal, r_refdef.frustum[r_refdef.frustum_numplanes].normal));
r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] *= -scale;
r_refdef.frustum[r_refdef.frustum_numplanes].normal[1] *= -scale;
r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] *= -scale;
// r_refdef.frustum[r_refdef.frustum_numplanes].dist *= scale;
r_refdef.frustum[r_refdef.frustum_numplanes].dist = DotProduct(r_origin, r_refdef.frustum[r_refdef.frustum_numplanes].normal)-culldist;
scale = 1/sqrt(DotProduct(p->normal, p->normal));
p->normal[0] *= -scale;
p->normal[1] *= -scale;
p->normal[2] *= -scale;
// p->dist *= scale;
p->dist = DotProduct(r_origin, p->normal)-culldist;
r_refdef.frustum[r_refdef.frustum_numplanes].type = PLANE_ANYZ;
r_refdef.frustum[r_refdef.frustum_numplanes].signbits = SignbitsForPlane (&r_refdef.frustum[r_refdef.frustum_numplanes]);
r_refdef.frustum_numplanes++;
p->type = PLANE_ANYZ;
p->signbits = SignbitsForPlane (p);
}
}
#else

View File

@ -872,6 +872,20 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
{
char newname[MAX_QPATH];
console_t *edit;
if (!strncmp(filename, "./", 2))
filename+=2;
stepasm = !line || *line < 0;
//we can cope with no line info by displaying asm
if (editormodal || (stepasm && !statement))
{
if (fatal)
return DEBUG_TRACE_ABORT;
return DEBUG_TRACE_OFF; //whoops
}
if (!pr_debugger.ival)
{
Con_Printf("Set %s to trace\n", pr_debugger.name);
@ -880,26 +894,20 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
return DEBUG_TRACE_OFF; //get lost
}
if (!strncmp(filename, "./", 2))
filename+=2;
//we can cope with no line info by displaying asm
if (editormodal || !statement
|| !line || *line == -1 //FIXME
)
{
if (fatal)
return DEBUG_TRACE_ABORT;
return DEBUG_TRACE_OFF; //whoops
}
if (qrenderer == QR_NONE)
if (qrenderer == QR_NONE || stepasm)
{ //just dump the line of code that's being execed onto the console.
int i;
char buffer[8192];
char *r;
vfsfile_t *f;
if (stepasm)
{
prfncs->GenerateStatementString(prfncs, *statement, buffer, sizeof(buffer));
Con_Printf("%s", buffer);
return DEBUG_TRACE_INTO;
}
if (!line)
{ //please don't crash
if (fatal)
@ -924,10 +932,9 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
return DEBUG_TRACE_OUT; //only display the line itself.
}
stepasm = !line;
editprogfuncs = prfncs;
if (!COM_FCheckExists(filename))
if (!stepasm && *filename && !COM_FCheckExists(filename))
{
//people generally run their qcc from $mod/src/ or so, so paths are usually relative to that instead of the mod directory.
//this means we now need to try and guess what the user used.
@ -963,19 +970,19 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
}
if (filename != newname)
{
stepasm = true;
if (fatal)
{
Con_Printf(CON_ERROR "Unable to find file \"%s\"\n", filename);
return DEBUG_TRACE_ABORT;
}
else
Con_Printf(CON_WARNING "Unable to find file \"%s\"\n", filename);
return DEBUG_TRACE_OFF; //whoops
}
}
if (stepasm)
{
return DEBUG_TRACE_OFF;
if (fatal)
return DEBUG_TRACE_ABORT;
return DEBUG_TRACE_OFF; //whoops
}
else
{

View File

@ -293,8 +293,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define R_XFLIP //allow view to be flipped horizontally
#define TEXTEDITOR
#define IMAGEFMT_KTX //Khronos TeXture. common on gles3 devices for etc2 compression
#define IMAGEFMT_PKM //file format generally written by etcpack or android's etc1tool
#define IMAGEFMT_DDS //a sort of image file format.
#define IMAGEFMT_BLP //a sort of image file format.
#define DECOMPRESS_ETC2 //decompress etc2(core in gles3/gl4.3) if the graphics driver doesn't support it (eg d3d or crappy gpus with vulkan).
// #define DECOMPRESS_S3TC //allows bc1-3 to work even when drivers don't support it. This is probably only an issue on mobile chips. WARNING: not entirely sure if all patents expired yet...
#define DECOMPRESS_RGTC //bc4+bc5
#ifndef RTLIGHTS
#define RTLIGHTS //realtime lighting
#endif

View File

@ -1711,6 +1711,12 @@ float MSG_ReadCoord24 (void)
MSG_ReadData(&c, 3);
return MSG_FromCoord(c, 3);
}
float MSG_ReadCoordFloat (void)
{
coorddata c = {{0}};
MSG_ReadData(&c, 4);
return MSG_FromCoord(c, 4);
}
void MSG_ReadPos (vec3_t pos)
{

View File

@ -290,6 +290,7 @@ char *MSG_ReadString (void);
char *MSG_ReadStringLine (void);
float MSG_ReadCoord (void);
float MSG_ReadCoordFloat (void);
void MSG_ReadPos (float *pos);
float MSG_ReadAngle (void);
float MSG_ReadAngle16 (void);

View File

@ -127,7 +127,7 @@ typedef struct cvar_group_s
#define CVAR_NOTFROMSERVER (1<<7) //cvar cannot be set by gamecode. the console will ignore changes to cvars if set at from the server or any gamecode. This is to protect against security flaws - like qterm
#define CVAR_USERCREATED (1<<8) //write a 'set' or 'seta' in front of the var name.
#define CVAR_CHEAT (1<<9) //latch to the default, unless cheats are enabled.
#define CVAR_SEMICHEAT (1<<10) //if strict ruleset, force to 0/blank.
#define CVAR_SEMICHEAT (1<<10) //if strict ruleset, force to blank (aka 0).
#define CVAR_RENDERERLATCH (1<<11) //requires a vid_restart to reapply.
#define CVAR_SERVEROVERRIDE (1<<12) //the server has overridden out local value - should probably be called SERVERLATCH
#define CVAR_RENDERERCALLBACK (1<<13) //force callback for cvars on renderer change

View File

@ -3511,7 +3511,7 @@ static void CModQ3_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l)
maps /= 2;
{
int limit = min(sh_config.texture_maxsize / loadmodel->lightmaps.height, 16);//mod_mergeq3lightmaps.ival);
int limit = min(sh_config.texture2d_maxsize / loadmodel->lightmaps.height, 16);//mod_mergeq3lightmaps.ival);
loadmodel->lightmaps.merge = 1;
while (loadmodel->lightmaps.merge*2 <= limit && loadmodel->lightmaps.merge < maps)
loadmodel->lightmaps.merge *= 2;
@ -5881,6 +5881,19 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
VectorCopy (mins, trace_mins);
VectorCopy (maxs, trace_maxs);
if (1)
{
VectorAdd(trace_maxs, trace_mins, point);
VectorScale(point, 0.5, point);
VectorAdd(trace_start, point, trace_start);
VectorAdd(trace_end, point, trace_end);
VectorSubtract(trace_mins, point, trace_mins);
VectorSubtract(trace_maxs, point, trace_maxs);
}
// build a bounding box of the entire move (for patches)
ClearBounds (trace_absmins, trace_absmaxs);
@ -5890,8 +5903,8 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
trace_shape = shape_ispoint;
VectorSet (trace_extents, 1/32.0, 1/32.0, 1/32.0);
//acedemic
AddPointToBounds (start, trace_absmins, trace_absmaxs);
AddPointToBounds (end, trace_absmins, trace_absmaxs);
AddPointToBounds (trace_start, trace_absmins, trace_absmaxs);
AddPointToBounds (trace_end, trace_absmins, trace_absmaxs);
}
else if (capsule)
{
@ -5909,24 +5922,24 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
trace_extents[2] = ext+1;
//determine the total range
VectorSubtract (start, trace_extents, point);
VectorSubtract (trace_start, trace_extents, point);
AddPointToBounds (point, trace_absmins, trace_absmaxs);
VectorAdd (start, trace_extents, point);
VectorAdd (trace_start, trace_extents, point);
AddPointToBounds (point, trace_absmins, trace_absmaxs);
VectorSubtract (end, trace_extents, point);
VectorSubtract (trace_end, trace_extents, point);
AddPointToBounds (point, trace_absmins, trace_absmaxs);
VectorAdd (end, trace_extents, point);
VectorAdd (trace_end, trace_extents, point);
AddPointToBounds (point, trace_absmins, trace_absmaxs);
}
else
{
VectorAdd (start, trace_mins, point);
VectorAdd (trace_start, trace_mins, point);
AddPointToBounds (point, trace_absmins, trace_absmaxs);
VectorAdd (start, trace_maxs, point);
VectorAdd (trace_start, trace_maxs, point);
AddPointToBounds (point, trace_absmins, trace_absmaxs);
VectorAdd (end, trace_mins, point);
VectorAdd (trace_end, trace_mins, point);
AddPointToBounds (point, trace_absmins, trace_absmaxs);
VectorAdd (end, trace_maxs, point);
VectorAdd (trace_end, trace_maxs, point);
AddPointToBounds (point, trace_absmins, trace_absmaxs);
trace_shape = shape_isbox;
@ -5969,8 +5982,8 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
vec3_t c1, c2;
int topnode;
VectorAdd (start, mins, c1);
VectorAdd (start, maxs, c2);
VectorAdd (trace_start, mins, c1);
VectorAdd (trace_start, maxs, c2);
for (i=0 ; i<3 ; i++)
{
c1[i] -= 1;
@ -5998,7 +6011,7 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
if (trace_nearfraction == 1)
{
trace_trace.fraction = 1;
VectorCopy (trace_end, trace_trace.endpos);
VectorCopy (end, trace_trace.endpos);
}
else
{
@ -6006,7 +6019,7 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
trace_nearfraction=0;
trace_trace.fraction = trace_nearfraction;
for (i=0 ; i<3 ; i++)
trace_trace.endpos[i] = trace_start[i] + trace_trace.fraction * (trace_end[i] - trace_start[i]);
trace_trace.endpos[i] = start[i] + trace_trace.fraction * (end[i] - start[i]);
}
return trace_trace;
}

View File

@ -1321,9 +1321,10 @@ void Matrix4x4_Identity(float *outm)
outm[15] = 1;
}
void Matrix4x4_CM_Projection_Far(float *proj, float fovx, float fovy, float neard, float fard)
void Matrix4x4_CM_Projection_Far(float *proj, float fovx, float fovy, float neard, float fard, qboolean d3d)
{
double xmin, xmax, ymin, ymax;
double dn = (d3d?0:-1), df = 1;
//proj
ymax = neard * tan( fovy * M_PI / 360.0 );
@ -1352,8 +1353,8 @@ void Matrix4x4_CM_Projection_Far(float *proj, float fovx, float fovy, float near
proj[2] = 0;
proj[6] = 0;
proj[10] = (fard+neard)/(neard-fard);
proj[14] = (2*fard*neard)/(neard-fard);
proj[10] = (fard*df-neard*dn)/(neard-fard);
proj[14] = ((df-dn)*fard*neard)/(neard-fard);
proj[3] = 0;
proj[7] = 0;
@ -1361,10 +1362,10 @@ void Matrix4x4_CM_Projection_Far(float *proj, float fovx, float fovy, float near
proj[15] = 0;
}
void Matrix4x4_CM_Projection_Inf(float *proj, float fovx, float fovy, float neard)
void Matrix4x4_CM_Projection_Inf(float *proj, float fovx, float fovy, float neard, qboolean d3d)
{
float xmin, xmax, ymin, ymax;
float nudge = 1;
double dn = (d3d?0:-1), df = 1;
//proj
ymax = neard * tan( fovy * M_PI / 360.0 );
@ -1391,10 +1392,29 @@ void Matrix4x4_CM_Projection_Inf(float *proj, float fovx, float fovy, float near
proj[9] = (ymax + ymin) / (ymax - ymin);
proj[13] = 0;
#if 1
{
const double epsilon = 1.0/(1<<22);
proj[2] = 0;
proj[6] = 0;
proj[10] = epsilon-1;
proj[14] = (epsilon-(df-dn))*neard;
}
#elif 1
{ //mathematical target
const float fard = (1<<22);
proj[2] = 0;
proj[6] = 0;
proj[10] = (fard*df-neard*dn)/(neard-fard);
proj[14] = ((df-dn)*fard*neard)/(neard-fard);
}
#else
//old logic
proj[2] = 0;
proj[6] = 0;
proj[10] = -1 * ((float)(1<<21)/(1<<22));
proj[14] = -2*neard * nudge;
proj[14] = -2*neard;
#endif
proj[3] = 0;
proj[7] = 0;
@ -1793,7 +1813,7 @@ void Matrix4x4_CM_UnProject(const vec3_t in, vec3_t out, const vec3_t viewangles
float tempm[16];
Matrix4x4_CM_ModelViewMatrix(modelview, viewangles, vieworg);
Matrix4x4_CM_Projection_Inf(proj, fovx, fovy, 4);
Matrix4x4_CM_Projection_Inf(proj, fovx, fovy, 4, true);
Matrix4_Multiply(proj, modelview, tempm);
Matrix4_Invert(tempm, proj);
@ -1828,7 +1848,7 @@ qboolean Matrix4x4_CM_Project (const vec3_t in, vec3_t out, const vec3_t viewang
float proj[16];
Matrix4x4_CM_ModelViewMatrix(modelview, viewangles, vieworg);
Matrix4x4_CM_Projection_Inf(proj, fovx, fovy, 4);
Matrix4x4_CM_Projection_Inf(proj, fovx, fovy, 4, true);
{
float v[4], tempv[4];

View File

@ -184,9 +184,9 @@ void QuaternionSlerp(const vec4_t p, vec4_t q, float t, vec4_t qt);
//projection matricies of different types... gesh
void Matrix4x4_CM_Orthographic (float *proj, float xmin, float xmax, float ymax, float ymin, float znear, float zfar);
void Matrix4x4_CM_OrthographicD3D(float *proj, float xmin, float xmax, float ymax, float ymin, float znear, float zfar);
void Matrix4x4_CM_Projection_Far(float *proj, float fovx, float fovy, float neard, float fard);
void Matrix4x4_CM_Projection_Far(float *proj, float fovx, float fovy, float neard, float fard, qboolean d3d);
void Matrix4x4_CM_Projection2 (float *proj, float fovx, float fovy, float neard);
void Matrix4x4_CM_Projection_Inf(float *proj, float fovx, float fovy, float neard);
void Matrix4x4_CM_Projection_Inf(float *proj, float fovx, float fovy, float neard, qboolean d3d);
fixed16_t Mul16_30 (fixed16_t multiplier, fixed16_t multiplicand);
int Q_log2 (int val);

View File

@ -102,7 +102,15 @@ cvar_t net_enable_http = CVARD("net_enable_http", "1", "If enabled, tcp port
cvar_t net_enable_websockets = CVARD("net_enable_websockets", "1", "If enabled, tcp ports will accept websocket game clients.");
cvar_t net_enable_webrtcbroker = CVARD("net_enable_webrtcbroker", "1", "If 1, tcp ports will accept websocket connections from clients trying to broker direct webrtc connections. This should be low traffic, but might involve a lot of mostly-idle connections.");
#endif
cvar_t cl_delay_packets = CVARD("cl_delay_packets", "0", "Extra latency, in milliseconds.");
#ifndef SERVERONLY
static void cl_delay_packets_Announce(cvar_t *var, char *oldval)
{
if (cls.state >= ca_connected && cl.fpd & FPD_ANOUNCE_FAKE_LAG)
Cbuf_AddText(va("say Fake lag now %ims\n", var->ival), RESTRICT_LOCAL);
}
static cvar_t cl_delay_packets = CVARCD("cl_delay_packets", "0", cl_delay_packets_Announce, "Extra latency, in milliseconds.");
#endif
extern cvar_t sv_public, sv_listen_qw, sv_listen_nq, sv_listen_dp;
#ifdef QWOVERQ3
@ -6570,13 +6578,13 @@ neterr_t NET_SendPacket (netsrc_t netsrc, int length, const void *data, netadr_t
#else
collection = cls.sockets;
if (cl_delay_packets.value >= 1)
if (cl_delay_packets.ival >= 1 && !(cl.fpd & FPD_NO_FAKE_LAG))
{
struct ftenet_delayed_packet_s *p, **l;
if (!collection)
return NETERR_NOROUTE; //erk...
p = BZ_Malloc(sizeof(*p) - sizeof(p->data) + length);
p->sendtime = Sys_Milliseconds() + (int)cl_delay_packets.value;
p->sendtime = Sys_Milliseconds() + cl_delay_packets.ival;
p->next = NULL;
p->cursize = length;
p->dest = *to;
@ -7313,12 +7321,12 @@ void NET_Init (void)
Cvar_Register(&net_hybriddualstack, "networking");
Cvar_Register(&net_fakeloss, "networking");
Cvar_Register(&cl_delay_packets, "networking");
#ifndef CLIENTONLY
Cmd_AddCommand("sv_addport", SVNET_AddPort_f);
#endif
#ifndef SERVERONLY
Cvar_Register(&cl_delay_packets, "networking");
Cmd_AddCommand("cl_addport", NET_ClientPort_f);
#endif

View File

@ -773,6 +773,14 @@ void PM_AirMove (void)
vec3_t wishdir;
float wishspeed;
if (pmove.gravitydir[2] == -1 && (pmove.angles[0] == 90 || pmove.angles[0] == -90))
{ //HACK: attempt to avoid a stupid numerical precision issue.
//You know its a hack because I'm comparing exact angles.
vec3_t tmp;
VectorSet(tmp, pmove.angles[0]*0.99, pmove.angles[1], pmove.angles[2]);
AngleVectors (tmp, forward, right, up);
}
fmove = pmove.cmd.forwardmove;
smove = pmove.cmd.sidemove;
VectorMA(forward, -DotProduct(forward, pmove.gravitydir), pmove.gravitydir, forward); //z=0

View File

@ -53,7 +53,7 @@ void PF_Common_RegisterCvars(void)
_mm_setcsr(mxcsr & ~(0x8040));
}
else
Con_Printf(CON_WARNING "WARNING: denormalised floats are disabled. Use -nodaz to re-enable if mods malfunction\n");
Con_Printf(CON_WARNING "denormalised floats are disabled. Use -nodaz to re-enable if mods malfunction\n");
}
#else
volatile union
@ -64,7 +64,7 @@ void PF_Common_RegisterCvars(void)
a.i = 1;
b.i = 1;
if (!(a.f && b.f))
Con_Printf(CON_WARNING "WARNING: denormalised floats are disabled. Some mods might may malfunction\n");
Con_Printf(CON_WARNING "denormalised floats are disabled. Some mods might may malfunction\n");
#endif
#endif

View File

@ -78,6 +78,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PEXT2_PREDINFO 0x00000020 //movevar stats, NQ input sequences+acks.
#define PEXT2_NEWSIZEENCODING 0x00000040 //richer size encoding.
//EzQuake/Mvdsv extensions
#define EZPEXT1_FLOATENTCOORDS 0x00000001 //quirky - doesn't apply to broadcasts, just players+ents. this gives more precision, but will bug out if you try using it to increase map bounds in ways that may not be immediately apparent. iiuc this was added instead of fixing some inconsistent rounding...
#define EZPEXT1_SETANGLEREASON 0x00000002 //specifies the reason for an svc_setangles call. the mvdsv implementation will fuck over any mods that writebyte them. we'd need to modify our preparse stuff to work around the issue.
//ZQuake transparent protocol extensions.
#define Z_EXT_PM_TYPE (1<<0) // basic PM_TYPE functionality (reliable jump_held)
#define Z_EXT_PM_TYPE_NEW (1<<1) // adds PM_FLY, PM_SPECTATOR
@ -102,6 +106,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PROTOCOL_VERSION_FTE (('F'<<0) + ('T'<<8) + ('E'<<16) + ('X' << 24)) //fte extensions.
#define PROTOCOL_VERSION_FTE2 (('F'<<0) + ('T'<<8) + ('E'<<16) + ('2' << 24)) //fte extensions.
#define PROTOCOL_VERSION_EZQUAKE1 (('M'<<0) + ('V'<<8) + ('D'<<16) + ('1' << 24)) //ezquake/mvdsv extensions
#define PROTOCOL_VERSION_HUFFMAN (('H'<<0) + ('U'<<8) + ('F'<<16) + ('F' << 24)) //packet compression
#define PROTOCOL_VERSION_FRAGMENT (('F'<<0) + ('R'<<8) + ('A'<<16) + ('G' << 24)) //supports fragmentation/packets larger than 1450
#ifdef HAVE_DTLS

View File

@ -2748,21 +2748,21 @@ batch_t *D3D11BE_GetTempBatch(void)
return &shaderstate.wbatches[shaderstate.wbatch++];
}
float projd3dtogl[16] =
/*static float projd3dtogl[16] =
{
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 2.0, 0.0,
0.0, 0.0, -1.0, 1.0
};
float projgltod3d[16] =
};*/
static float projgltod3d[16] =
{
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.0, 0.0, 0.5, 1.0
};
void D3D11BE_SetupViewCBuffer(void)
static void D3D11BE_SetupViewCBuffer(void)
{
cbuf_view_t *cbv;
D3D11_MAPPED_SUBRESOURCE msr;
@ -2778,7 +2778,7 @@ void D3D11BE_SetupViewCBuffer(void)
//d3d uses 0 to 1 depth.
//so we scale the projection matrix by a bias
#if 1
Matrix4_Multiply(projgltod3d, r_refdef.m_projection_std, cbv->m_projection);
Matrix4_Multiply(projgltod3d, (shaderstate.depthrange<1)?r_refdef.m_projection_view:r_refdef.m_projection_std, cbv->m_projection);
#else
memcpy(cbv->m_projection, r_refdef.m_projection_std, sizeof(cbv->m_projection));
cbv->m_projection[10] = r_refdef.m_projection_std[10] * 0.5;
@ -2789,6 +2789,20 @@ void D3D11BE_SetupViewCBuffer(void)
ID3D11DeviceContext_Unmap(d3ddevctx, (ID3D11Resource*)shaderstate.vcbuffer, 0);
}
void D3D11BE_Set2D(void)
{
D3D11_VIEWPORT vport;
vport.TopLeftX = 0;
vport.TopLeftY = 0;
vport.Width = vid.pixelwidth;
vport.Height = vid.pixelheight;
vport.MinDepth = 0;
vport.MaxDepth = shaderstate.depthrange = 1;
ID3D11DeviceContext_RSSetViewports(d3ddevctx, 1, &vport);
D3D11BE_SetupViewCBuffer();
D3D11BE_Scissor(NULL);
}
void D3D11BE_SetupLightCBuffer(dlight_t *l, vec3_t colour)
{
extern cvar_t gl_specular;
@ -3096,6 +3110,8 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
vport.MinDepth = 0;
vport.MaxDepth = shaderstate.depthrange;
ID3D11DeviceContext_RSSetViewports(d3ddevctx, 1, &vport);
D3D11BE_SetupViewCBuffer();
}
}

View File

@ -111,8 +111,7 @@ static void Upload_Texture_32(ID3D11Texture2D *tex, unsigned int *data, int data
qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mips)
{
int bytesperpixel = 4;
int bcbytes = 0;
unsigned int blockbytes, blockwidth, blockheight;
HRESULT hr;
D3D11_TEXTURE2D_DESC tdesc = {0};
D3D11_SUBRESOURCE_DATA subresdesc[sizeof(mips->mip) / sizeof(mips->mip[0])];
@ -159,92 +158,108 @@ qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mi
case PTI_DEPTH16:
tdesc.Format = DXGI_FORMAT_D16_UNORM;
tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
bytesperpixel = 2;
break;
case PTI_DEPTH24:
tdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
bytesperpixel = 3;
break;
case PTI_DEPTH32:
tdesc.Format = DXGI_FORMAT_D32_FLOAT;
tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
bytesperpixel = 4;
break;
case PTI_DEPTH24_8:
tdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
bytesperpixel = 4;
break;
case PTI_RGB565:
tdesc.Format = DXGI_FORMAT_B5G6R5_UNORM;
bytesperpixel = 2;
break;
// case PTI_RGBA5551:
// tdesc.Format = DXGI_FORMAT_A1B5G5R5_UNORM;
// bytesperpixel = 2;
// break;
case PTI_ARGB1555:
tdesc.Format = DXGI_FORMAT_B5G5R5A1_UNORM;
bytesperpixel = 2;
break;
case PTI_RGBA4444:
tdesc.Format = DXGI_FORMAT_B4G4R4A4_UNORM;
bytesperpixel = 2;
break;
// case PTI_ARGB4444:
// tdesc.Format = DXGI_FORMAT_A4B4G4R4_UNORM;
// bytesperpixel = 2;
// break;
case PTI_RGBA8:
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bytesperpixel = 4;
break;
case PTI_RGBX8: //d3d11 has no alphaless format. be sure to proprly disable alpha in the shader.
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bytesperpixel = 4;
break;
case PTI_BGRA8:
tdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
bytesperpixel = 4;
break;
case PTI_BGRX8:
tdesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
bytesperpixel = 4;
break;
case PTI_RGBA8_SRGB:
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
bytesperpixel = 4;
break;
case PTI_RGBX8_SRGB: //d3d11 has no alphaless format. be sure to proprly disable alpha in the shader.
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
bytesperpixel = 4;
break;
case PTI_BGRA8_SRGB:
tdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
bytesperpixel = 4;
break;
case PTI_BGRX8_SRGB:
tdesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
bytesperpixel = 4;
break;
case PTI_S3RGB1: //d3d11 provides no way to disable alpha with dxt1. be sure to proprly disable alpha in the shader.
case PTI_S3RGBA1:
case PTI_BC1_RGB: //d3d11 provides no way to disable alpha with dxt1. be sure to proprly disable alpha in the shader.
case PTI_BC1_RGBA:
tdesc.Format = DXGI_FORMAT_BC1_UNORM;
bcbytes = 8;
break;
case PTI_S3RGBA3:
case PTI_BC2_RGBA:
tdesc.Format = DXGI_FORMAT_BC2_UNORM;
bcbytes = 16;
break;
case PTI_S3RGBA5:
case PTI_BC3_RGBA:
tdesc.Format = DXGI_FORMAT_BC3_UNORM;
bcbytes = 16;
break;
case PTI_BC1_RGB_SRGB: //d3d11 provides no way to disable alpha with dxt1. be sure to proprly disable alpha in the shader.
case PTI_BC1_RGBA_SRGB:
tdesc.Format = DXGI_FORMAT_BC1_UNORM_SRGB;
break;
case PTI_BC2_RGBA_SRGB:
tdesc.Format = DXGI_FORMAT_BC2_UNORM_SRGB;
break;
case PTI_BC3_RGBA_SRGB:
tdesc.Format = DXGI_FORMAT_BC3_UNORM_SRGB;
break;
case PTI_BC4_R8:
tdesc.Format = DXGI_FORMAT_BC4_UNORM;
break;
case PTI_BC4_R8_SIGNED:
tdesc.Format = DXGI_FORMAT_BC4_SNORM;
break;
case PTI_BC5_RG8:
tdesc.Format = DXGI_FORMAT_BC5_UNORM;
break;
case PTI_BC5_RG8_SIGNED:
tdesc.Format = DXGI_FORMAT_BC5_SNORM;
break;
case PTI_BC6_RGBF:
tdesc.Format = DXGI_FORMAT_BC6H_UF16;
break;
case PTI_BC6_RGBF_SIGNED:
tdesc.Format = DXGI_FORMAT_BC6H_SF16;
break;
case PTI_BC7_RGBA:
tdesc.Format = DXGI_FORMAT_BC7_UNORM;
break;
case PTI_BC7_RGBA_SRGB:
tdesc.Format = DXGI_FORMAT_BC7_UNORM_SRGB;
break;
}
Image_BlockSizeForEncoding(mips->encoding, &blockbytes, &blockwidth, &blockheight);
if (!mips->mip[0].data)
{
subresdesc[0].pSysMem = NULL;
@ -256,17 +271,9 @@ qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mi
for (i = 0; i < mips->mipcount; i++)
{
subresdesc[i].pSysMem = mips->mip[i].data;
if (bcbytes)
{
subresdesc[i].SysMemPitch = ((mips->mip[i].width+3)/4) * bcbytes;
subresdesc[i].SysMemPitch = ((mips->mip[i].width+blockwidth-1)/blockwidth) * blockbytes;
subresdesc[i].SysMemSlicePitch = mips->mip[i].datasize;
}
else
{
subresdesc[i].SysMemPitch = mips->mip[i].width*bytesperpixel;
subresdesc[i].SysMemSlicePitch = mips->mip[i].datasize;//mips->mip[i].width*mips->mip[i].height*bytesperpixel;
}
}
tdesc.MipLevels = i/tdesc.ArraySize;
}

View File

@ -34,29 +34,25 @@ qboolean D3D8_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
D3DSURFACE_DESC desc;
IDirect3DTexture8 *dt;
qboolean swap = false;
unsigned int pixelsize = 4;
unsigned int blocksize = 0;
unsigned int blockwidth, blockheight, blockbytes = 1;
switch(mips->encoding)
{
case PTI_RGB565:
pixelsize = 2;
fmt = D3DFMT_R5G6B5;
break;
case PTI_RGBA4444://not supported on d3d9
return false;
case PTI_ARGB4444:
pixelsize = 2;
fmt = D3DFMT_A4R4G4B4;
break;
case PTI_RGBA5551://not supported on d3d9
return false;
case PTI_ARGB1555:
pixelsize = 2;
fmt = D3DFMT_A1R5G5B5;
break;
case PTI_RGBA8:
// fmt = D3DFMT_A8B8G8R8; /*how do we check
// fmt = D3DFMT_A8B8G8R8; //how do we check
fmt = D3DFMT_A8R8G8B8;
swap = true;
break;
@ -73,24 +69,23 @@ qboolean D3D8_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
break;
//too lazy to support these for now
case PTI_S3RGB1:
case PTI_S3RGBA1: //d3d doesn't distinguish between these
case PTI_BC1_RGB:
case PTI_BC1_RGBA: //d3d doesn't distinguish between these
fmt = D3DFMT_DXT1;
blocksize = 8;
break;
case PTI_S3RGBA3:
case PTI_BC2_RGBA:
fmt = D3DFMT_DXT3;
blocksize = 16;
break;
case PTI_S3RGBA5:
case PTI_BC3_RGBA:
fmt = D3DFMT_DXT5;
blocksize = 16;
break;
default: //no idea
return false;
}
Image_BlockSizeForEncoding(mips->encoding, &blockbytes, &blockwidth, &blockheight);
if (!pD3DDev8)
return false; //can happen on errors
if (FAILED(IDirect3DDevice8_CreateTexture(pD3DDev8, mips->mip[0].width, mips->mip[0].height, mips->mipcount, 0, fmt, D3DPOOL_MANAGED, &dt)))
@ -110,17 +105,12 @@ qboolean D3D8_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
//can't do it in one go. pitch might contain padding or be upside down.
if (!mips->mip[i].data)
;
else if (blocksize)
{
if (lock.Pitch == ((mips->mip[i].width+3)/4)*blocksize)
//for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*pixelsize)
memcpy(lock.pBits, mips->mip[i].data, mips->mip[i].datasize);
}
else if (swap)
{
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*4)
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += rowbytes)
{
for (x = 0; x < mips->mip[i].width*4; x+=4)
for (x = 0; x < rowbytes; x+=4)
{
out[x+0] = in[x+2];
out[x+1] = in[x+1];
@ -131,8 +121,9 @@ qboolean D3D8_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
}
else
{
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*pixelsize)
memcpy(out, in, mips->mip[i].width*pixelsize);
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+blockheight, out += lock.Pitch, in += rowbytes)
memcpy(out, in, rowbytes);
}
IDirect3DTexture8_UnlockRect(dt, i);
}

View File

@ -54,9 +54,10 @@ extern LPDIRECT3DDEVICE9 pD3DDev9;
#define MAX_TC_TMUS 4
extern texid_t r_whiteimage;
extern float d3d_trueprojection[16];
extern float d3d_trueprojection_std[16];
extern float d3d_trueprojection_view[16];
static void BE_RotateForEntity (const entity_t *e, const model_t *mod);
static void D3D9BE_RotateForEntity (const entity_t *e, const model_t *mod);
/*========================================== tables for deforms =====================================*/
#define frand() (rand()*(1.0/RAND_MAX))
@ -158,6 +159,9 @@ typedef struct
backendmode_t mode;
unsigned int flags;
D3DVIEWPORT9 vport;
float *curprojection;
float curtime;
const entity_t *curentity;
const dlight_t *curdlight;
@ -671,6 +675,7 @@ void D3D9BE_Init(void)
be_maxpasses = MAX_TMUS;
memset(&shaderstate, 0, sizeof(shaderstate));
shaderstate.curvertdecl = -1;
shaderstate.curentity = &r_worldentity;
FTable_Init();
@ -693,6 +698,20 @@ void D3D9BE_Set2D(void)
shaderstate.curtime = r_refdef.time;
}
void D3D9BE_SetViewport(int x, int w, int y, int h)
{
shaderstate.vport.X = x;
shaderstate.vport.Y = y;
shaderstate.vport.Width = w;
shaderstate.vport.Height = h;
shaderstate.vport.MinZ = 0;
shaderstate.vport.MaxZ = 1;
IDirect3DDevice9_SetViewport(pD3DDev9, &shaderstate.vport);
shaderstate.curprojection = d3d_trueprojection_std;
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)shaderstate.curprojection);
}
static void allocvertexbuffer(IDirect3DVertexBuffer9 *buff, unsigned int bmaxsize, unsigned int *offset, void **data, unsigned int bytes)
{
unsigned int boff;
@ -1677,14 +1696,7 @@ static void deformgen(const deformv_t *deformv, int cnt, vecV_t *src, vecV_t *ds
for (j = 0; j < 3; j++)
rot_centre[j] = (quad[0][j] + quad[1][j] + quad[2][j] + quad[3][j]) * 0.25;
if (shaderstate.curentity)
{
VectorAdd(shaderstate.curentity->origin, rot_centre, tv);
}
else
{
VectorCopy(rot_centre, tv);
}
VectorSubtract(r_origin, tv, tv);
// filter any longest-axis-parts off the camera-direction
@ -1863,7 +1875,7 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
switch (pp->type)
{
case SP_M_PROJECTION:
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, d3d_trueprojection, 4);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, shaderstate.curprojection, 4);
break;
case SP_M_VIEW:
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, r_refdef.m_view, 4);
@ -1898,7 +1910,7 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
{
float mv[16], mvp[16];
Matrix4_Multiply(r_refdef.m_view, shaderstate.m_model, mv);
Matrix4_Multiply(d3d_trueprojection, mv, mvp);
Matrix4_Multiply(shaderstate.curprojection, mv, mvp);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, mvp, 4);
}
break;
@ -2048,7 +2060,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in
// if (p->permu[perm|PERMUTATION_DELUXE].h.loaded && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
// perm |= PERMUTATION_DELUXE;
#if MAXRLIGHTMAPS > 1
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].h.loaded)
if (shaderstate.curbatch && shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].h.loaded)
perm |= PERMUTATION_LIGHTSTYLES;
#endif
@ -2544,7 +2556,7 @@ qboolean D3D9BE_SelectDLight(dlight_t *dl, vec3_t colour, vec3_t axis[3], unsign
void D3D9BE_SelectEntity(entity_t *ent)
{
shaderstate.curentity = ent;
BE_RotateForEntity(ent, ent->model);
D3D9BE_RotateForEntity(ent, ent->model);
}
#if 1
@ -2983,10 +2995,11 @@ batch_t *D3D9BE_GetTempBatch(void)
return &shaderstate.wbatches[shaderstate.wbatch++];
}
static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
static void D3D9BE_RotateForEntity (const entity_t *e, const model_t *mod)
{
// float mv[16];
float *m = shaderstate.m_model;
float maxz;
shaderstate.curentity = e;
@ -3147,11 +3160,22 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m);
if (e->flags & RF_DEPTHHACK)
maxz = 0.333;
else
maxz = 1;
if (shaderstate.vport.MaxZ != maxz)
{
D3DVIEWPORT9 vport;
IDirect3DDevice9_GetViewport(pD3DDev9, &vport);
vport.MaxZ = (e->flags & RF_DEPTHHACK)?0.333:1;
IDirect3DDevice9_SetViewport(pD3DDev9, &vport);
shaderstate.vport.MaxZ = maxz;
if (maxz < 1)
shaderstate.curprojection = d3d_trueprojection_view;
else
shaderstate.curprojection = d3d_trueprojection_std;
IDirect3DDevice9_SetViewport(pD3DDev9, &shaderstate.vport);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)shaderstate.curprojection);
}
}
@ -3163,7 +3187,7 @@ void D3D9BE_SubmitBatch(batch_t *batch)
return;
if (shaderstate.curentity != batch->ent)
{
BE_RotateForEntity(batch->ent, batch->ent->model);
D3D9BE_RotateForEntity(batch->ent, batch->ent->model);
shaderstate.curtime = r_refdef.time - shaderstate.curentity->shaderTime;
}
shaderstate.batchvbo = batch->vbo;
@ -3379,7 +3403,7 @@ static void TransformDir(vec3_t in, vec3_t planea[3], vec3_t viewa[3], vec3_t re
}
static void R_RenderScene(void)
{
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection);
// IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view);
R_SetFrustum (r_refdef.m_projection_std, r_refdef.m_view);
Surf_DrawWorld();
@ -3491,7 +3515,7 @@ static void R_DrawPortal(batch_t *batch, batch_t **blist)
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection);
// IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view);
R_SetFrustum (r_refdef.m_projection_std, r_refdef.m_view);
}
@ -3603,7 +3627,7 @@ void D3D9BE_DrawWorld (batch_t **worldbatches)
batch_t *batches[SHADER_SORT_COUNT];
RSpeedLocals();
shaderstate.curentity = NULL;
shaderstate.curentity = &r_worldentity;
if (!r_refdef.recurse)
{
@ -3677,7 +3701,7 @@ void D3D9BE_DrawWorld (batch_t **worldbatches)
R_RenderDlights ();
BE_RotateForEntity(&r_worldentity, NULL);
D3D9BE_RotateForEntity(&r_worldentity, NULL);
}
void D3D9BE_VBO_Begin(vbobctx_t *ctx, size_t maxsize)
{

View File

@ -27,25 +27,21 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
D3DSURFACE_DESC desc;
IDirect3DBaseTexture9 *dbt;
qboolean swap = false;
unsigned int pixelsize = 4;
unsigned int blocksize = 0;
unsigned int blockwidth, blockheight, blockbytes;
switch(mips->encoding)
{
case PTI_RGB565:
pixelsize = 2;
fmt = D3DFMT_R5G6B5;
break;
case PTI_RGBA4444://not supported on d3d9
return false;
case PTI_ARGB4444:
pixelsize = 2;
fmt = D3DFMT_A4R4G4B4;
break;
case PTI_RGBA5551://not supported on d3d9
return false;
case PTI_ARGB1555:
pixelsize = 2;
fmt = D3DFMT_A1R5G5B5;
break;
case PTI_RGBA8_SRGB:
@ -70,24 +66,30 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
break;
//too lazy to support these for now
case PTI_S3RGB1:
case PTI_S3RGBA1: //d3d doesn't distinguish between these
case PTI_BC1_RGB_SRGB:
case PTI_BC1_RGBA_SRGB: //d3d doesn't distinguish between these
case PTI_BC1_RGB:
case PTI_BC1_RGBA: //d3d doesn't distinguish between these
fmt = D3DFMT_DXT1;
blocksize = 8;
break;
case PTI_S3RGBA3:
case PTI_BC2_RGBA_SRGB:
case PTI_BC2_RGBA:
fmt = D3DFMT_DXT3;
blocksize = 16;
break;
case PTI_S3RGBA5:
case PTI_BC3_RGBA_SRGB:
case PTI_BC3_RGBA:
fmt = D3DFMT_DXT5;
blocksize = 16;
break;
//bc4-7 not supported on d3d9.
//etc2 have no chance.
default: //no idea
return false;
}
Image_BlockSizeForEncoding(mips->encoding, &blockbytes, &blockwidth, &blockheight);
if (!pD3DDev9)
return false; //can happen on errors
if (mips->type == PTI_CUBEMAP)
@ -111,17 +113,12 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
//can't do it in one go. pitch might contain padding or be upside down.
if (!mips->mip[i].data)
;
else if (blocksize)
{
if (lock.Pitch == ((mips->mip[i].width+3)/4)*blocksize)
//for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*pixelsize)
memcpy(lock.pBits, mips->mip[i].data, mips->mip[i].datasize);
}
else if (swap)
{ //only works for blockbytes=4
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
{
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*4)
{
for (x = 0; x < mips->mip[i].width*4; x+=4)
for (x = 0; x < rowbytes; x+=4)
{
out[x+0] = in[x+2];
out[x+1] = in[x+1];
@ -132,8 +129,9 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
}
else
{
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*pixelsize)
memcpy(out, in, mips->mip[i].width*pixelsize);
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
memcpy(out, in, rowbytes);
}
IDirect3DCubeTexture9_UnlockRect(dt, i%6, i/6);
}
@ -159,17 +157,12 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
//can't do it in one go. pitch might contain padding or be upside down.
if (!mips->mip[i].data)
;
else if (blocksize)
{
if (lock.Pitch == ((mips->mip[i].width+3)/4)*blocksize)
//for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*pixelsize)
memcpy(lock.pBits, mips->mip[i].data, mips->mip[i].datasize);
}
else if (swap)
{
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*4)
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
{
for (x = 0; x < mips->mip[i].width*4; x+=4)
for (x = 0; x < rowbytes; x+=4)
{
out[x+0] = in[x+2];
out[x+1] = in[x+1];
@ -180,8 +173,9 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
}
else
{
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*pixelsize)
memcpy(out, in, mips->mip[i].width*pixelsize);
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
memcpy(out, in, rowbytes);
}
IDirect3DTexture9_UnlockRect(dt, i);
}

View File

@ -605,7 +605,7 @@ void D3D9Shader_Init(void)
sh_config.texture_non_power_of_two = true;
}
sh_config.texture_maxsize = min(caps.MaxTextureWidth, caps.MaxTextureHeight);
sh_config.texturecube_maxsize = sh_config.texture2d_maxsize = min(caps.MaxTextureWidth, caps.MaxTextureHeight);
}
#endif

View File

@ -59,7 +59,8 @@ static void resetD3D9(void);
static LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pD3DDev9;
static D3DPRESENT_PARAMETERS d3dpp;
float d3d_trueprojection[16];
float d3d_trueprojection_std[16];
float d3d_trueprojection_view[16];
qboolean vid_initializing;
@ -619,8 +620,17 @@ static qboolean initD3D9Device(HWND hWnd, rendererstate_t *info, unsigned int de
{PTI_ARGB1555, D3DFMT_A1R5G5B5, D3DUSAGE_QUERY_FILTER},
{PTI_ARGB4444, D3DFMT_A4R4G4B4, D3DUSAGE_QUERY_FILTER},
{PTI_BGRX8_SRGB, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD},
{PTI_BGRA8_SRGB, D3DFMT_A8R8G8B8, D3DUSAGE_QUERY_SRGBREAD},
{PTI_BGRX8_SRGB, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER|D3DUSAGE_QUERY_SRGBREAD},
{PTI_BGRA8_SRGB, D3DFMT_A8R8G8B8, D3DUSAGE_QUERY_FILTER|D3DUSAGE_QUERY_SRGBREAD},
{PTI_BC1_RGB, D3DFMT_DXT1, D3DUSAGE_QUERY_FILTER},
{PTI_BC1_RGBA, D3DFMT_DXT1, D3DUSAGE_QUERY_FILTER},
{PTI_BC2_RGBA, D3DFMT_DXT3, D3DUSAGE_QUERY_FILTER},
{PTI_BC3_RGBA, D3DFMT_DXT5, D3DUSAGE_QUERY_FILTER},
{PTI_BC1_RGB_SRGB, D3DFMT_DXT1, D3DUSAGE_QUERY_FILTER|D3DUSAGE_QUERY_SRGBREAD},
{PTI_BC1_RGBA_SRGB, D3DFMT_DXT1, D3DUSAGE_QUERY_FILTER|D3DUSAGE_QUERY_SRGBREAD},
{PTI_BC2_RGBA_SRGB, D3DFMT_DXT3, D3DUSAGE_QUERY_FILTER|D3DUSAGE_QUERY_SRGBREAD},
{PTI_BC3_RGBA_SRGB, D3DFMT_DXT5, D3DUSAGE_QUERY_FILTER|D3DUSAGE_QUERY_SRGBREAD},
};
for (i = 0; i < countof(fmts); i++)
if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(pD3D, devno, devtype, d3dpp.BackBufferFormat, fmts[i].usage, D3DRTYPE_TEXTURE, fmts[i].d3d9)))
@ -919,11 +929,9 @@ static void (D3D9_VID_SetWindowCaption) (const char *msg)
void D3D9_Set2D (void)
{
float m[16];
D3DVIEWPORT9 vport;
// IDirect3DDevice9_EndScene(pD3DDev9);
Matrix4x4_CM_OrthographicD3D(m, 0 + (0.5*vid.width/vid.pixelwidth), vid.width + (0.5*vid.width/vid.pixelwidth), 0 + (0.5*vid.height/vid.pixelheight), vid.height + (0.5*vid.height/vid.pixelheight), 0, 100);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)m);
Matrix4x4_CM_OrthographicD3D(d3d_trueprojection_std, 0 + (0.5*vid.width/vid.pixelwidth), vid.width + (0.5*vid.width/vid.pixelwidth), 0 + (0.5*vid.height/vid.pixelheight), vid.height + (0.5*vid.height/vid.pixelheight), 0, 100);
Matrix4x4_Identity(m);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m);
@ -931,15 +939,6 @@ void D3D9_Set2D (void)
Matrix4x4_Identity(m);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)m);
vport.X = 0;
vport.Y = 0;
vport.Width = vid.pixelwidth;
vport.Height = vid.pixelheight;
vport.MinZ = 0;
vport.MaxZ = 1;
IDirect3DDevice9_SetViewport(pD3DDev9, &vport);
vid.fbvwidth = vid.width;
vid.fbvheight = vid.height;
vid.fbpwidth = vid.pixelwidth;
@ -951,6 +950,7 @@ void D3D9_Set2D (void)
r_refdef.pxrect.height = vid.fbpheight;
D3D9BE_Set2D();
D3D9BE_SetViewport(0, vid.fbpwidth, 0, vid.fbpheight);
}
static int d3d9error(int i)
@ -1196,8 +1196,7 @@ static void D3D9_SetupViewPortProjection(void)
int x, x2, y2, y, w, h;
float fov_x, fov_y;
D3DVIEWPORT9 vport;
float fovv_x, fovv_y;
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
@ -1223,21 +1222,17 @@ static void D3D9_SetupViewPortProjection(void)
w = x2 - x;
h = y2 - y;
vport.X = x;
vport.Y = y;
vport.Width = w;
vport.Height = h;
vport.MinZ = 0;
vport.MaxZ = 1;
IDirect3DDevice9_SetViewport(pD3DDev9, &vport);
fov_x = r_refdef.fov_x;//+sin(cl.time)*5;
fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5;
fovv_x = r_refdef.fovv_x;
fovv_y = r_refdef.fovv_y;
if ((r_refdef.flags & RDF_UNDERWATER) && !(r_refdef.flags & RDF_WATERWARP))
{
fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
fovv_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fovv_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
}
/*view matrix*/
@ -1247,19 +1242,21 @@ static void D3D9_SetupViewPortProjection(void)
if (r_refdef.maxdist)
{
/*d3d projection matricies scale depth to 0 to 1*/
Matrix4x4_CM_Projection_Far(d3d_trueprojection, fov_x, fov_y, r_refdef.mindist/2, r_refdef.maxdist);
Matrix4x4_CM_Projection_Far(d3d_trueprojection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist, true);
Matrix4x4_CM_Projection_Far(d3d_trueprojection_view, fovv_x, fovv_y, r_refdef.mindist, r_refdef.maxdist, true);
/*ogl projection matricies scale depth to -1 to 1, and I would rather my code used consistant culling*/
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist, false);
}
else
{
/*d3d projection matricies scale depth to 0 to 1*/
Matrix4x4_CM_Projection_Inf(d3d_trueprojection, fov_x, fov_y, r_refdef.mindist/2);
Matrix4x4_CM_Projection_Inf(d3d_trueprojection_std, fov_x, fov_y, r_refdef.mindist, true);
Matrix4x4_CM_Projection_Inf(d3d_trueprojection_view, fovv_x, fovv_y, r_refdef.mindist, true);
/*ogl projection matricies scale depth to -1 to 1, and I would rather my code used consistant culling*/
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist);
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, false);
}
d3d9error(IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection));
D3D9BE_SetViewport(x, w, y, h);
}
static void (D3D9_R_RenderView) (void)

View File

@ -839,13 +839,18 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA
sh_config.texture_non_power_of_two_pic = true; //always supported in d3d11, supposedly, even with d3d9 devices.
sh_config.npot_rounddown = false;
if (flevel>=D3D_FEATURE_LEVEL_11_0)
sh_config.texture_maxsize = 16384;
sh_config.texture2d_maxsize = 16384;
else if (flevel>=D3D_FEATURE_LEVEL_10_0)
sh_config.texture_maxsize = 8192;
sh_config.texture2d_maxsize = 8192;
else if (flevel>=D3D_FEATURE_LEVEL_9_3)
sh_config.texture_maxsize = 4096;
sh_config.texture2d_maxsize = 4096;
else
sh_config.texture_maxsize = 2048;
sh_config.texture2d_maxsize = 2048;
if (flevel>=D3D_FEATURE_LEVEL_9_3)
sh_config.texture2d_maxsize = 4096;
else
sh_config.texture2d_maxsize = 512;
//11.1 formats
#define DXGI_FORMAT_B4G4R4A4_UNORM 115
@ -860,13 +865,26 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, &support); sh_config.texfmt[PTI_RGBA8_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, &support); sh_config.texfmt[PTI_BGRA8_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, &support); sh_config.texfmt[PTI_BGRX8_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC1_UNORM, &support); sh_config.texfmt[PTI_S3RGBA1] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC2_UNORM, &support); sh_config.texfmt[PTI_S3RGBA3] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC3_UNORM, &support); sh_config.texfmt[PTI_S3RGBA5] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC1_UNORM, &support); sh_config.texfmt[PTI_BC1_RGBA] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC2_UNORM, &support); sh_config.texfmt[PTI_BC2_RGBA] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC3_UNORM, &support); sh_config.texfmt[PTI_BC3_RGBA] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC1_UNORM_SRGB, &support); sh_config.texfmt[PTI_BC1_RGBA_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC2_UNORM_SRGB, &support); sh_config.texfmt[PTI_BC2_RGBA_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC3_UNORM_SRGB, &support); sh_config.texfmt[PTI_BC3_RGBA_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC4_UNORM, &support); sh_config.texfmt[PTI_BC4_R8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC4_SNORM, &support); sh_config.texfmt[PTI_BC4_R8_SIGNED] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC5_UNORM, &support); sh_config.texfmt[PTI_BC5_RG8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC5_SNORM, &support); sh_config.texfmt[PTI_BC5_RG8_SIGNED] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC6H_UF16, &support); sh_config.texfmt[PTI_BC6_RGBF] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC6H_SF16, &support); sh_config.texfmt[PTI_BC6_RGBF_SIGNED] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC7_UNORM, &support); sh_config.texfmt[PTI_BC7_RGBA] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC7_UNORM_SRGB, &support); sh_config.texfmt[PTI_BC7_RGBA_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
//these formats are not officially supported as specified, but noone cares
sh_config.texfmt[PTI_RGBX8] = sh_config.texfmt[PTI_RGBA8];
sh_config.texfmt[PTI_S3RGB1] = sh_config.texfmt[PTI_S3RGBA1];
sh_config.texfmt[PTI_RGBX8_SRGB] = sh_config.texfmt[PTI_RGBA8_SRGB];
sh_config.texfmt[PTI_BC1_RGB] = sh_config.texfmt[PTI_BC1_RGBA];
sh_config.texfmt[PTI_BC1_RGB_SRGB] = sh_config.texfmt[PTI_BC1_RGBA_SRGB];
vid.srgb = info->srgb>1;
@ -1184,34 +1202,22 @@ static void (D3D11_VID_SetWindowCaption) (const char *msg)
void D3D11_Set2D (void)
{
D3D11_VIEWPORT vport;
// Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0 + (0.5*vid.width/vid.pixelwidth), vid.width + (0.5*vid.width/vid.pixelwidth), 0 + (0.5*vid.height/vid.pixelheight), vid.height + (0.5*vid.height/vid.pixelheight), 0, 100);
Matrix4x4_CM_Orthographic(r_refdef.m_projection_std, 0, vid.width, vid.height, 0, 0, 99999);
Matrix4x4_Identity(r_refdef.m_view);
vport.TopLeftX = 0;
vport.TopLeftY = 0;
vport.Width = vid.pixelwidth;
vport.Height = vid.pixelheight;
vport.MinDepth = 0;
vport.MaxDepth = 1;
ID3D11DeviceContext_RSSetViewports(d3ddevctx, 1, &vport);
D3D11BE_SetupViewCBuffer();
vid.fbvwidth = vid.width;
vid.fbvheight = vid.height;
vid.fbpwidth = vid.pixelwidth;
vid.fbpheight = vid.pixelheight;
D3D11BE_Scissor(NULL);
r_refdef.pxrect.x = 0;
r_refdef.pxrect.y = 0;
r_refdef.pxrect.width = vid.fbpwidth;
r_refdef.pxrect.height = vid.fbpheight;
D3D11BE_Set2D();
}
static qboolean (D3D11_SCR_UpdateScreen) (void)
@ -1407,8 +1413,7 @@ static void D3D11_SetupViewPort(void)
int x, x2, y2, y;
float fov_x, fov_y;
// D3DVIEWPORT9 vport;
float fovv_x, fovv_y;
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
@ -1433,19 +1438,29 @@ static void D3D11_SetupViewPort(void)
fov_x = r_refdef.fov_x;//+sin(cl.time)*5;
fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5;
fovv_x = r_refdef.fovv_x;
fovv_y = r_refdef.fovv_y;
if ((r_refdef.flags & RDF_UNDERWATER) && !(r_refdef.flags & RDF_WATERWARP))
{
fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
fovv_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fovv_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
}
/*view matrix*/
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_refdef.vieworg);
if (r_refdef.maxdist)
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist);
{
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist, false);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_view, fovv_x, fovv_y, r_refdef.mindist, r_refdef.maxdist, false);
}
else
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist);
{
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, false);
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_view, fovv_x, fovv_y, r_refdef.mindist, false);
}
}
static void (D3D11_R_RenderView) (void)

View File

@ -515,7 +515,7 @@ void D3D8Shader_Init(void)
sh_config.texture_non_power_of_two = true;
}
sh_config.texture_maxsize = min(caps.MaxTextureWidth, caps.MaxTextureHeight);
sh_config.texture2d_maxsize = min(caps.MaxTextureWidth, caps.MaxTextureHeight);
}
#if (WINVER < 0x500) && !defined(__GNUC__)
@ -1292,16 +1292,16 @@ static void D3D8_SetupViewPortProjection(void)
if (r_refdef.maxdist)
{
/*d3d projection matricies scale depth to 0 to 1*/
Matrix4x4_CM_Projection_Far(d3d_trueprojection, fov_x, fov_y, r_refdef.mindist/2, r_refdef.maxdist);
Matrix4x4_CM_Projection_Far(d3d_trueprojection, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist, true);
/*ogl projection matricies scale depth to -1 to 1, and I would rather my code used consistant culling*/
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist, false);
}
else
{
/*d3d projection matricies scale depth to 0 to 1*/
Matrix4x4_CM_Projection_Inf(d3d_trueprojection, fov_x, fov_y, r_refdef.mindist/2);
Matrix4x4_CM_Projection_Inf(d3d_trueprojection, fov_x, fov_y, r_refdef.mindist, true);
/*ogl projection matricies scale depth to -1 to 1, and I would rather my code used consistant culling*/
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist);
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, false);
}
d3d8error(IDirect3DDevice8_SetTransform(pD3DDev8, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection));

View File

@ -3923,7 +3923,7 @@ qboolean GLBE_SelectDLight(dlight_t *dl, vec3_t colour, vec3_t axis[3], unsigned
float view[16];
float proj[16];
extern cvar_t r_shadow_shadowmapping_nearclip;
Matrix4x4_CM_Projection_Far(proj, dl->fov, dl->fov, r_shadow_shadowmapping_nearclip.value, dl->radius);
Matrix4x4_CM_Projection_Far(proj, dl->fov, dl->fov, r_shadow_shadowmapping_nearclip.value, dl->radius, false);
Matrix4x4_CM_ModelViewMatrixFromAxis(view, axis[0], axis[1], axis[2], dl->origin);
Matrix4_Multiply(proj, view, shaderstate.lightprojmatrix);
}

View File

@ -442,8 +442,8 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
if (tex->flags & IF_TEXTYPE)
{
targface = cubeface[i];
j = 0;
targface = cubeface[i%countof(cubeface)];
j = i/countof(cubeface);
}
else
{
@ -452,12 +452,13 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
}
switch(encoding)
{
#ifdef FTE_TARGET_WEB
case PTI_WHOLEFILE:
case PTI_MAX:
#ifdef FTE_TARGET_WEB
if (!i)
emscriptenfte_gl_loadtexturefile(tex->num, &tex->width, &tex->height, mips->mip[i].data, mips->mip[i].datasize);
break;
#endif
break;
case PTI_DEPTH16:
qglTexImage2D(targface, j, gl_config.gles?GL_DEPTH_COMPONENT:GL_DEPTH_COMPONENT16_ARB, mips->mip[i].width, mips->mip[i].height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, mips->mip[i].data);
break;
@ -480,7 +481,6 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
case PTI_BGRX8:
qglTexImage2D(targface, j, compress?GL_COMPRESSED_RGB_ARB:GL_RGB, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
default:
case PTI_BGRA8:
qglTexImage2D(targface, j, compress?GL_COMPRESSED_RGBA_ARB:GL_RGBA, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
@ -519,19 +519,65 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
case PTI_RGB565:
qglTexImage2D(targface, j, compress?GL_COMPRESSED_RGBA_ARB:GL_RGB, mips->mip[i].width, mips->mip[i].height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, mips->mip[i].data);
break;
//(desktop) compressed formats
case PTI_S3RGB1:
//legacy formats
case PTI_RGB8:
qglTexImage2D(targface, j, GL_RGB8, mips->mip[i].width, mips->mip[i].height, 0, GL_RGB, GL_UNSIGNED_BYTE, mips->mip[i].data);
break;
case PTI_LUMINANCE8_ALPHA8:
qglTexImage2D(targface, j, GL_LUMINANCE8_ALPHA8, mips->mip[i].width, mips->mip[i].height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, mips->mip[i].data);
break;
//s3tc (desktop) compressed formats
case PTI_BC1_RGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_S3RGBA1:
case PTI_BC1_RGBA:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_S3RGBA3:
case PTI_BC2_RGBA:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_S3RGBA5:
case PTI_BC3_RGBA:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC1_RGB_SRGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC1_RGBA_SRGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC2_RGBA_SRGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC3_RGBA_SRGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
//atin/rgtc (desktop) compressed formats (derived from bc3's alpha channel)
case PTI_BC4_R8:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RED_RGTC1, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC4_R8_SIGNED:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SIGNED_RED_RGTC1, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC5_RG8:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RG_RGTC2, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC5_RG8_SIGNED:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SIGNED_RG_RGTC2, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
//bptc desktop formats
case PTI_BC6_RGBF:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC6_RGBF_SIGNED:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC7_RGBA:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_BC7_RGBA_SRGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
//(mobile) compressed formats
case PTI_ETC1_RGB8:
case PTI_ETC2_RGB8:
@ -547,6 +593,56 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
case PTI_ETC2_RGB8A8:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA8_ETC2_EAC, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_ETC2_RGB8_SRGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ETC2, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_ETC2_RGB8A1_SRGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_ETC2_RGB8A8_SRGB:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_EAC_R11:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_R11_EAC, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_EAC_R11_SIGNED:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SIGNED_R11_EAC, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_EAC_RG11:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RG11_EAC, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
case PTI_EAC_RG11_SIGNED:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SIGNED_RG11_EAC, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;
//astc variations...
case PTI_ASTC_4X4: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_4X4_SRGB: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_5X4: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_5X4_SRGB: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_5X5: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_5X5_SRGB: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_6X5: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_6X5_SRGB: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_6X6: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_6X6_SRGB: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_8X5: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_8X5_SRGB: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_8X6: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_8X6_SRGB: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_10X5: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_10X5_SRGB: qglCompressedTexImage2DARB(targface, j,GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_10X6: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_10X6_SRGB: qglCompressedTexImage2DARB(targface, j,GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_8X8: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_8X8_SRGB: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_10X8: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_10X8_SRGB: qglCompressedTexImage2DARB(targface, j,GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_10X10: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_10X10_SRGB: qglCompressedTexImage2DARB(targface, j,GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_12X10: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_12X10_SRGB: qglCompressedTexImage2DARB(targface, j,GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_12X12: qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
case PTI_ASTC_12X12_SRGB: qglCompressedTexImage2DARB(targface, j,GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data); break;
}
}
}

View File

@ -2937,8 +2937,8 @@ static void Mod_Batches_AllocLightmaps(model_t *mod)
mod->lightmaps.width = 1<<i;
for (i = 0; (1<<i) < mod->lightmaps.height; i++);
mod->lightmaps.height = 1<<i;
mod->lightmaps.width = bound(64, mod->lightmaps.width, sh_config.texture_maxsize);
mod->lightmaps.height = bound(64, mod->lightmaps.height, sh_config.texture_maxsize);
mod->lightmaps.width = bound(64, mod->lightmaps.width, sh_config.texture2d_maxsize);
mod->lightmaps.height = bound(64, mod->lightmaps.height, sh_config.texture2d_maxsize);
Mod_LightmapAllocInit(&lmallocator, mod->deluxdata != NULL, mod->lightmaps.width, mod->lightmaps.height, 0x50);

View File

@ -602,6 +602,7 @@ void R_GenDlightBatches(batch_t *batches[])
if (!r_lightprepass)
return;
modes = 0;
if (r_shadow_realtime_dlight.ival)
modes |= LFLAG_NORMALMODE;
if (r_shadow_realtime_world.ival)

View File

@ -576,13 +576,13 @@ void R_SetupGL (float stereooffset, int i)
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI;
// MYgluPerspective (yfov, screenaspect, 4, 4096);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_view, fovv_x, fovv_y, r_refdef.mindist, r_refdef.maxdist);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist, false);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_view, fovv_x, fovv_y, r_refdef.mindist, r_refdef.maxdist, false);
}
else
{
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist);
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_view, fovv_x, fovv_y, r_refdef.mindist);
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, false);
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_view, fovv_x, fovv_y, r_refdef.mindist, false);
}
}
else
@ -2002,8 +2002,8 @@ void GLR_RenderView (void)
}
//well... err... meh.
vid.fbpwidth = bound(1, vid.fbpwidth, sh_config.texture_maxsize);
vid.fbpheight = bound(1, vid.fbpheight, sh_config.texture_maxsize);
vid.fbpwidth = bound(1, vid.fbpwidth, sh_config.texture2d_maxsize);
vid.fbpheight = bound(1, vid.fbpheight, sh_config.texture2d_maxsize);
vid.fbvwidth = vid.fbpwidth;
vid.fbvheight = vid.fbpheight;

View File

@ -445,9 +445,6 @@ void GLR_DeInit (void)
// Cmd_RemoveCommand ("makewad");
Cvar_Unhook(&vid_conautoscale);
Cvar_Unhook(&vid_conheight);
Cvar_Unhook(&vid_conwidth);
// Cvar_Unhook(&v_gamma);
// Cvar_Unhook(&v_contrast);
// Cvar_Unhook(&v_brightness);

View File

@ -356,6 +356,24 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
lhs = false;
else if (!Q_stricmp(token, "loweroverlay"))
lhs = false;
//these are for compat/documentation purposes with qfusion/warsow
else if (!Q_stricmp(token, "maxTextureSize"))
lhs = sh_config.texture2d_maxsize;
else if (!Q_stricmp(token, "maxTextureCubemapSize"))
lhs = sh_config.texturecube_maxsize;
else if (!Q_stricmp(token, "maxTextureUnits"))
lhs = 0;
else if (!Q_stricmp(token, "textureCubeMap"))
lhs = sh_config.havecubemaps;
// else if (!Q_stricmp(token, "GLSL"))
// lhs = 1;
else if (!Q_stricmp(token, "deluxeMaps") || !Q_stricmp(token, "deluxe"))
lhs = r_deluxmapping;
else if (!Q_stricmp(token, "portalMaps"))
lhs = false;
//end qfusion
else
{
cv = Cvar_Get(token, "", 0, "Shader Conditions");
@ -3531,7 +3549,7 @@ static void Shaderpass_CubeMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{
char *token = Shader_ParseString(ptr);
if (pass->tcgen == TC_GEN_BASE)
if (pass->tcgen == TC_GEN_UNSPECIFIED)
pass->tcgen = TC_GEN_SKYBOX;
pass->texgen = T_GEN_CUBEMAP;
pass->anim_frames[0] = Shader_FindImage(token, IF_CUBEMAP);
@ -3593,14 +3611,14 @@ static shaderkey_t shaderpasskeys[] =
//qfusion/warsow compat
{"material", Shaderpass_QF_Material, "qf"},
{"animclampmap",Shaderpass_QF_AnimClampMap, "qf"},
// {"cubemap", Shaderpass_CubeMap, "qf"},
// {"shadecubemap",Shaderpass_ShadeCubeMap, "qf"},
// {"surroundmap", Shaderpass_SurroundMap, "qf"},
// {"distortion", Shaderpass_Distortion, "qf"},
// {"celshade", Shaderpass_Celshade, "qf"},
// {"grayscale", Shaderpass_Greyscale, "qf"},
// {"greyscale", Shaderpass_Greyscale, "qf"},
// {"skip", Shaderpass_Skip, "qf"},
// {"cubemap", Shaderpass_QF_CubeMap, "qf"},
// {"shadecubemap",Shaderpass_QF_ShadeCubeMap, "qf"},
{"surroundmap", Shaderpass_CubeMap, "qf"},
// {"distortion", Shaderpass_QF_Distortion, "qf"},
// {"celshade", Shaderpass_QF_Celshade, "qf"},
// {"grayscale", Shaderpass_QF_Greyscale, "qf"},
// {"greyscale", Shaderpass_QF_Greyscale, "qf"},
// {"skip", Shaderpass_QF_Skip, "qf"},
{NULL, NULL}
};

View File

@ -2406,7 +2406,7 @@ qboolean Sh_GenShadowMap (dlight_t *l, vec3_t axis[3], qbyte *lvis, int smsize)
oprect = r_refdef.pxrect;
smesh = SHM_BuildShadowMesh(l, lvis, SMT_SHADOWMAP);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, l->fov?l->fov:90, l->fov?l->fov:90, r_shadow_shadowmapping_nearclip.value, l->radius);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, l->fov?l->fov:90, l->fov?l->fov:90, r_shadow_shadowmapping_nearclip.value, l->radius, false);
switch(qrenderer)
{

View File

@ -2884,25 +2884,35 @@ qboolean GL_Init(rendererstate_t *info, void *(*getglfunction) (char *name))
qglGetError(); /*suck up the invalid operation error for non-debug contexts*/
#endif
sh_config.texture_maxsize = 256; //early minidrivers might not implement this, but anything else should.
qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &sh_config.texture_maxsize);
sh_config.texture2d_maxsize = 256; //early minidrivers might not implement this, but anything else should.
qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &sh_config.texture2d_maxsize);
//always supported
sh_config.texfmt[PTI_RGBA8] = true;
if (GL_CheckExtension("GL_EXT_texture_compression_s3tc"))
{
sh_config.texfmt[PTI_S3RGB1] = true;
sh_config.texfmt[PTI_S3RGBA1] = true;
sh_config.texfmt[PTI_S3RGBA3] = true;
sh_config.texfmt[PTI_S3RGBA5] = true;
sh_config.texfmt[PTI_BC1_RGB] = true;
sh_config.texfmt[PTI_BC1_RGBA] = true;
sh_config.texfmt[PTI_BC2_RGBA] = true;
sh_config.texfmt[PTI_BC3_RGBA] = true;
}
else if (gl_config.gles)
{
sh_config.texfmt[PTI_S3RGB1] =
sh_config.texfmt[PTI_S3RGBA1] = GL_CheckExtension("GL_EXT_texture_compression_dxt1");
sh_config.texfmt[PTI_S3RGBA3] = GL_CheckExtension("GL_ANGLE_texture_compression_dxt3");
sh_config.texfmt[PTI_S3RGBA5] = GL_CheckExtension("GL_ANGLE_texture_compression_dxt5");
sh_config.texfmt[PTI_BC1_RGB] =
sh_config.texfmt[PTI_BC1_RGBA] = GL_CheckExtension("GL_EXT_texture_compression_dxt1");
sh_config.texfmt[PTI_BC2_RGBA] = GL_CheckExtension("GL_ANGLE_texture_compression_dxt3");
sh_config.texfmt[PTI_BC3_RGBA] = GL_CheckExtension("GL_ANGLE_texture_compression_dxt5");
}
if (GL_CheckExtension("GL_ARB_texture_compression_rgtc") || GL_CheckExtension("GL_EXT_texture_compression_rgtc"))
{
sh_config.texfmt[PTI_BC4_R8] = true;
sh_config.texfmt[PTI_BC4_R8_SIGNED] = true;
sh_config.texfmt[PTI_BC5_RG8] = true;
sh_config.texfmt[PTI_BC5_RG8_SIGNED] = true;
}
if ((!gl_config.gles && gl_config.glversion >= 4.2) || GL_CheckExtension("GL_ARB_texture_compression_bptc"))
sh_config.texfmt[PTI_BC6_RGBF] = sh_config.texfmt[PTI_BC6_RGBF_SIGNED] =
sh_config.texfmt[PTI_BC7_RGBA] = sh_config.texfmt[PTI_BC7_RGBA_SRGB] = true;
#ifdef FTE_TARGET_WEB
if (GL_CheckExtension("WEBGL_compressed_texture_etc"))
@ -2913,17 +2923,45 @@ qboolean GL_Init(rendererstate_t *info, void *(*getglfunction) (char *name))
//webgl tries to cater to d3d, so doesn't support this gles3 feature, because browser writers are lazy.
//warning: while support is mandatory, it may just be a driver trick with the hardware using uncompressed data.
sh_config.texfmt[PTI_ETC1_RGB8] = true;
sh_config.texfmt[PTI_ETC2_RGB8] = true;
sh_config.texfmt[PTI_ETC2_RGB8A1] = true;
sh_config.texfmt[PTI_ETC2_RGB8A8] = true;
sh_config.texfmt[PTI_EAC_R11] = true;
sh_config.texfmt[PTI_EAC_R11_SIGNED] = true;
sh_config.texfmt[PTI_EAC_RG11] = true;
sh_config.texfmt[PTI_EAC_RG11_SIGNED] = true;
}
else
{
sh_config.texfmt[PTI_ETC2_RGB8] = GL_CheckExtension("GL_OES_compressed_ETC2_RGB8_texture");
sh_config.texfmt[PTI_ETC2_RGB8A1] = GL_CheckExtension("GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture");
sh_config.texfmt[PTI_ETC2_RGB8] = GL_CheckExtension("GL_OES_compressed_ETC2_RGBA8_texture");
sh_config.texfmt[PTI_ETC1_RGB8] = sh_config.texfmt[PTI_ETC2_RGB8] || GL_CheckExtension("GL_OES_compressed_ETC1_RGB8_texture");
sh_config.texfmt[PTI_ETC1_RGB8] = GL_CheckExtension("GL_OES_compressed_ETC1_RGB8_texture");
sh_config.texfmt[PTI_ETC2_RGB8] = GL_CheckExtension("GL_OES_compressed_ETC2_RGB8_texture"); //or OES_compressed_ETC2_sRGB8_texture...
sh_config.texfmt[PTI_ETC2_RGB8A1] = GL_CheckExtension("GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture"); //or OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture...
sh_config.texfmt[PTI_ETC2_RGB8A8] = GL_CheckExtension("GL_OES_compressed_ETC2_RGBA8_texture"); //or OES_compressed_ETC2_sRGB8_alpha8_texture
sh_config.texfmt[PTI_EAC_R11] = GL_CheckExtension("GL_OES_compressed_EAC_R11_unsigned_texture");
sh_config.texfmt[PTI_EAC_R11_SIGNED] = GL_CheckExtension("GL_OES_compressed_EAC_R11_signed_texture");
sh_config.texfmt[PTI_EAC_RG11] = GL_CheckExtension("GL_OES_compressed_EAC_RG11_unsigned_texture");
sh_config.texfmt[PTI_EAC_RG11_SIGNED] = GL_CheckExtension("GL_OES_compressed_EAC_RG11_signed_texture");
}
sh_config.texfmt[PTI_ETC1_RGB8] |= sh_config.texfmt[PTI_ETC2_RGB8];
if (GL_CheckExtension("GL_KHR_texture_compression_astc_ldr"))
{ //24 different formats...
//hdr profile adds 3d slices, and support for the hdr subblocks (ldr-only will decode them as fixed-colour errors)
//full profile adds 3d blocks
//we don't do 3d astc textures, so the api doesn't change. either the gpu supports the data or parts get decoded as fixed colours, which is still better than our crappy fallback texture.
int gah;
for (gah = PTI_ASTC_4X4; gah <= PTI_ASTC_12X12_SRGB; gah++)
sh_config.texfmt[gah] = true;
}
/*note regarding GL_COMPRESSED_TEXTURE_FORMATS:
nvidia lists bc1-3, oes paletted, etc2, astc, astc_srgb.
so the only listed formats that the hardware actually supports are bc1-3.
and bc4-7 are NOT listed, despite eg vulkan supporting them.
or in other words, this info is utterly useless (its deprecated somewhere, so this shouldn't be a huge surprise).
*/
if (gl_config.gles)
{
@ -3023,8 +3061,19 @@ qboolean GL_Init(rendererstate_t *info, void *(*getglfunction) (char *name))
sh_config.texfmt[PTI_RGBA8_SRGB] = sh_config.texfmt[PTI_RGBA8] && srgb;
sh_config.texfmt[PTI_BGRX8_SRGB] = sh_config.texfmt[PTI_BGRX8] && srgb;
sh_config.texfmt[PTI_BGRA8_SRGB] = sh_config.texfmt[PTI_BGRA8] && srgb;
sh_config.texfmt[PTI_BC1_RGB_SRGB] = sh_config.texfmt[PTI_BC1_RGB] && srgb;
sh_config.texfmt[PTI_BC1_RGBA_SRGB] = sh_config.texfmt[PTI_BC1_RGBA] && srgb;
sh_config.texfmt[PTI_BC2_RGBA_SRGB] = sh_config.texfmt[PTI_BC2_RGBA] && srgb;
sh_config.texfmt[PTI_BC3_RGBA_SRGB] = sh_config.texfmt[PTI_BC3_RGBA] && srgb;
sh_config.texfmt[PTI_ETC2_RGB8_SRGB] = sh_config.texfmt[PTI_ETC2_RGB8] && srgb;
sh_config.texfmt[PTI_ETC2_RGB8A1_SRGB] = sh_config.texfmt[PTI_ETC2_RGB8A1] && srgb;
sh_config.texfmt[PTI_ETC2_RGB8A8_SRGB] = sh_config.texfmt[PTI_ETC2_RGB8A8] && srgb;
}
sh_config.texturecube_maxsize = 0;
if (sh_config.havecubemaps)
qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &sh_config.texturecube_maxsize);
sh_config.progs_supported = gl_config.arb_shader_objects;
sh_config.progs_required = gl_config_nofixedfunc;

View File

@ -981,14 +981,10 @@ static qboolean VID_SetWindowedMode (rendererstate_t *info)
Con_Printf("Can't run GL in non-RGB mode\n");
return false;
}
vid.dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
vid.dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(NULL, hdc);
WindowRect.top = WindowRect.left = 0;
WindowRect.right = info->width;
WindowRect.bottom = info->height;
#ifndef FTE_SDL
if (sys_parentwindow)
{
@ -1001,8 +997,8 @@ static qboolean VID_SetWindowedMode (rendererstate_t *info)
pwidth = sys_parentwidth;
pheight = sys_parentheight;
WindowRect.right = sys_parentwidth;
WindowRect.bottom = sys_parentheight;
wwidth = sys_parentwidth;
wheight = sys_parentheight;
}
else
#endif
@ -1018,21 +1014,27 @@ static qboolean VID_SetWindowedMode (rendererstate_t *info)
pwidth = GetSystemMetrics(SM_CXSCREEN);
pheight = GetSystemMetrics(SM_CYSCREEN);
/*Assume dual monitors, and chop the width to try to put it on only one screen*/
if (pwidth >= pheight*2)
pwidth /= 2;
/*Assume dual monitors, and chop the width to try to put it on only one screen
"Because of app compatibility reasons these system metrics return the size of the primary monitor"
so we shouldn't need this...
*/
// if (pwidth >= pheight*2)
// pwidth /= 2;
wwidth = info->width;
wheight = info->height;
/*win8 code:
HMONITOR mod = MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST);
if (mon != INVALID_HANDLE_VALUE)
GetDpiForMonitor(mon, 0, &vid.dpi_x, &vid.dpi_y);
*/
wwidth = (wwidth*vid.dpi_x)/96;
wheight = (wheight*vid.dpi_y)/96;
}
DIBWidth = WindowRect.right - WindowRect.left;
DIBHeight = WindowRect.bottom - WindowRect.top;
rect = WindowRect;
AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0);
wwidth = rect.right - rect.left;
wheight = rect.bottom - rect.top;
WindowRect = centerrect(pleft, ptop, pwidth, pheight, wwidth, wheight);
if (!sys_parentwindow)
AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0);
// Create the DIB window
if (WinNT)
@ -1072,6 +1074,12 @@ static qboolean VID_SetWindowedMode (rendererstate_t *info)
return false;
}
GetClientRect(dibwindow, &WindowRect);
WindowRect.right -= WindowRect.left;
WindowRect.bottom -= WindowRect.top;
DIBWidth = WindowRect.right;
DIBHeight = WindowRect.bottom;
SendMessage (dibwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon);
SendMessage (dibwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon);

View File

@ -622,6 +622,18 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif
#ifndef GL_COMPRESSED_RED_RGTC1
#define GL_COMPRESSED_RED_RGTC1 0x8DBB
#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
#define GL_COMPRESSED_RG_RGTC2 0x8DBD
#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
#endif
#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM_ARB
#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
#endif
#ifndef GL_EXT_texture_sRGB
#define GL_EXT_texture_sRGB 1
@ -647,10 +659,10 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
#define GL_ETC1_RGB8_OES 0x8D64 //4*4 blocks of 8 bytes
#endif
#ifndef GL_COMPRESSED_RGB8_ETC2
//#define GL_COMPRESSED_R11_EAC 0x9270
//#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
//#define GL_COMPRESSED_RG11_EAC 0x9272
//#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
#define GL_COMPRESSED_R11_EAC 0x9270
#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
#define GL_COMPRESSED_RG11_EAC 0x9272
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
#define GL_COMPRESSED_RGB8_ETC2 0x9274 //4*4 blocks of 8 bytes. also accepts valid etc1 images
#define GL_COMPRESSED_SRGB8_ETC2 0x9275
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 //
@ -658,6 +670,36 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 //4*4 blocks of 8+8 bytes.
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
#endif
#ifndef GL_COMPRESSED_RGBA_ASTC_4x4_KHR
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
#endif
#ifndef GL_ARB_pixel_buffer_object
#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB

View File

@ -741,7 +741,8 @@ typedef struct
unsigned int max_gpu_bones; //max number of bones supported by uniforms.
qboolean texfmt[PTI_MAX]; //which texture formats are supported (renderable not implied)
unsigned int texture_maxsize; //max size of a 2d texture
unsigned int texture2d_maxsize; //max size of a 2d texture
unsigned int texturecube_maxsize;
qboolean texture_non_power_of_two; //full support for npot
qboolean texture_non_power_of_two_pic; //npot only works with clamp-to-edge mipless images.
qboolean npot_rounddown; //memory limited systems can say that they want to use less ram.
@ -859,6 +860,7 @@ void D3D9BE_Scissor(srect_t *rect);
void D3D9Shader_Init(void);
void D3D9BE_Reset(qboolean before);
void D3D9BE_Set2D(void);
void D3D9BE_SetViewport(int x, int y, int w, int h);
#endif
#ifdef D3D11QUAKE
void D3D11BE_Init(void);
@ -878,7 +880,7 @@ qboolean D3D11BE_SelectDLight(dlight_t *dl, vec3_t colour, vec3_t axis[3], unsig
qboolean D3D11Shader_Init(unsigned int featurelevel);
void D3D11BE_Reset(qboolean before);
void D3D11BE_SetupViewCBuffer(void);
void D3D11BE_Set2D(void);
void D3D11_UploadLightmap(lightmapinfo_t *lm);
void D3D11BE_VBO_Begin(vbobctx_t *ctx, size_t maxsize);
void D3D11BE_VBO_Data(vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray);

View File

@ -56,7 +56,8 @@
//any globals or functions that the server might want access to need to be known also.
#define luaextragloballist \
globalstring (true, startspot) \
globalstring (true, ClientReEnter)
globalstring (true, ClientReEnter) \
globalfloat (false, dimension_default)
typedef struct
{
@ -107,7 +108,7 @@ static struct
luafld_t entflds[1024]; //fld->offset+type
qboolean triedlib;
dllhandle_t lib;
dllhandle_t *lib;
lua_State * (QDECL *newstate) (lua_Alloc f, void *ud);
lua_CFunction (QDECL *atpanic) (lua_State *L, lua_CFunction panicf);
@ -431,7 +432,7 @@ static int my_lua_entity_set(lua_State *L) //__newindex
lua.getfield(L, 1, "entnum");
entnum = lua.tointegerx(L, -1, NULL);
lua.pop(L, 1);
if (entnum < lua.maxedicts && lua.edicttable[entnum] && !lua.edicttable[entnum]->isfree)
if (entnum < lua.maxedicts && lua.edicttable[entnum] && !ED_ISFREE(lua.edicttable[entnum]))
{
eval = (eval_t*)((char*)lua.edicttable[entnum]->v + fld->offset);
switch(fld->type)
@ -450,7 +451,7 @@ static int my_lua_entity_set(lua_State *L) //__newindex
eval->function = 0; //so the engine can distinguish between nil and not.
else
eval->function = fld->offset | ((entnum+1)<<10);
lua.pushlightuserdata(L, (void *)fld->offset); //execute only knows a function id, so we need to translate the store to match.
lua.pushlightuserdata(L, (void *)(qintptr_t)fld->offset); //execute only knows a function id, so we need to translate the store to match.
lua.replace(L, 2);
lua.rawset(L, 1);
return 0;
@ -459,7 +460,7 @@ static int my_lua_entity_set(lua_State *L) //__newindex
eval->string = 0; //so the engine can distinguish between nil and not.
else
eval->string = fld->offset | ((entnum+1)<<10);
lua.pushlightuserdata(L, (void *)fld->offset); //execute only knows a string id, so we need to translate the store to match.
lua.pushlightuserdata(L, (void *)(qintptr_t)fld->offset); //execute only knows a string id, so we need to translate the store to match.
lua.replace(L, 2);
lua.rawset(L, 1);
return 0;
@ -517,7 +518,7 @@ static int my_lua_entity_get(lua_State *L) //__index
return 1;
case ev_function:
case ev_string:
lua.pushlightuserdata(L, (void *)(eval->function & 1023)); //execute only knows a function id, so we need to translate the store to match.
lua.pushlightuserdata(L, (void *)(qintptr_t)(eval->function & 1023)); //execute only knows a function id, so we need to translate the store to match.
lua.replace(L, 2);
lua.rawget(L, 1);
return 1;
@ -619,7 +620,7 @@ static int my_lua_global_get(lua_State *L) //__index
lua.pushnumber(L, eval->_float);
return 1;
case ev_function:
lua.pushlightuserdata(L, (void *)eval->function); //execute only knows a function id, so we need to translate the store to match.
lua.pushlightuserdata(L, (void *)(qintptr_t)eval->function); //execute only knows a function id, so we need to translate the store to match.
lua.replace(L, 2);
lua.rawget(L, 1);
return 1;
@ -667,7 +668,7 @@ static int bi_lua_lightstyle(lua_State *L)
}
static int bi_lua_spawn(lua_State *L)
{
edict_t *e = lua.progfuncs.EntAlloc(&lua.progfuncs);
edict_t *e = lua.progfuncs.EntAlloc(&lua.progfuncs, false, 0);
if (e)
{
lua.pushlightuserdata(L, e);
@ -811,7 +812,7 @@ static int bi_lua_sound(lua_State *L)
//note: channel & 256 == reliable
SVQ1_StartSound (NULL, (wedict_t*)EDICT_NUM((&lua.progfuncs), entnum), channel, samp, volume*255, attenuation, 0);
SVQ1_StartSound (NULL, (wedict_t*)EDICT_NUM((&lua.progfuncs), entnum), channel, samp, volume*255, attenuation, 0, 0, 0);
return 0;
}
@ -850,7 +851,7 @@ static int bi_lua_droptofloor(lua_State *L)
vec3_t start;
trace_t trace;
const float *gravitydir;
extern const vec3_t standardgravity;
static const vec3_t standardgravity = {0,0,-1};
pubprogfuncs_t *prinst = &lua.progfuncs;
world_t *world = prinst->parms->user;
@ -887,9 +888,10 @@ static int bi_lua_checkbottom(lua_State *L)
{
qboolean okay;
int entnum;
vec3_t up = {0,0,1};
lua.getfield(L, 1, "entnum");
entnum = lua.tointegerx(L, -1, NULL);
okay = World_CheckBottom(&sv.world, (wedict_t*)EDICT_NUM((&lua.progfuncs), entnum));
okay = World_CheckBottom(&sv.world, (wedict_t*)EDICT_NUM((&lua.progfuncs), entnum), up);
lua.pushboolean(L, okay);
return 1;
}
@ -946,11 +948,11 @@ static void set_trace_globals(trace_t *trace)
pr_global_struct->trace_fraction = trace->fraction;
pr_global_struct->trace_inwater = trace->inwater;
pr_global_struct->trace_inopen = trace->inopen;
pr_global_struct->trace_surfaceflags = trace->surface?trace->surface->flags:0;
pr_global_struct->trace_surfaceflagsf = trace->surface?trace->surface->flags:0;
pr_global_struct->trace_surfaceflagsi = trace->surface?trace->surface->flags:0;
if (pr_global_struct->trace_surfacename)
prinst->SetStringField(prinst, NULL, &pr_global_struct->trace_surfacename, tr->surface?tr->surface->name:"", true);
pr_global_struct->trace_endcontents = trace->contents;
// if (pr_global_struct->trace_surfacename)
// prinst->SetStringField(prinst, NULL, &pr_global_struct->trace_surfacename, tr->surface?tr->surface->name:"", true);
pr_global_struct->trace_endcontentsf = trace->contents;
pr_global_struct->trace_endcontentsi = trace->contents;
// if (trace.fraction != 1)
// VectorMA (trace->endpos, 4, trace->plane.normal, P_VEC(trace_endpos));
@ -1011,7 +1013,7 @@ static int bi_lua_walkmove(lua_State *L)
float yaw, dist;
vec3_t move;
int oldself;
vec3_t axis;
vec3_t axis[3];
ent = PROG_TO_WEDICT(prinst, *world->g.self);
yaw = lua.tonumberx(L, 1, NULL);
@ -1070,7 +1072,7 @@ static int bi_lua_nextent(lua_State *L)
break;
}
ent = WEDICT_NUM(world->progs, i);
if (!ent->isfree)
if (!ED_ISFREE(ent))
{
break;
}
@ -1098,7 +1100,7 @@ static int bi_lua_nextclient(lua_State *L)
break;
}
ent = WEDICT_NUM(world->progs, i);
if (!ent->isfree)
if (!ED_ISFREE(ent))
{
break;
}
@ -1145,7 +1147,7 @@ static int bi_lua_vectoangles(lua_State *L)
lua_readvector(L, 1, up);
uv = up;
}
VectorAngles(forward, up, ret);
VectorAngles(forward, uv, ret, true);
lua.createtable(L, 0, 0);
//FIXME: should provide a metatable with a __tostring
@ -1203,7 +1205,7 @@ static int bi_lua_findradiuschain(lua_State *L)
for (i=1 ; i<world->num_edicts ; i++)
{
ent = EDICT_NUM(world->progs, i);
if (ent->isfree)
if (ED_ISFREE(ent))
continue;
if (ent->v->solid == SOLID_NOT && (progstype != PROG_QW || !((int)ent->v->flags & FL_FINDABLE_NONSOLID)) && !sv_gameplayfix_blowupfallenzombies.value)
continue;
@ -1242,7 +1244,7 @@ static int bi_lua_findradiustable(lua_State *L)
for (i=1 ; i<world->num_edicts ; i++)
{
ent = EDICT_NUM(world->progs, i);
if (ent->isfree)
if (ED_ISFREE(ent))
continue;
if (ent->v->solid == SOLID_NOT && (progstype != PROG_QW || !((int)ent->v->flags & FL_FINDABLE_NONSOLID)) && !sv_gameplayfix_blowupfallenzombies.value)
continue;
@ -1408,7 +1410,7 @@ typedef struct
lua_State *L;
int idx;
} luafsenum_t;
static int QDECL lua_file_enumerate(const char *fname, qofs_t fsize, void *param, searchpathfuncs_t *spath)
static int QDECL lua_file_enumerate(const char *fname, qofs_t fsize, time_t mtime, void *param, searchpathfuncs_t *spath)
{
luafsenum_t *e = param;
lua.pushinteger(e->L, e->idx++);
@ -1651,7 +1653,7 @@ void Lua_EntClear (pubprogfuncs_t *pf, edict_t *e)
{
int num = e->entnum;
memset (e->v, 0, sv.world.edict_size);
e->isfree = false;
e->ereftype = ER_ENTITY;
e->entnum = num;
}
edict_t *Lua_CreateEdict(unsigned int num)
@ -1671,7 +1673,7 @@ static void QDECL Lua_EntRemove(pubprogfuncs_t *pf, edict_t *e)
if (!ED_CanFree(e))
return;
e->isfree = true;
e->ereftype = ER_FREE;
e->freetime = sv.time;
//clear out the lua version of the entity, so that it can be garbage collected.
@ -1713,7 +1715,7 @@ static edict_t *Lua_DoRespawn(pubprogfuncs_t *pf, edict_t *e, int num)
lua.settable(L, LUA_REGISTRYINDEX);
return e;
}
static edict_t *QDECL Lua_EntAlloc(pubprogfuncs_t *pf)
static edict_t *QDECL Lua_EntAlloc(pubprogfuncs_t *pf, pbool isobject, size_t extrasize)
{
int i;
edict_t *e;
@ -1722,7 +1724,7 @@ static edict_t *QDECL Lua_EntAlloc(pubprogfuncs_t *pf)
e = (edict_t*)EDICT_NUM(pf, i);
// the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy
if (!e || (e->isfree && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) ))
if (!e || (ED_ISFREE(e) && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) ))
{
e = Lua_DoRespawn(pf, e, i);
return (struct edict_s *)e;
@ -1736,7 +1738,7 @@ static edict_t *QDECL Lua_EntAlloc(pubprogfuncs_t *pf)
e = (edict_t*)EDICT_NUM(pf, i);
// the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy
if (!e || (e->isfree))
if (!e || ED_ISFREE(e))
{
e = Lua_DoRespawn(pf, e, i);
return (struct edict_s *)e;
@ -1757,7 +1759,7 @@ static edict_t *QDECL Lua_EntAlloc(pubprogfuncs_t *pf)
return (struct edict_s *)e;
}
static int QDECL Lua_LoadEnts(pubprogfuncs_t *pf, char *mapstring, float spawnflags)
static int QDECL Lua_LoadEnts(pubprogfuncs_t *pf, const char *mapstring, void *ctx, void (PDECL *callback) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend))
{
lua_State *L = lua.ctx;
int i = 0;
@ -1769,7 +1771,7 @@ static int QDECL Lua_LoadEnts(pubprogfuncs_t *pf, char *mapstring, float spawnfl
lua.pushstring(L, com_token);
lua.settable(L, -3);
}
lua.pushinteger(L, spawnflags);
// lua.pushinteger(L, spawnflags);
if (lua.pcall(L, 2, 0, 0) != 0)
{
@ -1871,7 +1873,7 @@ static void QDECL Lua_SetStringField(pubprogfuncs_t *prinst, edict_t *ed, string
*fld = base | val; //set the engine's value
//set the stuff so that lua can read it properly.
lua.pushlightuserdata(L, (void *)val);
lua.pushlightuserdata(L, (void *)(qintptr_t)val);
lua.pushfstring(L, "%s", str);
lua.rawset(L, -3);
@ -1902,7 +1904,7 @@ static const char *ASMCALL QDECL Lua_StringToNative(pubprogfuncs_t *prinst, stri
}
//read the function from the table
lua.pushlightuserdata(lua.ctx, (void *)str);
lua.pushlightuserdata(lua.ctx, (void *)(qintptr_t)str);
lua.rawget(lua.ctx, -2);
ret = lua.tolstring(lua.ctx, -1, NULL);
lua.pop(lua.ctx, 2); //pop the table+string.
@ -2044,7 +2046,7 @@ void QDECL Lua_ExecuteProgram(pubprogfuncs_t *funcs, func_t func)
}
//read the function from the table
lua.pushlightuserdata(lua.ctx, (void *)func);
lua.pushlightuserdata(lua.ctx, (void *)(qintptr_t)func);
lua.rawget(lua.ctx, -2);
//and now invoke it.
@ -2131,7 +2133,7 @@ qboolean PR_LoadLua(void)
my_lua_registerbuiltins(lua.ctx);
//spawn the world, woo.
world->edicts = (wedict_t*)pf->EntAlloc(pf);
world->edicts = (wedict_t*)pf->EntAlloc(pf,false,0);
//load the gamecode now. it should be safe for it to call various builtins.
if (0 != lua.load(lua.ctx, my_lua_Reader, sourcefile, "progs.lua", "bt")) //load the file, embed it within a function and push it

View File

@ -127,7 +127,7 @@ cvar_t sv_listen_q3 = CVAR("sv_listen_q3", "0");
#ifdef HAVE_DTLS
cvar_t sv_listen_dtls = CVARCD("net_enable_dtls", "", SV_Listen_Dtls_Changed, "Controls serverside dtls support.\n0: dtls blocked, not advertised.\n1: available in desired.\n2: used where possible (recommended setting).\n3: disallow non-dtls clients (sv_port_tcp should be eg tls://[::]:27500 to also disallow unencrypted tcp connections).");
#endif
cvar_t sv_reportheartbeats = CVAR("sv_reportheartbeats", "1");
cvar_t sv_reportheartbeats = CVARD("sv_reportheartbeats", "2", "Print a notice each time a heartbeat is sent to a master server. When set to 2, the message will be displayed once.");
cvar_t sv_highchars = CVAR("sv_highchars", "1");
cvar_t sv_maxrate = CVAR("sv_maxrate", "30000");
cvar_t sv_maxdrate = CVARAF("sv_maxdrate", "500000",
@ -541,6 +541,9 @@ void SV_DropClient (client_t *drop)
{
case GT_MAX:
break;
#ifdef VM_LUA
case GT_LUA:
#endif
case GT_Q1QVM:
case GT_PROGS:
if (svprogfuncs)

View File

@ -56,6 +56,7 @@ cvar_t sv_waterfriction = CVAR( "sv_waterfriction", "4");
cvar_t sv_gameplayfix_noairborncorpse = CVAR( "sv_gameplayfix_noairborncorpse", "0");
cvar_t sv_gameplayfix_multiplethinks = CVARD( "sv_gameplayfix_multiplethinks", "1", "Enables multiple thinks per entity per frame so small nextthink times are accurate. QuakeWorld mods expect a value of 1.");
cvar_t sv_gameplayfix_stepdown = CVARD( "sv_gameplayfix_stepdown", "0", "Attempt to step down steps, instead of only up them. Affects non-predicted movetype_walk.");
cvar_t sv_gameplayfix_bouncedownslopes = CVARD( "sv_gameplayfix_grenadebouncedownslopes", "0", "MOVETYPE_BOUNCE speeds are calculated relative to the impacted surface, instead of the vertical, reducing the chance of grenades just sitting there on slopes.");
#if !defined(CLIENTONLY) && defined(NQPROT) && !defined(NOLEGACY)
cvar_t sv_gameplayfix_spawnbeforethinks = CVARD( "sv_gameplayfix_spawnbeforethinks", "0", "Fixes an issue where player thinks (including Pre+Post) can be called before PutClientInServer. Unfortunately at least one mod depends upon PreThink being called first in order to correctly determine spawn positions.");
#endif
@ -92,6 +93,7 @@ void WPhys_Init(void)
Cvar_Register (&sv_gameplayfix_noairborncorpse, cvargroup_serverphysics);
Cvar_Register (&sv_gameplayfix_multiplethinks, cvargroup_serverphysics);
Cvar_Register (&sv_gameplayfix_stepdown, cvargroup_serverphysics);
Cvar_Register (&sv_gameplayfix_bouncedownslopes, cvargroup_serverphysics);
#if !defined(CLIENTONLY) && defined(NQPROT) && !defined(NOLEGACY)
Cvar_Register (&sv_gameplayfix_spawnbeforethinks, cvargroup_serverphysics);
@ -1383,12 +1385,19 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
VectorCopy(trace.endpos, move);
if (ent->v->movetype == MOVETYPE_BOUNCE)
{
if (ent->xv->bouncefactor)
backoff = 1 + ent->xv->bouncefactor;
else
backoff = 1.5;
}
else if (ent->v->movetype == MOVETYPE_BOUNCEMISSILE)
{
// if (progstype == PROG_H2 && ent->v->solid == SOLID_PHASEH2 && ((int)((wedict_t*)trace.ent)->v->flags & (FL_MONSTER|FL_CLIENT)))
if (ent->xv->bouncefactor)
backoff = 1 + ent->xv->bouncefactor;
// else if (progstype == PROG_H2 && ent->v->solid == SOLID_PHASEH2 && ((int)((wedict_t*)trace.ent)->v->flags & (FL_MONSTER|FL_CLIENT)))
// backoff = 0;
// else
else
backoff = 2;
}
else
@ -1401,7 +1410,15 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
// stop if on ground
if ((-DotProduct(gravitydir, trace.plane.normal) > 0.7) && (ent->v->movetype != MOVETYPE_BOUNCEMISSILE))
{
if (-DotProduct(gravitydir, ent->v->velocity) < 60 || ent->v->movetype != MOVETYPE_BOUNCE )
float bouncespeed;
float bouncestop = ent->xv->bouncestop;
if (!bouncestop)
bouncestop = 60;
if (sv_gameplayfix_bouncedownslopes.ival)
bouncespeed = DotProduct(trace.plane.normal, ent->v->velocity);
else
bouncespeed = -DotProduct(gravitydir, ent->v->velocity);
if (bouncespeed < bouncestop || ent->v->movetype != MOVETYPE_BOUNCE )
{
ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
ent->v->groundentity = EDICT_TO_PROG(w->progs, trace.ent);
@ -1926,7 +1943,7 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir)
if (fabs(start_velocity[0]) < 0.03125 && fabs(start_velocity[1]) < 0.03125)
return;
if (ent->v->movetype != MOVETYPE_FLY)
if (ent->v->movetype != MOVETYPE_FLY && ent->v->movetype != MOVETYPE_FLY_WORLDONLY)
{
// return if gibbed by a trigger
if (ent->v->movetype != MOVETYPE_WALK)
@ -2173,6 +2190,19 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent)
break;
case MOVETYPE_FLY_WORLDONLY:
case MOVETYPE_FLY:
if (svent)
{ //NQ players with movetype_fly are not like non-players.
if (!WPhys_RunThink (w, ent))
return;
if (ent->xv->gravitydir[2] || ent->xv->gravitydir[1] || ent->xv->gravitydir[0])
gravitydir = ent->xv->gravitydir;
else
gravitydir = w->g.defaultgravitydir;
WPhys_CheckStuck (w, ent);
WPhys_WalkMove (w, ent, gravitydir);
break;
}
//fallthrough
case MOVETYPE_H2SWIM:
case MOVETYPE_TOSS:
case MOVETYPE_BOUNCE:

View File

@ -103,8 +103,8 @@ extern cvar_t pm_flyfriction;
cvar_t sv_pushplayers = CVAR("sv_pushplayers", "0");
//yes, realip cvars need to be fully initialised or realip will be disabled
cvar_t sv_getrealip = CVARD("sv_getrealip", "0", "Attempt to obtain a more reliable IP for clients, rather than just their proxy.");
cvar_t sv_realip_kick = CVAR("sv_realip_kick", "0");
cvar_t sv_getrealip = CVARD("sv_getrealip", "0", "Attempt to obtain a more reliable IP for clients, rather than just their proxy.\n0: Don't attempt.\n1: Unreliable checks.\n2: Validate if possible.\n3: Mandatory validation.");
cvar_t sv_realip_kick = CVARD("sv_realip_kick", "0", "Kicks clients if their realip could not be validated to the level specified by sv_getrealip.");
cvar_t sv_realiphostname_ipv4 = CVARD("sv_realiphostname_ipv4", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable");
cvar_t sv_realiphostname_ipv6 = CVARD("sv_realiphostname_ipv6", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable");
cvar_t sv_realip_timeout = CVAR("sv_realip_timeout", "10");

View File

@ -930,7 +930,7 @@ void SW_R_RenderView(void)
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
if (r_refdef.useperspective)
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, r_refdef.fov_x, r_refdef.fov_y, r_refdef.mindist);
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, r_refdef.fov_x, r_refdef.fov_y, r_refdef.mindist, false);
else
Matrix4x4_CM_Orthographic(r_refdef.m_projection_std, -r_refdef.fov_x/2, r_refdef.fov_x/2, -r_refdef.fov_y/2, r_refdef.fov_y/2, r_refdef.mindist, r_refdef.maxdist>=1?r_refdef.maxdist:9999);
VectorCopy(r_refdef.viewangles, newa);

View File

@ -3586,11 +3586,23 @@ static void BE_DrawMeshChain_Internal(void)
continue;
if (p->prog)
{
if (shaderstate.batchvbo)
{
vertexbuffers[VK_BUFF_TC] = shaderstate.batchvbo->texcoord.vk.buff;
vertexoffsets[VK_BUFF_TC] = shaderstate.batchvbo->texcoord.vk.offs;
vertexbuffers[VK_BUFF_LMTC] = shaderstate.batchvbo->lmcoord[0].vk.buff;
vertexoffsets[VK_BUFF_LMTC] = shaderstate.batchvbo->lmcoord[0].vk.offs;
}
else
{
float *map;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec2_t), &vertexbuffers[VK_BUFF_TC], &vertexoffsets[VK_BUFF_TC]);
BE_GenerateTCMods(p, map);
vertexbuffers[VK_BUFF_LMTC] = vertexbuffers[VK_BUFF_TC];
vertexoffsets[VK_BUFF_LMTC] = vertexoffsets[VK_BUFF_TC];
}
BE_GenerateColourMods(vertcount, p, &vertexbuffers[VK_BUFF_COL], &vertexoffsets[VK_BUFF_COL]);
@ -4191,7 +4203,7 @@ void VKBE_SetupLightCBuffer(dlight_t *l, vec3_t colour)
float view[16];
float proj[16];
extern cvar_t r_shadow_shadowmapping_nearclip;
Matrix4x4_CM_Projection_Far(proj, l->fov, l->fov, r_shadow_shadowmapping_nearclip.value, l->radius);
Matrix4x4_CM_Projection_Far(proj, l->fov, l->fov, r_shadow_shadowmapping_nearclip.value, l->radius, false);
Matrix4x4_CM_ModelViewMatrixFromAxis(view, l->axis[0], l->axis[1], l->axis[2], l->origin);
Matrix4_Multiply(proj, view, cbl->l_cubematrix);
}
@ -4229,14 +4241,16 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
shaderstate.curentity = e;
if (e->flags & RF_DEPTHHACK)
proj = r_refdef.m_projection_view;
else
proj = r_refdef.m_projection_std;
if ((e->flags & RF_WEAPONMODEL) && r_refdef.playerview->viewentity > 0)
{
float em[16];
float vm[16];
proj = r_refdef.m_projection_view;
if (e->flags & RF_WEAPONMODELNOBOB)
{
vm[0] = vpn[0];
@ -4306,8 +4320,6 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
}
else
{
proj = r_refdef.m_projection_std;
m[0] = e->axis[0][0];
m[1] = e->axis[0][1];
m[2] = e->axis[0][2];

View File

@ -451,6 +451,7 @@ static qboolean VK_CreateSwapChain(void)
}
if (!vk.vsync && swapinfo.presentMode != VK_PRESENT_MODE_IMMEDIATE_KHR)
if (!vk.swapchain) //only warn on vid_restart, otherwise its annoying when resizing.
Con_Printf("Warning: vulkan graphics driver does not support VK_PRESENT_MODE_IMMEDIATE_KHR.\n");
vk.srgbcapable = false;
@ -887,62 +888,99 @@ vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t lay
ret.layout = staging?VK_IMAGE_LAYOUT_PREINITIALIZED:VK_IMAGE_LAYOUT_UNDEFINED;
//16bit formats.
if (encoding == PTI_RGB565)
format = VK_FORMAT_R5G6B5_UNORM_PACK16;
else if (encoding == PTI_RGBA4444)
format = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
else if (encoding == PTI_ARGB4444)
format = VK_FORMAT_B4G4R4A4_UNORM_PACK16; //fixme: this seems wrong.
else if (encoding == PTI_RGBA5551)
format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
else if (encoding == PTI_ARGB1555)
format = VK_FORMAT_A1R5G5B5_UNORM_PACK16;
switch(encoding)
{
case PTI_RGB565: format = VK_FORMAT_R5G6B5_UNORM_PACK16; break;
case PTI_RGBA4444: format = VK_FORMAT_R4G4B4A4_UNORM_PACK16; break;
case PTI_ARGB4444: format = VK_FORMAT_B4G4R4A4_UNORM_PACK16; break; //fixme: this seems wrong...
case PTI_RGBA5551: format = VK_FORMAT_R5G5B5A1_UNORM_PACK16; break;
case PTI_ARGB1555: format = VK_FORMAT_A1R5G5B5_UNORM_PACK16; break;
//float formats
else if (encoding == PTI_RGBA16F)
format = VK_FORMAT_R16G16B16A16_SFLOAT;
else if (encoding == PTI_RGBA32F)
format = VK_FORMAT_R32G32B32A32_SFLOAT;
case PTI_RGBA16F: format = VK_FORMAT_R16G16B16A16_SFLOAT; break;
case PTI_RGBA32F: format = VK_FORMAT_R32G32B32A32_SFLOAT; break;
//weird formats
else if (encoding == PTI_R8)
format = VK_FORMAT_R8_UNORM;
else if (encoding == PTI_RG8)
format = VK_FORMAT_R8G8_UNORM;
case PTI_R8: format = VK_FORMAT_R8_UNORM; break;
case PTI_RG8: format = VK_FORMAT_R8G8_UNORM; break;
case PTI_R8_SIGNED: format = VK_FORMAT_R8_SNORM; break;
case PTI_RG8_SIGNED: format = VK_FORMAT_R8G8_SNORM; break;
//compressed formats
else if (encoding == PTI_S3RGB1)
format = VK_FORMAT_BC1_RGB_UNORM_BLOCK;
else if (encoding == PTI_S3RGBA1)
format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
else if (encoding == PTI_S3RGBA3)
format = VK_FORMAT_BC2_UNORM_BLOCK;
else if (encoding == PTI_S3RGBA5)
format = VK_FORMAT_BC3_UNORM_BLOCK;
else if (encoding == PTI_ETC1_RGB8) //vulkan doesn't support etc1, but etc2 is a superset so its all okay.
format = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
else if (encoding == PTI_ETC2_RGB8)
format = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
else if (encoding == PTI_ETC2_RGB8A1)
format = VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
else if (encoding == PTI_ETC2_RGB8A8)
format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
case PTI_BC1_RGB: format = VK_FORMAT_BC1_RGB_UNORM_BLOCK; break;
case PTI_BC1_RGB_SRGB: format = VK_FORMAT_BC1_RGB_SRGB_BLOCK; break;
case PTI_BC1_RGBA: format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK; break;
case PTI_BC1_RGBA_SRGB: format = VK_FORMAT_BC1_RGBA_SRGB_BLOCK; break;
case PTI_BC2_RGBA: format = VK_FORMAT_BC2_UNORM_BLOCK; break;
case PTI_BC2_RGBA_SRGB: format = VK_FORMAT_BC2_SRGB_BLOCK; break;
case PTI_BC3_RGBA: format = VK_FORMAT_BC3_UNORM_BLOCK; break;
case PTI_BC3_RGBA_SRGB: format = VK_FORMAT_BC3_SRGB_BLOCK; break;
case PTI_BC4_R8: format = VK_FORMAT_BC4_UNORM_BLOCK; break;
case PTI_BC4_R8_SIGNED: format = VK_FORMAT_BC4_SNORM_BLOCK; break;
case PTI_BC5_RG8: format = VK_FORMAT_BC5_UNORM_BLOCK; break;
case PTI_BC5_RG8_SIGNED: format = VK_FORMAT_BC5_SNORM_BLOCK; break;
case PTI_BC6_RGBF: format = VK_FORMAT_BC6H_UFLOAT_BLOCK; break;
case PTI_BC6_RGBF_SIGNED: format = VK_FORMAT_BC6H_SFLOAT_BLOCK; break;
case PTI_BC7_RGBA: format = VK_FORMAT_BC7_UNORM_BLOCK; break;
case PTI_BC7_RGBA_SRGB: format = VK_FORMAT_BC7_SRGB_BLOCK; break;
case PTI_ETC1_RGB8: format = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; break; //vulkan doesn't support etc1, but etc2 is a superset so its all okay.
case PTI_ETC2_RGB8: format = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; break;
case PTI_ETC2_RGB8_SRGB: format = VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK; break;
case PTI_ETC2_RGB8A1: format = VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK; break;
case PTI_ETC2_RGB8A1_SRGB: format = VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK; break;
case PTI_ETC2_RGB8A8: format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; break;
case PTI_ETC2_RGB8A8_SRGB: format = VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK; break;
case PTI_EAC_R11: format = VK_FORMAT_EAC_R11_UNORM_BLOCK; break;
case PTI_EAC_R11_SIGNED: format = VK_FORMAT_EAC_R11_SNORM_BLOCK; break;
case PTI_EAC_RG11: format = VK_FORMAT_EAC_R11G11_UNORM_BLOCK; break;
case PTI_EAC_RG11_SIGNED: format = VK_FORMAT_EAC_R11G11_SNORM_BLOCK; break;
case PTI_ASTC_4X4: format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK; break;
case PTI_ASTC_4X4_SRGB: format = VK_FORMAT_ASTC_4x4_SRGB_BLOCK; break;
case PTI_ASTC_5X4: format = VK_FORMAT_ASTC_5x4_UNORM_BLOCK; break;
case PTI_ASTC_5X4_SRGB: format = VK_FORMAT_ASTC_5x4_SRGB_BLOCK; break;
case PTI_ASTC_5X5: format = VK_FORMAT_ASTC_5x5_UNORM_BLOCK; break;
case PTI_ASTC_5X5_SRGB: format = VK_FORMAT_ASTC_5x5_SRGB_BLOCK; break;
case PTI_ASTC_6X5: format = VK_FORMAT_ASTC_6x5_UNORM_BLOCK; break;
case PTI_ASTC_6X5_SRGB: format = VK_FORMAT_ASTC_6x5_SRGB_BLOCK; break;
case PTI_ASTC_6X6: format = VK_FORMAT_ASTC_6x6_UNORM_BLOCK; break;
case PTI_ASTC_6X6_SRGB: format = VK_FORMAT_ASTC_6x6_SRGB_BLOCK; break;
case PTI_ASTC_8X5: format = VK_FORMAT_ASTC_8x5_UNORM_BLOCK; break;
case PTI_ASTC_8X5_SRGB: format = VK_FORMAT_ASTC_8x5_SRGB_BLOCK; break;
case PTI_ASTC_8X6: format = VK_FORMAT_ASTC_8x6_UNORM_BLOCK; break;
case PTI_ASTC_8X6_SRGB: format = VK_FORMAT_ASTC_8x6_SRGB_BLOCK; break;
case PTI_ASTC_8X8: format = VK_FORMAT_ASTC_8x8_UNORM_BLOCK; break;
case PTI_ASTC_8X8_SRGB: format = VK_FORMAT_ASTC_8x8_SRGB_BLOCK; break;
case PTI_ASTC_10X5: format = VK_FORMAT_ASTC_10x5_UNORM_BLOCK; break;
case PTI_ASTC_10X5_SRGB: format = VK_FORMAT_ASTC_10x5_SRGB_BLOCK; break;
case PTI_ASTC_10X6: format = VK_FORMAT_ASTC_10x6_UNORM_BLOCK; break;
case PTI_ASTC_10X6_SRGB: format = VK_FORMAT_ASTC_10x6_SRGB_BLOCK; break;
case PTI_ASTC_10X8: format = VK_FORMAT_ASTC_10x8_UNORM_BLOCK; break;
case PTI_ASTC_10X8_SRGB: format = VK_FORMAT_ASTC_10x8_SRGB_BLOCK; break;
case PTI_ASTC_10X10: format = VK_FORMAT_ASTC_10x10_UNORM_BLOCK; break;
case PTI_ASTC_10X10_SRGB: format = VK_FORMAT_ASTC_10x10_SRGB_BLOCK; break;
case PTI_ASTC_12X10: format = VK_FORMAT_ASTC_12x10_UNORM_BLOCK; break;
case PTI_ASTC_12X10_SRGB: format = VK_FORMAT_ASTC_12x10_SRGB_BLOCK; break;
case PTI_ASTC_12X12: format = VK_FORMAT_ASTC_12x12_UNORM_BLOCK; break;
case PTI_ASTC_12X12_SRGB: format = VK_FORMAT_ASTC_12x12_SRGB_BLOCK; break;
//depth formats
else if (encoding == PTI_DEPTH16)
format = VK_FORMAT_D16_UNORM;
else if (encoding == PTI_DEPTH24)
format = VK_FORMAT_X8_D24_UNORM_PACK32;
else if (encoding == PTI_DEPTH32)
format = VK_FORMAT_D32_SFLOAT;
else if (encoding == PTI_DEPTH24_8)
format = VK_FORMAT_D24_UNORM_S8_UINT;
case PTI_DEPTH16: format = VK_FORMAT_D16_UNORM; break;
case PTI_DEPTH24: format = VK_FORMAT_X8_D24_UNORM_PACK32; break;
case PTI_DEPTH32: format = VK_FORMAT_D32_SFLOAT; break;
case PTI_DEPTH24_8: format = VK_FORMAT_D24_UNORM_S8_UINT; break;
//srgb formats
else if (encoding == PTI_BGRA8_SRGB || encoding == PTI_BGRX8_SRGB)
format = VK_FORMAT_B8G8R8A8_SRGB;
else if (encoding == PTI_RGBA8_SRGB || encoding == PTI_RGBX8_SRGB)
format = VK_FORMAT_R8G8B8A8_SRGB;
case PTI_BGRA8_SRGB:
case PTI_BGRX8_SRGB: format = VK_FORMAT_B8G8R8A8_SRGB; break;
case PTI_RGBA8_SRGB:
case PTI_RGBX8_SRGB: format = VK_FORMAT_R8G8B8A8_SRGB; break;
//standard formats
else if (encoding == PTI_BGRA8 || encoding == PTI_BGRX8)
format = VK_FORMAT_B8G8R8A8_UNORM;
else //if (encoding == PTI_RGBA8 || encoding == PTI_RGBX8)
format = VK_FORMAT_R8G8B8A8_UNORM;
case PTI_BGRA8:
case PTI_BGRX8: format = VK_FORMAT_B8G8R8A8_UNORM; break;
case PTI_RGBA8:
case PTI_RGBX8: format = VK_FORMAT_R8G8B8A8_UNORM; break;
default:
Sys_Error("VK_CreateTexture2DArray: Unrecognised image encoding: %u\n", encoding);
format = VK_FORMAT_UNDEFINED;
break;
}
ici.flags = (ret.type==PTI_CUBEMAP)?VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:0;
ici.imageType = VK_IMAGE_TYPE_2D;
ici.format = format;
@ -1188,7 +1226,7 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
VkCommandBuffer vkloadcmd;
vk_image_t target;
uint32_t i;
uint32_t blocksize;
uint32_t blockwidth, blockheight;
uint32_t blockbytes;
uint32_t layers;
uint32_t mipcount = mips->mipcount;
@ -1213,57 +1251,7 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
}
}
switch(mips->encoding)
{
case PTI_RGB565:
case PTI_RGBA4444:
case PTI_ARGB4444:
case PTI_RGBA5551:
case PTI_ARGB1555:
blocksize = 1;
blockbytes = 2; //16bit formats
break;
case PTI_RGBA8:
case PTI_RGBX8:
case PTI_BGRA8:
case PTI_BGRX8:
case PTI_RGBA8_SRGB:
case PTI_RGBX8_SRGB:
case PTI_BGRA8_SRGB:
case PTI_BGRX8_SRGB:
blocksize = 1; //in texels
blockbytes = 4;
break;
case PTI_S3RGB1:
case PTI_S3RGBA1:
blocksize = 4;
blockbytes = 8;
break;
case PTI_S3RGBA3:
case PTI_S3RGBA5:
blocksize = 4;
blockbytes = 16;
break;
case PTI_RGBA16F:
blocksize = 1;
blockbytes = 4*2;
break;
case PTI_RGBA32F:
blocksize = 1;
blockbytes = 4*4;
break;
case PTI_R8:
blocksize = 1;
blockbytes = 1;
break;
case PTI_RG8:
blocksize = 1;
blockbytes = 2;
break;
default:
return false;
}
Image_BlockSizeForEncoding(mips->encoding, &blockbytes, &blockwidth, &blockheight);
fence = VK_FencedBegin(VK_TextureLoaded, sizeof(*fence));
fence->mips = mipcount;
@ -1346,10 +1334,10 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
bci.size = 0;
for (i = 0; i < mipcount; i++)
{
uint32_t blockwidth = (mips->mip[i].width+blocksize-1) / blocksize;
uint32_t blockheight = (mips->mip[i].height+blocksize-1) / blocksize;
uint32_t blockswidth = (mips->mip[i].width+blockwidth-1) / blockwidth;
uint32_t blocksheight = (mips->mip[i].height+blockheight-1) / blockheight;
bci.size += blockwidth*blockheight*blockbytes;
bci.size += blockswidth*blocksheight*blockbytes;
}
bci.flags = 0;
bci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
@ -1378,18 +1366,18 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
//figure out the number of 'blocks' in the image.
//for non-compressed formats this is just the width directly.
//for compressed formats (ie: s3tc/dxt) we need to round up to deal with npot.
uint32_t blockwidth = (mips->mip[i].width+blocksize-1) / blocksize;
uint32_t blockheight = (mips->mip[i].height+blocksize-1) / blocksize;
uint32_t blockswidth = (mips->mip[i].width+blockwidth-1) / blockwidth;
uint32_t blocksheight = (mips->mip[i].height+blockheight-1) / blockheight;
if (mips->mip[i].data)
memcpy((char*)mapdata + bci.size, (char*)mips->mip[i].data, blockwidth*blockbytes*blockheight);
memcpy((char*)mapdata + bci.size, (char*)mips->mip[i].data, blockswidth*blockbytes*blocksheight);
else
memset((char*)mapdata + bci.size, 0, blockwidth*blockbytes*blockheight);
memset((char*)mapdata + bci.size, 0, blockswidth*blockbytes*blocksheight);
//queue up a buffer->image copy for this mip
region.bufferOffset = bci.size;
region.bufferRowLength = blockwidth*blocksize;//*blockbytes;
region.bufferImageHeight = blockheight*blocksize;
region.bufferRowLength = blockswidth*blockwidth;
region.bufferImageHeight = blocksheight*blockheight;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = i%(mipcount/layers);
region.imageSubresource.baseArrayLayer = i/(mipcount/layers);
@ -1397,13 +1385,13 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
region.imageOffset.x = 0;
region.imageOffset.y = 0;
region.imageOffset.z = 0;
region.imageExtent.width = mips->mip[i].width;//blockwidth*blocksize;
region.imageExtent.height = mips->mip[i].height;//blockheight*blocksize;
region.imageExtent.width = mips->mip[i].width;//blockswidth*blockwidth;
region.imageExtent.height = mips->mip[i].height;//blocksheight*blockheight;
region.imageExtent.depth = 1;
vkCmdCopyBufferToImage(vkloadcmd, fence->stagingbuffer, target.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
bci.size += blockwidth*blockheight*blockbytes;
bci.size += blockswidth*blocksheight*blockbytes;
}
vkUnmapMemory(vk.device, fence->stagingmemory);
#else
@ -1416,8 +1404,8 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
//figure out the number of 'blocks' in the image.
//for non-compressed formats this is just the width directly.
//for compressed formats (ie: s3tc/dxt) we need to round up to deal with npot.
uint32_t blockwidth = (mips->mip[i].width+blocksize-1) / blocksize;
uint32_t blockheight = (mips->mip[i].height+blocksize-1) / blocksize;
uint32_t blockswidth = (mips->mip[i].width+blockwidth-1) / blockwidth;
uint32_t blocksheight = (mips->mip[i].height+blockheight-1) / blockheight;
fence->staging[i] = VK_CreateTexture2DArray(mips->mip[i].width, mips->mip[i].height, 0, 1, mips->encoding, PTI_2D);
subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -1428,7 +1416,7 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
if (mapdata)
{
for (y = 0; y < blockheight; y++)
memcpy((char*)mapdata + layout.offset + y*layout.rowPitch, (char*)mips->mip[i].data + y*blockwidth*blockbytes, blockwidth*blockbytes);
memcpy((char*)mapdata + layout.offset + y*layout.rowPitch, (char*)mips->mip[i].data + y*blockswidth*blockbytes, blockswidth*blockbytes);
}
else
Sys_Error("Unable to map staging image\n");
@ -1527,17 +1515,22 @@ void VK_R_DeInit (void)
void VK_SetupViewPortProjection(qboolean flipy)
{
float fov_x, fov_y;
float fovv_x, fovv_y;
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
fov_x = r_refdef.fov_x;//+sin(cl.time)*5;
fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5;
fovv_x = r_refdef.fovv_x;
fovv_y = r_refdef.fovv_y;
if ((r_refdef.flags & RDF_UNDERWATER) && !(r_refdef.flags & RDF_WATERWARP))
{
fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
fovv_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fovv_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
}
// screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
@ -1557,9 +1550,15 @@ void VK_SetupViewPortProjection(qboolean flipy)
r_refdef.flipcull = 0;
}
if (r_refdef.maxdist)
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist);
{
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, r_refdef.maxdist, false);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection_view, fovv_x, fovv_y, r_refdef.mindist, r_refdef.maxdist, false);
}
else
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist);
{
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_std, fov_x, fov_y, r_refdef.mindist, false);
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection_view, fovv_x, fovv_y, r_refdef.mindist, false);
}
}
void VK_Set2D(void)
@ -3373,21 +3372,69 @@ void VK_CheckTextureFormats(void)
{PTI_RGBA32F, VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT},
{PTI_R8, VK_FORMAT_R8_UNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_RG8, VK_FORMAT_R8G8_UNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_R8_SIGNED, VK_FORMAT_R8_SNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_RG8_SIGNED, VK_FORMAT_R8G8_SNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_DEPTH16, VK_FORMAT_D16_UNORM, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT},
{PTI_DEPTH24, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT},
{PTI_DEPTH32, VK_FORMAT_D32_SFLOAT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT},
{PTI_DEPTH24_8, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT},
{PTI_S3RGB1, VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_S3RGBA1, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_S3RGBA3, VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_S3RGBA5, VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ETC1_RGB8, VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT}, //vulkan doesn't support etc1.
{PTI_BC1_RGB, VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC1_RGBA, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC2_RGBA, VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC3_RGBA, VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC1_RGB_SRGB, VK_FORMAT_BC1_RGB_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC1_RGBA_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC2_RGBA_SRGB, VK_FORMAT_BC2_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC3_RGBA_SRGB, VK_FORMAT_BC3_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC4_R8, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC4_R8_SIGNED, VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC5_RG8, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC5_RG8_SIGNED, VK_FORMAT_BC5_SNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC6_RGBF, VK_FORMAT_BC6H_UFLOAT_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC6_RGBF_SIGNED, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC7_RGBA, VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC7_RGBA_SRGB, VK_FORMAT_BC7_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ETC1_RGB8, VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT}, //vulkan doesn't support etc1 (but that's okay, because etc2 is a superset).
{PTI_ETC2_RGB8, VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ETC2_RGB8A1, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ETC2_RGB8A8, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ETC2_RGB8_SRGB, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ETC2_RGB8A1_SRGB, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ETC2_RGB8A8_SRGB, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_EAC_R11, VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_EAC_R11_SIGNED, VK_FORMAT_EAC_R11_SNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_EAC_RG11, VK_FORMAT_EAC_R11G11_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_EAC_RG11_SIGNED, VK_FORMAT_EAC_R11G11_SNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_4X4, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_4X4_SRGB, VK_FORMAT_ASTC_4x4_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_5X4, VK_FORMAT_ASTC_5x4_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_5X4_SRGB, VK_FORMAT_ASTC_5x4_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_5X5, VK_FORMAT_ASTC_5x5_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_5X5_SRGB, VK_FORMAT_ASTC_5x5_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_6X5, VK_FORMAT_ASTC_6x5_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_6X5_SRGB, VK_FORMAT_ASTC_6x5_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_6X6, VK_FORMAT_ASTC_6x6_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_6X6_SRGB, VK_FORMAT_ASTC_6x6_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_8X5, VK_FORMAT_ASTC_8x5_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_8X5_SRGB, VK_FORMAT_ASTC_8x5_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_8X6, VK_FORMAT_ASTC_8x6_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_8X6_SRGB, VK_FORMAT_ASTC_8x6_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_8X8, VK_FORMAT_ASTC_8x8_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_8X8_SRGB, VK_FORMAT_ASTC_8x8_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_10X5, VK_FORMAT_ASTC_10x5_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_10X5_SRGB, VK_FORMAT_ASTC_10x5_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_10X6, VK_FORMAT_ASTC_10x6_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_10X6_SRGB, VK_FORMAT_ASTC_10x6_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_10X8, VK_FORMAT_ASTC_10x8_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_10X8_SRGB, VK_FORMAT_ASTC_10x8_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_10X10, VK_FORMAT_ASTC_10x10_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_10X10_SRGB, VK_FORMAT_ASTC_10x10_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_12X10, VK_FORMAT_ASTC_12x10_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_12X10_SRGB, VK_FORMAT_ASTC_12x10_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_12X12, VK_FORMAT_ASTC_12x12_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_ASTC_12X12_SRGB, VK_FORMAT_ASTC_12x12_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
};
unsigned int i;
VkPhysicalDeviceProperties props;
@ -3395,7 +3442,8 @@ void VK_CheckTextureFormats(void)
vkGetPhysicalDeviceProperties(vk.gpu, &props);
vk.limits = props.limits;
sh_config.texture_maxsize = props.limits.maxImageDimension2D;
sh_config.texture2d_maxsize = props.limits.maxImageDimension2D;
sh_config.texturecube_maxsize = props.limits.maxImageDimensionCube;
for (i = 0; i < countof(texfmt); i++)
{
@ -3803,6 +3851,7 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre
//try to enable whatever we can use, if we can.
features.robustBufferAccess = avail.robustBufferAccess;
features.textureCompressionBC = avail.textureCompressionBC;
features.textureCompressionETC2 = avail.textureCompressionETC2;
features.samplerAnisotropy = avail.samplerAnisotropy;
features.geometryShader = avail.geometryShader;
features.tessellationShader = avail.tessellationShader;
@ -3923,7 +3972,6 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre
sh_config.minver = -1;
sh_config.maxver = -1;
sh_config.texture_maxsize = 4096; //must be at least 4096, FIXME: query this properly
sh_config.texture_non_power_of_two = true; //is this always true?
sh_config.texture_non_power_of_two_pic = true; //probably true...
sh_config.npot_rounddown = false;