rework hlmdl subblends. apparently they're some sort of grid.

fix decals again. clampmap should work properly with them, also removed the extra part.
fix rtlight pvs issue with respect to portals
fix vid_reload causing the d3d9 renderer to use nearest sampling
terrain system should now mostly work with d3d9. still has issues.
fix q3 volumetric fog not applying to models

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5174 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2017-11-30 17:59:11 +00:00
parent 7314c78135
commit 9cd425e945
35 changed files with 995 additions and 222 deletions

View file

@ -2843,7 +2843,7 @@ static void CL_AddDecal_Callback(void *vctx, vec3_t *fte_restrict points, size_t
for (v = 0; v < numpoints; v++)
{
VectorCopy(points[v], cl_strisvertv[cl_numstrisvert+v]);
cl_strisvertt[cl_numstrisvert+v][0] = (DotProduct(points[v], ctx->axis[1]) - ctx->offset[1]) * ctx->scale[1];
cl_strisvertt[cl_numstrisvert+v][0] = 1+(DotProduct(points[v], ctx->axis[1]) - ctx->offset[1]) * ctx->scale[1];
cl_strisvertt[cl_numstrisvert+v][1] = -(DotProduct(points[v], ctx->axis[2]) - ctx->offset[2]) * ctx->scale[2];
cl_strisvertc[cl_numstrisvert+v][0] = ctx->rgbavalue[0];
cl_strisvertc[cl_numstrisvert+v][1] = ctx->rgbavalue[1];
@ -2908,7 +2908,7 @@ void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t
ctx.t = t;
VectorCopy(rgbvalue, ctx.rgbavalue);
ctx.rgbavalue[3] = alphavalue;
Mod_ClipDecal(cl.worldmodel, origin, ctx.axis[0], ctx.axis[1], ctx.axis[2], radius*2, 0,0, CL_AddDecal_Callback, &ctx);
Mod_ClipDecal(cl.worldmodel, origin, ctx.axis[0], ctx.axis[1], ctx.axis[2], radius, 0,0, CL_AddDecal_Callback, &ctx);
if (!t->numidx)
cl_numstris--;

View file

@ -604,6 +604,8 @@ void VQ3_RenderView(const q3refdef_t *ref)
r_refdef.maxdist = gl_maxdist.value;
r_refdef.playerview = &cl.playerview[0];
memset(&r_refdef.globalfog, 0, sizeof(r_refdef.globalfog));
if (r_torch.ival)
{
dlight_t *dl;

View file

@ -720,7 +720,7 @@ const char *presetname[] =
"Realtime", //everything on
NULL
};
#define PRESET_NUM 6
#define PRESET_NUM (countof(presetname)-1)
// this is structured like this for a possible future feature
// also don't include cvars that need a restart here

View file

@ -54,6 +54,7 @@ typedef struct {
#ifdef HALFLIFEMODELS
float subblendfrac; //hl models are weird
float subblend2frac; //very weird.
#endif
int endbone;
@ -465,7 +466,7 @@ typedef struct rendererinfo_s {
//Generates an optimised VBO, one for each texture on the map
void (*BE_GenBrushModelVBO)(struct model_s *mod);
//Destroys the given vbo
void (*BE_ClearVBO)(struct vbo_s *vbo);
void (*BE_ClearVBO)(struct vbo_s *vbo, qboolean dataonly);
//Uploads all modified lightmaps
void (*BE_UploadAllLightmaps)(void);
void (*BE_SelectEntity)(struct entity_s *ent);

View file

@ -588,7 +588,9 @@ static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t
out->bonecontrols[3] = in->xv->bonecontrol4;
out->bonecontrols[4] = in->xv->bonecontrol5;
out->g[FS_REG].subblendfrac = in->xv->subblendfrac;
out->g[FS_REG].subblend2frac = in->xv->subblend2frac;
out->g[FST_BASE].subblendfrac = in->xv->subblendfrac;
out->g[FST_BASE].subblend2frac = in->xv->subblend2frac;
#endif
//FTE_CSQC_BASEFRAME
@ -1042,7 +1044,17 @@ static void QCBUILTIN PF_R_RemoveEntity(pubprogfuncs_t *prinst, struct globalvar
void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t rgbvalue, float alphavalue);
static void QCBUILTIN PF_R_AddDecal(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
shader_t *shader = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL);
shader_t *shader = R_RegisterShader(PR_GetStringOfs(prinst, OFS_PARM0), SUF_NONE,
"{\n"
"polygonOffset\n"
"surfaceparms nodlight\n"
"{\n"
"map $diffuse\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"blendfunc gl_one gl_one_minus_src_alpha\n"
"}\n"
"}\n");
float *org = G_VECTOR(OFS_PARM1);
float *up = G_VECTOR(OFS_PARM2);
float *side = G_VECTOR(OFS_PARM3);

View file

@ -2888,7 +2888,7 @@ R_DrawWorld
=============
*/
static pvsbuffer_t surf_frustumvis;
static pvsbuffer_t surf_frustumvis[R_MAX_RECURSE];
void Surf_DrawWorld (void)
{
//surfvis vs entvis - the key difference is that surfvis is surfaces while entvis is volume. though surfvis should be frustum culled also for lighting. entvis doesn't care.
@ -3045,9 +3045,10 @@ void Surf_DrawWorld (void)
#if defined(Q2BSPS) || defined(Q3BSPS)
if (currentmodel->fromgame == fg_quake2 || currentmodel->fromgame == fg_quake3)
{
if (surf_frustumvis.buffersize < currentmodel->pvsbytes)
surf_frustumvis.buffer = BZ_Realloc(surf_frustumvis.buffer, surf_frustumvis.buffersize=currentmodel->pvsbytes);
frustumvis = surf_frustumvis.buffer;
pvsbuffer_t *vis = &surf_frustumvis[r_refdef.recurse];
if (vis->buffersize < currentmodel->pvsbytes)
vis->buffer = BZ_Realloc(vis->buffer, vis->buffersize=currentmodel->pvsbytes);
frustumvis = vis->buffer;
memset(frustumvis, 0, currentmodel->pvsbytes);
if (!r_refdef.areabitsknown)
@ -3106,13 +3107,15 @@ void Surf_DrawWorld (void)
// entvis = surfvis = R_MarkLeafSurfaces_Q1();
// else
{
pvsbuffer_t *vis = &surf_frustumvis[r_refdef.recurse];
entvis = R_MarkLeaves_Q1 (false);
if (!(r_novis.ival & 2))
VectorCopy (r_origin, modelorg);
if (surf_frustumvis.buffersize < currentmodel->pvsbytes)
surf_frustumvis.buffer = BZ_Realloc(surf_frustumvis.buffer, surf_frustumvis.buffersize=currentmodel->pvsbytes);
frustumvis = surf_frustumvis.buffer;
if (vis->buffersize < currentmodel->pvsbytes)
vis->buffer = BZ_Realloc(vis->buffer, vis->buffersize=currentmodel->pvsbytes);
frustumvis = vis->buffer;
memset(frustumvis, 0, currentmodel->pvsbytes);
if (r_refdef.useperspective)
@ -3189,8 +3192,9 @@ void Surf_DeInit(void)
if (lightmap)
BZ_Free(lightmap);
Z_Free(surf_frustumvis.buffer);
memset(&surf_frustumvis, 0, sizeof(surf_frustumvis));
for (i = 0; i < R_MAX_RECURSE; i++)
Z_Free(surf_frustumvis[i].buffer);
memset(surf_frustumvis, 0, sizeof(surf_frustumvis));
lightmap=NULL;
numlightmaps=0;
@ -3221,7 +3225,7 @@ void Surf_Clear(model_t *mod)
{
vbo = mod->vbos;
mod->vbos = vbo->next;
BE_ClearVBO(vbo);
BE_ClearVBO(vbo, false);
}
if (!mod->submodelof)

View file

@ -414,7 +414,7 @@ cvar_t r_shadows = CVARFD ("r_shadows", "0", CVAR_ARCHIVE, "Draw basic blo
cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground.");
cvar_t r_showfields = CVARD("r_showfields", "0", "Debugging. Shows entity fields boxes (entity closest to crosshair). 1=ssqc, 2=csqc.");
cvar_t r_showshaders = CVARD("r_showshaders", "0", "Debugging. Shows the name of the (worldmodel) shader being pointed to.");
cvar_t r_lightprepass_cvar = CVARFD("r_lightprepass", "0", CVAR_SHADERSYSTEM, "Experimental. Attempt to use a different lighting mechanism.");
cvar_t r_lightprepass_cvar = CVARFD("r_lightprepass", "0", CVAR_ARCHIVE, "Experimental. Attempt to use a different lighting mechanism. Requires vid_reload to take effect.");
int r_lightprepass;
cvar_t r_shadow_bumpscale_basetexture = CVARD ("r_shadow_bumpscale_basetexture", "0", "bumpyness scaler for generation of fallback normalmap textures from models");
@ -1729,6 +1729,7 @@ void R_ReloadRenderer_f (void)
Con_DPrintf("teardown = %f\n", Sys_DoubleTime() - time);
//reloads textures without destroying video context.
R_ApplyRenderer_Load(NULL);
Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK);
}
//use Cvar_ApplyLatches(CVAR_RENDERERLATCH) beforehand.
@ -1901,7 +1902,7 @@ void R_RestartRenderer (rendererstate_t *newr)
return;
}
TRACE(("dbg: R_RestartRenderer_f renderer %i\n", newr.renderer));
TRACE(("dbg: R_RestartRenderer_f renderer %p\n", newr->renderer));
memcpy(&oldr, &currentrendererstate, sizeof(rendererstate_t));
if (!R_ApplyRenderer(newr))

View file

@ -201,7 +201,7 @@ static void Headless_BE_Init (void)
static void Headless_BE_GenBrushModelVBO (struct model_s *mod)
{
}
static void Headless_BE_ClearVBO (struct vbo_s *vbo)
static void Headless_BE_ClearVBO (struct vbo_s *vbo, qboolean dataonly)
{
}
static void Headless_BE_UploadAllLightmaps (void)

View file

@ -940,7 +940,7 @@ void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt )
qt[3] = p[2];
sclp = sin( (1.0 - t) * 0.5 * M_PI);
sclq = sin( t * 0.5 * M_PI);
for (i = 0; i < 3; i++) {
for (i = 0; i < 4; i++) {
qt[i] = sclp * p[i] + sclq * qt[i];
}
}

View file

@ -2674,7 +2674,7 @@ void D3D11BE_GenBrushModelVBO(model_t *mod)
}
/*Wipes a vbo*/
void D3D11BE_ClearVBO(vbo_t *vbo)
void D3D11BE_ClearVBO(vbo_t *vbo, qboolean dataonly)
{
ID3D11Buffer *vbuff = vbo->coord.d3d.buff;
ID3D11Buffer *ebuff = vbo->indicies.d3d.buff;
@ -2691,6 +2691,7 @@ void D3D11BE_ClearVBO(vbo_t *vbo)
vbo->coord.d3d.buff = NULL;
vbo->indicies.d3d.buff = NULL;
if (!dataonly)
BZ_Free(vbo);
}

View file

@ -2620,7 +2620,7 @@ void D3D8BE_GenBrushModelVBO(model_t *mod)
}
#endif
/*Wipes a vbo*/
void D3D8BE_ClearVBO(vbo_t *vbo)
void D3D8BE_ClearVBO(vbo_t *vbo, qboolean dataonly)
{
IDirect3DVertexBuffer8 *vbuff = vbo->coord.d3d.buff;
IDirect3DIndexBuffer8 *ebuff = vbo->indicies.d3d.buff;
@ -2631,6 +2631,7 @@ void D3D8BE_ClearVBO(vbo_t *vbo)
vbo->coord.d3d.buff = NULL;
vbo->indicies.d3d.buff = NULL;
if (!dataonly)
free(vbo);
}

View file

@ -1211,7 +1211,7 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa
((pass->rgbgen == RGB_GEN_VERTEX_LIGHTING) ||
(pass->rgbgen == RGB_GEN_VERTEX_EXACT) ||
(pass->rgbgen == RGB_GEN_ONE_MINUS_VERTEX)) &&
(pass->alphagen == ALPHA_GEN_VERTEX)))
(pass->alphagen == ALPHA_GEN_VERTEX)) && shaderstate.batchvbo->colours_bytes)
{
//fixme
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours[0].d3d.buff, shaderstate.batchvbo->colours[0].d3d.offs, sizeof(vbovdata_t)));
@ -1957,11 +1957,13 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
case SP_E_TOPCOLOURS:
R_FetchPlayerColour(shaderstate.curentity->topcolour, param4);
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, param4, 3);
param4[3] = 1;
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, param4, 1);
break;
case SP_E_BOTTOMCOLOURS:
R_FetchPlayerColour(shaderstate.curentity->bottomcolour, param4);
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, param4, 3);
param4[3] = 1;
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, param4, 1);
break;
case SP_E_LMSCALE:
@ -1979,7 +1981,11 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
VectorSet(param4, identitylighting, identitylighting, identitylighting);
}
param4[3] = 1;
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, param4, 3);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, param4, 1);
break;
case SP_W_FOG:
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, r_refdef.globalfog.colour, 2); //colour and density
break;
case SP_M_ENTBONES:
@ -1987,7 +1993,6 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
case SP_E_VLSCALE:
case SP_E_ORIGIN:
case SP_E_GLOWMOD:
case SP_W_FOG:
case SP_M_INVVIEWPROJECTION:
case SP_M_INVMODELVIEWPROJECTION:
case SP_SOURCESIZE:
@ -2053,6 +2058,8 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in
perm |= PERMUTATION_LIGHTSTYLES;
#endif
vdec |= BE_GenerateColourMods(vertcount, s->passes);
BE_ApplyUniforms(p, perm);
@ -2547,7 +2554,7 @@ void D3D9BE_SelectEntity(entity_t *ent)
}
#if 1
static void D3D9BE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch)
void D3D9BE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch)
{
int maxvboelements;
int maxvboverts;
@ -2618,9 +2625,18 @@ static void D3D9BE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *
vbovdata->coord[3] = 1;
Vector2Copy(m->st_array[i], vbovdata->tex);
Vector2Copy(m->lmst_array[0][i], vbovdata->lm);
if (m->normals_array)
{
VectorCopy(m->normals_array[i], vbovdata->ndir);
VectorCopy(m->snormals_array[i], vbovdata->sdir);
VectorCopy(m->tnormals_array[i], vbovdata->tdir);
}
else
{
VectorSet(vbovdata->ndir, 0, 0, 1);
VectorSet(vbovdata->sdir, 1, 0, 0);
VectorSet(vbovdata->tdir, 0, 1, 0);
}
Vector4Scale(m->colors4f_array[0][i], 255, vbovdata->colorsb);
vbovdata++;
@ -2719,7 +2735,7 @@ void D3D9BE_GenBrushModelVBO(model_t *mod)
if (!mod->textures[t])
continue;
vbo = &mod->textures[t]->vbo;
BE_ClearVBO(vbo);
BE_ClearVBO(vbo, false);
maxvboverts = 0;
maxvboelements = 0;
@ -2869,7 +2885,7 @@ void D3D9BE_GenBrushModelVBO(model_t *mod)
}
#endif
/*Wipes a vbo*/
void D3D9BE_ClearVBO(vbo_t *vbo)
void D3D9BE_ClearVBO(vbo_t *vbo, qboolean dataonly)
{
IDirect3DVertexBuffer9 *vbuff = vbo->coord.d3d.buff;
IDirect3DIndexBuffer9 *ebuff = vbo->indicies.d3d.buff;
@ -2880,6 +2896,7 @@ void D3D9BE_ClearVBO(vbo_t *vbo)
vbo->coord.d3d.buff = NULL;
vbo->indicies.d3d.buff = NULL;
if (!dataonly)
free(vbo);
}

View file

@ -16,7 +16,20 @@ typedef struct {
} D3DXMACRO;
#define D3DXHANDLE void *
#define LPD3DXINCLUDE void *
typedef enum D3DXINCLUDE_TYPE {
D3DXINC_LOCAL = 0,
D3DXINC_SYSTEM = 1,
D3DXINC_FORCE_DWORD = 0x7fffffff
} D3DXINCLUDE_TYPE, *LPD3DXINCLUDE_TYPE;
#undef INTERFACE
#define INTERFACE myID3DXInclude
DECLARE_INTERFACE(myID3DXInclude)
{
STDMETHOD_(HRESULT,Open)(THIS_ D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE;
STDMETHOD_(HRESULT,Close)(THIS_ LPCVOID pData) PURE;
};
typedef struct myID3DXInclude *LPD3DXINCLUDE;
#undef INTERFACE
#define INTERFACE d3dxbuffer
@ -141,8 +154,111 @@ static dllhandle_t *shaderlib;
(This)->lpVtbl -> Release(This)
#endif
static HRESULT STDMETHODCALLTYPE myID3DXIncludeVtbl_Close(myID3DXInclude *cls, LPCVOID pData)
{
return S_OK;
}
static HRESULT STDMETHODCALLTYPE myID3DXIncludeVtbl_Open(myID3DXInclude *cls, D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes)
{
char *file = NULL;
// "sys/defs.h"
// "sys/skeletal.h"
// "sys/offsetmapping.h"
if (!strcmp(pFileName, "sys/fog.h"))
{
file =
"#ifdef FRAGMENT_SHADER\n"
"#ifdef FOG\n"
"#ifndef DEFS_DEFINED\n"
"float4 w_fog[2];\n"
"#define w_fogcolour w_fog[0].rgb\n"
"#define w_fogalpha w_fog[0].a\n"
"#define w_fogdensity w_fog[1].x\n"
"#define w_fogdepthbias w_fog[1].y\n"
"#endif\n"
"static const float r_fog_exp2 = 1.0;\n"
"float3 fog3(float3 regularcolour, float distance)"
"{"
"float z = w_fogdensity * -distance;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"if (r_fog_exp2)\n"
"z *= z;\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return lerp(w_fogcolour, regularcolour, fac);\n"
"}\n"
"float3 fog3additive(float3 regularcolour, float distance)"
"{"
"float z = w_fogdensity * -distance;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"if (r_fog_exp2)\n"
"z *= z;\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * fac;\n"
"}\n"
"float4 fog4(float4 regularcolour, float distance)"
"{"
"return float4(fog3(regularcolour.rgb, distance), 1.0) * regularcolour.a;\n"
"}\n"
"float4 fog4additive(float4 regularcolour, float distance)"
"{"
"float z = w_fogdensity * -distance;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"if (r_fog_exp2)\n"
"z *= z;\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * float4(fac, fac, fac, 1.0);\n"
"}\n"
"float4 fog4blend(float4 regularcolour, float distance)"
"{"
"float z = w_fogdensity * -distance;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"if (r_fog_exp2)\n"
"z *= z;\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * float4(1.0, 1.0, 1.0, fac);\n"
"}\n"
"#else\n"
/*don't use macros for this - mesa bugs out*/
"float3 fog3(float3 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float3 fog3additive(float3 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float4 fog4(float4 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float4 fog4additive(float4 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float4 fog4blend(float4 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"#endif\n"
"#endif\n"
;
}
else if (!strcmp(pFileName, "sys/pcf.h"))
{
file =
"#define ShadowmapFilter(smap,proj) 1.0\n"
;
}
if (file)
{
*ppData = file;
*pBytes = strlen(file);
return S_OK;
}
else
return E_FAIL;
}
static struct myID3DXIncludeVtbl myID3DXIncludeVtbl_C =
{
myID3DXIncludeVtbl_Open,
myID3DXIncludeVtbl_Close
};
static struct myID3DXInclude myID3DXIncludeVtbl_Instance = {&myID3DXIncludeVtbl_C};
static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *geom, const char *frag, qboolean silent, vfsfile_t *blobfile)
{
D3DXMACRO defines[64];
LPD3DXBUFFER code = NULL, errors = NULL;
qboolean success = false;
@ -209,7 +325,7 @@ static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, un
success = true;
defines[0].Name = "VERTEX_SHADER";
if (FAILED(pD3DXCompileShader(vert, strlen(vert), defines, NULL, "main", "vs_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].h.hlsl.ctabv)))
if (FAILED(pD3DXCompileShader(vert, strlen(vert), defines, &myID3DXIncludeVtbl_Instance, "main", "vs_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].h.hlsl.ctabv)))
success = false;
else
{
@ -224,7 +340,7 @@ static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, un
}
defines[0].Name = "FRAGMENT_SHADER";
if (FAILED(pD3DXCompileShader(frag, strlen(frag), defines, NULL, "main", "ps_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].h.hlsl.ctabf)))
if (FAILED(pD3DXCompileShader(frag, strlen(frag), defines, &myID3DXIncludeVtbl_Instance, "main", "ps_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].h.hlsl.ctabf)))
success = false;
else
{

View file

@ -1268,6 +1268,13 @@ static void (D3D9_R_RenderView) (void)
{
Surf_SetupFrame();
if (!r_refdef.globalfog.density)
{
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[1].density)?1:0;
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog[fogtype], realtime, &cl.fog[fogtype]);
r_refdef.globalfog.density /= 64; //FIXME
}
//check if we can do underwater warp
if (cls.protocol != CP_QUAKE2) //quake2 tells us directly
{

View file

@ -23,7 +23,7 @@
>
<Tool
Name="VCNMakeTool"
BuildCommandLine="cd $(InputDir)\.. &amp;&amp; vcify make droid-dbg ANDROID_HOME=C:/Games/tools/android-sdk ANDROID_NDK_ROOT=C:/Games/tools/android-ndk-r8e ANT=C:/Games/tools/apache-ant-1.8.2/bin/ant JAVATOOL=&quot;C:/Program\ Files/Java/jdk1.7.0_02/bin/&quot; -j8 DROID_ARCH=&quot;armeabi x86 armeabi-v7a&quot;"
BuildCommandLine="cd $(InputDir)\.. &amp;&amp; vcify make droid-dbg ANDROID_HOME=C:/Games/tools/android-sdk ANDROID_NDK_ROOT=C:/Games/tools/android-ndk-r8e ANT=C:/Games/tools/apache-ant-1.8.2/bin/ant JAVATOOL=&quot;C:/Program\ Files/Java/jdk1.7.0_02/bin/&quot; -j8 DROID_ARCH=&quot;armeabi x86 armeabi-v7a&quot; ZIPALIGN=C:/Games/tools/android-sdk/build-tools/23.0.3/zipalign DROID_ABI_VER=4.6"
ReBuildCommandLine=""
CleanCommandLine="cd $(InputDir)\.. &amp;&amp; vcify make clean -j8"
Output=""
@ -43,7 +43,7 @@
>
<Tool
Name="VCNMakeTool"
BuildCommandLine="cd $(InputDir)\.. &amp;&amp; vcify make droid-rel ANDROID_HOME=C:/Games/tools/android-sdk ANDROID_NDK_ROOT=C:/Games/tools/android-ndk-r8e ANT=C:/Games/tools/apache-ant-1.8.2/bin/ant JAVATOOL=&quot;C:/Program\ Files/Java/jdk1.7.0_02/bin/&quot; -j8 DROID_ARCH=&quot;armeabi x86&quot;"
BuildCommandLine="cd $(InputDir)\.. &amp;&amp; vcify make droid-rel ANDROID_HOME=C:/Games/tools/android-sdk ANDROID_NDK_ROOT=C:/Games/tools/android-ndk-r8e ANT=C:/Games/tools/apache-ant-1.8.2/bin/ant JAVATOOL=&quot;C:/Program\ Files/Java/jdk1.7.0_02/bin/&quot; -j8 DROID_ARCH=&quot;armeabi x86&quot; ZIPALIGN=C:/Games/tools/android-sdk/build-tools/23.0.3/zipalign CFLAGS=-DCRAZYDEBUGGING DROID_ABI_VER=4.6"
ReBuildCommandLine=""
CleanCommandLine=""
Output="$(TargetDir)\FTEDroid.apk"

View file

@ -1577,7 +1577,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
b->buildmeshes = R_GAlias_DrawBatch;
b->ent = e;
#ifdef Q3BSPS
#if defined(Q3BSPS) || defined(RFBSPS)
b->fog = Mod_FogForOrigin(cl.worldmodel, e->origin);
#endif
b->mesh = NULL;

View file

@ -1619,12 +1619,11 @@ static void tcgen_fog(float *st, unsigned int numverts, float *xyz, mfog_t *fog)
Vector4Scale(zmat, shaderstate.fogfar, zmat);
if (fog->visibleplane)
if (fog && fog->visibleplane)
{
eye = (DotProduct(r_refdef.vieworg, fog->visibleplane->normal) - fog->visibleplane->dist);
else
eye = 1;
// if (eye < 1)
// eye = 1;
if (eye < 1)
eye = 1; //avoids a nan
for (i = 0 ; i < numverts ; i++, xyz += sizeof(vecV_t)/sizeof(vec_t), st += 2 )
{
@ -1635,13 +1634,20 @@ static void tcgen_fog(float *st, unsigned int numverts, float *xyz, mfog_t *fog)
point = (DotProduct(xyz, fog->visibleplane->normal) - fog->visibleplane->dist);
else
point = 1;
if (eye < 0)
st[1] = (point < 0)?1:0;
else
st[1] = point / (point - eye);
if (st[1] > 31/32.0)
st[1] = 31/32.0;
}
}
else
{
for (i = 0 ; i < numverts ; i++, xyz += sizeof(vecV_t)/sizeof(vec_t), st += 2 )
{
z = DotProduct(xyz, zmat) + zmat[3];
st[0] = z;
st[1] = 31/32.0;
}
}
}
static void GenerateTCFog(int passnum, mfog_t *fog)
{
@ -3832,18 +3838,21 @@ void GLBE_SelectEntity(entity_t *ent)
shaderstate.lastuniform = 0;
}
#if 0
#if 1
static void BE_SelectFog(vec3_t colour, float alpha, float density)
{
float zscale;
density /= 64;
GL_DeSelectProgram();
zscale = 2048; /*this value is meant to be the distance at which fog the value becomes as good as fully fogged, just hack it to 2048...*/
GenerateFogTexture(&shaderstate.fogtexture, density, zscale);
shaderstate.fogfar = 1/zscale; /*scaler for z coords*/
qglColor4f(colour[0], colour[1], colour[2], alpha);
VectorCopy(colour, shaderstate.pendingcolourflat);
shaderstate.pendingcolourflat[3] = alpha;
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
}
#endif
#ifdef RTLIGHTS
@ -4256,10 +4265,8 @@ static void DrawMeshes(void)
case BEM_FOG:
#ifndef GLSLONLY
GL_DeSelectProgram();
GenerateTCFog(0, NULL);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR) | (1u<<VATTR_LEG_TMU0), 0);
BE_SubmitMeshChain(false);
#endif
break;
@ -4460,6 +4467,8 @@ static void DrawMeshes(void)
}
if (shaderstate.curbatch->fog && shaderstate.curbatch->fog->shader)
{
//FIXME: if glsl, do this fog volume crap properly!
GL_DeSelectProgram();
GenerateFogTexture(&shaderstate.fogtexture, shaderstate.curbatch->fog->shader->fog_dist, 2048);
@ -5761,7 +5770,7 @@ void GLBE_DrawWorld (batch_t **worldbatches)
shaderstate.depthrange = 0;
TRACE(("GLBE_DrawWorld: %i %p\n", drawworld, vis));
TRACE(("GLBE_DrawWorld: %p\n", worldbatches));
//reset batches if we needed more mem, to avoid allocations mid-frame.
if (!r_refdef.recurse)
@ -5866,13 +5875,16 @@ void GLBE_DrawWorld (batch_t **worldbatches)
GLBE_SubmitMeshes(worldbatches, SHADER_SORT_SEETHROUGH+1, SHADER_SORT_NEAREST);
RSpeedEnd(RSPEED_TRANSPARENTS);
/* if (r_refdef.gfog_alpha)
{
#ifndef GLSLONLY
if (r_refdef.globalfog.density && !gl_config.arb_shader_objects)
{ //fixed function-only. with global fog. that means we need to hack something in.
//FIXME: should really be doing this on a per-shader basis, for custom shaders that don't use glsl
BE_SelectMode(BEM_FOG);
BE_SelectFog(r_refdef.gfog_rgb, r_refdef.gfog_alpha, r_refdef.gfog_density);
GLBE_SubmitMeshes(true, batches, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
BE_SelectFog(r_refdef.globalfog.colour, r_refdef.globalfog.alpha, r_refdef.globalfog.density);
GLBE_SubmitMeshes(worldbatches, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
}
*/
#endif
#ifdef GL_LINE //no gles
if (r_wireframe.ival && qglPolygonMode)

View file

@ -332,12 +332,22 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
GL_MTBind(0, targ, tex);
if (tex->flags&IF_CLAMP)
{
if (gl_config.glversion < 1.2 && !gl_config_gles)
{ //warning: crappy path! gl1.1 is shite and doesn't support clamp-to-edge! there's ALWAYS some wrap component!
qglTexParameteri(targ, GL_TEXTURE_WRAP_S, GL_CLAMP);
qglTexParameteri(targ, GL_TEXTURE_WRAP_T, GL_CLAMP);
if (targ != GL_TEXTURE_2D)
qglTexParameteri(targ, GL_TEXTURE_WRAP_R, GL_CLAMP);
}
else
{
qglTexParameteri(targ, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(targ, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (targ != GL_TEXTURE_2D)
qglTexParameteri(targ, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
}
}
else
{
qglTexParameteri(targ, GL_TEXTURE_WRAP_S, GL_REPEAT);

View file

@ -1952,15 +1952,21 @@ void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusa
hm->relight = NULL;
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL && qglDeleteBuffersARB)
if (qrenderer == QR_OPENGL)
{
if (qglDeleteBuffersARB)
{
qglDeleteBuffersARB(1, &s->vbo.coord.gl.vbo);
s->vbo.coord.gl.vbo = 0;
qglDeleteBuffersARB(1, &s->vbo.indicies.gl.vbo);
s->vbo.indicies.gl.vbo = 0;
}
}
else
#endif
//FIXME: BE_ClearVBO(&s->vbo);
{
BE_ClearVBO(&s->vbo, true);
}
Z_Free(s->ents);
Z_Free(s->mesh.xyz_array);
@ -2713,6 +2719,21 @@ static void Terr_RebuildMesh(model_t *model, hmsection_t *s, int x, int y)
s->vbo = *vbo;
}
#endif
#ifdef D3D9QUAKE
if (qrenderer == QR_DIRECT3D9)
{
void D3D9BE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch);
batch_t batch = {0};
mesh_t *meshes = &s->mesh;
vbo_t *vbo = NULL;
batch.maxmeshes = 1;
batch.mesh = &meshes;
//BE_ClearVBO(&s->vbo);
D3D9BE_GenBatchVBOs(&vbo, &batch, NULL);
s->vbo = *vbo;
}
#endif
#ifdef D3D11QUAKE
if (qrenderer == QR_DIRECT3D11)
{
@ -5409,6 +5430,8 @@ void Terr_FinishTerrain(model_t *mod)
//FIXME: these maps are a legacy thing, and could be removed if third-party glsl properly contains s_diffuse
"{\n"
"map $diffuse\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"{\n"
"map $upperoverlay\n"

View file

@ -540,14 +540,14 @@ void HL_CalcBoneAdj(hlmodel_t *model)
=======================================================================================================================
*/
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt );
void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, float subblendfrac, float frametime, float *matrix)
void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, float subblendfrac1, float subblendfrac2, float frametime, float *matrix)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int i;
int i, j;
vec3_t organg1[2];
vec3_t organg2[2];
vec3_t organgb[2];
vec4_t quat1, quat2, quatb;
vec4_t quat1, quat2;
int frame1, frame2;
@ -654,54 +654,170 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
FIXME: we don't handle frame2.
*/
if (sequence->hasblendseq>1 && sequence->hasblendseq<9)
if (sequence->hasblendseq>1)
{
//I have no idea how to deal with > 1.
//some CS models seem to have 9 here, but some look like they're fucked.
if (subblendfrac < 0)
subblendfrac = 0;
if (subblendfrac > 1)
subblendfrac = 1;
for(i = firstbone; i < lastbone; i++, matrix+=12)
int bf0, bf1;
int bweights;
struct
{
//calc first blend (writes organgb+quatb)
HL_CalculateBones(frame1, model->adjust, model->bones + i, animation + i, organgb[0]);
QuaternionGLAngle(organgb[1], quatb); /* A quaternion */
if (frame1 != frame2)
int frame;
float weight;
hlmdl_anim_t *anim;
} blend[8];
//right, so, this stuff is annoying.
//we have two different blend factors.
//we have up to 9 blend weights. figure out which frames are what
switch(sequence->hasblendseq)
{
HL_CalculateBones(frame2, model->adjust, model->bones + i, animation + i, organg2[0]);
QuaternionGLAngle(organg2[1], quat2); /* A quaternion */
QuaternionSlerp(quatb, quat2, frametime, quatb);
VectorInterpolate(organgb[0], frametime, organg2[0], organgb[0]);
case 0: //erk?
return;
case 1: //no blending.
bf0 = bf1 = 1;
break;
default:
case 2: //mix(0, 1, weight0)
case 3: //mix(0, 1, 2, weight0);
case 8: //weight0 only...
bf0 = sequence->hasblendseq;
bf1 = 1;
break;
case 4: //mix(mix(0, 1, weight0), mix(2, 3, weight0), weight1)
bf0 = bf1 = 2;
break;
//case 6: //???
// bf[0] = 3; bf[1] = 2;
// break;
case 9: //mix(mix(0, 1, 2, weight0), mix(2, 3, 4, weight0), mix(5, 6, 7, weight0), weight1)
bf0 = bf1 = 3;
break;
}
//calc first blend (writes organg1+quat1)
HL_CalculateBones(frame1, model->adjust, model->bones + i, animation + i + model->header->numbones, organg1[0]);
QuaternionGLAngle(organg1[1], quat1); /* A quaternion */
if (frame1 != frame2)
subblendfrac1 = (subblendfrac1+1)/2;
subblendfrac2 = (subblendfrac2+1)/2;
bweights = 0;
if (bf0 > 1)
{
HL_CalculateBones(frame2, model->adjust, model->bones + i, animation + i + model->header->numbones, organg2[0]);
QuaternionGLAngle(organg2[1], quat2); /* A quaternion */
float frac = (bf0-1) * bound(0, subblendfrac1, 1);
int f1 = bound(0, frac, bf0-1);
int f2 = bound(0, f1+1, bf0-1);
frac = (frac-f1);
frac = bound(0, frac, 1);
if (bf1 > 1)
{
float frac2 = (bf1-1) * bound(0, subblendfrac2, 1);
int a1 = bound(0, frac2, bf1-1);
int a2 = bound(0, a1+1, bf1-1);
frac2 = (frac2-a1);
frac2 = bound(0, frac2, 1);
QuaternionSlerp(quat1, quat2, frametime, quat1);
VectorInterpolate(organg1[0], frametime, organg2[0], organg1[0]);
if (frac2)
{
if (frac)
{
blend[bweights].frame = frame1;
blend[bweights].anim = animation + model->header->numbones * (f2 + a2*bf0);
blend[bweights++].weight = frac*frac2;
}
if (1-frac)
{
blend[bweights].frame = frame1;
blend[bweights].anim = animation + model->header->numbones * (f1 + a2*bf0);
blend[bweights++].weight = (1-frac)*frac2;
}
}
//blend the two, figure out a matrix.
QuaternionSlerp(quatb, quat1, subblendfrac, quat1);
QuaternionGLMatrix(quat1[0], quat1[1], quat1[2], quat1[3], (vec4_t*)matrix);
FloatInterpolate(organgb[0][0], subblendfrac, organg1[0][0], matrix[0*4+3]);
FloatInterpolate(organgb[0][1], subblendfrac, organg1[0][1], matrix[1*4+3]);
FloatInterpolate(organgb[0][2], subblendfrac, organg1[0][2], matrix[2*4+3]);
if (1-frac2)
{
if (frac)
{
blend[bweights].frame = frame1;
blend[bweights].anim = animation + model->header->numbones * (f2 + a1*bf0);
blend[bweights++].weight = frac*(1-frac2);
}
if (1-frac)
{
blend[bweights].frame = frame1;
blend[bweights].anim = animation + model->header->numbones * (f1 + a1*bf0);
blend[bweights++].weight = (1-frac)*(1-frac2);
}
}
}
else
{
//FIXME: disgusting hack to get CS player models not looking like total idiots. but merely regular ones instead.
if (sequence->hasblendseq == 9)
animation += 4*model->header->numbones;
if (frac)
{
blend[bweights].frame = frame1;
blend[bweights].anim = animation + model->header->numbones * f1;
blend[bweights++].weight = frac;
}
if (1-frac)
{
blend[bweights].frame = frame1;
blend[bweights].anim = animation + model->header->numbones * f2;
blend[bweights++].weight = 1-frac;
}
}
}
else
{
blend[bweights].frame = frame1;
blend[bweights].anim = animation;
blend[bweights++].weight = 1;
}
if (frame1 != frame2)
{
for (i = 0; i < bweights; i++)
{
blend[bweights+i].frame = frame2;
blend[bweights+i].anim = blend[i].anim;
blend[bweights+i].weight = blend[i].weight;
blend[i].weight *= 1-frametime;
blend[bweights+i].weight *= frametime;
}
bweights *= 2;
}
for(i = firstbone; i < lastbone; i++, matrix+=12)
{
vec3_t t;
float len;
HL_CalculateBones(blend[0].frame, model->adjust, model->bones + i, blend[0].anim + i, organgb[0]);
QuaternionGLAngle(organgb[1], quat2);
Vector4Scale(quat2, blend[0].weight, quat1);
VectorScale(organgb[0], blend[0].weight, t);
for (j = 1; j < bweights; j++)
{
HL_CalculateBones(blend[j].frame, model->adjust, model->bones + i, blend[j].anim + i, organgb[0]);
QuaternionGLAngle(organgb[1], quat2);
if (DotProduct4(quat2, quat1) < 0) //negative quats are annoying
Vector4MA(quat1, -blend[j].weight, quat2, quat1);
else
Vector4MA(quat1, blend[j].weight, quat2, quat1);
VectorMA(t, blend[j].weight, organgb[0], t);
}
//we were lame and didn't use slerp. boo hiss. now we need to normalise the things and hope we didn't hit any singularities
len = sqrt(DotProduct4(quat1,quat1));
if (len && len != 1)
{
len = 1/len;
quat1[0] *= len;
quat1[1] *= len;
quat1[2] *= len;
quat1[3] *= len;
}
QuaternionGLMatrix(quat1[0], quat1[1], quat1[2], quat1[3], (vec4_t*)matrix);
matrix[0*4+3] = t[0];
matrix[1*4+3] = t[1];
matrix[2*4+3] = t[2];
}
}
else
{
for(i = firstbone; i < lastbone; i++, matrix+=12)
{
HL_CalculateBones(frame1, model->adjust, model->bones + i, animation + i, organg1[0]);
@ -797,7 +913,7 @@ static int HLMDL_GetBoneData_Internal(hlmodel_t *model, int firstbone, int lastb
lastbone = model->header->numbones;
if (cbone >= lastbone)
continue;
HL_SetupBones(model, fstate->g[bgroup].frame[0], cbone, lastbone, (fstate->g[bgroup].subblendfrac+1)*0.5, fstate->g[bgroup].frametime[0], result); /* Setup the bones */
HL_SetupBones(model, fstate->g[bgroup].frame[0], cbone, lastbone, fstate->g[bgroup].subblendfrac, fstate->g[bgroup].subblend2frac, fstate->g[bgroup].frametime[0], result); /* Setup the bones */
cbone = lastbone;
}
return cbone;
@ -1064,7 +1180,7 @@ void R_HL_BuildFrame(hlmodel_t *model, hlmdl_submodel_t *amodel, entity_t *curen
lastbone = model->header->numbones;
if (cbone >= lastbone)
continue;
HL_SetupBones(model, curent->framestate.g[bgroup].frame[0], cbone, lastbone, (curent->framestate.g[bgroup].subblendfrac+1)*0.5, curent->framestate.g[bgroup].frametime[0], relatives); // Setup the bones
HL_SetupBones(model, curent->framestate.g[bgroup].frame[0], cbone, lastbone, curent->framestate.g[bgroup].subblendfrac, curent->framestate.g[bgroup].frametime[0], relatives); // Setup the bones
cbone = lastbone;
}
*/

View file

@ -3351,7 +3351,7 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
}
mt = (miptex_t *)((qbyte *)m + m->dataofs[i]);
TRACE(("dbg: Mod_LoadTextures: texture %s\n", loadname));
TRACE(("dbg: Mod_LoadTextures: texture %s\n", mt->name));
if (!*mt->name) //I HATE MAPPERS!
{

View file

@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern cvar_t gl_lightmap_nearest;
void GLBE_ClearVBO(vbo_t *vbo)
void GLBE_ClearVBO(vbo_t *vbo, qboolean dataonly)
{
int vboh[6 + MAXRLIGHTMAPS];
int i, j;
@ -41,6 +41,14 @@ void GLBE_ClearVBO(vbo_t *vbo)
for (i = 0; i < MAXRLIGHTMAPS; i++)
vboh[6+i] = vbo->lmcoord[i].gl.vbo;
memset (&vbo->indicies, 0, sizeof(vbo->indicies));
memset (&vbo->coord, 0, sizeof(vbo->coord));
memset (&vbo->texcoord, 0, sizeof(vbo->texcoord));
memset (&vbo->normals, 0, sizeof(vbo->normals));
memset (&vbo->svector, 0, sizeof(vbo->svector));
memset (&vbo->tvector, 0, sizeof(vbo->tvector));
memset (&vbo->lmcoord, 0, sizeof(vbo->lmcoord));
for (i = 0; i < 7; i++)
{
if (!vboh[i])
@ -55,7 +63,10 @@ void GLBE_ClearVBO(vbo_t *vbo)
}
if (vbo->vertdata)
BZ_Free(vbo->vertdata);
vbo->vertdata = NULL;
BZ_Free(vbo->meshlist);
vbo->meshlist = NULL;
if (!dataonly)
BZ_Free(vbo);
}

View file

@ -64,6 +64,11 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_setwindow(JNIEnv *env, jobj
r_forceheadless = (sys_jsurface == NULL);
if (r_forceheadless)
Sys_Printf("Running without a window\n");
else
Sys_Printf("Got a window\n");
if (qrenderer) //if the window changed then we need to restart everything to match it, BEFORE we return from this function... :(
R_RestartRenderer_f();
}
@ -276,6 +281,7 @@ static qboolean VKVID_Init (rendererstate_t *info, unsigned char *palette)
//this is simpler than most platforms, as the window itself is handled by java code, and we can't create/destroy it here
//(android surfaces can be resized/resampled separately from their window, and are always 'fullscreen' anyway, so this isn't actually an issue for once)
const char *extnames[] = {VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, NULL};
Sys_Printf("initialising vulkan...\n");
if (!sys_jsurface)
{
Sys_Printf("VKVID_Init failed: no window known yet\n");

View file

@ -10658,7 +10658,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"colorscale *= 1.0-(dot(spot,spot));\n"
"#endif\n"
"#ifdef PCF\n"
"colorscale *= ShadowmapFilter(s_t5);\n"
"colorscale *= ShadowmapFilter(s_t5, vtexprojcoord);\n"
"#endif\n"
"r.rgb *= colorscale * l_lightcolour;\n"
@ -10677,6 +10677,217 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
},
#endif
#ifdef D3D9QUAKE
{QR_DIRECT3D9, 9, "terrain",
"!!permu FOG\n"
"!!samps 5\n"
"#include \"sys/fog.h\"\n"
//FIXME: too lazy to implement this right now.
"#undef RTLIGHT\n"
"#undef PCF\n"
"#undef CUBE\n"
"struct a2v\n"
"{\n"
"float3 pos: POSITION0;\n"
"float2 tc: TEXCOORD0;\n"
"float2 lm: TEXCOORD1;\n"
"float4 vc: COLOR;\n"
"#ifdef RTLIGHT\n"
"attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n"
"attribute vec3 v_tvector;\n"
"#endif\n"
"};\n"
"struct v2f\n"
"{\n"
"float1 depth: TEXCOORD1;\n"
"float4 tclm: TEXCOORD0;\n"
"float4 vc: COLOR;\n"
"#ifdef RTLIGHT\n"
"varying vec3 lightvector;\n"
// #if defined(SPECULAR) || defined(OFFSETMAPPING)
// varying vec3 eyevector;
// #endif
"#if defined(PCF) || defined(CUBE) || defined(SPOT)\n"
"varying vec4 vtexprojcoord;\n"
"#endif\n"
"#endif\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_model;\n"
"float4x4 m_view;\n"
"float4x4 m_projection;\n"
"#ifdef RTLIGHT\n"
"uniform vec3 l_lightposition;\n"
// #if defined(SPECULAR) || defined(OFFSETMAPPING)
// uniform vec3 e_eyepos;
// #endif
"#if defined(PCF) || defined(CUBE) || defined(SPOT)\n"
"uniform mat4 l_cubematrix;\n"
"#endif\n"
"#endif\n"
"float3 e_lmscale;\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.tclm = float4(inp.tc, inp.lm);\n"
"outp.vc = inp.vc;\n"
"float4 pos = float4(inp.pos, 1);\n"
"pos = mul(m_model, pos);\n"
"pos = mul(m_view, pos);\n"
"outp.depth = pos.z;\n"
"pos = mul(m_projection, pos);\n"
"outp.pos = pos;\n"
"#ifdef RTLIGHT\n"
//light position is in model space, which is handy.
"vec3 lightminusvertex = l_lightposition - v_position.xyz;\n"
//no bumpmapping, so we can just use distance without regard for actual surface direction. we still do scalecos stuff. you might notice it on steep slopes.
"lightvector = lightminusvertex;\n"
// lightvector.x = dot(lightminusvertex, v_svector.xyz);
// lightvector.y = dot(lightminusvertex, v_tvector.xyz);
// lightvector.z = dot(lightminusvertex, v_normal.xyz);
// #if defined(SPECULAR)||defined(OFFSETMAPPING)
// vec3 eyeminusvertex = e_eyepos - v_position.xyz;
// eyevector.x = dot(eyeminusvertex, v_svector.xyz);
// eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
// eyevector.z = dot(eyeminusvertex, v_normal.xyz);
// #endif
"#if defined(PCF) || defined(SPOT) || defined(CUBE)\n"
//for texture projections/shadowmapping on dlights
"vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0));\n"
"#endif\n"
"#else\n"
"outp.vc.rgb *= e_lmscale.rgb;\n"
"#endif\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
//four texture passes
"sampler s_t0;\n"
"sampler s_t1;\n"
"sampler s_t2;\n"
"sampler s_t3;\n"
//mix values
"sampler s_t4;\n"
"#ifdef PCF\n"
"uniform sampler2DShadow s_t5;\n"
"#include \"sys/pcf.h\"\n"
"#endif\n"
"#ifdef CUBE\n"
"uniform samplerCube s_t6;\n"
"#endif\n"
"#ifdef RTLIGHT\n"
"uniform float l_lightradius;\n"
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightcolourscale;\n"
"#endif\n"
"float4 main (v2f inp) : COLOR\n"
"{\n"
"float2 lm = inp.tclm.zw;\n"
"float2 tc = inp.tclm.xy;\n"
"float4 vc = inp.vc;\n"
"float4 r;\n"
"float4 m = tex2D(s_t4, lm);\n"
"r = tex2D(s_t0, tc)*m.r;\n"
"r += tex2D(s_t1, tc)*m.g;\n"
"r += tex2D(s_t2, tc)*m.b;\n"
"r += tex2D(s_t3, tc)*(1.0 - (m.r + m.g + m.b));\n"
"r.a = 1.0;\n"
//vertex colours provide a scaler that applies even through rtlights.
"r *= vc;\n"
"#ifdef RTLIGHT\n"
"vec3 nl = normalize(lightvector);\n"
"float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);\n"
"vec3 diff;\n"
// #ifdef BUMP
// colorscale *= (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0));
// #else
"colorscale *= (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));\n"
// #endif
// #ifdef SPECULAR
// vec3 halfdir = normalize(normalize(eyevector) + nl);
// float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);
// diff += l_lightcolourscale.z * spec * specs.rgb;
// #endif
"#if defined(SPOT)\n"
"if (vtexprojcoord.w < 0.0) discard;\n"
"vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);\n"
"colorscale *= 1.0-(dot(spot,spot));\n"
"#endif\n"
"#ifdef PCF\n"
"colorscale *= ShadowmapFilter(s_t5);\n"
"#endif\n"
"r.rgb *= colorscale * l_lightcolour;\n"
"#ifdef CUBE\n"
"r.rgb *= textureCube(s_t6, vtexprojcoord.xyz).rgb;\n"
"#endif\n"
"r = fog4additive(r, inp.pos);\n"
"#else\n"
//lightmap is greyscale in m.a. probably we should just scale the texture mix, but precision errors when editing make me paranoid.
"r.rgb *= m.aaa;\n"
"r = fog4(r, inp.depth);\n"
"#endif\n"
"return r;\n"
"}\n"
"#endif\n"
},
#endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "terrain",
"struct a2v\n"

View file

@ -787,7 +787,7 @@ void GLBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, unsig
void GLBE_SubmitBatch(batch_t *batch);
batch_t *GLBE_GetTempBatch(void);
void GLBE_GenBrushModelVBO(model_t *mod);
void GLBE_ClearVBO(vbo_t *vbo);
void GLBE_ClearVBO(vbo_t *vbo, qboolean dataonly);
void GLBE_UploadAllLightmaps(void);
void GLBE_DrawWorld (batch_t **worldbatches);
qboolean GLBE_LightCullModel(vec3_t org, model_t *model);
@ -817,7 +817,7 @@ void D3D8BE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, uns
void D3D8BE_SubmitBatch(batch_t *batch);
batch_t *D3D8BE_GetTempBatch(void);
void D3D8BE_GenBrushModelVBO(model_t *mod);
void D3D8BE_ClearVBO(vbo_t *vbo);
void D3D8BE_ClearVBO(vbo_t *vbo, qboolean dataonly);
void D3D8BE_UploadAllLightmaps(void);
void D3D8BE_DrawWorld (batch_t **worldbatches);
qboolean D3D8BE_LightCullModel(vec3_t org, model_t *model);
@ -842,7 +842,7 @@ void D3D9BE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, uns
void D3D9BE_SubmitBatch(batch_t *batch);
batch_t *D3D9BE_GetTempBatch(void);
void D3D9BE_GenBrushModelVBO(model_t *mod);
void D3D9BE_ClearVBO(vbo_t *vbo);
void D3D9BE_ClearVBO(vbo_t *vbo, qboolean dataonly);
void D3D9BE_UploadAllLightmaps(void);
void D3D9BE_DrawWorld (batch_t **worldbatches);
qboolean D3D9BE_LightCullModel(vec3_t org, model_t *model);
@ -867,7 +867,7 @@ void D3D11BE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, un
void D3D11BE_SubmitBatch(batch_t *batch);
batch_t *D3D11BE_GetTempBatch(void);
void D3D11BE_GenBrushModelVBO(model_t *mod);
void D3D11BE_ClearVBO(vbo_t *vbo);
void D3D11BE_ClearVBO(vbo_t *vbo, qboolean dataonly);
void D3D11BE_UploadAllLightmaps(void);
void D3D11BE_DrawWorld (batch_t **worldbatches);
qboolean D3D11BE_LightCullModel(vec3_t org, model_t *model);

View file

@ -318,8 +318,10 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(bonecontrol3,"Halflife model format bone controller. On player models, this typically affects the spine's yaw.") /*FTE_CSQC_HALFLIFE_MODELS*/\
comfieldfloat(bonecontrol4,"Halflife model format bone controller. On player models, this typically affects the spine's yaw.") /*FTE_CSQC_HALFLIFE_MODELS*/\
comfieldfloat(bonecontrol5,"Halflife model format bone controller. This typically affects the mouth.") /*FTE_CSQC_HALFLIFE_MODELS*/\
comfieldfloat(subblendfrac,"Weird animation value specific to halflife models. On player models, this typically affects the spine's pitch.") /*FTE_CSQC_HALFLIFE_MODELS*/\
comfieldfloat(basesubblendfrac,"See basebone") /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/
comfieldfloat(subblendfrac,"Weird animation value specific to halflife models. On player models, this typically affects the spine's pitch, or yaw, or...") /*FTE_CSQC_HALFLIFE_MODELS*/\
comfieldfloat(subblend2frac,"Weird animation value specific to halflife models. I've no idea what this does, probably nothing for most models.") /*FTE_CSQC_HALFLIFE_MODELS*/\
comfieldfloat(basesubblendfrac,"See basebone") /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/\
comfieldfloat(basesubblend2frac,"See basebone") /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/
#else
#define HALFLIFEMODEL_FIELDS
#endif

View file

@ -1041,9 +1041,10 @@ static void GHL_GetFrameState(hledict_t *ent, framestate_t *fstate)
fstate->g[FS_REG].frametime[0] = (SVHL_Globals.time - ent->v.framestarttime) * ent->v.framerate;
fstate->g[FS_REG].frame[0] = ent->v.frame;
fstate->g[FS_REG].lerpweight[0] = 1;
fstate->g[FS_REG].subblendfrac = ent->v.blending[0]; //fixme: which is upper?
fstate->g[FS_REG].subblendfrac = ent->v.blending[0];
fstate->g[FS_REG].subblend2frac = ent->v.blending[1];
//FIXME: no lower parts.
//FIXME: no lower parts set here.
fstate->bonecontrols[0] = ent->v.controller[0] / 255.0;
fstate->bonecontrols[1] = ent->v.controller[1] / 255.0;

View file

@ -135,7 +135,7 @@ void main (void)
colorscale *= 1.0-(dot(spot,spot));
#endif
#ifdef PCF
colorscale *= ShadowmapFilter(s_t5);
colorscale *= ShadowmapFilter(s_t5, vtexprojcoord);
#endif
r.rgb *= colorscale * l_lightcolour;

View file

@ -0,0 +1,207 @@
!!permu FOG
!!samps 5
#include "sys/fog.h"
//FIXME: too lazy to implement this right now.
#undef RTLIGHT
#undef PCF
#undef CUBE
struct a2v
{
float3 pos: POSITION0;
float2 tc: TEXCOORD0;
float2 lm: TEXCOORD1;
float4 vc: COLOR;
#ifdef RTLIGHT
attribute vec3 v_normal;
attribute vec3 v_svector;
attribute vec3 v_tvector;
#endif
};
struct v2f
{
float1 depth: TEXCOORD1;
float4 tclm: TEXCOORD0;
float4 vc: COLOR;
#ifdef RTLIGHT
varying vec3 lightvector;
// #if defined(SPECULAR) || defined(OFFSETMAPPING)
// varying vec3 eyevector;
// #endif
#if defined(PCF) || defined(CUBE) || defined(SPOT)
varying vec4 vtexprojcoord;
#endif
#endif
#ifndef FRAGMENT_SHADER
float4 pos: POSITION;
#endif
};
#ifdef VERTEX_SHADER
float4x4 m_model;
float4x4 m_view;
float4x4 m_projection;
#ifdef RTLIGHT
uniform vec3 l_lightposition;
// #if defined(SPECULAR) || defined(OFFSETMAPPING)
// uniform vec3 e_eyepos;
// #endif
#if defined(PCF) || defined(CUBE) || defined(SPOT)
uniform mat4 l_cubematrix;
#endif
#endif
float3 e_lmscale;
v2f main (a2v inp)
{
v2f outp;
outp.tclm = float4(inp.tc, inp.lm);
outp.vc = inp.vc;
float4 pos = float4(inp.pos, 1);
pos = mul(m_model, pos);
pos = mul(m_view, pos);
outp.depth = pos.z;
pos = mul(m_projection, pos);
outp.pos = pos;
#ifdef RTLIGHT
//light position is in model space, which is handy.
vec3 lightminusvertex = l_lightposition - v_position.xyz;
//no bumpmapping, so we can just use distance without regard for actual surface direction. we still do scalecos stuff. you might notice it on steep slopes.
lightvector = lightminusvertex;
// lightvector.x = dot(lightminusvertex, v_svector.xyz);
// lightvector.y = dot(lightminusvertex, v_tvector.xyz);
// lightvector.z = dot(lightminusvertex, v_normal.xyz);
// #if defined(SPECULAR)||defined(OFFSETMAPPING)
// vec3 eyeminusvertex = e_eyepos - v_position.xyz;
// eyevector.x = dot(eyeminusvertex, v_svector.xyz);
// eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
// eyevector.z = dot(eyeminusvertex, v_normal.xyz);
// #endif
#if defined(PCF) || defined(SPOT) || defined(CUBE)
//for texture projections/shadowmapping on dlights
vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0));
#endif
#else
outp.vc.rgb *= e_lmscale.rgb;
#endif
return outp;
}
#endif
#ifdef FRAGMENT_SHADER
//four texture passes
sampler s_t0;
sampler s_t1;
sampler s_t2;
sampler s_t3;
//mix values
sampler s_t4;
#ifdef PCF
uniform sampler2DShadow s_t5;
#include "sys/pcf.h"
#endif
#ifdef CUBE
uniform samplerCube s_t6;
#endif
#ifdef RTLIGHT
uniform float l_lightradius;
uniform vec3 l_lightcolour;
uniform vec3 l_lightcolourscale;
#endif
float4 main (v2f inp) : COLOR
{
float2 lm = inp.tclm.zw;
float2 tc = inp.tclm.xy;
float4 vc = inp.vc;
float4 r;
float4 m = tex2D(s_t4, lm);
r = tex2D(s_t0, tc)*m.r;
r += tex2D(s_t1, tc)*m.g;
r += tex2D(s_t2, tc)*m.b;
r += tex2D(s_t3, tc)*(1.0 - (m.r + m.g + m.b));
r.a = 1.0;
//vertex colours provide a scaler that applies even through rtlights.
r *= vc;
#ifdef RTLIGHT
vec3 nl = normalize(lightvector);
float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);
vec3 diff;
// #ifdef BUMP
// colorscale *= (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0));
// #else
colorscale *= (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));
// #endif
// #ifdef SPECULAR
// vec3 halfdir = normalize(normalize(eyevector) + nl);
// float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);
// diff += l_lightcolourscale.z * spec * specs.rgb;
// #endif
#if defined(SPOT)
if (vtexprojcoord.w < 0.0) discard;
vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);
colorscale *= 1.0-(dot(spot,spot));
#endif
#ifdef PCF
colorscale *= ShadowmapFilter(s_t5);
#endif
r.rgb *= colorscale * l_lightcolour;
#ifdef CUBE
r.rgb *= textureCube(s_t6, vtexprojcoord.xyz).rgb;
#endif
r = fog4additive(r, inp.pos);
#else
//lightmap is greyscale in m.a. probably we should just scale the texture mix, but precision errors when editing make me paranoid.
r.rgb *= m.aaa;
r = fog4(r, inp.depth);
#endif
return r;
}
#endif

View file

@ -170,7 +170,7 @@ struct batch_s *SWBE_GetTempBatch(void);
void SWBE_DrawWorld(batch_t **worldbatches);
void SWBE_Init(void);
void SWBE_GenBrushModelVBO(struct model_s *mod);
void SWBE_ClearVBO(struct vbo_s *vbo);
void SWBE_ClearVBO(struct vbo_s *vbo, qboolean dataonly);
void SWBE_UploadAllLightmaps(void);
void SWBE_SelectEntity(struct entity_s *ent);
qboolean SWBE_SelectDLight(struct dlight_s *dl, vec3_t colour, vec3_t axis[3], unsigned int lmode);

View file

@ -654,7 +654,7 @@ void SWBE_Init(void)
void SWBE_GenBrushModelVBO(struct model_s *mod)
{
}
void SWBE_ClearVBO(struct vbo_s *vbo)
void SWBE_ClearVBO(struct vbo_s *vbo, qboolean dataonly)
{
}
void SWBE_UploadAllLightmaps(void)

View file

@ -4010,8 +4010,20 @@ static void VKBE_SafeClearVBO(void *vboptr)
BZ_Free(vbo);
}
/*Wipes a vbo*/
void VKBE_ClearVBO(vbo_t *vbo)
void VKBE_ClearVBO(vbo_t *vbo, qboolean dataonly)
{
if (dataonly)
{
//create one for the safe callback to clear.
vbo_t *nvbo = BZ_Malloc(sizeof(*vbo));
nvbo->indicies = vbo->indicies;
nvbo->coord = vbo->coord;
//scrub it now
memset(&vbo->indicies, 0, sizeof(vbo->indicies));
memset(&vbo->coord, 0, sizeof(vbo->coord));
vbo = nvbo;
}
VK_AtFrameEnd(VKBE_SafeClearVBO, &vbo, sizeof(vbo));
}

View file

@ -410,7 +410,7 @@ void VKBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, unsig
void VKBE_SubmitBatch(batch_t *batch);
batch_t *VKBE_GetTempBatch(void);
void VKBE_GenBrushModelVBO(model_t *mod);
void VKBE_ClearVBO(vbo_t *vbo);
void VKBE_ClearVBO(vbo_t *vbo, qboolean dataonly);
void VKBE_UploadAllLightmaps(void);
void VKBE_DrawWorld (batch_t **worldbatches);
qboolean VKBE_LightCullModel(vec3_t org, model_t *model);