1
0
Fork 0
forked from fte/fteqw

merge gl+vk win32 code. include egl support on windows (useful for ANGLE).

fix misc bugs.
rewrote skeletal code to use gpu-friendly skeletal data for all skeletal formats.
add modelframecount builtin, to easily get the number of frames in a model.
integrate hlmdl a little better.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5031 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2016-12-13 11:50:15 +00:00
parent 151adc38ed
commit 6e825e42dd
39 changed files with 1469 additions and 2777 deletions

View file

@ -1081,7 +1081,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
NPFTE_CFLAGS=$(NPFTECFLAGS) $(W32_CFLAGS) -DMULTITHREAD
NPFTEB_DIR=npfte_mgw$(BITS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidnt.o vk_win32.o $(WINDOWS_OBJS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidnt.o gl_videgl.o $(WINDOWS_OBJS)
M_EXE_NAME=../fteqw$(BITS)$(EXEPOSTFIX)
MCL_EXE_NAME=../fteqwcl$(BITS)$(EXEPOSTFIX)
M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows
@ -1097,7 +1097,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
D3DB_DIR=d3d_mgw$(BITS)
D3DCL_DIR=d3dcl_mgw$(BITS)
VKCL_OBJS=$(GLQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) $(WINDOWS_OBJS) vk_win32.o
VKCL_OBJS=$(GLQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) $(WINDOWS_OBJS) gl_vidnt.o
VK_EXE_NAME=../ftevkqw$(BITS)$(EXEPOSTFIX)
VKCL_EXE_NAME=../ftevkclqw$(BITS)$(EXEPOSTFIX)
VK_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows

View file

@ -1112,6 +1112,7 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
end = (pv->cam_spec_track + 1) % MAX_CLIENTS;
else
end = pv->cam_spec_track;
end = max(0, end) % cl.allocated_client_slots;
i = end;
do
{

View file

@ -1462,7 +1462,7 @@ void SCR_DrawFPS (void)
double t;
extern int fps_count;
static float lastfps;
static float deviationtimes[64];
static double deviationtimes[64];
static int deviationframe;
char str[80];
int sfps, frame;

View file

@ -1399,13 +1399,6 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
typedef struct {
menucustom_t *list;
char intermediatefilename[MAX_QPATH];
char pathprefix[MAX_QPATH];
int downloadablessequence;
qboolean populated;
} dlmenu_t;
static void COM_QuotedConcat(const char *cat, char *buf, size_t bufsize)
{
@ -2294,9 +2287,6 @@ void PM_Command_f (void)
{
Con_Printf("Package Manager is not implemented in this build\n");
}
void Menu_Download_Update(void)
{
}
void PM_LoadPackages(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, int minpri, int maxpri)
{
}
@ -2309,6 +2299,14 @@ void PM_Shutdown(void)
#endif
#ifdef DOWNLOADMENU
typedef struct {
menucustom_t *list;
char intermediatefilename[MAX_QPATH];
char pathprefix[MAX_QPATH];
int downloadablessequence;
qboolean populated;
} dlmenu_t;
static int autoupdatesetting = UPD_UNSUPPORTED;
static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
{
@ -2735,6 +2733,9 @@ void Menu_Download_Update(void)
PM_UpdatePackageList(true, 2);
}
#else
void Menu_Download_Update(void)
{
}
void Menu_DownloadStuff_f (void)
{
Con_Printf("Download menu not implemented in this build\n");

View file

@ -2805,21 +2805,25 @@ static unsigned int genhsv(float h_, float s, float v)
#include "com_mesh.h"
#ifdef SKELETALMODELS
static void M_BoneDisplay(entity_t *e, galiasbone_t *b, int *y, int depth, int parent, int first, int last)
static void M_BoneDisplayLame(entity_t *e, int *y, int depth, int parent, int first, int last)
{
int i;
for (i = first; i < last; i++)
{
if (b[i].parent == parent)
int p = Mod_GetBoneParent(e->model, i+1);
if (p == parent)
{
const char *bname = Mod_GetBoneName(e->model, i+1);
float result[12];
if (!bname)
bname = "NULL";
memset(result, 0, sizeof(result));
if (Mod_GetTag(e->model, i+1, &e->framestate, result))
Draw_FunString(depth*16, *y, va("%i: %s (%g %g %g)", i, b[i].name, result[3], result[7], result[11]));
Draw_FunString(depth*16, *y, va("%i: %s (%g %g %g)", i, bname, result[3], result[7], result[11]));
else
Draw_FunString(depth*16, *y, va("%i: %s", i, b[i].name));
Draw_FunString(depth*16, *y, va("%i: %s", i, bname));
*y += 8;
M_BoneDisplay(e, b, y, depth+1, i, i+1, last);
M_BoneDisplayLame(e, y, depth+1, i+1, i+1, last);
}
}
}
@ -2832,7 +2836,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
const char *fname;
shader_t *shader;
vec2_t fs = {8,8};
float bones[12*MAX_BONES];
// float bones[12*MAX_BONES];
modelview_t *mods = c->dptr;
@ -2892,15 +2896,30 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
ent.customskin = Mod_RegisterSkinFile(va("%s_0.skin", mods->modelname));
// ent.framestate.bonecount = Mod_GetNumBones(ent.model, false);
ent.framestate.bonestate = bones;
ent.framestate.bonecount = Mod_GetBoneRelations(ent.model, 0, MAX_BONES, &ent.framestate, ent.framestate.bonestate);
ent.framestate.skeltype = SKEL_RELATIVE;
// ent.framestate.bonestate = bones;
// ent.framestate.bonecount = Mod_GetBoneRelations(ent.model, 0, MAX_BONES, &ent.framestate, ent.framestate.bonestate);
// ent.framestate.skeltype = SKEL_RELATIVE;
ent.light_avg[0] = ent.light_avg[1] = ent.light_avg[2] = 0.66;
ent.light_range[0] = ent.light_range[1] = ent.light_range[2] = 0.33;
ent.light_dir[0] = 0; ent.light_dir[1] = 1; ent.light_dir[2] = 0;
ent.light_known = 2;
switch(ent.model->loadstate)
{
case MLS_LOADED:
break;
case MLS_NOTLOADED:
Draw_FunString(0, 0, va("%s not loaded", ent.model->name));
return;
case MLS_LOADING:
Draw_FunString(0, 0, va("%s still loading", ent.model->name));
return;
case MLS_FAILED:
Draw_FunString(0, 0, va("Unable to load %s", ent.model->name));
return;
}
V_AddEntity(&ent);
V_ApplyRefdef();
@ -2950,13 +2969,12 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
case MV_BONES:
#ifdef SKELETALMODELS
{
int bonecount;
galiasbone_t *b = Mod_GetBoneInfo(ent.model, &bonecount);
if (b && bonecount)
int bonecount = Mod_GetNumBones(ent.model, false);
if (bonecount)
{
Draw_FunString(0, y, va("Bones: "));
y+=8;
M_BoneDisplay(&ent, b, &y, 0, -1, 0, bonecount);
M_BoneDisplayLame(&ent, &y, 0, 0, 0, bonecount);
}
else
R_DrawTextField(r_refdef.grect.x, r_refdef.grect.y+y, r_refdef.grect.width, r_refdef.grect.height-y, "No bones in model", CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_default, fs);

View file

@ -176,6 +176,7 @@ extern void Mod_Think (void);
extern int Mod_SkinNumForName (struct model_s *model, int surfaceidx, const char *name);
extern int Mod_FrameNumForName (struct model_s *model, int surfaceidx, const char *name);
extern float Mod_GetFrameDuration (struct model_s *model, int surfaceidx, int framenum);
extern int Mod_GetFrameCount (struct model_s *model);
#undef FNC
@ -186,7 +187,7 @@ int Mod_GetNumBones(struct model_s *model, qboolean allowtags);
int Mod_GetBoneRelations(struct model_s *model, int firstbone, int lastbone, framestate_t *fstate, float *result);
int Mod_GetBoneParent(struct model_s *model, int bonenum);
struct galiasbone_s *Mod_GetBoneInfo(struct model_s *model, int *numbones);
char *Mod_GetBoneName(struct model_s *model, int bonenum);
const char *Mod_GetBoneName(struct model_s *model, int bonenum);
void Draw_FunString(float x, float y, const void *str);
void Draw_AltFunString(float x, float y, const void *str);

View file

@ -5736,6 +5736,9 @@ static struct {
{"hash_getcb", PF_hash_getcb, 293},
{"checkcommand", PF_checkcommand, 294},
{"argescape", PF_argescape, 295},
{"modelframecount", PF_modelframecount, 0},
//300
{"clearscene", PF_R_ClearScene, 300}, // #300 void() clearscene (EXT_CSQC)
{"addentities", PF_R_AddEntityMask, 301}, // #301 void(float mask) addentities (EXT_CSQC)

View file

@ -2332,6 +2332,17 @@ void QCBUILTIN PF_frameduration (pubprogfuncs_t *prinst, struct globalvars_s *pr
else
G_FLOAT(OFS_RETURN) = 0;
}
void QCBUILTIN PF_modelframecount (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
unsigned int modelindex = G_FLOAT(OFS_PARM0);
model_t *mod = w->Get_CModel(w, modelindex);
if (mod)
G_FLOAT(OFS_RETURN) = Mod_GetFrameCount(mod);
else
G_FLOAT(OFS_RETURN) = 0;
}
//string(float modidx, float skinnum) skintoname
void QCBUILTIN PF_skintoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)

View file

@ -119,12 +119,6 @@ void GLVID_Crashed(void);
void GLVID_Update (vrect_t *rects);
// flushes the given rectangles from the view buffer to the screen
int GLVID_SetMode (rendererstate_t *info, unsigned char *palette);
// sets the mode; only used by the Quake engine for resetting to mode 0 (the
// base mode) on memory allocation failures
qboolean GLVID_Is8bit(void);
void GLVID_SwapBuffers(void);
enum uploadfmt;
char *GLVID_GetRGBInfo(int *truewidth, int *trueheight, enum uploadfmt *fmt);

View file

@ -131,6 +131,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#if (defined(D3D9QUAKE) || defined(D3D11QUAKE)) && !defined(D3DQUAKE)
#define D3DQUAKE
#endif
#if defined(_WIN32) && defined(GLQUAKE)
#define USE_EGL
#endif
#if defined(_MSC_VER) && !defined(BOTLIB_STATIC) //too lazy to fix up the makefile
#define BOTLIB_STATIC

File diff suppressed because it is too large Load diff

View file

@ -56,9 +56,9 @@ struct galiasbone_s
float inverse[12];
};
typedef struct FTE_DEPRECATED
typedef struct
{
//DEPRECATED
//should be load-time only
//use of this prevents the use of glsl acceleration. the framerate loss is of the order of 90%
//skeletal poses refer to this.
int vertexindex;
@ -148,8 +148,8 @@ typedef struct galiasinfo_s
float *baseframeofs; /*non-heirachical*/
int numbones;
galiasbone_t *ofsbones;
int numswtransforms;
galisskeletaltransforms_t *ofsswtransforms;
//FTE_DEPRECATED int numswtransforms;
//FTE_DEPRECATED galisskeletaltransforms_t *ofsswtransforms;
vecV_t *ofs_skel_xyz;
vec3_t *ofs_skel_norm;
@ -172,9 +172,15 @@ typedef struct galiasinfo_s
void *ebomem;
//these exist only in the root mesh.
#ifdef MD3MODELS
int numtagframes;
int numtags;
md3tag_t *ofstags;
#else
FTE_DEPRECATED int numtagframes;
FTE_DEPRECATED int numtags;
FTE_DEPRECATED md3tag_t *ofstags;
#endif
unsigned int warned; //passed around at load time, so we don't spam warnings
} galiasinfo_t;
@ -224,9 +230,9 @@ qboolean Mod_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **nam
void Mod_DoCRC(model_t *mod, char *buffer, int buffersize);
void Mod_AccumulateTextureVectors(vecV_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx);
void Mod_AccumulateTextureVectors(vecV_t *const vc, vec2_t *const tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, const index_t *idx, int numidx, qboolean calcnorms);
void Mod_AccumulateMeshTextureVectors(mesh_t *mesh);
void Mod_NormaliseTextureVectors(vec3_t *n, vec3_t *s, vec3_t *t, int v);
void Mod_NormaliseTextureVectors(vec3_t *n, vec3_t *s, vec3_t *t, int v, qboolean calcnorms);
void R_Generate_Mesh_ST_Vectors(mesh_t *mesh);
#ifdef __cplusplus

View file

@ -758,7 +758,7 @@ static int QDECL COM_Dir_List(const char *name, qofs_t size, time_t mtime, void
Q_snprintfz(link, sizeof(link), "\\map\\%s", name);
colour = "^4"; //disconnects
}
else if (!Q_strcasecmp(link, "bsp") || !Q_strcasecmp(link, "spr") || !Q_strcasecmp(link, "mdl") || !Q_strcasecmp(link, "md3") || !Q_strcasecmp(link, "iqm") || !Q_strcasecmp(link, "psk") || !Q_strcasecmp(link, "dpm") || !Q_strcasecmp(link, "zym"))
else if (!Q_strcasecmp(link, "bsp") || !Q_strcasecmp(link, "spr") || !Q_strcasecmp(link, "mdl") || !Q_strcasecmp(link, "md3") || !Q_strcasecmp(link, "iqm") || !Q_strcasecmp(link, "psk") || !Q_strcasecmp(link, "dpm") || !Q_strcasecmp(link, "zym") || !Q_strcasecmp(link, "md5mesh") || !Q_strcasecmp(link, "md5anim"))
Q_snprintfz(link, sizeof(link), "\\modelviewer\\%s", name);
else if (!Q_strcasecmp(link, "qc") || !Q_strcasecmp(link, "src") || !Q_strcasecmp(link, "qh") || !Q_strcasecmp(link, "h") || !Q_strcasecmp(link, "c")
|| !Q_strcasecmp(link, "cfg") || !Q_strcasecmp(link, "rc")

View file

@ -2776,7 +2776,7 @@ void CModRBSP_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd)
}
Mod_AccumulateMeshTextureVectors(out->mesh);
Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes);
Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes, false);
}
void CModQ3_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd)
@ -2845,7 +2845,7 @@ void CModQ3_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd)
}
Mod_AccumulateMeshTextureVectors(out->mesh);
Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes);
Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes, false);
}
qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)

View file

@ -448,7 +448,7 @@ void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross)
cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
}
vec_t Length(vec3_t v)
vec_t Length(const vec3_t v)
{
int i;
float length;

View file

@ -132,7 +132,7 @@ void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross);
void FloorDivMod (double numer, double denom, int *quotient, int *rem);
int GreatestCommonDivisor (int i1, int i2);
fixed16_t Invert24To16 (fixed16_t val);
vec_t Length (vec3_t v);
vec_t Length (const vec3_t v);
void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up);
float Q_rsqrt(float number);

View file

@ -6083,6 +6083,7 @@ lh_extension_t QSG_Extensions[] = {
{"DP_CON_SETA", 0, NULL, {NULL}, "The 'seta' console command exists, like the 'set' command, but also marks the cvar for archiving, allowing it to be written into the user's config. Use this command in your default.cfg file."},
#endif
{"DP_EF_ADDITIVE"},
//--{"DP_ENT_ALPHA"}, //listed above
{"DP_EF_BLUE"}, //hah!! This is QuakeWorld!!!
{"DP_EF_FULLBRIGHT"}, //Rerouted to hexen2 support.
{"DP_EF_NODEPTHTEST"}, //for cheats
@ -6090,10 +6091,10 @@ lh_extension_t QSG_Extensions[] = {
{"DP_EF_NOGUNBOB"}, //nogunbob. sane people should use csqc instead.
{"DP_EF_NOSHADOW"},
{"DP_EF_RED"},
// {"DP_ENT_COLORMOD"},
//--{"DP_ENT_COLORMOD"}, //listed above
{"DP_ENT_CUSTOMCOLORMAP"},
{"DP_ENT_EXTERIORMODELTOCLIENT"},
{"DP_ENT_SCALE"},
//--{"DP_ENT_SCALE"}, //listed above
{"DP_ENT_TRAILEFFECTNUM", 1, NULL, {"particleeffectnum"}, "self.traileffectnum=particleeffectnum(\"myeffectname\"); can be used to attach a particle trail to the given server entity. This is equivelent to calling trailparticles each frame."},
//only in dp6 currently {"DP_ENT_GLOW"},
{"DP_ENT_VIEWMODEL"},

View file

@ -257,6 +257,7 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_
void QCBUILTIN PF_skintoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_frameforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_frameduration (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_modelframecount (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_skinforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_gettaginfo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_gettagindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);

View file

@ -375,7 +375,7 @@ static LRESULT WINAPI D3D11_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
SetWindowPos(hWnd, NULL, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, SWP_SHOWWINDOW|SWP_FRAMECHANGED);
modestate = MS_FULLSCREEN;
}
if (!d3dscreen && modestate == MS_FULLSCREEN)
IDXGISwapChain_GetContainingOutput(d3dswapchain, &d3dscreen);
IDXGISwapChain_SetFullscreenState(d3dswapchain, modestate == MS_FULLSCREEN, (modestate == MS_FULLSCREEN)?d3dscreen:NULL);

View file

@ -29423,6 +29423,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_videgl.c"
>
</File>
<File
RelativePath="..\gl\gl_vidnt.c"
>
@ -29949,10 +29953,6 @@
RelativePath="..\vk\vk_init.c"
>
</File>
<File
RelativePath="..\vk\vk_win32.c"
>
</File>
<File
RelativePath="..\vk\vkrenderer.h"
>

View file

@ -322,6 +322,7 @@ qboolean QDECL Mod_LoadHLModel (model_t *mod, void *buffer, size_t fsize)
Z_Free(texmem);
mod->type = mod_halflife;
mod->numframes = model->header->numseq;
mod->meshinfo = model;
model->numgeomsets = model->header->numbodyparts;
@ -396,6 +397,8 @@ int HLMDL_BoneForName(model_t *mod, const char *name)
if (!strcmp(bones[i].name, name))
return i+1;
}
//FIXME: hlmdl has tags as well as bones.
return 0;
}
@ -616,8 +619,10 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
FIXME: we don't handle frame2.
*/
if (sequence->hasblendseq>1)
if (sequence->hasblendseq>1 && sequence->hasblendseq<9)
{
//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)
@ -652,12 +657,16 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
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][0], subblendfrac, organg1[0][1], matrix[1*4+3]);
FloatInterpolate(organgb[0][0], subblendfrac, organg1[0][2], matrix[2*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]);
}
}
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;
for(i = firstbone; i < lastbone; i++, matrix+=12)
{
HL_CalculateBones(frame1, model->adjust, model->bones + i, animation + i, organg1[0]);
@ -692,6 +701,24 @@ int HLMDL_GetNumBones(model_t *mod)
return mc->header->numbones;
}
int HLMDL_GetBoneParent(model_t *mod, int bonenum)
{
hlmodel_t *model = Mod_Extradata(mod);
if (bonenum >= 0 && bonenum < model->header->numbones)
return model->bones[bonenum].parent;
return -1;
}
const char *HLMDL_GetBoneName(model_t *mod, int bonenum)
{
hlmodel_t *model = Mod_Extradata(mod);
if (bonenum >= 0 && bonenum < model->header->numbones)
return model->bones[bonenum].name;
return NULL;
}
int HLMDL_GetBoneData(model_t *mod, int firstbone, int lastbone, framestate_t *fstate, float *result)
{
int b, cbone, bgroup;
@ -854,7 +881,7 @@ void R_HalfLife_WalkMeshes(entity_t *rent, batch_t *b, batch_t **batches)
static mesh_t bmesh, *mptr = &bmesh;
skinfile_t *sk = NULL;
unsigned int entity_body = rent->bottomcolour;
unsigned int entity_body = 0;
if (rent->customskin)
sk = Mod_LookupSkin(rent->customskin);

View file

@ -2652,6 +2652,8 @@ qboolean Mod_LoadTexinfo (model_t *loadmodel, qbyte *mod_base, lump_t *l)
out->texture = r_notexture_mip; // texture not found
out->flags = 0;
}
if (!strncmp(out->texture->name, "scroll", 6) || ((*out->texture->name == '*' || *out->texture->name == '{' || *out->texture->name == '!') && !strncmp(out->texture->name+1, "scroll", 6)))
out->flags |= TI_FLOWING;
}
return true;
@ -2846,7 +2848,7 @@ qboolean Mod_LoadFaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, lump_t *
continue;
}
if (!Q_strncmp(out->texinfo->texture->name,"*",1)) // turbulent
if (*out->texinfo->texture->name == '*' || (*out->texinfo->texture->name == '!' && loadmodel->fromgame == fg_halflife)) // turbulent
{
out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
for (i=0 ; i<2 ; i++)
@ -3194,7 +3196,14 @@ static int Mod_Batches_Generate(model_t *mod)
surf = mod->surfaces + mod->firstmodelsurface + i;
shader = surf->texinfo->texture->shader;
if (shader)
if (surf->flags & SURF_NODRAW)
{
shader = R_RegisterShader("nodraw", SUF_NONE, "{\nsurfaceparm nodraw\n}");
sortid = shader->sort;
VectorClear(plane);
plane[3] = 0;
}
else if (shader)
{
sortid = shader->sort;
@ -3227,6 +3236,7 @@ static int Mod_Batches_Generate(model_t *mod)
if (lbatch && (
lbatch->texture == surf->texinfo->texture &&
lbatch->shader == shader &&
lbatch->lightmap[0] == lmmerge(surf->lightmaptexturenums[0]) &&
Vector4Compare(plane, lbatch->plane) &&
lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) &&
@ -3243,6 +3253,7 @@ static int Mod_Batches_Generate(model_t *mod)
{
if (
batch->texture == surf->texinfo->texture &&
lbatch->shader == shader &&
batch->lightmap[0] == lmmerge(surf->lightmaptexturenums[0]) &&
Vector4Compare(plane, batch->plane) &&
batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES &&
@ -3265,7 +3276,7 @@ static int Mod_Batches_Generate(model_t *mod)
batch->lightmap[3] = lmmerge(surf->lightmaptexturenums[3]);
#endif
batch->texture = surf->texinfo->texture;
batch->shader = surf->texinfo->texture->shader;
batch->shader = shader;
if (surf->texinfo->texture->alternate_anims || surf->texinfo->texture->anim_total)
{
if (mod->fromgame == fg_quake2)
@ -5024,6 +5035,19 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
if (submod->hulls[j].available)
Q1BSP_CheckHullNodes(&submod->hulls[j]);
}
if (mod->fromgame == fg_halflife && i)
{
for (j=bm->firstface ; j<bm->firstface+bm->numfaces ; j++)
{
if (mod->surfaces[j].flags & SURF_DRAWTURB)
{
if (mod->surfaces[j].plane->type == PLANE_Z && mod->surfaces[j].plane->dist == bm->maxs[2]-1)
continue;
mod->surfaces[j].flags |= SURF_NODRAW;
}
}
}
submod->firstmodelsurface = bm->firstface;
submod->nummodelsurfaces = bm->numfaces;

View file

@ -327,14 +327,15 @@ typedef struct
#define SURF_PLANEBACK 0x00002
#define SURF_DRAWSKY 0x00004
#define SURF_DRAWSPRITE 0x00008
#define SURF_DRAWTURB 0x00010
#define SURF_DRAWTILED 0x00020
#define SURF_DRAWTURB 0x00010 //water warp effect
#define SURF_DRAWTILED 0x00020 //no need for a sw surface cache... (read: no lightmap)
#define SURF_DRAWBACKGROUND 0x00040
#define SURF_UNDERWATER 0x00080
#define SURF_DONTWARP 0x00100
//#define SURF_BULLETEN 0x00200
#define SURF_NOFLAT 0x08000
#define SURF_DRAWALPHA 0x10000
#define SURF_NODRAW 0x20000 //set on non-vertical halflife water submodel surfaces
// !!! if this is changed, it must be changed in asm_draw.h too !!!
typedef struct

View file

@ -5686,7 +5686,7 @@ void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args)
}
if (!builtin && (*shortname == '*'))
if (!builtin && (*shortname == '*' || *shortname == '!'))
{
builtin = Shader_DefaultBSPWater(s, shortname);
}

View file

@ -1053,6 +1053,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
gl_config.arb_depth_texture = GL_CheckExtension("GL_OES_depth_texture"); //gles2
gl_config.arb_depth_texture |= GL_CheckExtension("GL_CHROMIUM_depth_texture"); //nacl
gl_config.arb_depth_texture |= GL_CheckExtension("GL_WEBGL_depth_texture"); //webgl. duh.
gl_config.arb_depth_texture |= GL_CheckExtension("GL_ANGLE_depth_texture"); //gah. should just use wildcards huh (no uploads)
}
else
{
@ -2770,6 +2771,13 @@ void GL_Init(void *(*getglfunction) (char *name))
sh_config.texfmt[PTI_S3RGBA3] = true;
sh_config.texfmt[PTI_S3RGBA5] = 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");
}
if (gl_config.gles)
{

View file

@ -1,32 +1,36 @@
#include "bothdefs.h"
#include "quakedef.h"
#if defined(GLQUAKE) && defined(USE_EGL)
#include "gl_videgl.h"
extern cvar_t vid_vsync;
EGLContext eglctx = EGL_NO_CONTEXT;
EGLDisplay egldpy = EGL_NO_DISPLAY;
EGLSurface eglsurf = EGL_NO_SURFACE;
static dllhandle_t egllibrary;
static dllhandle_t eslibrary;
static dllhandle_t *egllibrary;
static dllhandle_t *eslibrary;
static EGLint (*qeglGetError)(void);
static EGLint (EGLAPIENTRY *qeglGetError)(void);
static EGLDisplay (*qeglGetDisplay)(EGLNativeDisplayType display_id);
static EGLBoolean (*qeglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
static EGLBoolean (*qeglTerminate)(EGLDisplay dpy);
static EGLDisplay (EGLAPIENTRY *qeglGetDisplay)(EGLNativeDisplayType display_id);
static EGLBoolean (EGLAPIENTRY *qeglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
static EGLBoolean (EGLAPIENTRY *qeglTerminate)(EGLDisplay dpy);
static EGLBoolean (*qeglGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
static EGLBoolean (*qeglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
static EGLBoolean (EGLAPIENTRY *qeglGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
static EGLBoolean (EGLAPIENTRY *qeglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
static EGLSurface (*qeglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
static EGLBoolean (*qeglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
static EGLBoolean (*qeglQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
static EGLSurface (EGLAPIENTRY *qeglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
static EGLBoolean (EGLAPIENTRY *qeglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
static EGLBoolean (EGLAPIENTRY *qeglQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
static EGLBoolean (*qeglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
static EGLBoolean (*qeglMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
static EGLContext (*qeglCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
static EGLBoolean (*qeglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
static void *(*qeglGetProcAddress) (char *name);
static EGLBoolean (EGLAPIENTRY *qeglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
static EGLBoolean (EGLAPIENTRY *qeglMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
static EGLContext (EGLAPIENTRY *qeglCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
static EGLBoolean (EGLAPIENTRY *qeglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
static void * (EGLAPIENTRY *qeglGetProcAddress) (char *name);
static EGLBoolean (EGLAPIENTRY *qeglSwapInterval) (EGLDisplay display, EGLint interval);
static dllfunction_t qeglfuncs[] =
{
@ -50,6 +54,9 @@ static dllfunction_t qeglfuncs[] =
{(void*)&qeglGetProcAddress, "eglGetProcAddress"},
//EGL 1.1
{(void*)&qeglSwapInterval, "eglSwapInterval"},
{NULL}
};
@ -99,6 +106,7 @@ qboolean EGL_LoadLibrary(char *driver)
}
else
Sys_Printf("success\n");
#ifndef _WIN32
if (!eslibrary)
{
eslibrary = dlopen("libGL", RTLD_NOW|RTLD_GLOBAL);
@ -114,6 +122,7 @@ qboolean EGL_LoadLibrary(char *driver)
eslibrary = dlopen("libGL.so.1", RTLD_NOW|RTLD_GLOBAL);
if (eslibrary) Sys_Printf("Loaded libGL.so.1\n");
}
#endif
if (!eslibrary)
Sys_Printf("unable to load some libGL\n");
@ -152,6 +161,18 @@ void EGL_Shutdown(void)
void EGL_SwapBuffers (void)
{
if (vid_vsync.modified)
{
int interval;
vid_vsync.modified = false;
if (*vid_vsync.string)
interval = vid_vsync.ival;
else
interval = 1; //default is to always vsync, according to EGL docs, so lets just do that.
if (qeglSwapInterval)
qeglSwapInterval(egldpy, interval);
}
TRACE(("EGL_SwapBuffers\n"));
TRACE(("swapping buffers\n"));
qeglSwapBuffers(egldpy, eglsurf);
@ -180,7 +201,7 @@ qboolean EGL_Init (rendererstate_t *info, unsigned char *palette, EGLNativeWindo
};
EGLint contextattr[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_CONTEXT_CLIENT_VERSION, 2, //requires EGL 1.3
EGL_NONE, EGL_NONE
};
@ -246,6 +267,9 @@ qboolean EGL_Init (rendererstate_t *info, unsigned char *palette, EGLNativeWindo
return false;
}
vid_vsync.modified = true;
return true;
}
#endif

View file

@ -4,7 +4,9 @@
#include "quakedef.h"
#define NativeWindowType EGLNativeWindowType
#include <EGL/egl.h>
#include <dlfcn.h>
#ifndef _WIN32
#include <dlfcn.h>
#endif
void *EGL_Proc(char *f);
void EGL_UnloadLibrary(void);

View file

@ -1446,22 +1446,45 @@ void GLVID_SwapBuffers (void)
void X_StoreIcon(Window wnd)
{
int i;
unsigned long data[64*64+2];
unsigned int *indata = (unsigned int*)icon.pixel_data;
unsigned int inwidth = icon.width;
unsigned int inheight = icon.height;
//FIXME: support loading an icon from the filesystem.
Atom propname = x11.pXInternAtom(vid_dpy, "_NET_WM_ICON", false);
Atom proptype = x11.pXInternAtom(vid_dpy, "CARDINAL", false);
data[0] = inwidth;
data[1] = inheight;
for (i = 0; i < data[0]*data[1]; i++)
data[i+2] = indata[i];
size_t filesize;
qbyte *filedata = FS_LoadMallocFile("icon.png", &filesize);
if (!filedata)
FS_LoadMallocFile("icon.tga", &filesize);
if (!filedata)
FS_LoadMallocFile("icon.jpg", &filesize);
if (filedata)
{
int imagewidth, imageheight;
int *iconblob;
qboolean hasalpha;
qbyte *imagedata = Read32BitImageFile(filedata, filesize, &imagewidth, &imageheight, &hasalpha, "icon.png");
Z_Free(filedata);
x11.pXChangeProperty(vid_dpy, wnd, propname, proptype, 32, PropModeReplace, (void*)data, data[0]*data[1]+2);
iconblob = BZ_Malloc(sizeof(int)*(2+imagewidth*imageheight));
iconblob[0] = imagewidth;
iconblob[1] = imageheight;
//needs to be 0xARGB, rather than RGBA bytes
for (i = 0; i < imagewidth*imageheight; i++)
iconblob[i+2] = (imagedata[i*4+3]<<24) | (imagedata[i*4+0]<<16) | (imagedata[i*4+1]<<8) | (imagedata[i*4+2]<<0);
Z_Free(imagedata);
x11.pXChangeProperty(vid_dpy, wnd, propname, proptype, 32, PropModeReplace, (void*)iconblob, 2+imagewidth*imageheight);
BZ_Free(iconblob);
}
else
{
//fall back to the embedded icon.
unsigned long data[64*64+2];
data[0] = icon.width;
data[1] = icon.height;
for (i = 0; i < data[0]*data[1]; i++)
data[i+2] = ((unsigned int*)icon.pixel_data)[i];
x11.pXChangeProperty(vid_dpy, wnd, propname, proptype, 32, PropModeReplace, (void*)data, data[0]*data[1]+2);
}
}
void X_GoFullscreen(void)

File diff suppressed because it is too large Load diff

View file

@ -1902,8 +1902,7 @@ void QuakifyThings(model_t *mod, dthing_t *thingsl)
ptr += strlen(ptr);
}
mod->entities = BZ_Malloc(ptr-newlump+1);
memcpy(mod->entities, newlump, ptr-newlump+1);
Mod_SetEntitiesStringLen(mod, newlump, ptr-newlump);
}
void Doom_GeneratePlanes(ddoomnode_t *nodel)

View file

@ -1005,18 +1005,6 @@ extern void (APIENTRY *qglTranslatef) (GLfloat x, GLfloat y, GLfloat z);
extern FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4x3fv;
extern FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix3x4fv;
#ifdef _WIN32
extern BOOL (WINAPI *qwglCopyContext)(HGLRC, HGLRC, UINT);
extern HGLRC (WINAPI *qwglCreateContext)(HDC);
extern HGLRC (WINAPI *qwglCreateLayerContext)(HDC, int);
extern BOOL (WINAPI *qwglDeleteContext)(HGLRC);
extern HGLRC (WINAPI *qwglGetCurrentContext)(VOID);
extern HDC (WINAPI *qwglGetCurrentDC)(VOID);
extern PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
extern BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
extern BOOL (WINAPI *qSwapBuffers)(HDC);
#endif
extern const GLubyte * (APIENTRY * qglGetStringi) (GLenum name, GLuint index);
/*

View file

@ -272,4 +272,6 @@ int HLMDL_FrameForName(model_t *mod, const char *name);
const char *HLMDL_FrameNameForNum(model_t *model, int surfaceidx, int num);
qboolean HLMDL_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **name, int *numframes, float *duration, qboolean *loop);
int HLMDL_GetNumBones(model_t *mod);
int HLMDL_GetBoneParent(model_t *mod, int bonenum);
const char *HLMDL_GetBoneName(model_t *mod, int bonenum);
int HLMDL_GetBoneData(model_t *model, int firstbone, int lastbone, framestate_t *fstate, float *result);

View file

@ -4483,7 +4483,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwall",
"!!ver 110 // 130\n"
"!!ver 100 120 // 130\n"
"!!permu DELUXE\n"
"!!permu FULLBRIGHT\n"
"!!permu FOG\n"
@ -4496,7 +4496,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/defs.h\"\n"
"#if GL_VERSION >= 130\n"
"#if __VERSION__ >= 130\n"
"#define texture2D texture\n"
"#define textureCube texture\n"
"#define gl_FragColor gl_FragData[0]\n"
@ -4586,7 +4586,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
"#if GL_VERSION >= 130\n"
"#if __VERSION__ >= 130\n"
"vec2 lmsize = vec2(textureSize(s_lightmap0, 0));\n"
"#else\n"
"#define lmsize vec2(128.0,2048.0)\n"

View file

@ -292,8 +292,6 @@ void GLVID_Crashed(void);
void GLVID_Update (vrect_t *rects);
int GLVID_SetMode (rendererstate_t *info, unsigned char *palette);
void GLVID_SetCaption(const char *caption)
{
}

View file

@ -10295,7 +10295,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
// {"cvar_setlatch", PF_cvar_setlatch, 0, 0, 0, ???, "void(string cvarname, optional string value)"},
{"clusterevent", PF_clusterevent, 0, 0, 0, 0, D("void(string dest, string from, string cmd, string info)", "Only functions in mapcluster mode. Sends an event to whichever server the named player is on. The destination server can then dispatch the event to the client or handle it itself via the SV_ParseClusterEvent entrypoint. If dest is empty, the event is broadcast to ALL servers. If the named player can't be found, the event will be returned to this server with the cmd prefixed with 'error:'.")},
{"clustertransfer", PF_clustertransfer, 0, 0, 0, 0, D("string(entity player, optional string newnode)", "Only functions in mapcluster mode. Initiate transfer of the player to a different node. Can take some time. If dest is specified, returns null on error. Otherwise returns the current/new target node (or null if not transferring).")},
{"modelframecount", PF_modelframecount, 0, 0, 0, 0, D("float(float mdlidx)", "Retrieves the number of frames in the specified model.")},
{"clearscene", PF_Fixme, 0, 0, 0, 300, D("void()", "Forgets all rentities, polygons, and temporary dlights. Resets all view properties to their default values.")},// (EXT_CSQC)
{"addentities", PF_Fixme, 0, 0, 0, 301, D("void(float mask)", "Walks through all entities effectively doing this:\n if (ent.drawmask&mask){ if (!ent.predaw()) addentity(ent); }\nIf mask&MASK_DELTA, non-csqc entities, particles, and related effects will also be added to the rentity list.\n If mask&MASK_STDVIEWMODEL then the default view model will also be added.")},// (EXT_CSQC)

View file

@ -174,8 +174,7 @@ int QDECL GHL_ModelFrames(int midx)
{
bi_trace();
//returns the number of frames(sequences I assume) this model has
ignore("ModelFrames");
return 1;
return Mod_GetFrameCount(sv.models[mdlidx], surfaceidx);
}
void QDECL GHL_SetSize(hledict_t *ed, float *mins, float *maxs)
{

View file

@ -1,4 +1,4 @@
!!ver 110 // 130
!!ver 100 120 // 130
!!permu DELUXE
!!permu FULLBRIGHT
!!permu FOG
@ -11,7 +11,7 @@
#include "sys/defs.h"
#if GL_VERSION >= 130
#if __VERSION__ >= 130
#define texture2D texture
#define textureCube texture
#define gl_FragColor gl_FragData[0]
@ -101,7 +101,7 @@ void main ()
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
#if GL_VERSION >= 130
#if __VERSION__ >= 130
vec2 lmsize = vec2(textureSize(s_lightmap0, 0));
#else
#define lmsize vec2(128.0,2048.0)

View file

@ -209,8 +209,8 @@ void DIB_SwapBuffers(void)
*/
}
extern int window_width;
extern int window_height;
static int window_width;
static int window_height;
void SWV_UpdateWindowStatus(void)
{
POINT p;

File diff suppressed because it is too large Load diff