fix some d3d8+d3d11 issues. 2d stuff should work a bit better now.

setcursormode now available to menuqc too. this gives menuqc hardware cursor support (useful to revert some braindamage I added for dp compat - menuqc is a dp spec).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4953 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-07-31 13:23:32 +00:00
parent 6adb05d916
commit 9cb8a2d025
18 changed files with 430 additions and 168 deletions

View File

@ -240,6 +240,7 @@ cvar_t show_speed = SCVAR("show_speed", "0");
cvar_t show_speed_x = SCVAR("show_speed_x", "-1");
cvar_t show_speed_y = SCVAR("show_speed_y", "-9");
cvar_t scr_loadingrefresh = SCVAR("scr_loadingrefresh", "0");
cvar_t scr_showloading = CVAR("scr_showloading", "1");
cvar_t scr_showobituaries = CVAR("scr_showobituaries", "0");
void *scr_curcursor;
@ -252,6 +253,7 @@ void CLSCR_Init(void)
Cvar_Register(&con_stayhidden, cl_screengroup);
Cvar_Register(&scr_loadingrefresh, cl_screengroup);
Cvar_Register(&scr_showloading, cl_screengroup);
Cvar_Register(&show_fps, cl_screengroup);
Cvar_Register(&show_fps_x, cl_screengroup);
Cvar_Register(&show_fps_y, cl_screengroup);
@ -729,7 +731,7 @@ void SCR_DrawCursor(void)
if (key_customcursor[cmod].dirty)
{
if (key_customcursor[cmod].scale <= 0)
if (key_customcursor[cmod].scale <= 0 || !*key_customcursor[cmod].name)
{
key_customcursor[cmod].hotspot[0] = cl_cursorbiasx.value;
key_customcursor[cmod].hotspot[1] = cl_cursorbiasy.value;
@ -740,7 +742,9 @@ void SCR_DrawCursor(void)
oldcurs = key_customcursor[cmod].handle;
if (rf->VID_CreateCursor && strcmp(key_customcursor[cmod].name, "none"))
{
key_customcursor[cmod].handle = rf->VID_CreateCursor(key_customcursor[cmod].name, key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale);
key_customcursor[cmod].handle = NULL;
if (!key_customcursor[cmod].handle && *key_customcursor[cmod].name)
key_customcursor[cmod].handle = rf->VID_CreateCursor(key_customcursor[cmod].name, key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale);
if (!key_customcursor[cmod].handle)
key_customcursor[cmod].handle = rf->VID_CreateCursor("gfx/cursor.tga", key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale); //try the fallback
if (!key_customcursor[cmod].handle)
@ -1669,105 +1673,108 @@ void SCR_DrawLoading (qboolean opaque)
else if (opaque)
R2D_ConsoleBackground (0, vid.height, true);
qdepth = COM_FDepthFile("gfx/loading.lmp", true);
h2depth = COM_FDepthFile("gfx/menu/loading.lmp", true);
if (scr_showloading.ival)
{
qdepth = COM_FDepthFile("gfx/loading.lmp", true);
h2depth = COM_FDepthFile("gfx/menu/loading.lmp", true);
if (qdepth < h2depth || h2depth > 0xffffff)
{ //quake files
if (qdepth < h2depth || h2depth > 0xffffff)
{ //quake files
pic = R2D_SafeCachePic ("gfx/loading.lmp");
if (R_GetShaderSizes(pic, &w, &h, true))
{
x = (vid.width - w)/2;
y = (vid.height - 48 - h)/2;
R2D_ScalePic (x, y, w, h, pic);
x = (vid.width/2) - 96;
y += h + 8;
pic = R2D_SafeCachePic ("gfx/loading.lmp");
if (R_GetShaderSizes(pic, &w, &h, true))
{
x = (vid.width - w)/2;
y = (vid.height - 48 - h)/2;
R2D_ScalePic (x, y, w, h, pic);
x = (vid.width/2) - 96;
y += h + 8;
}
else
{
x = (vid.width/2) - 96;
y = (vid.height/2) - 8;
Draw_FunString((vid.width-7*8)/2, y-16, "Loading");
}
if (!total_loading_size)
total_loading_size = 1;
if (loading_stage > LS_CONNECTION)
{
sizex = current_loading_size * 192 / total_loading_size;
if (loading_stage == LS_SERVER)
{
R2D_ImageColours(1.0, 0.0, 0.0, 1.0);
R2D_FillBlock(x, y, sizex, 16);
R2D_ImageColours(0.0, 0.0, 0.0, 1.0);
R2D_FillBlock(x+sizex, y, 192-sizex, 16);
}
else
{
R2D_ImageColours(1.0, 1.0, 0.0, 1.0);
R2D_FillBlock(x, y, sizex, 16);
R2D_ImageColours(1.0, 0.0, 0.0, 1.0);
R2D_FillBlock(x+sizex, y, 192-sizex, 16);
}
Draw_FunString(x+8, y+4, va("Loading %s... %i%%",
(loading_stage == LS_SERVER) ? "server" : "client",
current_loading_size * 100 / total_loading_size));
}
y += 16;
if (loadingfile)
{
Draw_FunString(x+8, y+4, loadingfile);
y+=8;
}
}
else
{
x = (vid.width/2) - 96;
y = (vid.height/2) - 8;
Draw_FunString((vid.width-7*8)/2, y-16, "Loading");
}
if (!total_loading_size)
total_loading_size = 1;
if (loading_stage > LS_CONNECTION)
{
sizex = current_loading_size * 192 / total_loading_size;
if (loading_stage == LS_SERVER)
{ //hexen2 files
pic = R2D_SafeCachePic ("gfx/menu/loading.lmp");
if (R_GetShaderSizes(pic, &w, &h, true))
{
R2D_ImageColours(1.0, 0.0, 0.0, 1.0);
R2D_FillBlock(x, y, sizex, 16);
R2D_ImageColours(0.0, 0.0, 0.0, 1.0);
R2D_FillBlock(x+sizex, y, 192-sizex, 16);
int size, count, offset;
if (!scr_drawloading && loading_stage == 0)
return;
offset = (vid.width - w)/2;
R2D_ScalePic (offset, 0, w, h, pic);
if (loading_stage == LS_NONE)
return;
if (total_loading_size)
size = current_loading_size * 106 / total_loading_size;
else
size = 0;
if (loading_stage == LS_CLIENT)
count = size;
else
count = 106;
R2D_ImagePaletteColour (136, 1.0);
R2D_FillBlock (offset+42, 87, count, 1);
R2D_FillBlock (offset+42, 87+5, count, 1);
R2D_ImagePaletteColour (138, 1.0);
R2D_FillBlock (offset+42, 87+1, count, 4);
if (loading_stage == LS_SERVER)
count = size;
else
count = 0;
R2D_ImagePaletteColour(168, 1.0);
R2D_FillBlock (offset+42, 97, count, 1);
R2D_FillBlock (offset+42, 97+5, count, 1);
R2D_ImagePaletteColour(170, 1.0);
R2D_FillBlock (offset+42, 97+1, count, 4);
y = 104;
}
else
{
R2D_ImageColours(1.0, 1.0, 0.0, 1.0);
R2D_FillBlock(x, y, sizex, 16);
R2D_ImageColours(1.0, 0.0, 0.0, 1.0);
R2D_FillBlock(x+sizex, y, 192-sizex, 16);
}
Draw_FunString(x+8, y+4, va("Loading %s... %i%%",
(loading_stage == LS_SERVER) ? "server" : "client",
current_loading_size * 100 / total_loading_size));
}
y += 16;
if (loadingfile)
{
Draw_FunString(x+8, y+4, loadingfile);
y+=8;
}
}
else
{ //hexen2 files
pic = R2D_SafeCachePic ("gfx/menu/loading.lmp");
if (R_GetShaderSizes(pic, &w, &h, true))
{
int size, count, offset;
if (!scr_drawloading && loading_stage == 0)
return;
offset = (vid.width - w)/2;
R2D_ScalePic (offset, 0, w, h, pic);
if (loading_stage == LS_NONE)
return;
if (total_loading_size)
size = current_loading_size * 106 / total_loading_size;
else
size = 0;
if (loading_stage == LS_CLIENT)
count = size;
else
count = 106;
R2D_ImagePaletteColour (136, 1.0);
R2D_FillBlock (offset+42, 87, count, 1);
R2D_FillBlock (offset+42, 87+5, count, 1);
R2D_ImagePaletteColour (138, 1.0);
R2D_FillBlock (offset+42, 87+1, count, 4);
if (loading_stage == LS_SERVER)
count = size;
else
count = 0;
R2D_ImagePaletteColour(168, 1.0);
R2D_FillBlock (offset+42, 97, count, 1);
R2D_FillBlock (offset+42, 97+5, count, 1);
R2D_ImagePaletteColour(170, 1.0);
R2D_FillBlock (offset+42, 97+1, count, 4);
y = 104;
}
}
R2D_ImageColours(1, 1, 1, 1);

View File

@ -355,6 +355,38 @@ void QCBUILTIN PF_cl_keynumtostring (pubprogfuncs_t *prinst, struct globalvars_s
RETURN_TSTRING(Key_KeynumToString(code, 0));
}
//#343
void QCBUILTIN PF_cl_setcursormode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *world = prinst->parms->user;
if (G_FLOAT(OFS_PARM0))
key_dest_absolutemouse |= world->keydestmask;
else
key_dest_absolutemouse &= ~world->keydestmask;
if (prinst->callargc>1)
{
struct key_cursor_s *m = &key_customcursor[(world->keydestmask==kdm_game)?kc_game:kc_menu];
Q_strncpyz(m->name, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(m->name));
m->hotspot[0] = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+0):0;
m->hotspot[1] = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+1):0;
m->scale = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+2):0;
if (m->scale <= 0)
m->scale = 1;
m->dirty = true;
}
}
void QCBUILTIN PF_cl_getcursormode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *world = prinst->parms->user;
if (G_FLOAT(OFS_PARM0))
G_FLOAT(OFS_RETURN) = Key_MouseShouldBeFree();
else if (key_dest_absolutemouse & world->keydestmask)
G_FLOAT(OFS_RETURN) = true;
else
G_FLOAT(OFS_RETURN) = false;
}
void QCBUILTIN PF_cl_playingdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{

View File

@ -1253,7 +1253,7 @@ void QCBUILTIN PF_R_PolygonBegin(pubprogfuncs_t *prinst, struct globalvars_s *pr
if (csqc_isdarkplaces || (flags & 0x400))
flags |= BEF_FORCETWOSIDED;
if (csqc_poly_2d)
if (twod)
shader = R_RegisterPic(PR_GetStringOfs(prinst, OFS_PARM0));
else
shader = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL);
@ -2809,39 +2809,6 @@ static void cs_get_input_state (usercmd_t *cmd)
cmd->cursor_entitynumber = *csqcg.input_cursor_entitynumber;
}
//#343
static void QCBUILTIN PF_cl_setcursormode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *world = prinst->parms->user;
if (G_FLOAT(OFS_PARM0))
key_dest_absolutemouse |= world->keydestmask;
else
key_dest_absolutemouse &= ~world->keydestmask;
if (prinst->callargc>1)
{
struct key_cursor_s *m = &key_customcursor[(world->keydestmask==kdm_game)?kc_game:kc_menu];
Q_strncpyz(m->name, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(m->name));
m->hotspot[0] = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+0):0;
m->hotspot[1] = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+1):0;
m->scale = (prinst->callargc>2)?G_FLOAT(OFS_PARM2+2):0;
if (m->scale <= 0)
m->scale = 1;
m->dirty = true;
}
}
static void QCBUILTIN PF_cl_getcursormode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *world = prinst->parms->user;
if (G_FLOAT(OFS_PARM0))
G_FLOAT(OFS_RETURN) = Key_MouseShouldBeFree();
else if (key_dest_absolutemouse & world->keydestmask)
G_FLOAT(OFS_RETURN) = true;
else
G_FLOAT(OFS_RETURN) = false;
}
//get the input commands, and stuff them into some globals.
static void QCBUILTIN PF_cs_getinputstate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -6666,12 +6633,12 @@ qboolean CSQC_DrawView(void)
{
if (csqc_isdarkplaces)
{
static float oldtime;
static double oldtime;
if (cl.paused)
*csqcg.frametime = 0; //apparently people can't cope with microstutter when they're using this as a test to see if the game is paused.
else
*csqcg.frametime = bound(0, cl.servertime - oldtime, 0.1);
oldtime = cl.servertime;
*csqcg.frametime = bound(0, cl.time - oldtime, 0.1);
oldtime = cl.time;
}
else
*csqcg.frametime = host_frametime;

View File

@ -57,10 +57,10 @@ void QCBUILTIN PF_CL_drawsetcliparea (pubprogfuncs_t *prinst, struct globalvars_
srect_t srect;
csqc_dp_lastwas3d = false;
srect.x = G_FLOAT(OFS_PARM0) / (float)vid.width;
srect.y = (G_FLOAT(OFS_PARM1) / (float)vid.height);
srect.width = G_FLOAT(OFS_PARM2) / (float)vid.width;
srect.height = G_FLOAT(OFS_PARM3) / (float)vid.height;
srect.x = G_FLOAT(OFS_PARM0) / (float)vid.fbvwidth;
srect.y = G_FLOAT(OFS_PARM1) / (float)vid.fbvheight;
srect.width = G_FLOAT(OFS_PARM2) / (float)vid.fbvwidth;
srect.height = G_FLOAT(OFS_PARM3) / (float)vid.fbvheight;
srect.dmin = -99999;
srect.dmax = 99999;
srect.y = (1-srect.y) - srect.height;
@ -2010,6 +2010,8 @@ static struct {
{"keynumtostring_csqc", PF_cl_keynumtostring, 340},
{"stringtokeynum_csqc", PF_cl_stringtokeynum, 341},
{"getkeybind", PF_cl_getkeybind, 342},
{"setcursormode", PF_cl_setcursormode, 343},
{"getcursormode", PF_cl_getcursormode, 0},
//gap
{"isdemo", PF_isdemo, 349},
//gap

View File

@ -294,8 +294,10 @@ void R2D_Init(void)
"rgbgen const $r_menutint\n"
"}\n"
#else
"if $glsl && gl_menutint_shader != 0\n"
"if gl_menutint_shader != 0\n"
"program menutint\n"
"endif\n"
"if $haveprogram\n"
"{\n"
"map $currentrender\n"
"}\n"

View File

@ -62,7 +62,6 @@ void SCR_CheckDrawCenterString (void);
void SCR_DrawNet (void);
void SCR_DrawTurtle (void);
void SCR_DrawPause (void);
void SCR_VRectForPlayer(vrect_t *vrect, int pnum); //returns a region for the player's view
qboolean SCR_HardwareCursorIsActive(void);
void CLSCR_Init(void); //basically so I can register a few friendly cvars.

View File

@ -5886,6 +5886,7 @@ lh_extension_t QSG_Extensions[] = {
#endif
{"FTE_QC_CHECKCOMMAND", 1, NULL, {"checkcommand"}},
{"FTE_QC_CHECKPVS", 1, NULL, {"checkpvs"}},
{"FTE_QC_HARDWARECURSORS", 0, NULL, {NULL}, "setcursormode exists in both csqc+menuqc, and accepts additional arguments to specify a cursor image to use when this module has focus. If the image exceeds hardware limits, it will be emulated using regular draws - this at least still avoids conflicting cursors."},
{"FTE_QC_HASHTABLES", 6, NULL, {"hash_createtab", "hash_destroytab", "hash_add", "hash_get", "hash_delete", "hash_getkey"}},
{"FTE_QC_INTCONV", 4, NULL, {"stoi", "itos", "stoh", "htos"}},
{"FTE_QC_MATCHCLIENTNAME", 1, NULL, {"matchclientname"}},

View File

@ -392,6 +392,8 @@ void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s
void QCBUILTIN PF_cl_getkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_setmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_getmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_setcursormode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_getcursormode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_playingdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cs_media_create_http (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);

View File

@ -240,10 +240,13 @@ typedef struct
int indexstreamcycle;
int indexstreamoffset;
texid_t currentrender;
int numlivevbos;
int numliveshadowbuffers;
} d3d11backend_t;
extern D3D_FEATURE_LEVEL d3dfeaturelevel;
#define VERTEXSTREAMSIZE (1024*1024*2) //2mb = 1 PAE jumbo page
@ -315,6 +318,9 @@ void D3D11_UpdateFiltering(image_t *imagelist, int filtermip[3], int filterpic[3
sampdesc.MaxLOD = mipcap[1];
}
if (d3dfeaturelevel < D3D_FEATURE_LEVEL_10_0) //9.* sucks
sampdesc.MaxLOD = FLT_MAX;
if (shaderstate.sampstate[flags])
ID3D11SamplerState_Release(shaderstate.sampstate[flags]);
shaderstate.sampstate[flags] = NULL;
@ -394,6 +400,8 @@ static void BE_DestroyVariousStates(void)
shaderstate.ecbuffers[i] = NULL;
}
D3D11_DestroyTexture(shaderstate.currentrender);
//make sure the device doesn't have any textures still referenced.
for (i = 0; i < MAX_TMUS/*shaderstate.lastpasscount*/; i++)
{
@ -503,7 +511,7 @@ static void *D3D11BE_GenerateBlendState(unsigned int bits)
blend.RenderTarget[0].BlendEnable = FALSE;
}
blend.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blend.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;//blend.RenderTarget[0].SrcBlend;
blend.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;//blend.RenderTarget[0].SrcBlend;
blend.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;//blend.RenderTarget[0].DestBlend;
blend.RenderTarget[0].BlendOpAlpha = blend.RenderTarget[0].BlendOp;
@ -905,6 +913,57 @@ void D3D11BE_UnbindAllTextures(void)
}
}
const GUID DECLSPEC_SELECTANY IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c } };
static texid_t T_Gen_CurrentRender(void)
{
int vwidth, vheight;
int pwidth = vid.fbpwidth;
int pheight = vid.fbpheight;
ID3D11Texture2D *backbuf;
#ifdef WINRT
extern IDXGISwapChain1 *d3dswapchain;
#else
extern IDXGISwapChain *d3dswapchain;
#endif
D3D11_TEXTURE2D_DESC tdesc = {0};
if (r_refdef.recurse)
return r_nulltex;
//FIXME: should be willing to use the current rendertargets instead
IDXGISwapChain_GetBuffer(d3dswapchain, 0, &IID_ID3D11Texture2D, (LPVOID*)&backbuf);
ID3D11Texture2D_GetDesc(backbuf, &tdesc);
// copy the scene to texture
if (!TEXVALID(shaderstate.currentrender) || tdesc.Width != shaderstate.currentrender->width || tdesc.Height != shaderstate.currentrender->height)
{
if (!shaderstate.currentrender)
shaderstate.currentrender = Image_CreateTexture("***$currentrender***", NULL, 0);
if (!shaderstate.currentrender)
return r_nulltex; //err
shaderstate.currentrender->width = tdesc.Width;
shaderstate.currentrender->height = tdesc.Height;
tdesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
tdesc.CPUAccessFlags = 0;
if (shaderstate.currentrender->ptr)
ID3D11Texture2D_Release((ID3D11Texture2D*)shaderstate.currentrender->ptr);
shaderstate.currentrender->ptr = NULL;
ID3D11Device_CreateTexture2D(pD3DDev11, &tdesc, NULL, (ID3D11Texture2D**)&shaderstate.currentrender->ptr);
}
ID3D11DeviceContext_CopyResource(d3ddevctx, (ID3D11Resource*)shaderstate.currentrender->ptr, (ID3D11Resource*)backbuf);
if (shaderstate.currentrender->ptr2)
ID3D11ShaderResourceView_Release((ID3D11ShaderResourceView*)shaderstate.currentrender->ptr2);
shaderstate.currentrender->ptr2 = NULL;
return shaderstate.currentrender;
}
static void SelectPassTexture(unsigned int tu, const shaderpass_t *pass)
{
extern texid_t r_whiteimage, missing_texture_gloss, missing_texture_normal;
@ -966,9 +1025,9 @@ static void SelectPassTexture(unsigned int tu, const shaderpass_t *pass)
}
break;
/*case T_GEN_CURRENTRENDER:
FIXME: no code to grab the current screen and convert to a texture
break;*/
case T_GEN_CURRENTRENDER:
BindTexture(tu, T_Gen_CurrentRender());
break;
case T_GEN_VIDEOMAP:
#ifndef NOMEDIA
if (pass->cin)
@ -995,8 +1054,6 @@ static void SelectPassTexture(unsigned int tu, const shaderpass_t *pass)
BindTexture(tu, r_nulltex);
break;
case T_GEN_CURRENTRENDER://copy the current screen to a texture, and draw that
case T_GEN_SOURCECOLOUR: //used for render-to-texture targets
case T_GEN_SOURCEDEPTH: //used for render-to-texture targets
@ -1898,9 +1955,12 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
ID3D11DeviceContext_IASetPrimitiveTopology(d3ddevctx, prog->permu[permu].handle.hlsl.topology);
ID3D11DeviceContext_VSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
ID3D11DeviceContext_HSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
ID3D11DeviceContext_DSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
ID3D11DeviceContext_GSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
if (prog->permu[permu].handle.hlsl.hull)
ID3D11DeviceContext_HSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
if (prog->permu[permu].handle.hlsl.domain)
ID3D11DeviceContext_DSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
if (prog->permu[permu].handle.hlsl.geom)
ID3D11DeviceContext_GSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
ID3D11DeviceContext_PSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
}
@ -1950,7 +2010,10 @@ static void D3D11BE_Cull(unsigned int cullflags)
D3D11_RASTERIZER_DESC rasterdesc;
ID3D11RasterizerState *newrasterizerstate;
cullflags ^= r_refdef.flipcull;
if (shaderstate.flags & BEF_FORCETWOSIDED)
cullflags = 0;
else if (cullflags)
cullflags ^= r_refdef.flipcull;
if (shaderstate.curcull != cullflags)
{
@ -1985,7 +2048,7 @@ static void D3D11BE_Cull(unsigned int cullflags)
rasterdesc.FillMode = 0?D3D11_FILL_WIREFRAME:D3D11_FILL_SOLID;
rasterdesc.FrontCounterClockwise = false;
rasterdesc.MultisampleEnable = false;
rasterdesc.ScissorEnable = false;//true;
rasterdesc.ScissorEnable = true;
rasterdesc.SlopeScaledDepthBias = 0.0f;
if (FAILED(hr=ID3D11Device_CreateRasterizerState(pD3DDev11, &rasterdesc, &newrasterizerstate)))
@ -2289,7 +2352,10 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *mesh)
VectorClear(out[i].ndir);
VectorClear(out[i].sdir);
VectorClear(out[i].tdir);
Vector4Scale(mesh->colors4f_array[0][i], 255, out[i].colorsb);
out[i].colorsb[0] = bound(0, mesh->colors4f_array[0][i][0]*255, 255);
out[i].colorsb[1] = bound(0, mesh->colors4f_array[0][i][1]*255, 255);
out[i].colorsb[2] = bound(0, mesh->colors4f_array[0][i][2]*255, 255);
out[i].colorsb[3] = bound(0, mesh->colors4f_array[0][i][3]*255, 255);
}
}
else if (!mesh->normals_array && mesh->colors4b_array)
@ -3520,17 +3586,22 @@ void D3D11BE_Scissor(srect_t *rect)
D3D11_RECT drect;
if (rect)
{
drect.left = (rect->x)*vid.pixelwidth;
drect.right = (rect->x + rect->width)*vid.pixelwidth;
drect.bottom = (1-(rect->y))*vid.pixelheight;
drect.top = (1-(rect->y + rect->height))*vid.pixelheight;
drect.left = (rect->x)*vid.fbpwidth;
drect.right = (rect->x + rect->width)*vid.fbpwidth;
drect.bottom = (1-(rect->y))*vid.fbpheight;
drect.top = (1-(rect->y + rect->height))*vid.fbpheight;
if (drect.left < 0)
drect.left = 0;
if (drect.top < 0)
drect.top = 0;
}
else
{
drect.left = 0;
drect.right = vid.pixelwidth;
drect.right = vid.fbpwidth;
drect.top = 0;
drect.bottom = vid.pixelheight;
drect.bottom = vid.fbpheight;
}
ID3D11DeviceContext_RSSetScissorRects(d3ddevctx, 1, &drect);
}

View File

@ -668,7 +668,7 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
D3D11_SHADER_INPUT_BIND_DESC bdesc = {0};
for (i = prog->numsamplers; i < be_maxpasses; i++)
{
if (SUCCEEDED(freflect->lpVtbl->GetResourceBindingDescByName(freflect, va("t_%i", i), &bdesc)))
if (SUCCEEDED(freflect->lpVtbl->GetResourceBindingDescByName(freflect, va("t_t%i", i), &bdesc)))
prog->numsamplers = i+1;
}

View File

@ -770,9 +770,12 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
{
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_CONSTANT, shaderstate.passcolour);
last = D3DTA_CONSTANT;
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_COLORVERTEX, FALSE);
}
else
{
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_COLORVERTEX, TRUE);
// IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
last = D3DTA_DIFFUSE;
}
}
@ -2006,7 +2009,11 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in
void D3D9BE_Cull(unsigned int cullflags)
{
cullflags ^= r_refdef.flipcull;
if (shaderstate.flags & BEF_FORCETWOSIDED)
cullflags = 0;
else if (cullflags)
cullflags ^= r_refdef.flipcull;
if (shaderstate.curcull != cullflags)
{
shaderstate.curcull = cullflags;
@ -3333,10 +3340,10 @@ void D3D9BE_Scissor(srect_t *srect)
RECT rect;
if (srect)
{
rect.left = srect->x;
rect.right = srect->x + srect->width;
rect.top = srect->y;
rect.bottom = srect->y + srect->height;
rect.left = (srect->x) * vid.fbpwidth;
rect.right = (srect->x + srect->width) * vid.fbpwidth;
rect.top = (srect->y) * vid.fbpheight;
rect.bottom = (srect->y + srect->height) * vid.fbpheight;
}
else
{
@ -3346,6 +3353,7 @@ void D3D9BE_Scissor(srect_t *srect)
rect.bottom = vid.pixelheight;
}
IDirect3DDevice9_SetScissorRect(pD3DDev9, &rect);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SCISSORTESTENABLE, TRUE);
}
#endif

View File

@ -929,6 +929,11 @@ static void (D3D9_SCR_UpdateScreen) (void)
D3D9BE_Reset(false);
if (r_clear.ival)
{
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB((r_clear.ival&1)?255:0,(r_clear.ival&2)?255:0,(r_clear.ival&4)?255:0), 1, 0));
}
if (scr_disabled_for_loading)
{
extern float scr_disabled_time;
@ -1164,9 +1169,9 @@ static void (D3D9_R_RenderView) (void)
D3D9_SetupViewPortProjection();
if (r_clear.ival && !(r_refdef.flags & RDF_NOWORLDMODEL))
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,0,0), 1, 0));
else
// if (r_clear.ival && !(r_refdef.flags & RDF_NOWORLDMODEL))
// d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,0,0), 1, 0));
// else
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);

View File

@ -1159,6 +1159,8 @@ void D3D11_Set2D (void)
vid.fbvheight = vid.height;
vid.fbpwidth = vid.pixelwidth;
vid.fbpheight = vid.pixelheight;
D3D11BE_Scissor(NULL);
}
static void (D3D11_SCR_UpdateScreen) (void)
@ -1174,7 +1176,7 @@ static void (D3D11_SCR_UpdateScreen) (void)
if (r_clear.ival)
{
float colours[4] = {(r_clear.ival==2)?0:1, 0, 0, 0};
float colours[4] = {(r_clear.ival&1)?1:0, (r_clear.ival&2)?1:0, (r_clear.ival&4)?1:0, 1};
ID3D11DeviceContext_ClearRenderTargetView(d3ddevctx, fb_backbuffer, colours);
}

View File

@ -367,7 +367,7 @@ void Font_Init(void)
"endif\n"
"nomipmaps\n"
"{\n"
"map $nearest:$diffuse\n"
"map $diffuse\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"blendfunc blend\n"

View File

@ -1060,6 +1060,72 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
}
script = end;
}
else if (!strncmp(script, "!!cvard3", 8))
{
script += 8;
while (*script == ' ' || *script == '\t')
script++;
end = script;
while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_')
end++;
if (nummodifiers < MAXMODIFIERS && end - script < 64)
{
cvar_t *var;
char namebuf[64];
char valuebuf[64];
memcpy(namebuf, script, end - script);
namebuf[end - script] = 0;
while (*end == ' ' || *end == '\t')
end++;
if (*end == '=')
{
script = ++end;
while (*end && *end != '\n' && *end != '\r' && end < script+sizeof(namebuf)-1)
end++;
memcpy(valuebuf, script, end - script);
valuebuf[end - script] = 0;
}
else
strcpy(valuebuf, "0");
var = Cvar_Get(namebuf, valuebuf, CVAR_SHADERSYSTEM, "GLSL Variables");
if (var)
permutationdefines[nummodifiers++] = Z_StrDup(va("#define %s %s(%g,%g,%g)\n", namebuf, ((qrenderer == QR_OPENGL)?"vec3":"float3"), var->vec4[0], var->vec4[1], var->vec4[2]));
}
script = end;
}
else if (!strncmp(script, "!!cvard4", 8))
{
script += 8;
while (*script == ' ' || *script == '\t')
script++;
end = script;
while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_')
end++;
if (nummodifiers < MAXMODIFIERS && end - script < 64)
{
cvar_t *var;
char namebuf[64];
char valuebuf[64];
memcpy(namebuf, script, end - script);
namebuf[end - script] = 0;
while (*end == ' ' || *end == '\t')
end++;
if (*end == '=')
{
script = ++end;
while (*end && *end != '\n' && *end != '\r' && end < script+sizeof(namebuf)-1)
end++;
memcpy(valuebuf, script, end - script);
valuebuf[end - script] = 0;
}
else
strcpy(valuebuf, "0");
var = Cvar_Get(namebuf, valuebuf, CVAR_SHADERSYSTEM, "GLSL Variables");
if (var)
permutationdefines[nummodifiers++] = Z_StrDup(va("#define %s %s(%g,%g,%g,%g)\n", namebuf, ((qrenderer == QR_OPENGL)?"vec4":"float4"), var->vec4[0], var->vec4[1], var->vec4[2], var->vec4[3]));
}
script = end;
}
else if (!strncmp(script, "!!cvarf", 7))
{
script += 7;
@ -5252,7 +5318,7 @@ void Shader_Default2D(const char *shortname, shader_t *s, const void *genargs)
{
if (Shader_ParseShader("default2d", s))
return;
if (sh_config.progs_supported)
if (sh_config.progs_supported && qrenderer != QR_DIRECT3D9)
{
//hexen2 needs premultiplied alpha to avoid looking ugly
//but that results in problems where things are drawn with alpha not 0, so scale vertex colour by alpha in the fragment program

View File

@ -496,6 +496,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"SamplerState s_t0;\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"#ifdef PREMUL\n"
"inp.vcol.rgb *= inp.vcol.a;\n"
"#endif\n"
"return t_t0.Sample(s_t0, inp.tc) * inp.vcol;\n"
"}\n"
"#endif\n"
@ -2540,6 +2543,54 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
},
#endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "menutint",
"!!cvard3 r_menutint=0.2 0.2 0.2\n"
"!!cvardf r_menutint_inverse=0.0\n"
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_projection, inp.pos);\n"
"outp.tc = inp.tc;\n"
"outp.vcol = inp.vcol;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D t_t0;\n"
"SamplerState s_t0;\n"
"static const float3 lumfactors = float3 (0.299, 0.587, 0.114);\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"float4 texcolor = t_t0.Sample(s_t0, inp.tc);\n"
"float luminance = dot(lumfactors, texcolor.rgb);\n"
"texcolor.rgb = float3(luminance, luminance, luminance);\n"
"texcolor.rgb *= r_menutint;\n"
"texcolor.rgb = (r_menutint_inverse > 0) ? (1.0 - texcolor.rgb) : texcolor.rgb;\n"
"return texcolor * inp.vcol;\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "terrain",
"!!permu FOG\n"

View File

@ -29,6 +29,9 @@ struct v2f
SamplerState s_t0;
float4 main (v2f inp) : SV_TARGET
{
#ifdef PREMUL
inp.vcol.rgb *= inp.vcol.a;
#endif
return t_t0.Sample(s_t0, inp.tc) * inp.vcol;
}
#endif

View File

@ -0,0 +1,44 @@
!!cvard3 r_menutint=0.2 0.2 0.2
!!cvardf r_menutint_inverse=0.0
struct a2v
{
float4 pos: POSITION;
float2 tc: TEXCOORD0;
float4 vcol: COLOR0;
};
struct v2f
{
float4 pos: SV_POSITION;
float2 tc: TEXCOORD0;
float4 vcol: COLOR0;
};
#include <ftedefs.h>
#ifdef VERTEX_SHADER
v2f main (a2v inp)
{
v2f outp;
outp.pos = mul(m_projection, inp.pos);
outp.tc = inp.tc;
outp.vcol = inp.vcol;
return outp;
}
#endif
#ifdef FRAGMENT_SHADER
Texture2D t_t0;
SamplerState s_t0;
static const float3 lumfactors = float3 (0.299, 0.587, 0.114);
float4 main (v2f inp) : SV_TARGET
{
float4 texcolor = t_t0.Sample(s_t0, inp.tc);
float luminance = dot(lumfactors, texcolor.rgb);
texcolor.rgb = float3(luminance, luminance, luminance);
texcolor.rgb *= r_menutint;
texcolor.rgb = (r_menutint_inverse > 0) ? (1.0 - texcolor.rgb) : texcolor.rgb;
return texcolor * inp.vcol;
}
#endif