diff --git a/engine/client/cl_cam.c b/engine/client/cl_cam.c index 1cd9091d0..dc0f744ef 100644 --- a/engine/client/cl_cam.c +++ b/engine/client/cl_cam.c @@ -105,8 +105,8 @@ qboolean Cam_DrawViewModel(int pnum) // returns true if we should draw this player, we don't if we are chase camming qboolean Cam_DrawPlayer(int pnum, int playernum) { - if (playernum == cl.playernum[pnum]) - return false; +// if (playernum == cl.playernum[pnum]) +// return false; if (cl.spectator && autocam[pnum] && locked[pnum] && cl_chasecam.value && spec_track[pnum] == playernum) return false; diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 270a6417a..64201c561 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cl_ents.c -- entity parsing and management #include "quakedef.h" +#include "particles.h" extern cvar_t cl_predict_players; extern cvar_t cl_predict_players2; diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 79c859867..0586c4306 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -1064,7 +1064,7 @@ void CL_SendCmd (void) // // deliver the message // - Netchan_Transmit (&cls.netchan, buf.cursize, buf.data); + Netchan_Transmit (&cls.netchan, buf.cursize, buf.data, 2500); if (cls.netchan.fatal_error) { diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 2032acd35..9520088c0 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -781,9 +781,9 @@ void CL_Disconnect (void) final[0] = clc_stringcmd; strcpy (final+1, "drop"); } - Netchan_Transmit (&cls.netchan, strlen(final)+1, final); - Netchan_Transmit (&cls.netchan, strlen(final)+1, final); - Netchan_Transmit (&cls.netchan, strlen(final)+1, final); + Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); + Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); + Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); } cls.state = ca_disconnected; diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index 8d03d67dd..a59a031f9 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -567,7 +567,7 @@ void CL_PredictMovePNum (int pnum) return; } */ - if (cl.intermission) + if (cl.intermission && cl.intermission != 3) { cl.crouch[pnum] = 0; return; @@ -598,7 +598,10 @@ void CL_PredictMovePNum (int pnum) // this is the last frame received from the server from = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; - VectorCopy (cl.viewangles[pnum], cl.simangles[pnum]); + if (!cl.intermission) + { + VectorCopy (cl.viewangles[pnum], cl.simangles[pnum]); + } vel = from->playerstate[cl.playernum[pnum]].velocity; org = from->playerstate[cl.playernum[pnum]].origin; @@ -638,6 +641,8 @@ void CL_PredictMovePNum (int pnum) cls.netchan.outgoing_sequence; i++) { to = &cl.frames[(cls.netchan.incoming_sequence+i) & UPDATE_MASK]; + if (cl.intermission) + to->playerstate->pm_type = PM_FLY; CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]] , &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]); diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 41041b7ca..31c818206 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -1660,6 +1660,7 @@ CL_UpdateBeams */ void CL_UpdateBeams (void) { + extern int rt_lightning1; int i; beam_t *b; vec3_t dist, org; @@ -1741,6 +1742,14 @@ void CL_UpdateBeams (void) continue; } */ +// if (part_type[rt_lightning1].loaded) + { + trailstate_t ts; + memset(&ts, 0, sizeof(ts)); + R_RocketTrail(b->start, b->end, rt_lightning1, &ts); + continue; + } + // add new entities for the lightning VectorCopy (b->start, org); d = VectorNormalize(dist); diff --git a/engine/client/fragstats.c b/engine/client/fragstats.c index 13fca66f1..2a1c337a9 100644 --- a/engine/client/fragstats.c +++ b/engine/client/fragstats.c @@ -74,7 +74,7 @@ typedef struct { static fragstats_t fragstats; -void Stats_Message(char *msg, ...) +void VARGS Stats_Message(char *msg, ...) { } diff --git a/engine/client/r_part.c b/engine/client/r_part.c index b6759581a..f6598afa0 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -56,7 +56,10 @@ int pe_default, int rt_blastertrail, rt_railtrail, rt_bubbletrail, - rt_rocket; + rt_rocket, + rt_lightning1, + rt_lightning2, + rt_lightning3; //triangle fan sparks use these. static double sint[7] = {0.000000, 0.781832, 0.974928, 0.433884, -0.433884, -0.974928, -0.781832}; @@ -913,6 +916,10 @@ void R_InitParticles (void) rt_bubbletrail = AllocateParticleType("t_bubbletrail"); rt_rocket = AllocateParticleType("t_rocket"); + rt_lightning1 = AllocateParticleType("t_lightning1"); + rt_lightning2 = AllocateParticleType("t_lightning2"); + rt_lightning3 = AllocateParticleType("t_lightning3"); + pt_superbullet = AllocateParticleType("te_superbullet"); pt_bullet = AllocateParticleType("te_bullet"); pe_default = AllocateParticleType("pe_default"); @@ -2036,7 +2043,9 @@ void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up) void CLQ2_RailTrail (vec3_t start, vec3_t end) { - R_RocketTrail(start, end, rt_railtrail, 0); + trailstate_t ts; + memset(&ts, 0, sizeof(ts)); + R_RocketTrail(start, end, rt_railtrail, &ts); } void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts) @@ -2092,9 +2101,6 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts) len = ts->lastdist; - if (len/step > 1024) - return; - b = bfirst = NULL; while (len < stop) @@ -2272,15 +2278,15 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts) b->flags |= BS_LASTSEG; ts->lastbeam = b; - } - if (!free_particles || !free_beams) - { - if (ts->lastbeam) + if (!free_particles || !free_beams) { - b->flags &= ~BS_LASTSEG; - b->flags |= BS_NODRAW; - ts->lastbeam = NULL; + if (ts->lastbeam) + { + b->flags &= ~BS_LASTSEG; + b->flags |= BS_NODRAW; + ts->lastbeam = NULL; + } } } } @@ -2606,7 +2612,7 @@ void GL_DrawParticleBeam_Textured(beamseg_t *b, part_type_t *type) VectorSubtract(r_refdef.vieworg, q->org, v); VectorNormalize(v); CrossProduct(c->dir, v, cr); - ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin; + ts = (c->texture_s*type->rotationstartmin + particletime*type->rotationmin)/754; VectorMA(q->org, -q->scale, cr, point); glTexCoord2f(ts, 0); @@ -2623,7 +2629,7 @@ void GL_DrawParticleBeam_Textured(beamseg_t *b, part_type_t *type) VectorSubtract(r_refdef.vieworg, p->org, v); VectorNormalize(v); CrossProduct(b->dir, v, cr); // replace with old p->dir? - ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin; + ts = (b->texture_s*type->rotationstartmin + particletime*type->rotationmin)/754; VectorMA(p->org, p->scale, cr, point); glTexCoord2f(ts, 1); diff --git a/engine/client/renderer.c b/engine/client/renderer.c index fc5f70b20..fba06f876 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -137,6 +137,7 @@ cvar_t r_drawdisk = {"r_drawdisk", "1"}; cvar_t gl_compress = {"gl_compress", "0"}; cvar_t gl_savecompressedtex = {"gl_savecompressedtex", "0"}; extern cvar_t gl_dither; +extern cvar_t gl_maxdist; #ifdef SPECULAR cvar_t gl_specular = {"gl_specular", "0"}; @@ -268,6 +269,7 @@ void GLRenderer_Init(void) Cvar_Register (&gl_ztrick, GLRENDEREROPTIONS); Cvar_Register (&gl_max_size, GLRENDEREROPTIONS); + Cvar_Register (&gl_maxdist, GLRENDEREROPTIONS); Cvar_Register (&gl_2dscale, GLRENDEREROPTIONS); Cvar_Register (&gl_font, GRAPHICALNICETIES); diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index a555534f8..0cb74f7a1 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -67,6 +67,28 @@ void VARGS Sys_DebugLog(char *file, char *fmt, ...) va_start(argptr, fmt); _vsnprintf(data, sizeof(data)-1, fmt, argptr); va_end(argptr); + +#if defined(CRAZYDEBUGGING) && CRAZYDEBUGGING > 1 + { + static int sock; + if (!sock) + { + struct sockaddr_in sa; + netadr_t na; + int _true = true; + int listip; + listip = COM_CheckParm("-debugip"); + NET_StringToAdr(listip?com_argv[listip+1]:"127.0.0.1", &na); + NetadrToSockadr(&na, (struct sockaddr_qstorage*)&sa); + sa.sin_port = htons(10000); + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (-1==connect(sock, (struct sockaddr*)&sa, sizeof(sa))) + Sys_Error("Couldn't send debug log lines\n"); + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&_true, sizeof(_true)); + } + send(sock, data, strlen(data), 0); + } +#endif fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666); write(fd, data, strlen(data)); close(fd); diff --git a/engine/client/zqtp.c b/engine/client/zqtp.c index b5bbb9726..a111ecf53 100644 --- a/engine/client/zqtp.c +++ b/engine/client/zqtp.c @@ -86,7 +86,7 @@ static size_t strlcat (char *dst, const char *src, size_t size) } #endif -static void Q_snprintfz (char *dest, size_t size, char *fmt, ...) +static void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...) { va_list argptr; diff --git a/engine/common/common.c b/engine/common/common.c index febe1f589..4511dd5af 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -3989,6 +3989,10 @@ void COM_Gamedir (char *dir) } } +#ifdef Q3SHADERS + Shader_Init(); +#endif + Validation_FlushFileList(); //prevent previous hacks from making a difference. //FIXME: load new palette, if different cause a vid_restart. diff --git a/engine/common/console.h b/engine/common/console.h index 86bef2713..46f811600 100644 --- a/engine/common/console.h +++ b/engine/common/console.h @@ -98,7 +98,7 @@ void Con_ToggleConsole_f (void); void Con_NotifyBox (char *text); // during startup for sound / cd warnings #ifdef CRAZYDEBUGGING -#define TRACE(x) Con_Print x +#define TRACE(x) Con_Printf x #else #define TRACE(x) #endif diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 86e9ad7c1..dba75791c 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -332,11 +332,23 @@ int numvertexes; vec2_t *map_vertstmexcoords; vec2_t *map_vertlstmexcoords; +byte_vec4_t *map_colors_array; + +#ifdef Q3SHADERS +typedef struct { + char shader[MAX_QPATH]; + int brushNum; + int visibleSide; // the brush side that ray tests need to clip against (-1 == none) +} dfog_t; + +mfog_t *map_fogs; +int map_numfogs; +#endif q3cface_t *map_faces; int numfaces; -int *map_surfindexes; +index_t *map_surfindexes; int map_numsurfindexes; int *map_leaffaces; @@ -1893,6 +1905,7 @@ void CModQ3_LoadVertexes (lump_t *l) vec4_t *out; int i, count, j; vec2_t *lmout, *stout; + byte_vec4_t *cout; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) @@ -1905,9 +1918,11 @@ void CModQ3_LoadVertexes (lump_t *l) out = Hunk_Alloc ( count*sizeof(*out) ); stout = Hunk_Alloc ( count*sizeof(*stout) ); lmout = Hunk_Alloc ( count*sizeof(*lmout) ); + cout = Hunk_Alloc ( count*sizeof(*cout) ); map_verts = out; map_vertstmexcoords = stout; map_vertlstmexcoords = lmout; + map_colors_array = cout; numvertexes = count; for ( i=0 ; itexcoords)[j] ); lmout[i][j] = LittleFloat ( ((float *)in->texcoords)[j+2] ); } + for ( j=0 ; j < 4 ; j++) + { + cout[i][j] = in->color[j]; + } } } @@ -1986,6 +2005,56 @@ void CModQ3_LoadFaces (lump_t *l) #ifdef RGLQUAKE +/* +================= +Mod_LoadFogs +================= +*/ +#ifdef Q3SHADERS +void CModQ3_LoadFogs (lump_t *l) +{ + dfog_t *in; + mfog_t *out; + q2cbrush_t *brush; + q2cbrushside_t *visibleside, *brushsides; + int i, j, count; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = Hunk_Alloc ( count*sizeof(*out) ); + + map_fogs = out; + map_numfogs = count; + + for ( i=0 ; ivisibleSide ) == -1 ) + { + continue; + } + + brush = map_brushes + LittleLong ( in->brushNum ); + brushsides = map_brushsides + brush->firstbrushside; + visibleside = brushsides + LittleLong ( in->visibleSide ); + + out->visibleplane = visibleside->plane; + out->shader = R_RegisterShader ( in->shader ); + out->numplanes = brush->numsides; + out->planes = Hunk_Alloc ( out->numplanes*sizeof(cplane_t *) ); + + for ( j = 0; j < out->numplanes; j++ ) + { + out->planes[j] = brushsides[j].plane; + } + } + + if (count) + GL_InitFogTexture(); +} +#endif + //Convert a patch in to a list of glpolys #define MAX_ARRAY_VERTS 2048 @@ -2072,13 +2141,17 @@ float ColorNormalize (vec3_t in, vec3_t out) return f; } -int tempIndexesArray[MAX_ARRAY_VERTS*3]; +index_t tempIndexesArray[MAX_ARRAY_VERTS*3]; vec4_t tempxyz_array[MAX_ARRAY_VERTS]; //structure is used only at load. vec3_t tempnormals_array[MAX_ARRAY_VERTS]; //so what harm is there in doing this? vec2_t tempst_array[MAX_ARRAY_VERTS]; vec2_t templmst_array[MAX_ARRAY_VERTS]; byte_vec4_t tempcolors_array[MAX_ARRAY_VERTS]; +#ifdef Q3SHADERS +#define Hunk_TempAllocMore Hunk_Alloc +#endif + mesh_t *GL_CreateMeshForPatch ( model_t *mod, q3dface_t *surf ) { int numverts, numindexes, firstvert, patch_cp[2], step[2], size[2], flat[2], i, u, v, p; @@ -2086,7 +2159,7 @@ mesh_t *GL_CreateMeshForPatch ( model_t *mod, q3dface_t *surf ) lm_st[MAX_ARRAY_VERTS], tex_st[MAX_ARRAY_VERTS]; vec4_t c, colors2[MAX_ARRAY_VERTS], normals2[MAX_ARRAY_VERTS], lm_st2[MAX_ARRAY_VERTS], tex_st2[MAX_ARRAY_VERTS]; mesh_t *mesh; - int *indexes; + index_t *indexes; float subdivlevel; patch_cp[0] = LittleLong ( surf->patchwidth ); @@ -2105,7 +2178,7 @@ mesh_t *GL_CreateMeshForPatch ( model_t *mod, q3dface_t *surf ) for ( i = 0; i < numverts; i++ ) { VectorCopy ( map_verts[firstvert + i], points[i] ); // VectorCopy ( mod->bmodel->normals_array[firstvert + i], normals[i] ); -// Vector4Scale ( mod->bmodel->colors_array[firstvert + i], (1.0 / 255.0), colors[i] ); + Vector4Scale ( map_colors_array[firstvert + i], (1.0 / 255.0), colors[i] ); Vector2Copy ( map_vertstmexcoords[firstvert + i], tex_st[i] ); Vector2Copy ( map_vertlstmexcoords[firstvert + i], lm_st[i] ); } @@ -2186,18 +2259,26 @@ mesh_t *GL_CreateMeshForPatch ( model_t *mod, q3dface_t *surf ) // allocate and fill index table mesh->numindexes = numindexes; - mesh->indexes = (int *)Hunk_TempAllocMore ( numindexes * sizeof(int)); - memcpy (mesh->indexes, tempIndexesArray, numindexes * sizeof(int) ); + mesh->indexes = (index_t *)Hunk_TempAllocMore ( numindexes * sizeof(index_t)); + memcpy (mesh->indexes, tempIndexesArray, numindexes * sizeof(index_t) ); return mesh; } +#ifdef Q3SHADERS +#undef Hunk_TempAllocMore +#endif void CModQ3_LoadRFaces (lump_t *l) { +#ifndef Q3SHADERS int polysize = sizeof(glpoly_t) - VERTEXSIZE*sizeof(float); + glpoly_t *p; + int rv, fi; + int gv, v; +#endif q3dface_t *in; msurface_t *out; mplane_t *pl; @@ -2206,11 +2287,8 @@ void CModQ3_LoadRFaces (lump_t *l) int surfnum; int numverts, numindexes; - int gv, v; - int rv; - int fv, fi; + int fv; - glpoly_t *p; mesh_t *mesh; @@ -2219,7 +2297,7 @@ void CModQ3_LoadRFaces (lump_t *l) Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); out = Hunk_AllocName ( count*sizeof(*out), loadmodel->name ); - pl = Hunk_AllocName (count*sizeof(*p), loadmodel->name);//create a new array of planes for speed. + pl = Hunk_AllocName (count*sizeof(*pl), loadmodel->name);//create a new array of planes for speed. loadmodel->surfaces = out; loadmodel->numsurfaces = count; @@ -2251,12 +2329,31 @@ fv = LittleLong(in->firstvertex); if (in->fognum!=-1) continue; */ + if (map_surfaces[in->shadernum].c.value == 0 || map_surfaces[in->shadernum].c.value & Q3CONTENTS_TRANSLUCENT) //q3dm10's thingie is 0 out->flags |= SURF_DRAWALPHA; if (loadmodel->texinfo[in->shadernum].flags & SURF_SKY) out->flags |= SURF_DRAWSKY; + +#ifdef Q3SHADERS + if (!out->texinfo->texture->shader) + { + extern cvar_t r_vertexlight; + if (in->facetype == MST_FLARE) + out->texinfo->texture->shader = R_RegisterShader_Flare (out->texinfo->texture->name); + else if (in->facetype == MST_TRIANGLE_SOUP || r_vertexlight.value) + out->texinfo->texture->shader = R_RegisterShader_Vertex (out->texinfo->texture->name); + else + out->texinfo->texture->shader = R_RegisterShader(out->texinfo->texture->name); + } + + if (in->fognum == -1) + out->fog = NULL; + else + out->fog = map_fogs + in->fognum; +#endif if (map_surfaces[in->shadernum].c.flags & (Q3SURF_NODRAW | Q3SURF_SKIP)) { out->mesh = NULL; @@ -2264,9 +2361,11 @@ continue; } else if (in->facetype == MST_PATCH) { - mesh = GL_CreateMeshForPatch(loadmodel, in); - out->polys = GL_MeshToGLPoly(mesh); + out->mesh = GL_CreateMeshForPatch(loadmodel, in); +#ifndef Q3SHADERS + out->polys = GL_MeshToGLPoly(out->mesh); out->mesh = NULL; +#endif } else if (in->facetype == MST_PLANAR || in->facetype == MST_TRIANGLE_SOUP) { @@ -2274,11 +2373,11 @@ continue; numverts = LittleLong(in->num_vertices); if (numindexes%3) Host_Error("mesh indexes should be multiples of 3"); -/* - out->mesh = Hunk_Alloc(sizeof(mesh_t) + (sizeof(vec3_t) + sizeof(byte_vec4_t)) * numverts); - out->mesh->normals_array= (vec3_t *)(out->mesh+1); - out->mesh->colors_array = (byte_vec4_t *)(out->mesh->normals_array + numverts); +#ifdef Q3SHADERS + out->mesh = Hunk_Alloc(sizeof(mesh_t) + (sizeof(vec3_t)) * numverts); + out->mesh->normals_array= (vec3_t *)(out->mesh+1); + out->mesh->colors_array = map_colors_array + LittleLong(in->firstindex); out->mesh->indexes = map_surfindexes + LittleLong(in->firstindex); out->mesh->xyz_array = map_verts + LittleLong(in->firstvertex); out->mesh->st_array = map_vertstmexcoords + LittleLong(in->firstvertex); @@ -2286,7 +2385,7 @@ continue; out->mesh->numindexes = numindexes; out->mesh->numvertexes = numverts; -*/ +#else p = Hunk_AllocName (polysize*numindexes/3, "SDList"); fv = LittleLong(in->firstvertex); @@ -2311,7 +2410,31 @@ continue; out->polys = p; p = (glpoly_t *)((char *)p + polysize); } +#endif } + else + { + int r, g, b; + extern index_t r_quad_indexes[6]; + + mesh = out->mesh = (mesh_t *)Hunk_Alloc ( sizeof(mesh_t)); + mesh->xyz_array = (vec4_t *)Hunk_Alloc ( sizeof(vec4_t)); + mesh->numvertexes = 1; + mesh->indexes = r_quad_indexes; + mesh->numindexes = 6; + // VectorCopy ( out->origin, mesh->xyz_array[0] ); + +/* r = LittleFloat ( in->lightmapVecs[0][0] ) * 255.0f; + r = bound ( 0, r, 255 ); + + g = LittleFloat ( in->lightmapVecs[0][1] ) * 255.0f; + g = bound ( 0, g, 255 ); + + b = LittleFloat ( in->lightmapVecs[0][2] ) * 255.0f; + b = bound ( 0, b, 255 ); + + out->dlightbits = (unsigned int)COLOR_RGB ( r, g, b ); +*/ } } } #endif @@ -3062,6 +3185,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned GLMod_LoadLighting (&header.lumps[Q3LUMP_LIGHTMAPS]); //fixme: duplicated loading. CModQ3_LoadLightgrid (&header.lumps[Q3LUMP_LIGHTGRID]); CModQ3_LoadIndexes (&header.lumps[Q3LUMP_DRAWINDEXES]); +#ifdef Q3SHADERS + CModQ3_LoadFogs (&header.lumps[Q3LUMP_FOGS]); +#endif CModQ3_LoadRFaces (&header.lumps[Q3LUMP_SURFACES]); CModQ3_LoadMarksurfaces (&header.lumps[Q3LUMP_LEAFSURFACES]); //fixme: duplicated loading. } diff --git a/engine/common/net.h b/engine/common/net.h index 0a07f0e95..b0b2d2e4d 100644 --- a/engine/common/net.h +++ b/engine/common/net.h @@ -109,7 +109,7 @@ typedef struct // bandwidth estimator double cleartime; // if realtime > nc->cleartime, free to go - double rate; // seconds / qbyte +// double rate; // seconds / qbyte // sequencing variables int incoming_sequence; @@ -138,15 +138,15 @@ typedef struct extern int net_drop; // packets dropped before this one void Netchan_Init (void); -void Netchan_Transmit (netchan_t *chan, int length, qbyte *data); +void Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate); void Netchan_OutOfBand (netsrc_t sock, netadr_t adr, int length, qbyte *data); void VARGS Netchan_OutOfBandPrint (netsrc_t sock, netadr_t adr, char *format, ...); void VARGS Netchan_OutOfBandTPrintf (netsrc_t sock, netadr_t adr, int language, translation_t text, ...); qboolean Netchan_Process (netchan_t *chan); void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport); -qboolean Netchan_CanPacket (netchan_t *chan); -qboolean Netchan_CanReliable (netchan_t *chan); +qboolean Netchan_CanPacket (netchan_t *chan, int rate); +qboolean Netchan_CanReliable (netchan_t *chan, int rate); #ifdef HUFFNETWORK int Huff_PreferedCompressionCRC (void); diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 878f38e61..9c54b3d26 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -192,8 +192,6 @@ void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport) chan->message.maxsize = MAX_QWMSGLEN;//sizeof(chan->message_buf); chan->qport = qport; - - chan->rate = 1.0/2500; } @@ -205,11 +203,11 @@ Returns true if the bandwidth choke isn't active ================ */ #define MAX_BACKUP 200 -qboolean Netchan_CanPacket (netchan_t *chan) +qboolean Netchan_CanPacket (netchan_t *chan, int rate) { if (chan->remote_address.type == NA_LOOPBACK) return true; //don't ever drop packets due to possible routing problems when there is no routing. - if (chan->cleartime < realtime + MAX_BACKUP*chan->rate) + if (chan->cleartime < realtime + MAX_BACKUP/(float)rate) return true; return false; } @@ -222,11 +220,11 @@ Netchan_CanReliable Returns true if the bandwidth choke isn't ================ */ -qboolean Netchan_CanReliable (netchan_t *chan) +qboolean Netchan_CanReliable (netchan_t *chan, int rate) { if (chan->reliable_length) return false; // waiting for ack - return Netchan_CanPacket (chan); + return Netchan_CanPacket (chan, rate); } #ifdef SERVERONLY @@ -243,7 +241,7 @@ transmition / retransmition of the reliable messages. A 0 length will still generate a packet and deal with the reliable messages. ================ */ -void Netchan_Transmit (netchan_t *chan, int length, qbyte *data) +void Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate) { sizebuf_t send; qbyte send_buf[MAX_OVERALLMSGLEN + PACKET_HEADER]; @@ -369,9 +367,9 @@ void Netchan_Transmit (netchan_t *chan, int length, qbyte *data) } if (chan->cleartime < realtime) - chan->cleartime = realtime + send.cursize*chan->rate; + chan->cleartime = realtime + send.cursize/(float)rate; else - chan->cleartime += send.cursize*chan->rate; + chan->cleartime += send.cursize/(float)rate; #ifdef SERVERONLY if (ServerPaused()) chan->cleartime = realtime; diff --git a/engine/common/translate.c b/engine/common/translate.c index a1459e968..40e6876d7 100644 --- a/engine/common/translate.c +++ b/engine/common/translate.c @@ -492,7 +492,11 @@ void TranslateReset(void) char *Translate(char *message) { - trans_t *trans; + return message; + + //this is pointless. + +/* trans_t *trans; if (!*message) return message; if (Q_strncmp(language.string, lastlang, 8)) @@ -522,6 +526,7 @@ char *Translate(char *message) //strcpy(trans->foreign, message); return message; +*/ } char *untranslate(char *message) diff --git a/engine/ftequake/ftequake.dsp b/engine/ftequake/ftequake.dsp index e020f45f7..10cc6a373 100644 --- a/engine/ftequake/ftequake.dsp +++ b/engine/ftequake/ftequake.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Application" 0x0101 -CFG=ftequake - Win32 Release Dedicated Server +CFG=ftequake - Win32 Q3Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,7 +13,7 @@ CFG=ftequake - Win32 Release Dedicated Server !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "ftequake.mak" CFG="ftequake - Win32 Release Dedicated Server" +!MESSAGE NMAKE /f "ftequake.mak" CFG="ftequake - Win32 Q3Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE @@ -27,6 +27,7 @@ CFG=ftequake - Win32 Release Dedicated Server !MESSAGE "ftequake - Win32 MinGLRelease" (based on "Win32 (x86) Application") !MESSAGE "ftequake - Win32 Debug Dedicated Server" (based on "Win32 (x86) Application") !MESSAGE "ftequake - Win32 Release Dedicated Server" (based on "Win32 (x86) Application") +!MESSAGE "ftequake - Win32 Q3Debug" (based on "Win32 (x86) Application") !MESSAGE # Begin Project @@ -77,7 +78,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /G6 /ML /W3 /Gm /GX /ZI /Od /I "../client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SWQUAKE" /FR".\Debug/" /Fp".\Debug/qwcl.pch" /YX /Fo".\Debug/" /Fd".\Debug/" /FD /c +# ADD CPP /nologo /G6 /W3 /Gm /GX /ZI /Od /I "../client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SWQUAKE" /FR".\Debug/" /Fp".\Debug/qwcl.pch" /YX /Fo".\Debug/" /Fd".\Debug/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -87,7 +88,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /out:"../../fteqw.exe" /pdbtype:sept +# ADD LINK32 comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"../../fteqw.exe" /pdbtype:sept !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" @@ -314,6 +315,37 @@ LINK32=link.exe # ADD LINK32 winmm.lib wsock32.lib user32.lib shell32.lib /nologo /subsystem:console /incremental:no /pdb:".\GLDebug/dglqwcl.pdb" /map /machine:I386 /out:"../../fteqwsv.exe" # SUBTRACT LINK32 /pdb:none /debug +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "ftequake___Win32_Q3Debug" +# PROP BASE Intermediate_Dir "ftequake___Win32_Q3Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "ftequake___Win32_Q3Debug" +# PROP Intermediate_Dir "ftequake___Win32_Q3Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /D "AVAIL_OGGVORBIS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c +# SUBTRACT BASE CPP /X +# ADD CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /D "AVAIL_OGGVORBIS" /D "Q3SHADERS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c +# SUBTRACT CPP /X +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /pdb:".\GLDebug/dglqwcl.pdb" /debug /machine:I386 /out:"../../fteglqw.exe" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /pdb:".\GLDebug/dglqwcl.pdb" /debug /machine:I386 /out:"../../fteglqw.exe" +# SUBTRACT LINK32 /pdb:none + !ENDIF # Begin Target @@ -328,6 +360,7 @@ LINK32=link.exe # Name "ftequake - Win32 MinGLRelease" # Name "ftequake - Win32 Debug Dedicated Server" # Name "ftequake - Win32 Release Dedicated Server" +# Name "ftequake - Win32 Q3Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" @@ -447,6 +480,8 @@ SOURCE=..\client\cd_win.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -479,6 +514,8 @@ SOURCE=..\client\cl_cam.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -511,6 +548,8 @@ SOURCE=..\client\cl_demo.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -543,6 +582,8 @@ SOURCE=..\client\cl_ents.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -575,6 +616,8 @@ SOURCE=..\client\cl_input.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -607,6 +650,8 @@ SOURCE=..\client\cl_main.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -639,6 +684,8 @@ SOURCE=..\client\cl_parse.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -671,6 +718,8 @@ SOURCE=..\client\cl_pred.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -703,6 +752,8 @@ SOURCE=..\client\cl_screen.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -735,6 +786,8 @@ SOURCE=..\client\cl_tent.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -767,6 +820,8 @@ SOURCE=..\client\cl_ui.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -799,6 +854,8 @@ SOURCE=..\client\clq2_cin.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -831,6 +888,8 @@ SOURCE=..\client\clq2_ents.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -863,6 +922,8 @@ SOURCE=..\client\console.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -895,6 +956,8 @@ SOURCE=..\client\fragstats.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -927,6 +990,8 @@ SOURCE=..\client\image.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -959,6 +1024,8 @@ SOURCE=..\client\in_win.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -991,6 +1058,8 @@ SOURCE=..\client\keys.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1023,6 +1092,8 @@ SOURCE=..\client\m_items.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1055,6 +1126,8 @@ SOURCE=..\client\m_master.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1087,6 +1160,8 @@ SOURCE=..\client\m_mp3.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1119,6 +1194,8 @@ SOURCE=..\client\m_multi.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1151,6 +1228,8 @@ SOURCE=..\client\m_options.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1183,6 +1262,8 @@ SOURCE=..\client\m_script.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1215,6 +1296,8 @@ SOURCE=..\client\m_single.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1247,6 +1330,8 @@ SOURCE=..\client\menu.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1279,6 +1364,8 @@ SOURCE=..\client\net_master.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1311,6 +1398,8 @@ SOURCE=..\client\r_bulleten.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1344,6 +1433,8 @@ SOURCE=..\client\r_efrag.c # PROP Exclude_From_Build 1 # ADD CPP /G6 /O1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1376,6 +1467,8 @@ SOURCE=..\client\r_part.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1408,6 +1501,8 @@ SOURCE=..\client\r_partset.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1440,6 +1535,8 @@ SOURCE=..\client\renderer.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1472,6 +1569,8 @@ SOURCE=..\client\renderque.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1504,6 +1603,8 @@ SOURCE=..\client\roq_read.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1536,6 +1637,8 @@ SOURCE=..\client\sbar.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1568,6 +1671,8 @@ SOURCE=..\client\skin.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1600,6 +1705,8 @@ SOURCE=..\client\snd_dma.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1632,6 +1739,8 @@ SOURCE=..\client\snd_mem.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1664,6 +1773,8 @@ SOURCE=..\client\snd_mix.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1696,6 +1807,8 @@ SOURCE=..\client\snd_mp3.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1728,6 +1841,8 @@ SOURCE=..\client\snd_ov.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1760,6 +1875,8 @@ SOURCE=..\client\snd_win.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1792,6 +1909,8 @@ SOURCE=..\client\sys_win.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1824,6 +1943,8 @@ SOURCE=..\client\teamplay.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1856,6 +1977,8 @@ SOURCE=..\client\textedit.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1888,6 +2011,8 @@ SOURCE=..\client\valid.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1920,6 +2045,8 @@ SOURCE=..\client\view.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1952,6 +2079,8 @@ SOURCE=..\client\wad.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -1984,6 +2113,8 @@ SOURCE=..\client\zqtp.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2022,6 +2153,8 @@ SOURCE=..\gl\gl_alias.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2056,6 +2189,8 @@ SOURCE=..\gl\gl_backend.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2090,6 +2225,8 @@ SOURCE=..\gl\gl_draw.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2124,6 +2261,8 @@ SOURCE=..\gl\gltod3d\gl_fakegl.cpp # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2158,6 +2297,8 @@ SOURCE=..\gl\gl_hlmdl.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2192,6 +2333,8 @@ SOURCE=..\gl\gl_model.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2226,6 +2369,8 @@ SOURCE=..\gl\gl_ngraph.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2260,6 +2405,8 @@ SOURCE=..\gl\gl_ppl.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2292,6 +2439,8 @@ SOURCE=..\common\gl_q2bsp.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2326,6 +2475,8 @@ SOURCE=..\gl\gl_rlight.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2360,6 +2511,8 @@ SOURCE=..\gl\gl_rmain.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2394,6 +2547,8 @@ SOURCE=..\gl\gl_rmisc.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2428,6 +2583,8 @@ SOURCE=..\gl\gl_rsurf.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2462,6 +2619,57 @@ SOURCE=..\gl\gl_screen.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\gl\gl_shader.c + +!IF "$(CFG)" == "ftequake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2496,6 +2704,8 @@ SOURCE=..\gl\gl_vidcommon.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2530,6 +2740,8 @@ SOURCE=..\gl\gl_vidnt.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2564,6 +2776,8 @@ SOURCE=..\gl\gl_warp.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2598,6 +2812,8 @@ SOURCE=..\gl\glmod_doom.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -2632,8 +2848,14 @@ SOURCE=..\gl\LTFACE.C # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF +# End Source File +# Begin Source File + +SOURCE=..\gl\shader.h # End Source File # End Group # Begin Group "sw" @@ -2676,6 +2898,11 @@ SOURCE=..\sw\d_edge.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2716,6 +2943,11 @@ SOURCE=..\sw\d_fill.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2756,6 +2988,11 @@ SOURCE=..\sw\d_init.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2796,6 +3033,11 @@ SOURCE=..\sw\d_modech.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2836,6 +3078,11 @@ SOURCE=..\sw\d_part.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2876,6 +3123,11 @@ SOURCE=..\sw\d_polyse.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2916,6 +3168,11 @@ SOURCE=..\sw\d_scan.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2956,6 +3213,11 @@ SOURCE=..\sw\d_sky.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2996,6 +3258,11 @@ SOURCE=..\sw\d_sprite.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3036,6 +3303,11 @@ SOURCE=..\sw\d_surf.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3076,6 +3348,11 @@ SOURCE=..\sw\d_trans.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3116,6 +3393,11 @@ SOURCE=..\sw\d_vars.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3156,6 +3438,11 @@ SOURCE=..\sw\d_zpoint.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3196,6 +3483,11 @@ SOURCE=..\sw\nonintel.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3236,6 +3528,11 @@ SOURCE=..\sw\r_aclip.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3276,6 +3573,11 @@ SOURCE=..\sw\r_alias.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3316,6 +3618,11 @@ SOURCE=..\sw\r_bsp.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3356,6 +3663,11 @@ SOURCE=..\sw\r_draw.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3396,6 +3708,11 @@ SOURCE=..\sw\r_edge.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3436,6 +3753,11 @@ SOURCE=..\sw\r_light.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3476,6 +3798,11 @@ SOURCE=..\sw\r_main.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3516,6 +3843,11 @@ SOURCE=..\sw\r_misc.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3556,6 +3888,11 @@ SOURCE=..\sw\r_sky.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3596,6 +3933,11 @@ SOURCE=..\sw\r_sprite.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3636,6 +3978,11 @@ SOURCE=..\sw\r_surf.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3676,6 +4023,11 @@ SOURCE=..\sw\r_vars.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3716,6 +4068,11 @@ SOURCE=..\sw\sw_draw.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3756,6 +4113,11 @@ SOURCE=..\sw\sw_model.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3796,6 +4158,11 @@ SOURCE=..\sw\sw_screen.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3836,6 +4203,11 @@ SOURCE=..\sw\vid_ddraw.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3876,6 +4248,11 @@ SOURCE=..\sw\vid_dib.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -3916,6 +4293,11 @@ SOURCE=..\sw\vid_win2.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4037,6 +4419,10 @@ SOURCE=..\QCLIB\Comprout.c # End Source File # Begin Source File +SOURCE=..\qclib\execloop.h +# End Source File +# Begin Source File + SOURCE=..\QCLIB\hash.c # End Source File # Begin Source File @@ -4182,6 +4568,11 @@ InputName=d_draw # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4280,6 +4671,11 @@ InputName=d_draw16 # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4378,6 +4774,11 @@ InputName=d_parta # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4476,6 +4877,11 @@ InputName=d_polysa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4574,6 +4980,11 @@ InputName=d_scana # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4672,6 +5083,11 @@ InputName=d_spr8 # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4770,6 +5186,11 @@ InputName=d_varsa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4928,6 +5349,21 @@ InputName=math # End Custom Build +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# Begin Custom Build +OutDir=.\ftequake___Win32_Q3Debug +InputPath=..\common\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DSWQUAKE /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + !ENDIF # End Source File @@ -5026,6 +5462,11 @@ InputName=r_aclipa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5124,6 +5565,11 @@ InputName=r_aliasa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5222,6 +5668,11 @@ InputName=r_drawa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5320,6 +5771,11 @@ InputName=r_edgea # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5418,6 +5874,11 @@ InputName=r_varsa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5555,6 +6016,21 @@ InputName=snd_mixa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# Begin Custom Build +OutDir=.\ftequake___Win32_Q3Debug +InputPath=..\client\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DSWQUAKE /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + !ENDIF # End Source File @@ -5653,6 +6129,11 @@ InputName=surf16 # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5751,6 +6232,11 @@ InputName=surf8 # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5888,6 +6374,21 @@ InputName=sys_wina # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# Begin Custom Build +OutDir=.\ftequake___Win32_Q3Debug +InputPath=..\client\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DSWQUAKE /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + !ENDIF # End Source File @@ -6046,6 +6547,21 @@ InputName=worlda # End Custom Build +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# Begin Custom Build +OutDir=.\ftequake___Win32_Q3Debug +InputPath=..\server\worlda.s +InputName=worlda + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DSWQUAKE /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + !ENDIF # End Source File @@ -6170,6 +6686,8 @@ SOURCE=..\qux\m_x.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6202,6 +6720,8 @@ SOURCE=..\qux\qux.h # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6234,6 +6754,8 @@ SOURCE=..\qux\X.h # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6266,6 +6788,8 @@ SOURCE=..\qux\x_reqs.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6300,6 +6824,8 @@ SOURCE=..\qux\x_res.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6332,6 +6858,8 @@ SOURCE=..\qux\Xmd.h # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6364,6 +6892,8 @@ SOURCE=..\qux\Xproto.h # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6396,6 +6926,8 @@ SOURCE=..\qux\Xprotostr.h # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6443,6 +6975,11 @@ SOURCE=..\server\sv_sys_win.c !ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6486,6 +7023,11 @@ SOURCE=..\server\svmodel.c !ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6522,6 +7064,8 @@ SOURCE=..\client\winquake.rc # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + !ENDIF # End Source File @@ -6539,6 +7083,10 @@ SOURCE=..\sw\d_ifacea.h # End Source File # Begin Source File +SOURCE=..\gl\gl_model.h +# End Source File +# Begin Source File + SOURCE=..\common\protocol.h # End Source File # End Group @@ -6607,6 +7155,11 @@ SOURCE=..\..\mp3\libmad\bit.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6660,6 +7213,11 @@ SOURCE=..\..\mp3\libmad\decoder.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6713,6 +7271,11 @@ SOURCE=..\..\mp3\libmad\fixed.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6766,6 +7329,11 @@ SOURCE=..\..\mp3\libmad\frame.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6819,6 +7387,11 @@ SOURCE=..\..\mp3\libmad\huffman.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6872,6 +7445,11 @@ SOURCE=..\..\mp3\libmad\layer12.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6925,6 +7503,11 @@ SOURCE=..\..\mp3\libmad\layer3.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6978,6 +7561,11 @@ SOURCE=..\client\mymad.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7031,6 +7619,11 @@ SOURCE=..\..\mp3\libmad\stream.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7084,6 +7677,11 @@ SOURCE=..\..\mp3\libmad\synth.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7137,6 +7735,11 @@ SOURCE=..\..\mp3\libmad\timer.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7190,6 +7793,11 @@ SOURCE=..\..\mp3\libmad\version.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 Q3Debug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File diff --git a/engine/ftequake/ftequake.dsw b/engine/ftequake/ftequake.dsw index fac718e73..d8b441157 100644 --- a/engine/ftequake/ftequake.dsw +++ b/engine/ftequake/ftequake.dsw @@ -27,6 +27,18 @@ Package=<4> ############################################################################### +Project: "hud"=..\..\plugins\hud\hud.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + Project: "irc"=..\..\PLUGINS\IRC\irc.dsp - Package Owner=<4> Package=<5> diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 1640bb32f..065b6360a 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -42,8 +42,6 @@ typedef struct extern cvar_t gl_part_flame, gl_part_torch, r_fullbrightSkins, r_fb_models; extern cvar_t r_noaliasshadows; void R_TorchEffect (vec3_t pos, int type); -void GL_DrawMesh(mesh_t *mesh, shader_t *shader, int texturenum, int lmtexturenum); - void GLMod_FloodFillSkin( qbyte *skin, int skinwidth, int skinheight ); @@ -112,6 +110,8 @@ typedef struct { int base; int bump; int fullbright; + + shader_t *shader; } galiastexnum_t; typedef struct { @@ -375,7 +375,7 @@ static void R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, int f numTempVertexCoords = inf->numverts; } - mesh->indexes = (int*)((char *)inf + inf->ofs_indexes); + mesh->indexes = (index_t*)((char *)inf + inf->ofs_indexes); mesh->numindexes = inf->numindexes; mesh->st_array = (vec2_t*)((char *)inf + inf->ofs_st_array); mesh->lmst_array = NULL; @@ -668,7 +668,7 @@ static void R_CalcFacing(mesh_t *mesh, vec3_t lightpos) int i; - int *indexes = mesh->indexes; + index_t *indexes = mesh->indexes; int numtris = mesh->numindexes/3; @@ -724,7 +724,7 @@ static void R_DrawShadowVolume(mesh_t *mesh) int t; vec3_t *proj = ProjectedShadowVerts; vec4_t *verts = mesh->xyz_array; - int *indexes = mesh->indexes; + index_t *indexes = mesh->indexes; int *neighbours = mesh->trneighbors; int numtris = mesh->numindexes/3; @@ -778,6 +778,48 @@ static void R_DrawShadowVolume(mesh_t *mesh) glEnd(); } +void GL_DrawAliasMesh (mesh_t *mesh, int texnum) +{ + extern int gldepthfunc; +#ifdef Q3SHADERS + R_UnlockArrays(); +#endif + + glDepthFunc(gldepthfunc); + glDepthMask(1); + + GL_Bind(texnum); + + glVertexPointer(3, GL_FLOAT, 16, mesh->xyz_array); + glEnableClientState( GL_VERTEX_ARRAY ); + + if (mesh->normals_array) + { + glNormalPointer(GL_FLOAT, 0, mesh->normals_array); + glEnableClientState( GL_NORMAL_ARRAY ); + } + + if (mesh->colors_array) + { + glColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh->colors_array); + glEnableClientState( GL_COLOR_ARRAY ); + } + + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + glTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); + + glDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); + + glDisableClientState( GL_VERTEX_ARRAY ); + glDisableClientState( GL_COLOR_ARRAY ); + glDisableClientState( GL_NORMAL_ARRAY ); + glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + +#ifdef Q3SHADERS + R_IBrokeTheArrays(); +#endif +} + void R_DrawGAliasModel (entity_t *e) { model_t *clmodel = e->model; @@ -1090,21 +1132,46 @@ void R_DrawGAliasModel (entity_t *e) R_GAliasAddDlights(&mesh, e->origin, e->angles); skin = GL_ChooseSkin(inf, clmodel->name, e); c_alias_polys += mesh.numindexes/3; + if (!skin) - GL_DrawMesh(&mesh, NULL, 1, 0); + { + glEnable(GL_TEXTURE_2D); + GL_DrawAliasMesh(&mesh, 1); + } +#ifdef Q3SHADERS + else if (skin->shader) + { + meshbuffer_t mb; + + mb.entity = &r_worldentity; + mb.shader = skin->shader; + mb.fog = NULL; + mb.mesh = &mesh; + mb.infokey = currententity->keynum; + mb.dlightbits = 0; + + R_IBrokeTheArrays(); + + R_PushMesh(&mesh, skin->shader->features|MF_COLORS); + + R_RenderMeshBuffer ( &mb, false ); + } +#endif else { - if (skin->bump) - GL_DrawMeshBump(&mesh, skin->base, 0, skin->bump, 0); - else - GL_DrawMesh(&mesh, NULL, skin->base, 0); + glEnable(GL_TEXTURE_2D); +// if (skin->bump) +// GL_DrawMeshBump(&mesh, skin->base, 0, skin->bump, 0); +// else + GL_DrawAliasMesh(&mesh, skin->base); + if (skin->fullbright && r_fb_models.value && cls.allow_luma) { mesh.colors_array = NULL; glEnable(GL_BLEND); glColor4f(1, 1, 1, e->alpha*r_fb_models.value); c_alias_polys += mesh.numindexes/3; - GL_DrawMesh(&mesh, NULL, 0, skin->fullbright); + GL_DrawAliasMesh(&mesh, skin->fullbright); } } @@ -1299,7 +1366,10 @@ void R_DrawGAliasModelLighting (entity_t *e) { R_GAliasBuildMesh(&mesh, inf, e->frame, e->oldframe, e->lerptime, e->alpha); mesh.colors_array = NULL; +#ifdef Q3SHADERS +#else GL_DrawMesh(&mesh, NULL, 0, 0); +#endif if (inf->nextsurf) inf = (galiasinfo_t*)((char *)inf + inf->nextsurf); @@ -1784,7 +1854,7 @@ void GL_LoadQ1Model (model_t *mod, void *buffer) dstvert_t *pinstverts; dtriangle_t *pintriangles; int *seamremap; - int *indexes; + index_t *indexes; int size; @@ -1950,7 +2020,7 @@ int Mod_ReadFlagsFromMD1(char *name, int md3version) COM_StripExtension(name, fname); COM_DefaultExtension(fname, ".mdl"); - if (!strcmp(name, fname)) //md3 renamed as mdl + if (strcmp(name, fname)) //md3 renamed as mdl { COM_StripExtension(name, fname); //seeing as the md3 is named over the mdl, COM_DefaultExtension(fname, ".md1");//read from a file with md1 (one, not an ell) @@ -2009,7 +2079,7 @@ void GL_LoadQ2Model (model_t *mod, void *buffer) int i, j; dmd2stvert_t *pinstverts; dmd2triangle_t *pintri; - int *indexes; + index_t *indexes; int numindexes; vec3_t min; @@ -2206,6 +2276,7 @@ void GL_LoadQ2Model (model_t *mod, void *buffer) // move the complete, relocatable alias model to the cache // hunkend = Hunk_LowMark (); + Hunk_Alloc(0); hunktotal = hunkend - hunkstart; Cache_Alloc (&mod->cache, hunktotal, loadname); @@ -2340,13 +2411,13 @@ void GL_LoadQ3Model(model_t *mod, void *buffer) // int version; int s, i, j, d; - int *indexes; + index_t *indexes; vec3_t min; vec3_t max; galiaspose_t *pose; - galiasinfo_t *parent; + galiasinfo_t *parent, *root; galiasgroup_t *group; galiasskin_t *skin; @@ -2379,8 +2450,15 @@ void GL_LoadQ3Model(model_t *mod, void *buffer) // if (header->version != sdfs) // Sys_Error("GL_LoadQ3Model: Bad version\n"); + if (header->numSurfaces < 1) + { + mod->type = mod_alias; + return; + } + parent = NULL; + root = NULL; min[0] = min[1] = min[2] = 0; max[0] = max[1] = max[2] = 0; @@ -2396,7 +2474,10 @@ void GL_LoadQ3Model(model_t *mod, void *buffer) galias->numindexes = surf->numTriangles*3; galias->numskins = 1; if (parent) - parent->nextsurf = (qbyte *)surf - (qbyte *)parent; + parent->nextsurf = (qbyte *)galias - (qbyte *)parent; + else + root = galias; + parent = galias; st_array = Hunk_Alloc(sizeof(vec2_t)*galias->numindexes); galias->ofs_st_array = (qbyte*)st_array - (qbyte*)galias; @@ -2478,6 +2559,9 @@ void GL_LoadQ3Model(model_t *mod, void *buffer) skin->skinwidth = 0; skin->skinheight = 0; skin->skinspeed = 0; +#ifdef Q3SHADERS + texnum->shader = R_RegisterSkin(inshader->name); +#else texnum->base = Mod_LoadHiResTexture(inshader->name, true, true, true); if (!texnum->base) @@ -2529,7 +2613,7 @@ void GL_LoadQ3Model(model_t *mod, void *buffer) texnum->fullbright = Mod_LoadBumpmapTexture(name); } } - +#endif skin++; texnum++; @@ -2555,9 +2639,11 @@ void GL_LoadQ3Model(model_t *mod, void *buffer) // move the complete, relocatable alias model to the cache // + hunkend = Hunk_LowMark (); + mod->flags = Mod_ReadFlagsFromMD1(mod->name, 0); - hunkend = Hunk_LowMark (); + Hunk_Alloc(0); hunktotal = hunkend - hunkstart; Cache_Alloc (&mod->cache, hunktotal, loadname); @@ -2567,7 +2653,7 @@ void GL_LoadQ3Model(model_t *mod, void *buffer) Hunk_FreeToLowMark (hunkstart); return; } - memcpy (mod->cache.data, galias, hunktotal); + memcpy (mod->cache.data, root, hunktotal); Hunk_FreeToLowMark (hunkstart); } diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index fc0d89f4c..dcf9bb4c4 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -4,6 +4,77 @@ #ifdef RGLQUAKE +#define MAX_TEXTURE_UNITS 8 + +typedef struct { + GLenum currenttextures[MAX_TEXTURE_UNITS]; + GLenum texenvmode[MAX_TEXTURE_UNITS]; + + int currenttmu; + + qboolean in2d; +} gl_state_t; +gl_state_t gl_state; + +extern int *lightmap_textures; + +void GL_SelectTexture (GLenum target) +{ + gl_state.currenttmu = target - mtexid0; + if (qglClientActiveTextureARB) + { + qglClientActiveTextureARB(target); + qglActiveTextureARB(target); + } + else + qglSelectTextureSGIS(target); +} + +void GL_MBind( GLenum target, int texnum ) +{ + GL_SelectTexture( target ); + +// if ( gl_state.currenttextures[texnum-mtexid0] == texnum ) +// return; + + gl_state.currenttextures[texnum-mtexid0] = texnum; + bindTexFunc (GL_TEXTURE_2D, texnum); +} + +void GL_Bind (int texnum) +{ + if (gl_state.currenttextures[gl_state.currenttmu] == texnum) + return; + gl_state.currenttextures[gl_state.currenttmu] = texnum; + + bindTexFunc (GL_TEXTURE_2D, texnum); +} +void GL_BindType (int type, int texnum) +{ + bindTexFunc (type, texnum); + + gl_state.currenttextures[gl_state.currenttmu] = -1; +} + +//vid restarted. +void GL_FlushBinds(void) +{ + int i; + for (i = 0; i < MAX_TEXTURE_UNITS; i++) + { + gl_state.currenttextures[i] = -1; + gl_state.texenvmode[i] = -1; + } +} + + + + + + + +#ifndef Q3SHADERS + #define MAX_MESH_VERTS 8192 @@ -26,7 +97,7 @@ static float r_squaretable[FTABLE_SIZE]; static float r_sawtoothtable[FTABLE_SIZE]; static float r_inversesawtoothtable[FTABLE_SIZE]; -void GLR_MeshInit(void) +void R_BackendInit(void) { int i; double t; @@ -60,100 +131,100 @@ void GLR_MeshInit(void) nullshader.deforms[0].func.args[1] = 1; nullshader.deforms[0].func.args[3] = 10; - nullshader.pass[0].texturetype = GL_TEXTURE_2D; - nullshader.pass[0].envmode = GL_MODULATE; - nullshader.pass[0].blendsrc = GL_SRC_ALPHA; - nullshader.pass[0].blenddst = GL_ONE_MINUS_SRC_ALPHA; + nullshader.passes[0].texturetype = GL_TEXTURE_2D; + nullshader.passes[0].envmode = GL_MODULATE; + nullshader.passes[0].blendsrc = GL_SRC_ALPHA; + nullshader.passes[0].blenddst = GL_ONE_MINUS_SRC_ALPHA; - nullshader.pass[1].flags |= SHADER_PASS_BLEND; - nullshader.pass[1].tcgen = TC_GEN_LIGHTMAP; - nullshader.pass[1].blendsrc = GL_SRC_ALPHA; - nullshader.pass[1].blenddst = GL_ONE_MINUS_SRC_ALPHA; - nullshader.pass[1].texturetype = GL_TEXTURE_2D; + nullshader.passes[1].flags |= SHADER_PASS_BLEND; + nullshader.passes[1].tcgen = TC_GEN_LIGHTMAP; + nullshader.passes[1].blendsrc = GL_SRC_ALPHA; + nullshader.passes[1].blenddst = GL_ONE_MINUS_SRC_ALPHA; + nullshader.passes[1].texturetype = GL_TEXTURE_2D; } { modelbumpshader.numpasses = 3; if (1) - modelbumpshader.pass[0].mergedpasses = 4; + modelbumpshader.passes[0].numMergedPasses = 4; else - modelbumpshader.pass[0].mergedpasses = 2; - modelbumpshader.pass[2].mergedpasses = 1; + modelbumpshader.passes[0].numMergedPasses = 2; + modelbumpshader.passes[2].numMergedPasses = 1; - modelbumpshader.pass[0].tcgen = TC_GEN_BASE; - modelbumpshader.pass[0].envmode = GL_COMBINE_ARB; - modelbumpshader.pass[0].combinesrc0 = GL_TEXTURE; - modelbumpshader.pass[0].combinemode = GL_REPLACE; - modelbumpshader.pass[0].blendsrc = GL_SRC_ALPHA; - modelbumpshader.pass[0].blenddst = GL_ONE_MINUS_SRC_ALPHA; - modelbumpshader.pass[0].anim_frames[0] = 0;//bumpmap - modelbumpshader.pass[0].texturetype = GL_TEXTURE_2D; + modelbumpshader.passes[0].tcgen = TC_GEN_BASE; + modelbumpshader.passes[0].envmode = GL_COMBINE_ARB; + modelbumpshader.passes[0].combinesrc0 = GL_TEXTURE; + modelbumpshader.passes[0].combinemode = GL_REPLACE; + modelbumpshader.passes[0].blendsrc = GL_SRC_ALPHA; + modelbumpshader.passes[0].blenddst = GL_ONE_MINUS_SRC_ALPHA; + modelbumpshader.passes[0].anim_frames[0] = 0;//bumpmap + modelbumpshader.passes[0].texturetype = GL_TEXTURE_2D; - modelbumpshader.pass[1].tcgen = TC_GEN_DOTPRODUCT; - modelbumpshader.pass[1].envmode = GL_COMBINE_ARB; - modelbumpshader.pass[1].combinesrc0 = GL_TEXTURE; - modelbumpshader.pass[1].combinesrc1 = GL_PREVIOUS_ARB; - modelbumpshader.pass[1].combinemode = GL_DOT3_RGB_ARB; - modelbumpshader.pass[1].anim_frames[0] = 0;//delux - modelbumpshader.pass[1].texturetype = GL_TEXTURE_2D; + modelbumpshader.passes[1].tcgen = TC_GEN_DOTPRODUCT; + modelbumpshader.passes[1].envmode = GL_COMBINE_ARB; + modelbumpshader.passes[1].combinesrc0 = GL_TEXTURE; + modelbumpshader.passes[1].combinesrc1 = GL_PREVIOUS_ARB; + modelbumpshader.passes[1].combinemode = GL_DOT3_RGB_ARB; + modelbumpshader.passes[1].anim_frames[0] = 0;//delux + modelbumpshader.passes[1].texturetype = GL_TEXTURE_2D; - modelbumpshader.pass[2].flags |= SHADER_PASS_BLEND; - modelbumpshader.pass[2].tcgen = TC_GEN_BASE; - modelbumpshader.pass[2].envmode = GL_MODULATE; - modelbumpshader.pass[2].blendsrc = GL_DST_COLOR; - modelbumpshader.pass[2].blenddst = GL_ZERO; - modelbumpshader.pass[2].anim_frames[0] = 0;//texture - modelbumpshader.pass[2].texturetype = GL_TEXTURE_2D; + modelbumpshader.passes[2].flags |= SHADER_PASS_BLEND; + modelbumpshader.passes[2].tcgen = TC_GEN_BASE; + modelbumpshader.passes[2].envmode = GL_MODULATE; + modelbumpshader.passes[2].blendsrc = GL_DST_COLOR; + modelbumpshader.passes[2].blenddst = GL_ZERO; + modelbumpshader.passes[2].anim_frames[0] = 0;//texture + modelbumpshader.passes[2].texturetype = GL_TEXTURE_2D; //gl_combine states that we need to use a textures. - modelbumpshader.pass[3].tcgen = TC_GEN_BASE; //multiply by colors - modelbumpshader.pass[3].envmode = GL_COMBINE_ARB; - modelbumpshader.pass[3].combinesrc0 = GL_PREVIOUS_ARB; - modelbumpshader.pass[3].combinesrc1 = GL_PRIMARY_COLOR_ARB; - modelbumpshader.pass[3].combinemode = GL_MODULATE; - modelbumpshader.pass[3].anim_frames[0] = 1; //any, has to be present - modelbumpshader.pass[3].texturetype = GL_TEXTURE_2D; + modelbumpshader.passes[3].tcgen = TC_GEN_BASE; //multiply by colors + modelbumpshader.passes[3].envmode = GL_COMBINE_ARB; + modelbumpshader.passes[3].combinesrc0 = GL_PREVIOUS_ARB; + modelbumpshader.passes[3].combinesrc1 = GL_PRIMARY_COLOR_ARB; + modelbumpshader.passes[3].combinemode = GL_MODULATE; + modelbumpshader.passes[3].anim_frames[0] = 1; //any, has to be present + modelbumpshader.passes[3].texturetype = GL_TEXTURE_2D; } { wallbumpshader.numpasses = 4; if (1) - wallbumpshader.pass[0].mergedpasses = 4; + wallbumpshader.passes[0].numMergedPasses = 4; else - wallbumpshader.pass[0].mergedpasses = 2; - wallbumpshader.pass[2].mergedpasses = 2; + wallbumpshader.passes[0].numMergedPasses = 2; + wallbumpshader.passes[2].numMergedPasses = 2; - wallbumpshader.pass[0].tcgen = TC_GEN_BASE; - wallbumpshader.pass[0].envmode = GL_COMBINE_ARB; - wallbumpshader.pass[0].combinesrc0 = GL_TEXTURE; - wallbumpshader.pass[0].combinemode = GL_REPLACE; - wallbumpshader.pass[0].anim_frames[0] = 0;//bumpmap - wallbumpshader.pass[0].blendsrc = GL_SRC_ALPHA; - wallbumpshader.pass[0].blenddst = GL_ONE_MINUS_SRC_ALPHA; - wallbumpshader.pass[0].texturetype = GL_TEXTURE_2D; + wallbumpshader.passes[0].tcgen = TC_GEN_BASE; + wallbumpshader.passes[0].envmode = GL_COMBINE_ARB; + wallbumpshader.passes[0].combinesrc0 = GL_TEXTURE; + wallbumpshader.passes[0].combinemode = GL_REPLACE; + wallbumpshader.passes[0].anim_frames[0] = 0;//bumpmap + wallbumpshader.passes[0].blendsrc = GL_SRC_ALPHA; + wallbumpshader.passes[0].blenddst = GL_ONE_MINUS_SRC_ALPHA; + wallbumpshader.passes[0].texturetype = GL_TEXTURE_2D; - wallbumpshader.pass[1].tcgen = TC_GEN_LIGHTMAP; - wallbumpshader.pass[1].envmode = GL_COMBINE_ARB; - wallbumpshader.pass[1].combinesrc0 = GL_TEXTURE; - wallbumpshader.pass[1].combinesrc1 = GL_PREVIOUS_ARB; - wallbumpshader.pass[1].combinemode = GL_DOT3_RGB_ARB; - wallbumpshader.pass[1].anim_frames[0] = 0;//delux - wallbumpshader.pass[1].texturetype = GL_TEXTURE_2D; + wallbumpshader.passes[1].tcgen = TC_GEN_LIGHTMAP; + wallbumpshader.passes[1].envmode = GL_COMBINE_ARB; + wallbumpshader.passes[1].combinesrc0 = GL_TEXTURE; + wallbumpshader.passes[1].combinesrc1 = GL_PREVIOUS_ARB; + wallbumpshader.passes[1].combinemode = GL_DOT3_RGB_ARB; + wallbumpshader.passes[1].anim_frames[0] = 0;//delux + wallbumpshader.passes[1].texturetype = GL_TEXTURE_2D; - wallbumpshader.pass[2].flags |= SHADER_PASS_BLEND; - wallbumpshader.pass[2].tcgen = TC_GEN_BASE; - wallbumpshader.pass[2].envmode = GL_MODULATE; - wallbumpshader.pass[2].blendsrc = GL_DST_COLOR; - wallbumpshader.pass[2].blenddst = GL_ZERO; - wallbumpshader.pass[2].anim_frames[0] = 0;//texture - wallbumpshader.pass[2].texturetype = GL_TEXTURE_2D; + wallbumpshader.passes[2].flags |= SHADER_PASS_BLEND; + wallbumpshader.passes[2].tcgen = TC_GEN_BASE; + wallbumpshader.passes[2].envmode = GL_MODULATE; + wallbumpshader.passes[2].blendsrc = GL_DST_COLOR; + wallbumpshader.passes[2].blenddst = GL_ZERO; + wallbumpshader.passes[2].anim_frames[0] = 0;//texture + wallbumpshader.passes[2].texturetype = GL_TEXTURE_2D; - wallbumpshader.pass[3].tcgen = TC_GEN_LIGHTMAP; - wallbumpshader.pass[3].envmode = GL_BLEND; - wallbumpshader.pass[3].anim_frames[0] = 0;//lightmap - wallbumpshader.pass[3].texturetype = GL_TEXTURE_2D; + wallbumpshader.passes[3].tcgen = TC_GEN_LIGHTMAP; + wallbumpshader.passes[3].envmode = GL_BLEND; + wallbumpshader.passes[3].anim_frames[0] = 0;//lightmap + wallbumpshader.passes[3].texturetype = GL_TEXTURE_2D; } } @@ -319,12 +390,12 @@ static void Mesh_SetShaderpassState ( shaderpass_t *pass, qboolean mtex ) static void Mesh_DrawPass(shaderpass_t *pass, mesh_t *mesh) { Mesh_SetShaderpassState(pass, false); - if (pass->mergedpasses>1 && gl_mtexarbable) + if (pass->numMergedPasses>1 && gl_mtexarbable) { int p; // Mesh_DrawPass(pass+2,mesh); // return; - for (p = 0; p < pass->mergedpasses; p++) + for (p = 0; p < pass->numMergedPasses; p++) { qglActiveTextureARB(GL_TEXTURE0_ARB+p); qglClientActiveTextureARB(GL_TEXTURE0_ARB+p); @@ -342,7 +413,7 @@ static void Mesh_DrawPass(shaderpass_t *pass, mesh_t *mesh) Mesh_DeformTextureCoords(mesh, pass+p); } glDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); - for (p = pass->mergedpasses-1; p >= 0; p--) + for (p = pass->numMergedPasses-1; p >= 0; p--) { qglActiveTextureARB(GL_TEXTURE0_ARB+p); qglClientActiveTextureARB(GL_TEXTURE0_ARB+p); @@ -374,6 +445,20 @@ static void Mesh_DrawPass(shaderpass_t *pass, mesh_t *mesh) } } +shader_t *currentshader; +void GL_PushShader(shader_t *shader) +{ + if (!shader) + { + glDisableClientState( GL_VERTEX_ARRAY ); + return; + } + + glEnableClientState( GL_VERTEX_ARRAY ); +} +void GL_PushMesh(mesh_t *mesh, int deluxnum, int lmnum) +{ +} void GL_DrawMesh(mesh_t *mesh, shader_t *shader, int texturenum, int lmtexturenum) { @@ -381,28 +466,28 @@ void GL_DrawMesh(mesh_t *mesh, shader_t *shader, int texturenum, int lmtexturenu if (!shader) { shader = &nullshader; - shader->pass[0].anim_frames[0] = texturenum; - shader->pass[0].mergedpasses=1; + shader->passes[0].anim_frames[0] = texturenum; + shader->passes[0].numMergedPasses=1; if (lmtexturenum && !texturenum) { - shader->pass[0].anim_frames[0] = lmtexturenum; + shader->passes[0].anim_frames[0] = lmtexturenum; shader->numpasses = 1; - shader->pass[0].flags |= SHADER_PASS_BLEND; + shader->passes[0].flags |= SHADER_PASS_BLEND; } else if (lmtexturenum) { shader->numpasses = 2; - shader->pass[1].anim_frames[0] = lmtexturenum;//lmtexture; - shader->pass[0].flags &= ~SHADER_PASS_BLEND; + shader->passes[1].anim_frames[0] = lmtexturenum;//lmtexture; + shader->passes[0].flags &= ~SHADER_PASS_BLEND; } else { - shader->pass[0].flags &= ~SHADER_PASS_BLEND; + shader->passes[0].flags &= ~SHADER_PASS_BLEND; shader->numpasses = 1; } - shader->pass[0].texturetype = GL_TEXTURE_2D; + shader->passes[0].texturetype = GL_TEXTURE_2D; } if (!shader->numdeforms) glVertexPointer(3, GL_FLOAT, 16, mesh->xyz_array); @@ -424,13 +509,12 @@ void GL_DrawMesh(mesh_t *mesh, shader_t *shader, int texturenum, int lmtexturenu glEnableClientState( GL_COLOR_ARRAY ); } - for (i =0 ; i < shader->numpasses; i+=shader->pass[i].mergedpasses) - Mesh_DrawPass(shader->pass+i, mesh); + for (i =0 ; i < shader->numpasses; i+=shader->passes[i].numMergedPasses) + Mesh_DrawPass(shader->passes+i, mesh); glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_COLOR_ARRAY ); glDisableClientState( GL_NORMAL_ARRAY ); - glDisableClientState( GL_NORMAL_ARRAY ); /* //show normals if (mesh->normals_array) @@ -462,29 +546,2203 @@ void GL_DrawMeshBump(mesh_t *mesh, int texturenum, int lmtexturenum, int bumpnum if (lmtexturenum) { shader = &wallbumpshader; - shader->pass[3].anim_frames[0] = lmtexturenum; + shader->passes[3].anim_frames[0] = lmtexturenum; } else shader = &modelbumpshader; - shader->pass[0].anim_frames[0] = bumpnum; + shader->passes[0].anim_frames[0] = bumpnum; if (deluxnum) { - shader->pass[1].anim_frames[0] = deluxnum; - shader->pass[1].tcgen = TC_GEN_LIGHTMAP; - shader->pass[1].texturetype = GL_TEXTURE_2D; + shader->passes[1].anim_frames[0] = deluxnum; + shader->passes[1].tcgen = TC_GEN_LIGHTMAP; + shader->passes[1].texturetype = GL_TEXTURE_2D; } else { - shader->pass[1].anim_frames[0] = normalisationCubeMap; - shader->pass[1].tcgen = TC_GEN_DOTPRODUCT; - shader->pass[1].texturetype = GL_TEXTURE_CUBE_MAP_ARB; + shader->passes[1].anim_frames[0] = normalisationCubeMap; + shader->passes[1].tcgen = TC_GEN_DOTPRODUCT; + shader->passes[1].texturetype = GL_TEXTURE_CUBE_MAP_ARB; } - shader->pass[2].anim_frames[0] = texturenum; + shader->passes[2].anim_frames[0] = texturenum; // mesh->colors_array=NULL; //don't bother coloring it. GL_DrawMesh(mesh, shader, 0, 0); } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#else + +/* +Copyright (C) 2002-2003 Victor Luchits + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#define MAX_ARRAY_VERTS 8192 +#define MAX_ARRAY_INDEXES 8192 +#define MAX_ARRAY_NEIGHBORS 8192 +#define MAX_ARRAY_TRIANGLES (8192/3) +#define M_TWO_PI (M_PI*2) + +cvar_t r_detailtextures = {"r_detailtextures", "1"}; +cvar_t r_showtris = {"r_showtris", "1"}; +cvar_t r_shownormals = {"r_shownormals", "1"}; + +float Q_rsqrt( float number ) +{ + long i; + float x2, y; + const float threehalfs = 1.5F; + + x2 = number * 0.5F; + y = number; + i = * ( long * ) &y; // evil floating point bit level hacking + i = 0x5f3759df - ( i >> 1 ); // what the fuck? + y = * ( float * ) &i; + y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration +// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed + + return y; +} + +void VectorNormalizeFast( vec3_t v ) +{ + float ilength; + + ilength = Q_rsqrt( DotProduct( v, v ) ); + + v[0] *= ilength; + v[1] *= ilength; + v[2] *= ilength; +} + + + +void GL_TexEnv( GLenum mode ) +{ + static int lastmodes[MAX_TEXTURE_UNITS] = { -1, -1 }; + + if ( mode != lastmodes[gl_state.currenttmu] ) + { + qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode ); + lastmodes[gl_state.currenttmu] = mode; + } +} +typedef vec3_t mat3_t[3]; +mat3_t axisDefault={{1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}}; + +void Matrix3_Transpose (mat3_t in, mat3_t out) +{ + out[0][0] = in[0][0]; + out[1][1] = in[1][1]; + out[2][2] = in[2][2]; + + out[0][1] = in[1][0]; + out[0][2] = in[2][0]; + out[1][0] = in[0][1]; + out[1][2] = in[2][1]; + out[2][0] = in[0][2]; + out[2][1] = in[1][2]; +} +void Matrix3_Multiply_Vec3 (mat3_t a, vec3_t b, vec3_t product) +{ + product[0] = a[0][0]*b[0] + a[0][1]*b[1] + a[0][2]*b[2]; + product[1] = a[1][0]*b[0] + a[1][1]*b[1] + a[1][2]*b[2]; + product[2] = a[2][0]*b[0] + a[2][1]*b[1] + a[2][2]*b[2]; +} + +void Matrix3_Multiply (mat3_t in1, mat3_t in2, mat3_t out) +{ + out[0][0] = in1[0][0]*in2[0][0] + in1[0][1]*in2[1][0] + in1[0][2]*in2[2][0]; + out[0][1] = in1[0][0]*in2[0][1] + in1[0][1]*in2[1][1] + in1[0][2]*in2[2][1]; + out[0][2] = in1[0][0]*in2[0][2] + in1[0][1]*in2[1][2] + in1[0][2]*in2[2][2]; + out[1][0] = in1[1][0]*in2[0][0] + in1[1][1]*in2[1][0] + in1[1][2]*in2[2][0]; + out[1][1] = in1[1][0]*in2[0][1] + in1[1][1]*in2[1][1] + in1[1][2]*in2[2][1]; + out[1][2] = in1[1][0]*in2[0][2] + in1[1][1]*in2[1][2] + in1[1][2]*in2[2][2]; + out[2][0] = in1[2][0]*in2[0][0] + in1[2][1]*in2[1][0] + in1[2][2]*in2[2][0]; + out[2][1] = in1[2][0]*in2[0][1] + in1[2][1]*in2[1][1] + in1[2][2]*in2[2][1]; + out[2][2] = in1[2][0]*in2[0][2] + in1[2][1]*in2[1][2] + in1[2][2]*in2[2][2]; +} + +int Matrix3_Compare(mat3_t in, mat3_t out) +{ + return memcmp(in, out, sizeof(mat3_t)); +} +extern model_t *currentmodel; + +#define clamp(v,min,max) (v) = (((v)<(min))?(min):(((v)>(max))?(max):(v))) +#define bound(min,v,max) (((v)<(min))?(min):(((v)>(max))?(max):(v))) + +extern qbyte FloatToByte( float x ); + + +#define FTABLE_SIZE 1024 +#define FTABLE_CLAMP(x) (((int)((x)*FTABLE_SIZE) & (FTABLE_SIZE-1))) +#define FTABLE_EVALUATE(table,x) (table ? table[FTABLE_CLAMP(x)] : frand()*((x)-floor(x))) + +static float r_sintable[FTABLE_SIZE]; +static float r_triangletable[FTABLE_SIZE]; +static float r_squaretable[FTABLE_SIZE]; +static float r_sawtoothtable[FTABLE_SIZE]; +static float r_inversesawtoothtable[FTABLE_SIZE]; + +index_t *indexesArray; +int *neighborsArray; +vec3_t *trNormalsArray; + +vec2_t *coordsArray; +vec2_t *lightmapCoordsArray; + +vec4_t vertexArray[MAX_ARRAY_VERTS*2]; +vec3_t normalsArray[MAX_ARRAY_VERTS]; + +vec4_t tempVertexArray[MAX_ARRAY_VERTS]; +vec3_t tempNormalsArray[MAX_ARRAY_VERTS]; +index_t tempIndexesArray[MAX_ARRAY_INDEXES]; + +index_t inIndexesArray[MAX_ARRAY_INDEXES]; +int inNeighborsArray[MAX_ARRAY_NEIGHBORS]; +vec3_t inTrNormalsArray[MAX_ARRAY_TRIANGLES]; +vec2_t inCoordsArray[MAX_ARRAY_VERTS]; +vec2_t inLightmapCoordsArray[MAX_ARRAY_VERTS]; +byte_vec4_t inColorsArray[MAX_ARRAY_VERTS]; + +static vec2_t tUnitCoordsArray[MAX_TEXTURE_UNITS][MAX_ARRAY_VERTS]; +static byte_vec4_t colorArray[MAX_ARRAY_VERTS]; + +int numVerts, numIndexes, numColors; + +qboolean r_arrays_locked; +qboolean r_blocked; + +int r_features; + +static int r_lmtex; + +static int r_texNums[SHADER_PASS_MAX]; +static int r_numUnits; + +index_t *currentIndex; +int *currentTrNeighbor; +float *currentTrNormal; +float *currentVertex; +float *currentNormal; +float *currentCoords; +float *currentLightmapCoords; +qbyte *currentColor; + +static int r_identityLighting; +static float r_localShaderTime; + +unsigned int r_numverts; +unsigned int r_numtris; +unsigned int r_numflushes; +int r_backendStart; + +void R_ResetTexState (void) +{ + coordsArray = inCoordsArray; + lightmapCoordsArray = inLightmapCoordsArray; + + currentCoords = coordsArray[0]; + currentLightmapCoords = lightmapCoordsArray[0]; + + numColors = 0; + currentColor = inColorsArray[0]; +} + + +void R_PushIndexes ( index_t *indexes, int *neighbors, vec3_t *trnormals, int numindexes, int features ) +{ + int i; + int numTris; + + // this is a fast path for non-batched geometry, use carefully + // used on pics, sprites, .dpm, .md3 and .md2 models + if ( features & MF_NONBATCHED ) { + if ( numindexes > MAX_ARRAY_INDEXES ) { + numindexes = MAX_ARRAY_INDEXES; + } + + // simply change indexesArray to point at indexes + numIndexes = numindexes; + indexesArray = indexes; + currentIndex = indexesArray + numIndexes; + + if ( neighbors ) { + neighborsArray = neighbors; + currentTrNeighbor = neighborsArray + numIndexes; + } + + if ( trnormals && (features & MF_TRNORMALS) ) { + numTris = numIndexes / 3; + + trNormalsArray = trnormals; + currentTrNormal = trNormalsArray[0] + numTris; + } + } + else + { + // clamp + if ( numIndexes + numindexes > MAX_ARRAY_INDEXES ) { + numindexes = MAX_ARRAY_INDEXES - numIndexes; + } + + numTris = numindexes / 3; + numIndexes += numindexes; + + // the following code assumes that R_PushIndexes is fed with triangles... + for ( i=0; iindexes || !mesh->xyz_array ) { + return; + } + + r_features = features; + + R_PushIndexes ( mesh->indexes, mesh->trneighbors, mesh->trnormals, mesh->numindexes, features ); + + numverts = mesh->numvertexes; + if ( numVerts + numverts > MAX_ARRAY_VERTS ) { + numverts = MAX_ARRAY_VERTS - numVerts; + } + + memcpy ( currentVertex, mesh->xyz_array, numverts * sizeof(vec4_t) ); + currentVertex += numverts * 4; + + if ( mesh->normals_array && (features & MF_NORMALS) ) { + memcpy ( currentNormal, mesh->normals_array, numverts * sizeof(vec3_t) ); + currentNormal += numverts * 3; + } + + if ( mesh->st_array && (features & MF_STCOORDS) ) { + if ( features & MF_NONBATCHED ) { + coordsArray = mesh->st_array; + currentCoords = coordsArray[0]; + } else { + memcpy ( currentCoords, mesh->st_array, numverts * sizeof(vec2_t) ); + } + + currentCoords += numverts * 2; + } + + if ( mesh->lmst_array && (features & MF_LMCOORDS) ) { + if ( features & MF_NONBATCHED ) { + lightmapCoordsArray = mesh->lmst_array; + currentLightmapCoords = lightmapCoordsArray[0]; + } else { + memcpy ( currentLightmapCoords, mesh->lmst_array, numverts * sizeof(vec2_t) ); + } + + currentLightmapCoords += numverts * 2; + } + + if ( mesh->colors_array && (features & MF_COLORS) ) { + memcpy ( currentColor, mesh->colors_array, numverts * sizeof(byte_vec4_t) ); + currentColor += numverts * 4; + } + + numVerts += numverts; + r_numverts += numverts; +} + + + +extern index_t r_quad_indexes[6];// = { 0, 1, 2, 0, 2, 3 }; + +void R_FinishMeshBuffer ( meshbuffer_t *mb ); + +static float frand(void) +{ + return (rand()&32767)* (1.0/32767); +} + +static float crand(void) +{ + return (rand()&32767)* (2.0/32767) - 1; +} + +/* +============== +R_BackendInit +============== +*/ +void R_BackendInit (void) +{ + int i; + double t; + + numVerts = 0; + numIndexes = 0; + numColors = 0; + + indexesArray = inIndexesArray; + currentIndex = indexesArray; + neighborsArray = inNeighborsArray; + trNormalsArray = inTrNormalsArray; + coordsArray = inCoordsArray; + lightmapCoordsArray = inLightmapCoordsArray; + + currentTrNeighbor = neighborsArray; + currentTrNormal = trNormalsArray[0]; + + currentVertex = vertexArray[0]; + currentNormal = normalsArray[0]; + + currentCoords = coordsArray[0]; + currentLightmapCoords = lightmapCoordsArray[0]; + + currentColor = inColorsArray[0]; + + r_arrays_locked = false; + r_blocked = false; + + qglVertexPointer( 3, GL_FLOAT, 16, vertexArray ); // padded for SIMD + qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); + + qglEnableClientState( GL_VERTEX_ARRAY ); + + //FIZME: FTE already has some stuff along these lines, surly... +// if ( !r_ignorehwgamma->value ) +// r_identityLighting = (int)(255.0f / pow(2, max(0, floor(r_overbrightbits->value)))); +// else + r_identityLighting = 255; + + for ( i = 0; i < FTABLE_SIZE; i++ ) { + t = (double)i / (double)FTABLE_SIZE; + + r_sintable[i] = sin ( t * M_TWO_PI ); + + if (t < 0.25) + r_triangletable[i] = t * 4.0; + else if (t < 0.75) + r_triangletable[i] = 2 - 4.0 * t; + else + r_triangletable[i] = (t - 0.75) * 4.0 - 1.0; + + if (t < 0.5) + r_squaretable[i] = 1.0f; + else + r_squaretable[i] = -1.0f; + + r_sawtoothtable[i] = t; + r_inversesawtoothtable[i] = 1.0 - t; + } +} + +void R_IBrokeTheArrays(void) +{ + qglVertexPointer( 3, GL_FLOAT, 16, vertexArray ); // padded for SIMD + qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); + + qglEnableClientState( GL_VERTEX_ARRAY ); +} + +/* +============== +R_BackendShutdown +============== +*/ +void R_BackendShutdown (void) +{ +} + +/* +============== +R_FastSin +============== +*/ +float R_FastSin ( float t ) +{ + return r_sintable[FTABLE_CLAMP(t)]; +} + +/* +============== +R_TableForFunc +============== +*/ +static float *R_TableForFunc ( unsigned int func ) +{ + switch (func) + { + case SHADER_FUNC_SIN: + return r_sintable; + + case SHADER_FUNC_TRIANGLE: + return r_triangletable; + + case SHADER_FUNC_SQUARE: + return r_squaretable; + + case SHADER_FUNC_SAWTOOTH: + return r_sawtoothtable; + + case SHADER_FUNC_INVERSESAWTOOTH: + return r_inversesawtoothtable; + } + + // assume noise + return NULL; +} + +/* +============== +R_BackendStartFrame +============== +*/ +void R_BackendStartFrame (void) +{ + r_numverts = 0; + r_numtris = 0; + r_numflushes = 0; +// r_backendStart = Sys_Milliseconds(); +} + +/* +============== +R_BackendEndFrame +============== +*/ +void R_BackendEndFrame (void) +{ + if (r_speeds.value) + { + Con_Printf( "%4i wpoly %4i leafs %4i verts %4i tris %4i flushes\n", + c_brush_polys, + 0/*c_world_leafs*/, + r_numverts, + r_numtris, + r_numflushes ); + } +// time_backend = Sys_Milliseconds() - r_backendStart; +// r_backendStart = 0; +} + +/* +============== +R_LockArrays +============== +*/ +void R_LockArrays ( int numverts ) +{ + if ( r_arrays_locked ) + return; + + if ( qglLockArraysEXT != 0 ) { + qglLockArraysEXT( 0, numverts ); + r_arrays_locked = true; + } +} + +/* +============== +R_UnlockArrays +============== +*/ +void R_UnlockArrays (void) +{ + if ( !r_arrays_locked ) + return; + + if ( qglUnlockArraysEXT != 0 ) { + qglUnlockArraysEXT(); + r_arrays_locked = false; + } +} + +/* +============== +R_DrawTriangleStrips + +This function looks for and sends tristrips. +Original code by Stephen C. Taylor (Aftershock 3D rendering engine) +============== +*/ +void R_DrawTriangleStrips (index_t *indexes, int numindexes) +{ + int toggle; + index_t a, b, c, *index; + + c = 0; + index = indexes; + while ( c < numindexes ) { + toggle = 1; + + qglBegin( GL_TRIANGLE_STRIP ); + + qglArrayElement( index[0] ); + qglArrayElement( b = index[1] ); + qglArrayElement( a = index[2] ); + + c += 3; + index += 3; + + while ( c < numindexes ) { + if ( a != index[0] || b != index[1] ) { + break; + } + + if ( toggle ) { + qglArrayElement( b = index[2] ); + } else { + qglArrayElement( a = index[2] ); + } + + c += 3; + index += 3; + toggle = !toggle; + } + + qglEnd(); + } +} + +/* +============== +R_ClearArrays +============== +*/ +void R_ClearArrays (void) +{ + numVerts = 0; + numIndexes = 0; + + indexesArray = inIndexesArray; + currentIndex = indexesArray; + neighborsArray = inNeighborsArray; + trNormalsArray = inTrNormalsArray; + + currentTrNeighbor = neighborsArray; + currentTrNormal = trNormalsArray[0]; + + currentVertex = vertexArray[0]; + currentNormal = normalsArray[0]; + + R_ResetTexState (); + + r_blocked = false; +} + +/* +============== +R_FlushArrays +============== +*/ +void R_FlushArrays (void) +{ + if ( !numVerts || !numIndexes ) { + return; + } + + if ( numColors > 1 ) { + qglEnableClientState( GL_COLOR_ARRAY ); + } else if ( numColors == 1 ) { + qglColor4ubv ( colorArray[0] ); + } + + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + if ( !r_arrays_locked ) { + R_DrawTriangleStrips ( indexesArray, numIndexes ); + } else { + qglDrawElements( GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexesArray ); + } + + r_numtris += numIndexes / 3; + + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + if ( numColors > 1 ) { + qglDisableClientState( GL_COLOR_ARRAY ); + } + + r_numflushes++; +} + +/* +============== +R_FlushArraysMtex +============== +*/ +void R_FlushArraysMtex (void) +{ + int i; + + if ( !numVerts || !numIndexes ) { + return; + } + + GL_MBind( mtexid0, r_texNums[0] ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + if ( numColors > 1 ) { + qglEnableClientState( GL_COLOR_ARRAY ); + } else if ( numColors == 1 ) { + qglColor4ubv ( colorArray[0] ); + } + + for ( i = 1; i < r_numUnits; i++ ) + { + GL_MBind( mtexid0 + i, r_texNums[i] ); + qglEnable ( GL_TEXTURE_2D ); + qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + } + + if ( !r_arrays_locked ) { + R_DrawTriangleStrips ( indexesArray, numIndexes ); + } else { + qglDrawElements( GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexesArray ); + } + + r_numtris += numIndexes / 3; + + for ( i = r_numUnits - 1; i >= 0; i-- ) + { + GL_SelectTexture ( mtexid0 + i ); + + if ( i ) { + qglDisable ( GL_TEXTURE_2D ); + } + qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + } + + if ( numColors > 1 ) { + qglDisableClientState( GL_COLOR_ARRAY ); + } + + r_numflushes++; +} + +/* +================ +R_DeformVertices +================ +*/ +void R_DeformVertices ( meshbuffer_t *mb ) +{ + int i, j, k, pw, ph, p; + float args[4], deflect; + float *quad[4], *table; + shader_t *shader; + deformv_t *deformv; + vec3_t tv, rot_centre; + + shader = mb->shader; + deformv = &shader->deforms[0]; + + for (i = 0; i < shader->numdeforms; i++, deformv++) + { + switch (deformv->type) + { + case DEFORMV_NONE: + break; + + case DEFORMV_WAVE: + args[0] = deformv->func.args[0]; + args[1] = deformv->func.args[1]; + args[3] = deformv->func.args[2] + deformv->func.args[3] * r_localShaderTime; + table = R_TableForFunc ( deformv->func.type ); + + for ( j = 0; j < numVerts; j++ ) { + deflect = deformv->args[0] * (vertexArray[j][0]+vertexArray[j][1]+vertexArray[j][2]) + args[3]; + deflect = FTABLE_EVALUATE ( table, deflect ) * args[1] + args[0]; + + // Deflect vertex along its normal by wave amount + VectorMA ( vertexArray[j], deflect, normalsArray[j], vertexArray[j] ); + } + break; + + case DEFORMV_NORMAL: + args[0] = deformv->args[1] * r_localShaderTime; + + for ( j = 0; j < numVerts; j++ ) { + args[1] = normalsArray[j][2] * args[0]; + + deflect = deformv->args[0] * R_FastSin ( args[1] ); + normalsArray[j][0] *= deflect; + deflect = deformv->args[0] * R_FastSin ( args[1] + 0.25 ); + normalsArray[j][1] *= deflect; + VectorNormalizeFast ( normalsArray[j] ); + } + break; + + case DEFORMV_MOVE: + table = R_TableForFunc ( deformv->func.type ); + deflect = deformv->func.args[2] + r_localShaderTime * deformv->func.args[3]; + deflect = FTABLE_EVALUATE (table, deflect) * deformv->func.args[1] + deformv->func.args[0]; + + for ( j = 0; j < numVerts; j++ ) + VectorMA ( vertexArray[j], deflect, deformv->args, vertexArray[j] ); + break; + + case DEFORMV_BULGE: + pw = mb->mesh->patchWidth; + ph = mb->mesh->patchHeight; + + args[0] = deformv->args[0] / (float)ph; + args[1] = deformv->args[1]; + args[2] = r_localShaderTime / (deformv->args[2]*pw); + + for ( k = 0, p = 0; k < ph; k++ ) { + deflect = R_FastSin ( (float)k * args[0] + args[2] ) * args[1]; + + for ( j = 0; j < pw; j++, p++ ) + VectorMA ( vertexArray[p], deflect, normalsArray[p], vertexArray[p] ); + } + break; + + case DEFORMV_AUTOSPRITE: + if ( numIndexes < 6 ) + break; + + for ( k = 0; k < numIndexes; k += 6 ) + { + mat3_t m0, m1, result; + + quad[0] = (float *)(vertexArray + indexesArray[k+0]); + quad[1] = (float *)(vertexArray + indexesArray[k+1]); + quad[2] = (float *)(vertexArray + indexesArray[k+2]); + + for ( j = 2; j >= 0; j-- ) { + quad[3] = (float *)(vertexArray + indexesArray[k+3+j]); + if ( !VectorCompare (quad[3], quad[0]) && + !VectorCompare (quad[3], quad[1]) && + !VectorCompare (quad[3], quad[2]) ) { + break; + } + } + + VectorSubtract ( quad[0], quad[1], m0[0] ); + VectorSubtract ( quad[2], quad[1], m0[1] ); + CrossProduct ( m0[0], m0[1], m0[2] ); + VectorNormalizeFast ( m0[2] ); + VectorVectors ( m0[2], m0[1], m0[0] ); + + VectorCopy ( (&r_world_matrix[0]), m1[0] ); + VectorCopy ( (&r_world_matrix[4]), m1[1] ); + VectorCopy ( (&r_world_matrix[8]), m1[2] ); + + Matrix3_Multiply ( m1, m0, result ); + + for ( j = 0; j < 3; j++ ) + rot_centre[j] = (quad[0][j] + quad[1][j] + quad[2][j] + quad[3][j]) * 0.25 + currententity->origin[j]; + + for ( j = 0; j < 4; j++ ) { + VectorSubtract ( quad[j], rot_centre, tv ); + Matrix3_Multiply_Vec3 ( result, tv, quad[j] ); + VectorAdd ( rot_centre, quad[j], quad[j] ); + } + } + break; + + case DEFORMV_AUTOSPRITE2: + if ( numIndexes < 6 ) + break; + + for ( k = 0; k < numIndexes; k += 6 ) + { + int long_axis, short_axis; + vec3_t axis; + float len[3]; + mat3_t m0, m1, m2, result; + + quad[0] = (float *)(vertexArray + indexesArray[k+0]); + quad[1] = (float *)(vertexArray + indexesArray[k+1]); + quad[2] = (float *)(vertexArray + indexesArray[k+2]); + + for ( j = 2; j >= 0; j-- ) { + quad[3] = (float *)(vertexArray + indexesArray[k+3+j]); + if ( !VectorCompare (quad[3], quad[0]) && + !VectorCompare (quad[3], quad[1]) && + !VectorCompare (quad[3], quad[2]) ) { + break; + } + } + + // build a matrix were the longest axis of the billboard is the Y-Axis + VectorSubtract ( quad[1], quad[0], m0[0] ); + VectorSubtract ( quad[2], quad[0], m0[1] ); + VectorSubtract ( quad[2], quad[1], m0[2] ); + len[0] = DotProduct ( m0[0], m0[0] ); + len[1] = DotProduct ( m0[1], m0[1] ); + len[2] = DotProduct ( m0[2], m0[2] ); + + if ( (len[2] > len[1]) && (len[2] > len[0]) ) + { + if ( len[1] > len[0] ) + { + long_axis = 1; + short_axis = 0; + } + else + { + long_axis = 0; + short_axis = 1; + } + } + else if ( (len[1] > len[2]) && (len[1] > len[0]) ) + { + if ( len[2] > len[0] ) + { + long_axis = 2; + short_axis = 0; + } + else + { + long_axis = 0; + short_axis = 2; + } + } + else if ( (len[0] > len[1]) && (len[0] > len[2]) ) + { + if ( len[2] > len[1] ) + { + long_axis = 2; + short_axis = 1; + } + else + { + long_axis = 1; + short_axis = 2; + } + } + + if ( DotProduct (m0[long_axis], m0[short_axis]) ) { + VectorNormalize2 ( m0[long_axis], axis ); + VectorCopy ( axis, m0[1] ); + + if ( axis[0] || axis[1] ) { + VectorVectors ( m0[1], m0[2], m0[0] ); + } else { + VectorVectors ( m0[1], m0[0], m0[2] ); + } + } else { + VectorNormalize2 ( m0[long_axis], axis ); + VectorNormalize2 ( m0[short_axis], m0[0] ); + VectorCopy ( axis, m0[1] ); + CrossProduct ( m0[0], m0[1], m0[2] ); + } + + for ( j = 0; j < 3; j++ ) + rot_centre[j] = (quad[0][j] + quad[1][j] + quad[2][j] + quad[3][j]) * 0.25; + + if ( currententity ) { + VectorAdd ( currententity->origin, rot_centre, tv ); + } else { + VectorCopy ( rot_centre, tv ); + } + VectorSubtract ( r_origin, tv, tv ); + + // filter any longest-axis-parts off the camera-direction + deflect = -DotProduct ( tv, axis ); + + VectorMA ( tv, deflect, axis, m1[2] ); + VectorNormalizeFast ( m1[2] ); + VectorCopy ( axis, m1[1] ); + CrossProduct ( m1[1], m1[2], m1[0] ); + + Matrix3_Transpose ( m1, m2 ); + Matrix3_Multiply ( m2, m0, result ); + + for ( j = 0; j < 4; j++ ) { + VectorSubtract ( quad[j], rot_centre, tv ); + Matrix3_Multiply_Vec3 ( result, tv, quad[j] ); + VectorAdd ( rot_centre, quad[j], quad[j] ); + } + } + break; + + case DEFORMV_PROJECTION_SHADOW: + break; + + default: + break; + } + } +} + +/* +============== +R_VertexTCBase +============== +*/ +void R_VertexTCBase ( int tcgen, int unit ) +{ + int i; + vec3_t t, n; + float *outCoords; + vec3_t transform; + mat3_t inverse_axis; + mat3_t axis; + + outCoords = tUnitCoordsArray[unit][0]; + qglTexCoordPointer( 2, GL_FLOAT, 0, outCoords ); + + if ( tcgen == TC_GEN_BASE ) + { + memcpy ( outCoords, coordsArray[0], sizeof(float) * 2 * numVerts ); + } else if ( tcgen == TC_GEN_LIGHTMAP ) + { + memcpy ( outCoords, lightmapCoordsArray[0], sizeof(float) * 2 * numVerts ); + } + else if ( tcgen == TC_GEN_ENVIRONMENT ) + { + if ( !currentmodel ) + { + VectorSubtract ( vec3_origin, currententity->origin, transform ); + AngleVectors(currententity->angles, axis[0], axis[1], axis[2]); + Matrix3_Transpose ( axis, inverse_axis ); + } + else if ( currentmodel == cl.worldmodel ) + { + VectorSubtract ( vec3_origin, r_origin, transform ); + } + else if ( currentmodel->type == mod_brush ) + { + VectorNegate ( currententity->origin, t ); + VectorSubtract ( t, r_origin, transform ); + AngleVectors(currententity->angles, axis[0], axis[1], axis[2]); + Matrix3_Transpose ( axis, inverse_axis ); + } + else + { + VectorSubtract ( vec3_origin, currententity->origin, transform ); + AngleVectors(currententity->angles, axis[0], axis[1], axis[2]); + Matrix3_Transpose ( axis, inverse_axis ); + } + + for ( i = 0; i < numVerts; i++, outCoords += 2 ) + { + VectorAdd ( vertexArray[i], transform, t ); + + // project vector + if ( currentmodel && (currentmodel == cl.worldmodel) ) + { + n[0] = normalsArray[i][0]; + n[1] = normalsArray[i][1]; + n[2] = Q_rsqrt ( DotProduct(t,t) ); + } + else + { + n[0] = DotProduct ( normalsArray[i], inverse_axis[0] ); + n[1] = DotProduct ( normalsArray[i], inverse_axis[1] ); + n[2] = Q_rsqrt ( DotProduct(t,t) ); + } + + outCoords[0] = t[0]*n[2] - n[0]; + outCoords[1] = t[1]*n[2] - n[1]; + } + } + else if ( tcgen == TC_GEN_VECTOR ) + { + for ( i = 0; i < numVerts; i++, outCoords += 2 ) + { + static vec3_t tc_gen_s = { 1.0f, 0.0f, 0.0f }; + static vec3_t tc_gen_t = { 0.0f, 1.0f, 0.0f }; + + outCoords[0] = DotProduct ( tc_gen_s, vertexArray[i] ); + outCoords[1] = DotProduct ( tc_gen_t, vertexArray[i] ); + } + } + +} + +/* +============== +R_ShaderpassTex +============== +*/ +int R_ShaderpassTex ( shaderpass_t *pass ) +{ + if ( pass->flags & SHADER_PASS_ANIMMAP ) { + return pass->anim_frames[(int)(pass->anim_fps * r_localShaderTime) % pass->anim_numframes]; + } + else if ( (pass->flags & SHADER_PASS_LIGHTMAP) && r_lmtex >= 0 ) + { + return lightmap_textures[r_lmtex]; + } + + return pass->anim_frames[0] ? pass->anim_frames[0] : 0; +} + +/* +================ +R_ModifyTextureCoords +================ +*/ +void R_ModifyTextureCoords ( shaderpass_t *pass, int unit ) +{ + int i, j; + float *table; + float t1, t2, sint, cost; + float *tcArray; + tcmod_t *tcmod; + + r_texNums[unit] = R_ShaderpassTex ( pass ); + + // we're smart enough not to copy data and simply switch the pointer + if ( !pass->numtcmods ) { + if ( pass->tcgen == TC_GEN_BASE ) { + qglTexCoordPointer( 2, GL_FLOAT, 0, coordsArray ); + } else if ( pass->tcgen == TC_GEN_LIGHTMAP ) { + qglTexCoordPointer( 2, GL_FLOAT, 0, lightmapCoordsArray ); + } else { + R_VertexTCBase ( pass->tcgen, unit ); + } + return; + } + + R_VertexTCBase ( pass->tcgen, unit ); + + for (i = 0, tcmod = pass->tcmods; i < pass->numtcmods; i++, tcmod++) + { + tcArray = tUnitCoordsArray[unit][0]; + + switch (tcmod->type) + { + case SHADER_TCMOD_ROTATE: + cost = tcmod->args[0] * r_localShaderTime; + sint = R_FastSin( cost ); + cost = R_FastSin( cost + 0.25 ); + + for ( j = 0; j < numVerts; j++, tcArray += 2 ) { + t1 = cost * (tcArray[0] - 0.5f) - sint * (tcArray[1] - 0.5f) + 0.5f; + t2 = cost * (tcArray[1] - 0.5f) + sint * (tcArray[0] - 0.5f) + 0.5f; + tcArray[0] = t1; + tcArray[1] = t2; + } + break; + + case SHADER_TCMOD_SCALE: + t1 = tcmod->args[0]; + t2 = tcmod->args[1]; + + for ( j = 0; j < numVerts; j++, tcArray += 2 ) { + tcArray[0] = tcArray[0] * t1; + tcArray[1] = tcArray[1] * t2; + } + break; + + case SHADER_TCMOD_TURB: + t1 = tcmod->args[2] + r_localShaderTime * tcmod->args[3]; + t2 = tcmod->args[1]; + + for ( j = 0; j < numVerts; j++, tcArray += 2 ) { + tcArray[0] = tcArray[0] + R_FastSin (tcArray[0]*t2+t1) * t2; + tcArray[1] = tcArray[1] + R_FastSin (tcArray[1]*t2+t1) * t2; + } + break; + + case SHADER_TCMOD_STRETCH: + table = R_TableForFunc ( tcmod->args[0] ); + t2 = tcmod->args[3] + r_localShaderTime * tcmod->args[4]; + t1 = FTABLE_EVALUATE ( table, t2 ) * tcmod->args[2] + tcmod->args[1]; + t1 = t1 ? 1.0f / t1 : 1.0f; + t2 = 0.5f - 0.5f * t1; + + for ( j = 0; j < numVerts; j++, tcArray += 2 ) { + tcArray[0] = tcArray[0] * t1 + t2; + tcArray[1] = tcArray[1] * t1 + t2; + } + break; + + case SHADER_TCMOD_SCROLL: + t1 = tcmod->args[0] * r_localShaderTime; + t2 = tcmod->args[1] * r_localShaderTime; + + for ( j = 0; j < numVerts; j++, tcArray += 2 ) { + tcArray[0] = tcArray[0] + t1; + tcArray[1] = tcArray[1] + t2; + } + break; + + case SHADER_TCMOD_TRANSFORM: + for ( j = 0; j < numVerts; j++, tcArray += 2 ) { + t1 = tcArray[0]; + t2 = tcArray[1]; + tcArray[0] = t1 * tcmod->args[0] + t2 * tcmod->args[2] + tcmod->args[4]; + tcArray[1] = t2 * tcmod->args[1] + t1 * tcmod->args[3] + tcmod->args[5]; + } + break; + + default: + break; + } + } +} + + +#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist) +#define VectorScalef(a, b, c) c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b + +/* +================ +R_ModifyColor +================ +*/ +void R_ModifyColor ( meshbuffer_t *mb, shaderpass_t *pass ) +{ + int i, b; + float *table, c, a; + vec3_t t, v; + shader_t *shader; + qbyte *bArray, *vArray; + qboolean fogged, noArray; + shaderfunc_t *rgbgenfunc, *alphagenfunc; + + shader = mb->shader; + fogged = mb->fog && (shader->sort >= SHADER_SORT_UNDERWATER) && + !(pass->flags & SHADER_PASS_DEPTHWRITE) && !shader->fog_dist; + noArray = (pass->flags & SHADER_PASS_NOCOLORARRAY) && !fogged; + rgbgenfunc = &pass->rgbgen_func; + alphagenfunc = &pass->alphagen_func; + + if ( noArray ) { + numColors = 1; + } else { + numColors = numVerts; + } + + bArray = colorArray[0]; + vArray = inColorsArray[0]; + + switch (pass->rgbgen) + { + case RGB_GEN_IDENTITY: + memset ( bArray, 255, sizeof(byte_vec4_t)*numColors ); + break; + + case RGB_GEN_IDENTITY_LIGHTING: + memset ( bArray, r_identityLighting, sizeof(byte_vec4_t)*numColors ); + break; + + case RGB_GEN_CONST: + for ( i = 0; i < numColors; i++, bArray += 4 ) { + bArray[0] = FloatToByte (rgbgenfunc->args[0]); + bArray[1] = FloatToByte (rgbgenfunc->args[1]); + bArray[2] = FloatToByte (rgbgenfunc->args[2]); + } + break; + + case RGB_GEN_WAVE: + table = R_TableForFunc ( rgbgenfunc->type ); + c = rgbgenfunc->args[2] + r_localShaderTime * rgbgenfunc->args[3]; + c = FTABLE_EVALUATE ( table, c ) * rgbgenfunc->args[1] + rgbgenfunc->args[0]; + clamp ( c, 0.0f, 1.0f ); + + memset ( bArray, FloatToByte (c), sizeof(byte_vec4_t)*numColors ); + break; + + case RGB_GEN_ENTITY: + Con_Printf("RGB_GEN_ENTITY\n"); + break; +/* for ( i = 0; i < numColors; i++, bArray += 4 ) { + *(int *)bArray = *(int *)currententity->shaderRGBA; + } + break; +*/ + case RGB_GEN_ONE_MINUS_ENTITY: + Con_Printf("RGB_GEN_ONE_MINUS_ENTITY\n"); + break; +/* for ( i = 0; i < numColors; i++, bArray += 4 ) { + bArray[0] = 255 - currententity->shaderRGBA[0]; + bArray[1] = 255 - currententity->shaderRGBA[1]; + bArray[2] = 255 - currententity->shaderRGBA[2]; + } + break; +*/ + case RGB_GEN_VERTEX: + case RGB_GEN_EXACT_VERTEX: + memcpy ( bArray, vArray, sizeof(byte_vec4_t)*numColors ); + break; + + case RGB_GEN_ONE_MINUS_VERTEX: + for ( i = 0; i < numColors; i++, bArray += 4, vArray += 4 ) { + bArray[0] = 255 - vArray[0]; + bArray[1] = 255 - vArray[1]; + bArray[2] = 255 - vArray[2]; + } + break; + + case RGB_GEN_LIGHTING_DIFFUSE: + if ( !currententity ) + { + memset ( bArray, 255, sizeof(byte_vec4_t)*numColors ); + } + else + { + memcpy ( bArray, vArray, sizeof(byte_vec4_t)*numColors ); + /* + vec3_t dif, amb, dir; + cl.worldmodel->funcs.LightPointValues(currententity->origin, dif, amb, dir); + bArray[0] = dif[0]*255; + bArray[1] = dif[1]*255; + bArray[2] = dif[2]*255; + //R_LightForEntity ( currententity, bArray ); + */ + } + break; + + default: + break; + } + + bArray = colorArray[0]; + vArray = inColorsArray[0]; + + switch (pass->alphagen) + { + case ALPHA_GEN_IDENTITY: + for ( i = 0; i < numColors; i++, bArray += 4 ) { + bArray[3] = 255; + } + break; + + case ALPHA_GEN_CONST: + b = FloatToByte ( alphagenfunc->args[0] ); + + for ( i = 0; i < numColors; i++, bArray += 4 ) { + bArray[3] = b; + } + break; + + case ALPHA_GEN_WAVE: + table = R_TableForFunc ( alphagenfunc->type ); + a = alphagenfunc->args[2] + r_localShaderTime * alphagenfunc->args[3]; + a = FTABLE_EVALUATE ( table, a ) * alphagenfunc->args[1] + alphagenfunc->args[0]; + b = FloatToByte ( bound (0.0f, a, 1.0f) ); + + for ( i = 0; i < numColors; i++, bArray += 4 ) { + bArray[3] = b; + } + break; + + case ALPHA_GEN_PORTAL: + VectorAdd ( vertexArray[0], currententity->origin, v ); + VectorSubtract ( r_origin, v, t ); + a = VectorLength ( t ) * (1.0 / 255.0); + clamp ( a, 0.0f, 1.0f ); + b = FloatToByte ( a ); + + for ( i = 0; i < numColors; i++, bArray += 4 ) { + bArray[3] = b; + } + break; + + case ALPHA_GEN_VERTEX: + for ( i = 0; i < numColors; i++, bArray += 4, vArray += 4 ) { + bArray[3] = vArray[3]; + } + break; + + case ALPHA_GEN_ENTITY: + for ( i = 0; i < numColors; i++, bArray += 4 ) { + bArray[3] = currententity->alpha*255; + } + break; + + + case ALPHA_GEN_SPECULAR: + { + mat3_t axis; + AngleVectors(currententity->angles, axis[0], axis[1], axis[2]); + VectorSubtract ( r_origin, currententity->origin, t ); + + if ( !Matrix3_Compare (axis, axisDefault) ) { + Matrix3_Multiply_Vec3 ( axis, t, v ); + } else { + VectorCopy ( t, v ); + } + + for ( i = 0; i < numColors; i++, bArray += 4 ) { + VectorSubtract ( v, vertexArray[i], t ); + a = DotProduct( t, normalsArray[i] ) * Q_rsqrt ( DotProduct(t,t) ); + a = a * a * a * a * a; + bArray[3] = FloatToByte ( bound (0.0f, a, 1.0f) ); + } + } + break; + + } + + + if ( fogged ) + { + float dist, vdist; + mplane_t *fogplane; + vec3_t diff, viewtofog, fog_vpn; + + fogplane = mb->fog->visibleplane; + dist = PlaneDiff ( r_origin, fogplane ); + + if ( shader->flags & SHADER_SKY ) + { + if ( dist > 0 ) + VectorScale( fogplane->normal, -dist, viewtofog ); + else + VectorClear( viewtofog ); + } + else + { + VectorCopy ( currententity->origin, viewtofog ); + } + + VectorScalef ( vpn, mb->fog->shader->fog_dist, fog_vpn ); + + bArray = colorArray[0]; + for ( i = 0; i < numColors; i++, bArray += 4 ) + { + VectorAdd ( vertexArray[i], viewtofog, diff ); + + // camera is inside the fog + if ( dist < 0 ) { + VectorSubtract ( diff, r_origin, diff ); + + c = DotProduct ( diff, fog_vpn ); + a = (1.0f - bound ( 0, c, 1.0f )) * (1.0 / 255.0); + } else { + vdist = PlaneDiff ( diff, fogplane ); + + if ( vdist < 0 ) { + VectorSubtract ( diff, r_origin, diff ); + + c = vdist / ( vdist - dist ); + c *= DotProduct ( diff, fog_vpn ); + a = (1.0f - bound ( 0, c, 1.0f )) * (1.0 / 255.0); + } else { + a = 1.0 / 255.0; + } + } + + if ( pass->blendmode == GL_ADD || + ((pass->blendsrc == GL_ZERO) && (pass->blenddst == GL_ONE_MINUS_SRC_COLOR)) ) { + bArray[0] = FloatToByte ( (float)bArray[0]*a ); + bArray[1] = FloatToByte ( (float)bArray[1]*a ); + bArray[2] = FloatToByte ( (float)bArray[2]*a ); + } else { + bArray[3] = FloatToByte ( (float)bArray[3]*a ); + } + } + } +} + +/* +================ +R_SetShaderState +================ +*/ +void R_SetShaderState ( shader_t *shader ) +{ +// Face culling + if ( !gl_cull.value || (r_features & MF_NOCULL) ) + { + qglDisable ( GL_CULL_FACE ); + } + else + { + if ( shader->flags & SHADER_CULL_FRONT ) + { + qglEnable ( GL_CULL_FACE ); + qglCullFace ( GL_FRONT ); + } + else if ( shader->flags & SHADER_CULL_BACK ) + { + qglEnable ( GL_CULL_FACE ); + qglCullFace ( GL_BACK ); + } + else + { + qglDisable ( GL_CULL_FACE ); + } + } + + if ( shader->flags & SHADER_POLYGONOFFSET ) + { + qglEnable ( GL_POLYGON_OFFSET_FILL ); + } + else + { + qglDisable ( GL_POLYGON_OFFSET_FILL ); + } +} + +/* +================ +R_SetShaderpassState +================ +*/ +void R_SetShaderpassState ( shaderpass_t *pass, qboolean mtex ) +{ + if ( (mtex && (pass->blendmode != GL_REPLACE)) || (pass->flags & SHADER_PASS_BLEND) ) + { + qglEnable ( GL_BLEND ); + qglBlendFunc ( pass->blendsrc, pass->blenddst ); + } + else + { + qglDisable ( GL_BLEND ); + } + + if ( pass->flags & SHADER_PASS_ALPHAFUNC ) + { + qglEnable ( GL_ALPHA_TEST ); + + if ( pass->alphafunc == SHADER_ALPHA_GT0 ) + { + qglAlphaFunc ( GL_GREATER, 0 ); + } + else if ( pass->alphafunc == SHADER_ALPHA_LT128 ) + { + qglAlphaFunc ( GL_LESS, 0.5f ); + } + else if ( pass->alphafunc == SHADER_ALPHA_GE128 ) + { + qglAlphaFunc ( GL_GEQUAL, 0.5f ); + } + } + else + { + qglDisable ( GL_ALPHA_TEST ); + } + + // nasty hack!!! + if ( !gl_state.in2d ) + { + extern int gldepthfunc; + if (gldepthfunc == GL_LEQUAL) + qglDepthFunc ( pass->depthfunc ); + else + { + switch(pass->depthfunc) + { + case GL_LESS: + qglDepthFunc ( GL_GREATER ); + break; + case GL_LEQUAL: + qglDepthFunc ( GL_GEQUAL ); + break; + case GL_GREATER: + qglDepthFunc ( GL_LESS ); + break; + case GL_GEQUAL: + qglDepthFunc ( GL_LEQUAL ); + break; + + case GL_NEVER: + case GL_EQUAL: + case GL_ALWAYS: + case GL_NOTEQUAL: + default: + qglDepthFunc ( pass->depthfunc ); + } + } + + if ( pass->flags & SHADER_PASS_DEPTHWRITE ) + { + qglDepthMask ( GL_TRUE ); + } + else + { + qglDepthMask ( GL_FALSE ); + } + } +} + +/* +================ +R_RenderMeshGeneric +================ +*/ +void R_RenderMeshGeneric ( meshbuffer_t *mb, shaderpass_t *pass ) +{ + R_SetShaderpassState ( pass, false ); + R_ModifyTextureCoords ( pass, 0 ); + R_ModifyColor ( mb, pass ); + + if ( pass->blendmode == GL_REPLACE ) + GL_TexEnv( GL_REPLACE ); + else + GL_TexEnv ( GL_MODULATE ); + GL_Bind ( r_texNums[0] ); + + R_FlushArrays (); +} + +/* +================ +R_RenderMeshMultitextured +================ +*/ + +void R_RenderMeshMultitextured ( meshbuffer_t *mb, shaderpass_t *pass ) +{ + int i; + + r_numUnits = pass->numMergedPasses; + + R_SetShaderpassState ( pass, true ); + R_ModifyColor ( mb, pass ); + R_ModifyTextureCoords ( pass, 0 ); + + GL_SelectTexture( mtexid0 ); + if ( pass->blendmode == GL_REPLACE ) + GL_TexEnv( GL_REPLACE ); + else + GL_TexEnv( GL_MODULATE ); + + for ( i = 1, pass++; i < r_numUnits; i++, pass++ ) + { + GL_SelectTexture( mtexid0 + i ); + GL_TexEnv( pass->blendmode ); + R_ModifyTextureCoords ( pass, i ); + } + + R_FlushArraysMtex (); +} + +/* +================ +R_RenderMeshCombined +================ +*/ +void R_RenderMeshCombined ( meshbuffer_t *mb, shaderpass_t *pass ) +{ + int i; + + r_numUnits = pass->numMergedPasses; + + R_SetShaderpassState ( pass, true ); + R_ModifyColor ( mb, pass ); + + GL_SelectTexture( mtexid0 ); + R_ModifyTextureCoords ( pass, 0 ); + if ( pass->blendmode == GL_REPLACE ) + GL_TexEnv( GL_REPLACE ); + else + GL_TexEnv( GL_MODULATE ); + + for ( i = 1, pass++; i < r_numUnits; i++, pass++ ) + { + GL_SelectTexture( mtexid1 + i ); + + if ( pass->blendmode ) + { + switch ( pass->blendmode ) + { + case GL_REPLACE: + case GL_MODULATE: + case GL_ADD: + // these modes are best set with TexEnv, Combine4 would need much more setup + GL_TexEnv (pass->blendmode); + break; + + case GL_DECAL: + // mimics Alpha-Blending in upper texture stage, but instead of multiplying the alpha-channel, they´re added + // this way it can be possible to use GL_DECAL in both texture-units, while still looking good + // normal mutlitexturing would multiply the alpha-channel which looks ugly + GL_TexEnv (GL_COMBINE_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD); + + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA); + + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA); + + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA); + break; + } + } + else + { + GL_TexEnv (GL_COMBINE4_NV); + qglTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD); + qglTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD); + + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA); + + switch ( pass->blendsrc ) + { + case GL_ONE: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_ZERO); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA); + break; + case GL_ZERO: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_ZERO); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA); + break; + case GL_DST_COLOR: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA); + break; + case GL_ONE_MINUS_DST_COLOR: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA); + break; + case GL_SRC_ALPHA: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_ALPHA); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA); + break; + case GL_ONE_MINUS_SRC_ALPHA: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_ALPHA); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA); + break; + case GL_DST_ALPHA: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_ALPHA); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA); + break; + case GL_ONE_MINUS_DST_ALPHA: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_ALPHA); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA); + break; + } + + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA); + + switch (pass->blenddst) + { + case GL_ONE: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_ZERO); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_ONE_MINUS_SRC_ALPHA); + break; + case GL_ZERO: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_ZERO); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_ALPHA); + break; + case GL_SRC_COLOR: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_ALPHA); + break; + case GL_ONE_MINUS_SRC_COLOR: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_ONE_MINUS_SRC_ALPHA); + break; + case GL_SRC_ALPHA: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_ALPHA); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_ALPHA); + break; + case GL_ONE_MINUS_SRC_ALPHA: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_ALPHA); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_TEXTURE); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_ONE_MINUS_SRC_ALPHA); + break; + case GL_DST_ALPHA: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_ALPHA); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_ALPHA); + break; + case GL_ONE_MINUS_DST_ALPHA: + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_ALPHA); + qglTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_PREVIOUS_EXT); + qglTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_ONE_MINUS_SRC_ALPHA); + break; + } + } + + R_ModifyTextureCoords ( pass, i ); + } + + R_FlushArraysMtex (); +} + +/* +================ +R_RenderMeshBuffer +================ +*/ +void R_RenderMeshBuffer ( meshbuffer_t *mb, qboolean shadowpass ) +{ + int i; + shader_t *shader; + shaderpass_t *pass; + + if ( !numVerts ) { + return; + } + + shader = mb->shader; + r_lmtex = mb->infokey; + +#ifdef FIZME + if ( currententity && !gl_state.in2d ) { + r_localShaderTime = r_refdef.time * 0.001f - currententity->shaderTime; + } else { + r_localShaderTime = Sys_Milliseconds() * 0.001f; + } +#else + r_localShaderTime = realtime; #endif + + R_SetShaderState ( shader ); + + if ( shader->numdeforms ) { + R_DeformVertices ( mb ); + } + + if ( !numIndexes || shadowpass ) { + return; + } + + R_LockArrays ( numVerts ); + + for ( i = 0, pass = shader->passes; i < shader->numpasses; ) + { + if ( !(pass->flags & SHADER_PASS_DETAIL) || r_detailtextures.value ) { + pass->flush ( mb, pass ); + } + + i += pass->numMergedPasses; + pass += pass->numMergedPasses; + } + + R_FinishMeshBuffer ( mb ); +} + + +/* +================ +R_RenderFogOnMesh +================ +*/ + +int r_fogtexture; +#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist) +void R_RenderFogOnMesh ( shader_t *shader, struct mfog_s *fog ) +{ +#define FOG_TEXTURE_HEIGHT 32 + + int i; + vec3_t diff, viewtofog, fog_vpn; + float dist, vdist; + shader_t *fogshader; + mplane_t *fogplane; + + if ( !fog->numplanes || !fog->shader || !fog->visibleplane ) + { + return; + } + + R_ResetTexState (); + + fogshader = fog->shader; + fogplane = fog->visibleplane; + + GL_Bind( r_fogtexture ); + + qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + + if ( !shader->numpasses || shader->fog_dist || (shader->flags & SHADER_SKY) ) + { + qglDepthFunc ( GL_LEQUAL ); + } + else + { + qglDepthFunc ( GL_EQUAL ); + } + + qglColor4ubv ( fogshader->fog_color ); + + // distance to fog + dist = PlaneDiff ( r_origin, fogplane ); + + if ( shader->flags & SHADER_SKY ) + { + if ( dist > 0 ) + VectorMA( r_origin, -dist, fogplane->normal, viewtofog ); + else + VectorCopy( r_origin, viewtofog ); + } + else + { + VectorCopy( currententity->origin, viewtofog ); + } + + VectorScale ( vpn, fogshader->fog_dist, fog_vpn ); + + for ( i = 0; i < numVerts; i++, currentCoords += 2 ) + { + VectorAdd ( viewtofog, vertexArray[i], diff ); + vdist = PlaneDiff ( diff, fogplane ); + VectorSubtract ( diff, r_origin, diff ); + + if ( dist < 0 ) + { // camera is inside the fog brush + currentCoords[0] = DotProduct ( diff, fog_vpn ); + } + else + { + if ( vdist < 0 ) + { + currentCoords[0] = vdist / ( vdist - dist ); + currentCoords[0] *= DotProduct ( diff, fog_vpn ); + } + else + { + currentCoords[0] = 0.0f; + } + } + + currentCoords[1] = -vdist * fogshader->fog_dist + 1.5f/(float)FOG_TEXTURE_HEIGHT; + } + + if ( !shader->numpasses ) + { + R_LockArrays ( numVerts ); + } + + R_FlushArrays (); +} + +/* +================ +R_DrawTriangleOutlines +================ +*/ +void R_DrawTriangleOutlines (void) +{ + R_ResetTexState (); + + qglDisable( GL_TEXTURE_2D ); + qglDisable( GL_DEPTH_TEST ); + qglColor4f( 1, 1, 1, 1 ); + qglDisable ( GL_BLEND ); + qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + R_FlushArrays (); + + qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + qglEnable( GL_DEPTH_TEST ); + qglEnable( GL_TEXTURE_2D ); +} + +/* +================ +R_DrawNormals +================ +*/ +void R_DrawNormals (void) +{ + int i; + + R_ResetTexState (); + + qglDisable( GL_TEXTURE_2D ); + qglColor4f( 1, 1, 1, 1 ); + qglDisable( GL_BLEND ); + + if ( gl_state.in2d ) { + qglBegin ( GL_POINTS ); + for ( i = 0; i < numVerts; i++ ) { + qglVertex3fv ( vertexArray[i] ); + } + qglEnd (); + } else { + qglDisable( GL_DEPTH_TEST ); + qglBegin ( GL_LINES ); + for ( i = 0; i < numVerts; i++ ) { + qglVertex3fv ( vertexArray[i] ); + qglVertex3f ( vertexArray[i][0] + normalsArray[i][0], + vertexArray[i][1] + normalsArray[i][1], + vertexArray[i][2] + normalsArray[i][2] ); + } + qglEnd (); + qglEnable( GL_DEPTH_TEST ); + } + + qglEnable( GL_TEXTURE_2D ); +} + +/* +================ +R_FinishMeshBuffer +Render dynamic lights, fog, triangle outlines, normals and clear arrays +================ +*/ +void R_FinishMeshBuffer ( meshbuffer_t *mb ) +{ + shader_t *shader; + qboolean fogged; + qboolean dlight; + + shader = mb->shader; + dlight = (mb->dlightbits != 0) && !(shader->flags & SHADER_FLARE); + fogged = mb->fog && ((shader->sort < SHADER_SORT_UNDERWATER && + (shader->flags & (SHADER_DEPTHWRITE|SHADER_SKY))) || shader->fog_dist); + + if ( dlight || fogged ) { + GL_DisableMultitexture ( ); + qglTexCoordPointer( 2, GL_FLOAT, 0, inCoordsArray[0] ); + + qglEnable ( GL_BLEND ); + qglDisable ( GL_ALPHA_TEST ); + qglDepthMask ( GL_FALSE ); + +//FIZME +// if ( dlight ) { +// R_AddDynamicLights ( mb ); +// } + + if ( fogged ) { + R_RenderFogOnMesh ( shader, mb->fog ); + } + } + + if ( r_showtris.value || r_shownormals.value ) { + GL_DisableMultitexture ( ); + + if ( r_showtris.value ) { + R_DrawTriangleOutlines (); + } + + if ( r_shownormals.value ) { + R_DrawNormals (); + } + } + + R_UnlockArrays (); + R_ClearArrays (); +} + +#endif + + + + + + + +#endif \ No newline at end of file diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 8a354a794..c63141c73 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -41,7 +41,7 @@ int sizeofuploadmemorybuffer; qbyte *uploadmemorybufferintermediate; int sizeofuploadmemorybufferintermediate; -int r_quad_indexes[6] = {0, 1, 2, 0, 2, 3}; +index_t r_quad_indexes[6] = {0, 1, 2, 0, 2, 3}; extern qbyte gammatable[256]; @@ -62,8 +62,6 @@ extern cvar_t gl_savecompressedtex; extern cvar_t gl_load24bit; -extern qboolean gl_compressable; - qbyte *draw_chars; // 8*8 graphic characters qpic_t *draw_disc; qpic_t *draw_backtile; @@ -110,25 +108,6 @@ typedef struct gltexture_s } gltexture_t; static gltexture_t *gltextures; - -void GL_Bind (int texnum) -{ - if (gl_nobind.value) - texnum = char_texture; - if (currenttexture == texnum) - return; - currenttexture = texnum; - - bindTexFunc (GL_TEXTURE_2D, texnum); -} -void GL_BindType (int type, int texnum) -{ - bindTexFunc (type, texnum); - -currenttexture=-1; -} - - /* ============================================================================= @@ -615,6 +594,46 @@ void GLDraw_TextureMode_f (void) } } +#ifdef Q3SHADERS +#define FOG_TEXTURE_WIDTH 32 +#define FOG_TEXTURE_HEIGHT 32 +extern int r_fogtexture; +void GL_InitFogTexture (void) +{ + qbyte data[FOG_TEXTURE_WIDTH*FOG_TEXTURE_HEIGHT]; + int x, y; + float tw = 1.0f / ((float)FOG_TEXTURE_WIDTH - 1.0f); + float th = 1.0f / ((float)FOG_TEXTURE_HEIGHT - 1.0f); + float tx, ty, t; + + if (r_fogtexture) + return; + + // + // fog texture + // + for ( y = 0, ty = 0.0f; y < FOG_TEXTURE_HEIGHT; y++, ty += th ) + { + for ( x = 0, tx = 0.0f; x < FOG_TEXTURE_WIDTH; x++, tx += tw ) + { + t = (float)(sqrt( tx ) * 255.0); + data[x+y*FOG_TEXTURE_WIDTH] = (qbyte)(min( t, 255.0f )); + } + + data[y] = 0; + } + + r_fogtexture = texture_extension_number++; + GL_Bind(r_fogtexture); + qglTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, FOG_TEXTURE_WIDTH, FOG_TEXTURE_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); + + qglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); + qglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + + qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); +} +#endif /* =============== Draw_Init @@ -660,8 +679,11 @@ void GLDraw_ReInit (void) skyboxtex[0] = 0; skyboxtex[1] = 0; skyboxtex[2] = 0; skyboxtex[3] = 0; skyboxtex[4] = 0; skyboxtex[5] = 0; lightmap_textures=0; filmtexture=0; - currenttexture=0; glmenu_numcachepics=0; +#ifdef Q3SHADERS + r_fogtexture=0; +#endif + GL_FlushBinds(); // GL_FlushSkinCache(); TRACE(("dbg: GLDraw_ReInit: GL_GAliasFlushSkinCache\n")); GL_GAliasFlushSkinCache(); @@ -784,6 +806,11 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); TRACE(("dbg: GLDraw_ReInit: GL_EndRendering\n")); GL_EndRendering (); + +#ifdef Q3SHADERS + Shader_Init(); +#endif + //now emit the conchars picture as if from a wad. strcpy(glmenu_cachepics[glmenu_numcachepics].name, "conchars"); glmenu_cachepics[glmenu_numcachepics].pic.width = 128; @@ -990,7 +1017,7 @@ void GLDraw_Init (void) memset(scrap_allocated, 0, sizeof(scrap_allocated)); - GLR_MeshInit(); + R_BackendInit(); Cmd_AddRemCommand ("gl_texturemode", &GLDraw_TextureMode_f); @@ -1007,6 +1034,7 @@ void GLDraw_Init (void) draw_mesh.normals_array = draw_mesh_normals; draw_mesh.st_array = draw_mesh_st; draw_mesh.lmst_array = draw_mesh_lmst; + } void GLDraw_DeInit (void) { @@ -1021,6 +1049,10 @@ void GLDraw_DeInit (void) uploadmemorybufferintermediate = NULL; sizeofuploadmemorybuffer = 0; //and give a nice safe sys_error if we try using it. sizeofuploadmemorybufferintermediate = 0; + +#ifdef Q3SHADERS + Shader_Shutdown(); +#endif } @@ -1075,13 +1107,12 @@ void GLDraw_Character (int x, int y, unsigned int num) draw_mesh_st[3][0] = fcol; draw_mesh_st[3][1] = frow+size; +#ifndef Q3SHADERS if (num&CON_2NDCHARSETTEXT) GL_DrawMesh(&draw_mesh, NULL, char_tex2, 0); else GL_DrawMesh(&draw_mesh, NULL, char_texture, 0); -return; - - +#else if (num&CON_2NDCHARSETTEXT) GL_Bind (char_tex2); @@ -1107,6 +1138,8 @@ return; glTexCoord2f (fcol, frow + size); glVertex2f (x, y+8); glEnd (); + +#endif } void GLDraw_ColouredCharacter (int x, int y, unsigned int num) @@ -1269,6 +1302,7 @@ void GLDraw_Pic (int x, int y, qpic_t *pic) Scrap_Upload (); gl = (glpic_t *)pic->data; +#ifndef Q3SHADERS draw_mesh_xyz[0][0] = x; draw_mesh_xyz[0][1] = y; draw_mesh_st[0][0] = gl->sl; @@ -1290,8 +1324,8 @@ void GLDraw_Pic (int x, int y, qpic_t *pic) draw_mesh_st[3][1] = gl->th; GL_DrawMesh(&draw_mesh, NULL, gl->texnum, 0); +#else -/* glColor4f (1,1,1,1); GL_Bind (gl->texnum); glBegin (GL_QUADS); @@ -1304,7 +1338,7 @@ void GLDraw_Pic (int x, int y, qpic_t *pic) glTexCoord2f (gl->sl, gl->th); glVertex2f (x, y+pic->height); glEnd (); - */ +#endif } void GLDraw_LevelPic (qpic_t *pic) //Fullscreen and stuff @@ -1404,7 +1438,11 @@ void GLDraw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int draw_mesh_st[3][0] = newsl; draw_mesh_st[3][1] = newth; +#ifdef Q3SHADERS + GL_DrawAliasMesh(&draw_mesh, gl->texnum); +#else GL_DrawMesh(&draw_mesh, NULL, gl->texnum, 0); +#endif } /* @@ -1665,7 +1703,11 @@ void GLDraw_Image(float x, float y, float w, float h, float s1, float t1, float draw_mesh_st[3][0] = s1; draw_mesh_st[3][1] = t2; +#ifdef Q3SHADERS + GL_DrawAliasMesh(&draw_mesh, gl->texnum); +#else GL_DrawMesh(&draw_mesh, NULL, gl->texnum, 0); +#endif } //============================================================================= @@ -2192,7 +2234,7 @@ qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_height, unsi int nummips; #define GETVAR(var) memcpy(var, file, sizeof(*var));file+=sizeof(*var); - if (!gl_compressable || !gl_compress.value) + if (!gl_config.arb_texture_compression || !gl_compress.value) return false; GETVAR(&nummips) @@ -2227,9 +2269,6 @@ qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_height, unsi return true; } -qboolean supported_GL_ARB_texture_non_power_of_two; -qboolean supported_GL_SGIS_generate_mipmap; - /* =============== GL_Upload32 @@ -2244,7 +2283,7 @@ void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean m TRACE(("dbg: GL_Upload32: %s %i %i\n", name, width, height)); - if (supported_GL_ARB_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors. + if (gl_config.arb_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors. { TRACE(("dbg: GL_Upload32: GL_ARB_texture_non_power_of_two\n")); scaled_width = width; @@ -2282,7 +2321,7 @@ void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean m Sys_Error ("GL_LoadTexture: too big"); samples = alpha ? gl_alpha_format : gl_solid_format; - if (gl_compressable && gl_compress.value && name&&mipmap) + if (gl_config.arb_texture_compression && gl_compress.value && name&&mipmap) samples = alpha ? GL_COMPRESSED_RGBA_ARB : GL_COMPRESSED_RGB_ARB; #if 0 @@ -2299,7 +2338,7 @@ void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean m #else texels += scaled_width * scaled_height; - if (supported_GL_SGIS_generate_mipmap&&mipmap) + if (gl_config.sgis_generate_mipmap&&mipmap) { TRACE(("dbg: GL_Upload32: GL_SGIS_generate_mipmap\n")); glTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); @@ -2307,7 +2346,7 @@ texels += scaled_width * scaled_height; if (scaled_width == width && scaled_height == height) { - if (!mipmap||supported_GL_SGIS_generate_mipmap) //gotta love this with NPOT textures... :) + if (!mipmap||gl_config.sgis_generate_mipmap) //gotta love this with NPOT textures... :) { TRACE(("dbg: GL_Upload32: non-mipmapped/unscaled\n")); glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); @@ -2320,7 +2359,7 @@ texels += scaled_width * scaled_height; TRACE(("dbg: GL_Upload32: recaled\n")); glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - if (mipmap && !supported_GL_SGIS_generate_mipmap) + if (mipmap && !gl_config.sgis_generate_mipmap) { miplevel = 0; TRACE(("dbg: GL_Upload32: mips\n")); @@ -2337,7 +2376,7 @@ texels += scaled_width * scaled_height; glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); } } - if (gl_compressable && gl_compress.value && gl_savecompressedtex.value && name&&mipmap) + if (gl_config.arb_texture_compression && gl_compress.value && gl_savecompressedtex.value && name&&mipmap) { FILE *out; int miplevels; @@ -2390,7 +2429,7 @@ texels += scaled_width * scaled_height; } } done: - if (supported_GL_SGIS_generate_mipmap&&mipmap) + if (gl_config.sgis_generate_mipmap&&mipmap) glTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE); #endif @@ -2413,7 +2452,7 @@ void GL_Upload8Grey (unsigned char*data, int width, int height, qboolean mipmap unsigned char *scaled = uploadmemorybuffer; int scaled_width, scaled_height; - if (supported_GL_ARB_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors. + if (gl_config.arb_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors. { TRACE(("dbg: GL_Upload32: GL_ARB_texture_non_power_of_two\n")); scaled_width = width; @@ -2629,7 +2668,7 @@ void GL_UploadBump(qbyte *data, int width, int height, qboolean mipmap) { s = width*height; //Resize to power of 2 and maximum texture size - if (supported_GL_ARB_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors. + if (gl_config.arb_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors. { TRACE(("dbg: GL_Upload32: GL_ARB_texture_non_power_of_two\n")); scaled_width = width; @@ -3187,7 +3226,7 @@ int GL_LoadCompressed(char *name) gltexture_t *glt; char inname[MAX_OSPATH]; - if (!gl_compressable || !gl_compress.value) + if (!gl_config.arb_texture_compression || !gl_compress.value) return 0; @@ -3321,10 +3360,3 @@ int GL_LoadPicTexture (qpic_t *pic) } /****************************************/ - -void GL_SelectTexture (GLenum target) -{ - if (!gl_mtexable) - return; - qglSelectTextureSGIS(target); -} diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 39ddc0497..e7fea9251 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -1217,6 +1217,7 @@ Mod_LoadLighting void GLMod_LoadLighting (lump_t *l) { qbyte *luxdata = NULL; + int mapcomeswith24bitcolouredlighting = false; loadmodel->rgblighting = false; //lit file light intensity is made to match the world's light intensity. @@ -1232,7 +1233,10 @@ void GLMod_LoadLighting (lump_t *l) return; } - if (r_loadlits.value && gl_bumpmappingpossible) //fixme: adjust the light intensities. + if (loadmodel->fromgame == fg_halflife || loadmodel->fromgame == fg_quake2 || loadmodel->fromgame == fg_quake3) + mapcomeswith24bitcolouredlighting = true; + + if (!mapcomeswith24bitcolouredlighting && r_loadlits.value && gl_bumpmappingpossible) //fixme: adjust the light intensities. { //the map util has a '-scalecos X' parameter. use 0 if you're going to use only just lux. without lux scalecos 0 is hideous. char luxname[MAX_QPATH]; if (!luxdata) @@ -1280,7 +1284,7 @@ void GLMod_LoadLighting (lump_t *l) } } - if (r_loadlits.value) + if (!mapcomeswith24bitcolouredlighting && r_loadlits.value) { qbyte *litdata = NULL; char *litname; @@ -1364,11 +1368,11 @@ void GLMod_LoadLighting (lump_t *l) // else //failed to find } - if (loadmodel->fromgame == fg_halflife || loadmodel->fromgame == fg_quake2 || loadmodel->fromgame == fg_quake3) + if (mapcomeswith24bitcolouredlighting) loadmodel->rgblighting = true; #ifdef RUNTIMELIGHTING - if (r_loadlits.value == 2 && !lightmodel && (loadmodel->rgblighting != true || (!luxdata && gl_bumpmappingpossible))) + else if (r_loadlits.value == 2 && !lightmodel && (loadmodel->rgblighting != true || (!luxdata && gl_bumpmappingpossible))) { qbyte *litdata = NULL; int i; diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 60036d645..c4a32b47f 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -46,7 +46,7 @@ typedef struct { int (*LeafForPoint) (vec3_t point, struct model_s *model); } bspfuncs_t; - +typedef int index_t; typedef struct mesh_s { int numvertexes; @@ -57,7 +57,7 @@ typedef struct mesh_s byte_vec4_t *colors_array; int numindexes; - int *indexes; + index_t *indexes; int *trneighbors; vec3_t *trnormals; @@ -144,6 +144,9 @@ typedef struct texture_s int gl_texturenumfb; int gl_texturenumbumpmap; int gl_texturenumspec; + + struct shader_s *shader; + struct msurface_s *texturechain; // for gl_texsort drawing int anim_total; // total tenths in sequence ( 0 = no) int anim_min, anim_max; // time for this frame min <=time< max @@ -200,6 +203,18 @@ typedef struct glpoly_s float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2 (ldir_xyz) } glpoly_t; +#ifdef Q3SHADERS +typedef struct mfog_s +{ + struct shader_s *shader; + + mplane_t *visibleplane; + + int numplanes; + mplane_t **planes; +} mfog_t; +#endif + typedef struct msurface_s { int visframe; // should be drawn when node is crossed @@ -221,6 +236,9 @@ typedef struct msurface_s int light_s, light_t; // gl lightmap coordinates +#ifdef Q3SHADERS + mfog_t *fog; +#endif mesh_t *mesh; entity_t *ownerent; glpoly_t *polys; // multiple if warped diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index 9dd23a4c2..af4b01b81 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -1,6 +1,7 @@ #include "quakedef.h" #ifdef RGLQUAKE #include "glquake.h" +#include "shader.h" //these are shared with gl_rsurf - move to header void R_MirrorChain (msurface_t *s); @@ -326,7 +327,7 @@ static void PPL_BaseChain_NoBump_2TMU(msurface_t *s, texture_t *tex) qglClientActiveTextureARB(GL_TEXTURE1_ARB); qglActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stl); @@ -440,7 +441,7 @@ static void PPL_BaseChain_Bump_2TMU(msurface_t *first, texture_t *tex) qglActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); vi = -1; for (s=first; s ; s=s->texturechain) @@ -515,7 +516,7 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) qglActiveTextureARB(GL_TEXTURE3_ARB); glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); qglClientActiveTextureARB(GL_TEXTURE3_ARB); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -836,7 +837,7 @@ void PPL_LoadSpecularFragmentProgram(void) //multiply by inverse lm and output the result. - "SUB lm.rgb, 1, lm;\n" +// "SUB lm.rgb, 1, lm;\n" "MUL_SAT ocol.rgb, diff, lm;\n" //that's all folks. "END"; @@ -854,7 +855,7 @@ void PPL_LoadSpecularFragmentProgram(void) varray_i_polytotri[i*3+2] = i+2; } - if (!gl_arb_fragment_program) + if (!gl_config.arb_fragment_program) return; glEnable(GL_FRAGMENT_PROGRAM_ARB); @@ -1232,8 +1233,90 @@ static void PPL_BaseTextureChain(msurface_t *first) { extern cvar_t gl_bump, gl_specular; texture_t *t; +#ifdef Q3SHADERS + if (first->texinfo->texture->shader) + { + meshbuffer_t mb; + msurface_t *s; + int vi=-1; + glRect_t *theRect; +// GL_PushShader(first->texinfo->texture->shader); + if (first->texinfo->texture->shader->flags & SHADER_FLARE ) + return; + + GL_DisableMultitexture(); + + glShadeModel(GL_SMOOTH); + + { + for (s = first; s ; s=s->texturechain) + { + if (vi != s->lightmaptexturenum) + { + vi = s->lightmaptexturenum; + if (vi >= 0) + { + GL_BindType(GL_TEXTURE_2D, deluxmap_textures[vi] ); + if (lightmap[vi]->deluxmodified) + { + lightmap[vi]->deluxmodified = false; + theRect = &lightmap[vi]->deluxrectchange; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, + LMBLOCK_WIDTH, theRect->h, GL_RGB, GL_UNSIGNED_BYTE, + lightmap[vi]->deluxmaps+(theRect->t) *LMBLOCK_WIDTH*3); + theRect->l = LMBLOCK_WIDTH; + theRect->t = LMBLOCK_HEIGHT; + theRect->h = 0; + theRect->w = 0; + } + GL_BindType(GL_TEXTURE_2D, lightmap_textures[vi] ); + if (lightmap[vi]->modified) + { + lightmap[vi]->modified = false; + theRect = &lightmap[vi]->rectchange; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, + LMBLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE, + lightmap[vi]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*lightmap_bytes); + theRect->l = LMBLOCK_WIDTH; + theRect->t = LMBLOCK_HEIGHT; + theRect->h = 0; + theRect->w = 0; + } + } + } + if (!s->mesh) + { + Con_Printf("Shaded surface with no mesh\n"); + } + else + { + /* MF_NONE = 1<<0, + MF_NORMALS = 1<<1, + MF_TRNORMALS = 1<<2, + MF_COLORS = 1<<3, + MF_STCOORDS = 1<<4, + MF_LMCOORDS = 1<<5, + MF_NOCULL = 1<<6*/ + + mb.entity = &r_worldentity; + mb.shader = first->texinfo->texture->shader; + mb.fog = s->fog; + mb.mesh = s->mesh; + mb.infokey = vi; + mb.dlightbits = 0; + R_PushMesh(s->mesh, mb.shader->features); + + R_RenderMeshBuffer ( &mb, false ); +// GL_PushMesh(s->mesh, deluxmap_textures[vi], lightmap_textures[vi]); + } + } + } +// GL_PushShader(NULL); //fixme: remove the need. + return; + } +#endif glEnable(GL_TEXTURE_2D); t = GLR_TextureAnimation (first->texinfo->texture); @@ -2972,7 +3055,7 @@ void PPL_AddLight(dlight_t *dl) sincrw = GL_INCR; sdecrw = GL_DECR; - if (gl_ext_stencil_wrap) + if (gl_config.ext_stencil_wrap) { //minamlise damage... sincrw = GL_INCR_WRAP_EXT; sdecrw = GL_DECR_WRAP_EXT; @@ -3050,7 +3133,6 @@ void PPL_AddLight(dlight_t *dl) glEnable(GL_CULL_FACE); - glStencilFunc( GL_EQUAL, 0, ~0 ); qglActiveStencilFaceEXT(GL_BACK); glStencilFunc( GL_EQUAL, 0, ~0 ); } @@ -3059,6 +3141,8 @@ void PPL_AddLight(dlight_t *dl) glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); + glEnable(GL_CULL_FACE); + glStencilFunc( GL_ALWAYS, 1, ~0 ); glCullFace(GL_BACK); @@ -3113,10 +3197,12 @@ void PPL_DrawWorld (void) // if (qglGetError()) // Con_Printf("GL Error before world\n"); //glColorMask(0,0,0,0); + TRACE(("dbg: calling PPL_BaseTextures\n")); PPL_BaseTextures(cl.worldmodel); // if (qglGetError()) // Con_Printf("GL Error during base textures\n"); //glColorMask(1,1,1,1); + TRACE(("dbg: calling PPL_BaseEntTextures\n")); PPL_BaseEntTextures(); // CL_NewDlightRGB(1, r_refdef.vieworg[0], r_refdef.vieworg[1]-16, r_refdef.vieworg[2]-24, 128, 1, 1, 1, 1); @@ -3151,6 +3237,7 @@ void PPL_DrawWorld (void) l->color[1]*=2.5; l->color[2]*=2.5; + TRACE(("dbg: calling PPL_AddLight\n")); PPL_AddLight(l); l->color[0]/=2.5; l->color[1]/=2.5; @@ -3166,6 +3253,7 @@ void PPL_DrawWorld (void) // if (qglGetError()) // Con_Printf("GL Error on shadow lighting\n"); + TRACE(("dbg: calling PPL_DrawEntFullBrights\n")); PPL_DrawEntFullBrights(); // if (qglGetError()) diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 973f3aa3d..cbd5496a9 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -55,9 +55,6 @@ int c_brush_polys, c_alias_polys; qboolean envmap; // true during envmap command capture -int currenttexture = -1; // to avoid unnecessary texture sets - - int particletexture; // little dot for particles int explosiontexture; int playertextures; // up to 16 color translated skins @@ -122,6 +119,7 @@ cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"}; cvar_t gl_finish = {"gl_finish","0"}; cvar_t gl_contrast = {"gl_contrast", "1"}; cvar_t gl_dither = {"gl_dither", "1"}; +cvar_t gl_maxdist = {"gl_maxdist", "8192"}; extern cvar_t gl_ati_truform; extern cvar_t gl_ati_truform_type; @@ -1113,7 +1111,7 @@ void R_SetupGL (void) // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI; // MYgluPerspective (yfov, screenaspect, 4, 4096); - MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 4096); + MYgluPerspective (r_refdef.fov_y, screenaspect, 4, gl_maxdist.value); } else { @@ -1209,8 +1207,10 @@ void R_RenderScene (void) if (!mirror) GLR_SetupFrame (); + TRACE(("dbg: calling R_SetFrustrum\n")); R_SetFrustum (); + TRACE(("dbg: calling R_SetupGL\n")); R_SetupGL (); if (!(r_refdef.flags & 1)) @@ -1219,23 +1219,31 @@ void R_RenderScene (void) if (!GLR_DoomWorld ()) #endif { + TRACE(("dbg: calling GLR_MarkLeaves\n")); GLR_MarkLeaves (); // done here so we know if we're in water + TRACE(("dbg: calling R_DrawWorld\n")); R_DrawWorld (); // adds static entities to the list } } S_ExtraUpdate (); // don't let sound get messed up if going slow + TRACE(("dbg: calling GLR_DrawEntitiesOnList\n")); GLR_DrawEntitiesOnList (); // R_DrawDecals(); + TRACE(("dbg: calling GL_DisableMultitexture\n")); GL_DisableMultitexture(); + TRACE(("dbg: calling R_RenderDlights\n")); R_RenderDlights (); if (cl.worldmodel) + { + TRACE(("dbg: calling R_DrawParticles\n")); R_DrawParticles (); + } #ifdef GLTEST Test_Draw (); diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index ef8fc860e..950225f9a 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -941,6 +941,7 @@ void GLR_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap * // bound, invert, and shift store: +#ifdef INVERTLIGHTMAPS switch (gl_lightmap_format) { #ifdef PEXT_LIGHTSTYLECOL @@ -1293,6 +1294,360 @@ store: default: Sys_Error ("Bad lightmap format"); } +#else + switch (gl_lightmap_format) + { +#ifdef PEXT_LIGHTSTYLECOL + case GL_RGBA: + stride -= (smax<<2); + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + + if (!r_stains.value) + isstained = false; + else + isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 0; + else if (t < 0) + dest[0] = 256; + else + dest[0] = (255-t); + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 0; + else if (t < 0) + dest[1] = 256; + else + dest[1] = (255-t); + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 0; + else if (t < 0) + dest[2] = 256; + else + dest[2] = (255-t); + + dest[3] = 0;//(dest[0]+dest[1]+dest[2])/3; + dest += 4; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= 7; + + g = *blg++; + g >>= 7; + + b = *blb++; + b >>= 7; + + if (isstained) //do we need to add the stain? + { + r += *stain++; + g += *stain++; + b += *stain++; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + //* + if ((r+cr) > 255) + dest[0] = 0; //inverse lighting + else if ((r+cr) < 0) + dest[0] = 255; + else + dest[0] = 255-(r+cr); + + if ((g+cg) > 255) + dest[1] = 0; + else if ((g+cg) < 0) + dest[1] = 255; + else + dest[1] = 255-(g+cg); + + if ((b+cb) > 255) + dest[2] = 0; + else if ((b+cb) < 0) + dest[2] = 255; + else + dest[2] = 255-(b+cb); +/*/ + if ((r+cr) > 255) + dest[0] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[0] = 0; + else + dest[0] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[2] = 255; + else if ((b+cb) < 0) + dest[2] = 0; + else + dest[2] = (b+cb); +*/ + + + + dest[3] = (dest[0]+dest[1]+dest[2])/3; //alpha?!?! + dest += 4; + } + } + } + break; + + case GL_RGB: + stride -= smax*3; + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + + if (!r_stains.value) + isstained = false; + else + isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 255; + else if (t < 0) + dest[0] = 0; + else + dest[0] = t; + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 255; + else if (t < 0) + dest[1] = 0; + else + dest[1] = t; + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 255; + else if (t < 0) + dest[2] = 0; + else + dest[2] = t; + + dest += 3; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= 7; + + g = *blg++; + g >>= 7; + + b = *blb++; + b >>= 7; + + if (isstained) //do we need to add the stain? + { + r += *stain++; + g += *stain++; + b += *stain++; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + //* + if ((r+cr) > 255) + dest[0] = 255; //inverse lighting + else if ((r+cr) < 0) + dest[0] = 0; + else + dest[0] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[2] = 255; + else if ((b+cb) < 0) + dest[2] = 0; + else + dest[2] = (b+cb); +/*/ + if ((r+cr) > 255) + dest[0] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[0] = 0; + else + dest[0] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[2] = 255; + else if ((b+cb) < 0) + dest[2] = 0; + else + dest[2] = (b+cb); +// */ + dest += 3; + } + } + } + break; +#else + case GL_RGBA: + stride -= (smax<<2); + bl = blocklights; + for (i=0 ; i>= 7; + if (t > 255) + t = 255; + dest[3] = t; + dest += 4; + } + } + break; +#endif + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + bl = blocklights; + for (i=0 ; i>= 7; + if (t > 255) + t = 255; + dest[j] = t; + } + } + break; + default: + Sys_Error ("Bad lightmap format"); + } +#endif } /* @@ -2796,7 +3151,6 @@ void R_DrawWorld (void) VectorCopy (r_refdef.vieworg, modelorg); currententity = &ent; - currenttexture = -1; #ifdef TERRAINMAPS if (ent.model->type == mod_terrain) @@ -2836,6 +3190,7 @@ void R_DrawWorld (void) #endif GLR_RecursiveWorldNode (cl.worldmodel->nodes); + TRACE(("dbg: calling PPL_DrawWorld\n")); // if (r_shadows.value >= 2 && gl_canstencil && gl_mtexable) PPL_DrawWorld(); // else diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index 4b3f5de85..d12a7b6a1 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -215,6 +215,9 @@ void GLSCR_UpdateScreen (void) Sbar_FinaleOverlay (); SCR_CheckDrawCenterString (); } + else if (cl.intermission == 3 && key_dest == key_game) + { + } else { Draw_Crosshair(); diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 8c0f08ccf..f4b19e887 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -67,6 +67,7 @@ void (APIENTRY *qglViewport) (GLint x, GLint y, GLsizei width, GLsizei height); void (APIENTRY *qglGetTexLevelParameteriv) (GLenum target, GLint level, GLenum pname, GLint *params); void (APIENTRY *qglDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +void (APIENTRY *qglArrayElement) (GLint i); void (APIENTRY *qglVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *qglNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer); void (APIENTRY *qglTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); @@ -86,7 +87,8 @@ PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB; PFNGLBINDPROGRAMARBPROC qglBindProgramARB; PFNGLGENPROGRAMSARBPROC qglGenProgramsARB; - +PFNGLLOCKARRAYSEXTPROC qglLockArraysEXT; +PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT; @@ -115,17 +117,16 @@ PFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT; BINDTEXFUNCPTR bindTexFunc; -qboolean gl_ext_stencil_wrap; int gl_mtexarbable=0; //max texture units qboolean gl_mtexable = false; -qboolean gl_compressable=false; int gl_bumpmappingpossible; -qboolean gl_arb_fragment_program; qboolean gammaworks; //if the gl drivers can set proper gamma. +gl_config_t gl_config; + //int texture_mode = GL_NEAREST; //int texture_mode = GL_NEAREST_MIPMAP_NEAREST; //int texture_mode = GL_NEAREST_MIPMAP_LINEAR; @@ -140,8 +141,8 @@ int texture_extension_number = 1; void GL_CheckExtensions (void *(*getglfunction) (char *name)) { extern cvar_t gl_bump; - qboolean support_GL_ARB_texture_env_combine, support_GL_ARB_texture_env_dot3, support_GL_ARB_texture_cube_map; + memset(&gl_config, 0, sizeof(gl_config)); //multitexture gl_mtexable = false; @@ -157,36 +158,29 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) //none of them bumpmapping possabilities. gl_bumpmappingpossible = false; - //no GL_EXT_stencil_wrap - gl_ext_stencil_wrap = false; - //no GL_ATI_separate_stencil qglStencilOpSeparateATI = NULL; //no GL_EXT_stencil_two_side qglActiveStencilFaceEXT = NULL; - //no GL_ARB_texture_compression - gl_compressable = false; - //no truform. sorry. qglPNTrianglesfATI = NULL; qglPNTrianglesiATI = NULL; //fragment programs - gl_arb_fragment_program = false; qglProgramStringARB = NULL; qglGetProgramivARB = NULL; qglBindProgramARB = NULL; qglGenProgramsARB = NULL; - supported_GL_ARB_texture_non_power_of_two = false; - supported_GL_SGIS_generate_mipmap = false; + gl_config.arb_texture_non_power_of_two = false; + gl_config.sgis_generate_mipmap = false; if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) - supported_GL_ARB_texture_non_power_of_two = true; + gl_config.arb_texture_non_power_of_two = true; if (strstr(gl_extensions, "GL_SGIS_generate_mipmap")) - supported_GL_SGIS_generate_mipmap = true; + gl_config.sgis_generate_mipmap = true; if (strstr(gl_extensions, "GL_ARB_multitexture") && !COM_CheckParm("-noamtex")) { //ARB multitexture is the popular choice. @@ -229,7 +223,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) } if (strstr(gl_extensions, "GL_EXT_stencil_wrap")) - gl_ext_stencil_wrap = true; + gl_config.ext_stencil_wrap = true; if (strstr(gl_extensions, "GL_ATI_separate_stencil")) qglStencilOpSeparateATI = (void *) getglext("glStencilOpSeparateATI"); @@ -247,7 +241,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglGetCompressedTexImageARB = NULL; } else - gl_compressable = true; + gl_config.arb_texture_compression = true; } if (strstr(gl_extensions, "GL_ATI_pn_triangles")) @@ -263,17 +257,21 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) bindTexFunc = (void *)getglext("glBindTexture"); } - support_GL_ARB_texture_env_combine = !!strstr(gl_extensions, "GL_ARB_texture_env_combine"); - support_GL_ARB_texture_env_dot3 = !!strstr(gl_extensions, "GL_ARB_texture_env_dot3"); - support_GL_ARB_texture_cube_map = !!strstr(gl_extensions, "GL_ARB_texture_cube_map"); + gl_config.tex_env_combine = !!strstr(gl_extensions, "GL_EXT_texture_env_combine"); + gl_config.env_add = !!strstr(gl_extensions, "GL_EXT_texture_env_add"); + gl_config.nv_tex_env_combine4 = !!strstr(gl_extensions, "GL_NV_texture_env_combine4"); - if (gl_mtexarbable && support_GL_ARB_texture_cube_map && support_GL_ARB_texture_env_combine && support_GL_ARB_texture_env_dot3 && !COM_CheckParm("-nobump") && gl_bump.value) + gl_config.arb_texture_env_combine = !!strstr(gl_extensions, "GL_ARB_texture_env_combine"); + gl_config.arb_texture_env_dot3 = !!strstr(gl_extensions, "GL_ARB_texture_env_dot3"); + gl_config.arb_texture_cube_map = !!strstr(gl_extensions, "GL_ARB_texture_cube_map"); + + if (gl_mtexarbable && gl_config.arb_texture_cube_map && gl_config.arb_texture_env_combine && gl_config.arb_texture_env_dot3 && !COM_CheckParm("-nobump") && gl_bump.value) gl_bumpmappingpossible = true; if (!!strstr(gl_extensions, "GL_ARB_fragment_program")) { - gl_arb_fragment_program = true; + gl_config.arb_fragment_program = true; qglProgramStringARB = (void *)getglext("glProgramStringARB"); qglGetProgramivARB = (void *)getglext("glGetProgramivARB"); qglBindProgramARB = (void *)getglext("glBindProgramARB"); @@ -352,6 +350,7 @@ void GL_Init(void *(*getglfunction) (char *name)) //various vertex array stuff. qglDrawElements = (void *)getglcore("glDrawElements"); + qglArrayElement = (void *)getglcore("glArrayElement"); qglVertexPointer = (void *)getglcore("glVertexPointer"); qglNormalPointer = (void *)getglcore("glNormalPointer"); qglTexCoordPointer = (void *)getglcore("glTexCoordPointer"); diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index 8b0f12d1f..8771bee93 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -320,28 +320,36 @@ void EmitSkyPolys (msurface_t *fa) vec3_t dir; float length; - for (p=fa->polys ; p ; p=p->next) + if (fa->mesh) { - glBegin (GL_POLYGON); - for (i=0,v=p->verts[0] ; inumverts ; i++, v+=VERTEXSIZE) + fa->mesh->colors_array = NULL; + GL_DrawAliasMesh(fa->mesh, 1); + } + else + { + for (p=fa->polys ; p ; p=p->next) { - VectorSubtract (v, r_origin, dir); - dir[2] *= 3; // flatten the sphere + glBegin (GL_POLYGON); + for (i=0,v=p->verts[0] ; inumverts ; i++, v+=VERTEXSIZE) + { + VectorSubtract (v, r_origin, dir); + dir[2] *= 3; // flatten the sphere - length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; - length = sqrt (length); - length = 6*63/length; + length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; + length = sqrt (length); + length = 6*63/length; - dir[0] *= length; - dir[1] *= length; + dir[0] *= length; + dir[1] *= length; - s = (speedscale + dir[0]) * (1.0/128); - t = (speedscale + dir[1]) * (1.0/128); + s = (speedscale + dir[0]) * (1.0/128); + t = (speedscale + dir[1]) * (1.0/128); - glTexCoord2f (s, t); - glVertex3fv (v); + glTexCoord2f (s, t); + glVertex3fv (v); + } + glEnd (); } - glEnd (); } } @@ -386,7 +394,7 @@ void R_DrawSkyChain (msurface_t *s) GL_DisableMultitexture(); - if (r_fastsky.value) //this is for visability only... we'd otherwise not stoop this low (and this IS low) + if (r_fastsky.value||!solidskytexture) //this is for visability only... we'd otherwise not stoop this low (and this IS low) { int fc; qbyte *pal; @@ -721,13 +729,27 @@ void R_DrawSkyBoxChain (msurface_t *s) for (fa=s ; fa ; fa=fa->texturechain) { - for (p=fa->polys ; p ; p=p->next) + if (fa->mesh) { - for (i=0 ; inumverts ; i++) + //triangulate + for (i=2 ; imesh->numvertexes ; i++) { - VectorSubtract (p->verts[i], r_origin, verts[i]); + VectorSubtract (fa->mesh->xyz_array[0], r_origin, verts[0]); + VectorSubtract (fa->mesh->xyz_array[i-1], r_origin, verts[1]); + VectorSubtract (fa->mesh->xyz_array[i], r_origin, verts[2]); + ClipSkyPolygon (3, verts[0], 0); + } + } + else + { + for (p=fa->polys ; p ; p=p->next) + { + for (i=0 ; inumverts ; i++) + { + VectorSubtract (p->verts[i], r_origin, verts[i]); + } + ClipSkyPolygon (p->numverts, verts[0], 0); } - ClipSkyPolygon (p->numverts, verts[0], 0); } } @@ -736,12 +758,17 @@ void R_DrawSkyBoxChain (msurface_t *s) glColorMask(0, 0, 0, 0); for (fa=s ; fa ; fa=fa->texturechain) { - for (p=fa->polys ; p ; p=p->next) + if (fa->mesh) + GL_DrawAliasMesh(fa->mesh, 1); + else { - glBegin(GL_POLYGON); - for (i = 0; i < p->numverts; i++) - glVertex3fv(p->verts[i]); - glEnd(); + for (p=fa->polys ; p ; p=p->next) + { + glBegin(GL_POLYGON); + for (i = 0; i < p->numverts; i++) + glVertex3fv(p->verts[i]); + glEnd(); + } } } glColorMask(1, 1, 1, 1); @@ -892,12 +919,17 @@ glEnable (GL_DEPTH_TEST); glColorMask(0, 0, 0, 0); //depth only. for (fa = s; fa; fa = fa->texturechain) { - for (poly = fa->polys; poly; poly = poly->next) + if (fa->mesh) + GL_DrawAliasMesh(fa->mesh, 1); + else { - glBegin (GL_POLYGON); - for (i = 0; i < poly->numverts; i++) - glVertex3fv (&poly->verts[0][0]+i*VERTEXSIZE); - glEnd (); + for (poly = fa->polys; poly; poly = poly->next) + { + glBegin (GL_POLYGON); + for (i = 0; i < poly->numverts; i++) + glVertex3fv (&poly->verts[0][0]+i*VERTEXSIZE); + glEnd (); + } } } glColorMask(1, 1, 1, 1); diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 86436568b..bd807ce0b 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -86,6 +86,26 @@ extern PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI; extern int texture_extension_number; extern int texture_mode; +typedef struct { + qboolean tex_env_combine; + qboolean nv_tex_env_combine4; + qboolean env_add; + + qboolean arb_texture_non_power_of_two; + qboolean sgis_generate_mipmap; + + qboolean arb_texture_env_combine; + qboolean arb_texture_env_dot3; + qboolean arb_texture_cube_map; + + qboolean arb_texture_compression; + qboolean arb_fragment_program; + qboolean ext_stencil_wrap; + int maxtmus; //max texture units +} gl_config_t; + +extern gl_config_t gl_config; + extern float gldepthmin, gldepthmax; void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean mipmap, qboolean alpha); //name was added for texture compression output @@ -172,7 +192,6 @@ extern texture_t *r_notexture_mip; extern int d_lightstylevalue[256]; // 8.8 fraction of base light value extern qboolean envmap; -extern int currenttexture; extern int particletexture; extern int explosiontexture; extern int netgraphtexture; // netgraph texture @@ -216,10 +235,8 @@ extern lpMTexFUNC qglMTexCoord2fSGIS; extern lpSelTexFUNC qglSelectTextureSGIS; -extern qboolean gl_ext_stencil_wrap; extern int gl_mtexarbable; //max texture units extern qboolean gl_mtexable; -extern qboolean gl_compressable; extern int mtexid0; extern int mtexid1; @@ -229,9 +246,6 @@ extern qboolean gl_mtexable; void GL_DisableMultitexture(void); void GL_EnableMultitexture(void); -extern qboolean supported_GL_SGIS_generate_mipmap; -extern qboolean supported_GL_ARB_texture_non_power_of_two; - // // gl_warp.c // @@ -686,6 +700,9 @@ extern PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB; extern PFNGLBINDPROGRAMARBPROC qglBindProgramARB; extern PFNGLGENPROGRAMSARBPROC qglGenProgramsARB; +extern PFNGLLOCKARRAYSEXTPROC qglLockArraysEXT; +extern PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT; + #define glAlphaFunc qglAlphaFunc #define glBlendFunc qglBlendFunc diff --git a/engine/gl/glsupp.h b/engine/gl/glsupp.h index 5f0885781..a4ecbcee6 100644 --- a/engine/gl/glsupp.h +++ b/engine/gl/glsupp.h @@ -112,31 +112,64 @@ extern qlpMTex2FUNC qglMultiTexCoord2fARB; //some of these were needed. //They were also not in the ones I could find on the web. -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND2_ALPHA_ARB 0x859A -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_CONSTANT_ARB 0x8576 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PREVIOUS_ARB 0x8578 +//GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 + + #define GL_DOT3_RGB_ARB 0x86AE #define GL_DOT3_RGBA_ARB 0x86AF +//GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 + +//GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B + /* GL_ARB_texture_compression */ @@ -392,4 +425,17 @@ typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); #endif +#ifndef GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 + +#define GL_EXT_compiled_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glLockArraysEXT (GLint, GLsizei); +extern void APIENTRY glUnlockArraysEXT (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); +#endif + #endif diff --git a/engine/gl/ltface.c b/engine/gl/ltface.c index 0eab5394e..e89e774d1 100644 --- a/engine/gl/ltface.c +++ b/engine/gl/ltface.c @@ -772,9 +772,10 @@ void LightFace (int surfnum) // // some surfaces don't need lightmaps // +#ifdef UTILITY for (j=0 ; jstyles[j] = 255; - +#endif if ( bsptexinfo(f->texinfo).flags & TEX_SPECIAL) { // non-lit texture #ifdef UTILITY @@ -842,6 +843,11 @@ void LightFace (int surfnum) #endif return; } + +#ifndef UTILITY + for (j=0 ; jstyles[j] = 255; +#endif // // save out the values diff --git a/engine/gl/shader.h b/engine/gl/shader.h index fcfa26aeb..2d03c8ef3 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -2,6 +2,37 @@ #define SHADER_MAX_TC_MODS 8 #define SHADER_DEFORM_MAX 8 #define SHADER_MAX_ANIMFRAMES 8 +#define SHADER_ANIM_FRAMES_MAX 16 + +typedef enum { + SHADER_BSP, + SHADER_BSP_VERTEX, + SHADER_BSP_FLARE, + SHADER_MD3, + SHADER_2D +} shadertype_t; + +typedef enum { + SHADER_SORT_NONE, + SHADER_SORT_SKY, + SHADER_SORT_PORTAL, + SHADER_SORT_OPAQUE, + SHADER_SORT_BANNER, + SHADER_SORT_UNDERWATER, + SHADER_SORT_ADDITIVE, + SHADER_SORT_NEAREST +} shadersort_t; + +typedef enum { + MF_NONE = 1<<0, + MF_NORMALS = 1<<1, + MF_TRNORMALS = 1<<2, + MF_COLORS = 1<<3, + MF_STCOORDS = 1<<4, + MF_LMCOORDS = 1<<5, + MF_NOCULL = 1<<6, + MF_NONBATCHED = 1<<7 +} meshfeatures_t; //colour manipulation typedef struct @@ -12,11 +43,30 @@ typedef struct SHADER_FUNC_SQUARE, SHADER_FUNC_SAWTOOTH, SHADER_FUNC_INVERSESAWTOOTH, - SHADER_FUNC_NOISE + SHADER_FUNC_NOISE, + SHADER_FUNC_CONSTANT } type; // SHADER_FUNC enum float args[4]; // offset, amplitude, phase_offset, rate } shaderfunc_t; +#if _MSC_VER || __BORLANDC__ +typedef unsigned __int64 msortkey_t; +#else +typedef unsigned long long msortkey_t; +#endif + +typedef struct meshbuffer_s +{ + msortkey_t sortkey; + int infokey; // lightmap number or mesh number + unsigned int dlightbits; + entity_t *entity; + struct shader_s *shader; + mesh_t *mesh; + struct mfog_s *fog; +} meshbuffer_t; + + //tecture coordinate manipulation typedef struct { @@ -25,7 +75,10 @@ typedef struct SHADER_TCMOD_SCALE, //some sorta tabled deformation SHADER_TCMOD_SCROLL, //boring moving texcoords with time SHADER_TCMOD_STRETCH, //constant factor - SHADER_TCMOD_ROTATE + SHADER_TCMOD_ROTATE, + SHADER_TCMOD_MAX, + SHADER_TCMOD_TRANSFORM, + SHADER_TCMOD_TURB } type; float args[6]; } tcmod_t; @@ -48,8 +101,8 @@ typedef struct } deformv_t; -typedef struct { - int mergedpasses; +typedef struct shaderpass_s { + int numMergedPasses; shaderfunc_t rgbgen_func; shaderfunc_t alphagen_func; @@ -71,7 +124,8 @@ typedef struct { TC_GEN_BASE, //basic specified texture coords TC_GEN_LIGHTMAP, //use loaded lightmap coords TC_GEN_ENVIRONMENT, - TC_GEN_DOTPRODUCT + TC_GEN_DOTPRODUCT, + TC_GEN_VECTOR } tcgen; enum { RGB_GEN_WAVE, @@ -82,28 +136,40 @@ typedef struct { RGB_GEN_ONE_MINUS_VERTEX, RGB_GEN_IDENTITY_LIGHTING, RGB_GEN_IDENTITY, - RGB_GEN_CONST + RGB_GEN_CONST, + RGB_GEN_UNKNOWN, + RGB_GEN_LIGHTING_DIFFUSE } rgbgen; enum { ALPHA_GEN_ENTITY, ALPHA_GEN_WAVE, ALPHA_GEN_PORTAL, ALPHA_GEN_SPECULAR, - ALPHA_GEN_IDENTITY + ALPHA_GEN_IDENTITY, + ALPHA_GEN_VERTEX, + ALPHA_GEN_CONST } alphagen; int numtcmods; - tcmod_t tcmod[SHADER_MAX_TC_MODS]; + tcmod_t tcmods[SHADER_MAX_TC_MODS]; + + void (*flush) (meshbuffer_t *mb, struct shaderpass_s *pass); int anim_numframes; int anim_frames[SHADER_MAX_ANIMFRAMES]; - float fps; + float anim_fps; unsigned int texturetype; enum { SHADER_PASS_BLEND = 1 << 0, SHADER_PASS_ALPHAFUNC = 1 << 1, - SHADER_PASS_DEPTHWRITE = 1 << 2 + SHADER_PASS_DEPTHWRITE = 1 << 2, + + SHADER_PASS_VIDEOMAP = 1 << 3, + SHADER_PASS_DETAIL = 1 << 4, + SHADER_PASS_LIGHTMAP = 1 << 5, + SHADER_PASS_NOCOLORARRAY = 1<< 6, + SHADER_PASS_ANIMMAP = 1 << 7 } flags; } shaderpass_t; @@ -114,21 +180,34 @@ typedef struct shader_s { //end of shared fields. byte_vec4_t fog_color; + float fog_dist; int numdeforms; deformv_t deforms[SHADER_DEFORM_MAX]; enum { - SHADER_SKY = 1 << 0, - SHADER_NOMIPMAPS = 1 << 1, - SHADER_NOPICMIP = 1 << 2, - SHADER_CULL_FRONT = 1 << 3, - SHADER_CULL_BACK = 1 << 4, - SHADER_DEFORMV_BULGE = 1 << 5, - SHADER_AUTOSPRITE = 1 << 5 + SHADER_SKY = 1 << 0, + SHADER_NOMIPMAPS = 1 << 1, + SHADER_NOPICMIP = 1 << 2, + SHADER_CULL_FRONT = 1 << 3, + SHADER_CULL_BACK = 1 << 4, + SHADER_DEFORMV_BULGE = 1 << 5, + SHADER_AUTOSPRITE = 1 << 6, + SHADER_FLARE = 1 << 7, + SHADER_POLYGONOFFSET = 1 << 8, + SHADER_ENTITY_MERGABLE = 1 << 9, + SHADER_VIDEOMAP = 1 << 10, + SHADER_DEPTHWRITE = 1 << 11, + SHADER_AGEN_PORTAL = 1 << 12 } flags; - shaderpass_t pass[SHADER_PASS_MAX]; + shaderpass_t passes[SHADER_PASS_MAX]; + + shadersort_t sort; + + meshfeatures_t features; + + int registration_sequence; } shader_t; @@ -137,3 +216,8 @@ typedef struct shader_s { void GLR_MeshInit(void); void GL_DrawMesh(mesh_t *mesh, shader_t *shader, int texturenum, int lmtexturenum); void GL_DrawMeshBump(mesh_t *mesh, int texturenum, int lmtexturenum, int bumpnum, int deluxnum); + + +void R_RenderMeshGeneric ( meshbuffer_t *mb, shaderpass_t *pass ); +void R_RenderMeshCombined ( meshbuffer_t *mb, shaderpass_t *pass ); +void R_RenderMeshMultitextured ( meshbuffer_t *mb, shaderpass_t *pass ); \ No newline at end of file diff --git a/engine/qclib/Makefile b/engine/qclib/Makefile index 63fb3e962..1ca5f8f0f 100644 --- a/engine/qclib/Makefile +++ b/engine/qclib/Makefile @@ -3,6 +3,11 @@ QCC_OBJS=qccmain.c qcc_cmdlib.c qcc_pr_comp.c qcc_pr_lex.c comprout.c hash.c qcd all: qcc - +win_nocyg: $(QCC_OBJS) qccgui.c qccguistuff.c + $(CC) -DQCCONLY -o fteqcc.exe -O3 -s $(QCC_OBJS) -mno-cygwin -mwindows +nocyg: $(QCC_OBJS) qccgui.c qccguistuff.c + $(CC) -DQCCONLY -o fteqcc.exe -O3 -s $(QCC_OBJS) -mno-cygwin +win: $(QCC_OBJS) qccgui.c qccguistuff.c + $(CC) -DQCCONLY -o fteqcc.exe -O3 -s $(QCC_OBJS) -mwindows qcc: $(QCC_OBJS) $(CC) -DQCCONLY -o fteqcc.bin -O3 -s $(QCC_OBJS) diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index cff8946b0..1273afb77 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -425,6 +425,41 @@ QCC_opcode_t pr_opcodes[] = +/* +{7, "!=", "GSTOREP_I", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GSTOREP_I, +{7, "!=", "GSTORE_F", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GSTOREP_F, //190 +{7, "!=", "GSTORE_ENT", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GSTOREP_ENT, +{7, "!=", "GSTORE_FLD", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GSTOREP_FLD, // integers +{7, "!=", "GSTORE_S", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GSTOREP_S, +{7, "!=", "GSTORE_FNC", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GSTOREP_FNC, // pointers +{7, "!=", "GSTORE_V", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GSTOREP_V, + +{7, "!=", "BOUNDCHECK", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GADDRESS, + +{7, "!=", "GLOAD_I", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GLOAD_I, +{7, "!=", "GLOAD_F", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GLOAD_F, +{7, "!=", "GLOAD_FLD", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GLOAD_FLD, +{7, "!=", "GLOAD_ENT", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GLOAD_ENT, //200 +{7, "!=", "GLOAD_S", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GLOAD_S, +{7, "!=", "GLOAD_FNC", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_GLOAD_FNC, + + {7, "!=", "BOUNDCHECK", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, + OP_BOUNDCHECK, +*/ {0, NULL} }; diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 5b8a7b3c9..052249d0e 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -1782,6 +1782,15 @@ int QCC_PR_CheakCompConst(void) pr_file_p = c->value; do { + p = strlen(buffer); + while(*pr_file_p <= ' ') //copy across whitespace + { + if (!*pr_file_p) + break; + buffer[p] = *pr_file_p++; + } + buffer[p] = 0; + pr_file_p = QCC_COM_Parse(pr_file_p); if (!pr_file_p) break; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 52458c3ed..f01db0b6d 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -7315,20 +7315,20 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs //some of these are a little iffy. //we support them for mvdsv compatability but some of them look very hacky. //these ones are not honoured with numbers, but can be used via the proper means. - {"teamfield", PF_teamfield, 0, 0, 0, 87}, - {"substr", PF_substr, 0, 0, 0, 88}, - {"mvdstrcat", PF_strcat, 0, 0, 0, 89}, - {"mvdstrlen", PF_strlen, 0, 0, 0, 90}, - {"str2byte", PF_str2byte, 0, 0, 0, 91}, - {"str2short", PF_str2short, 0, 0, 0, 92}, + {"teamfield", PF_teamfield, 0, 0, 0, 0}, + {"substr", PF_substr, 0, 0, 0, 0}, + {"mvdstrcat", PF_strcat, 0, 0, 0, 0}, + {"mvdstrlen", PF_strlen, 0, 0, 0, 0}, + {"str2byte", PF_str2byte, 0, 0, 0, 0}, + {"str2short", PF_str2short, 0, 0, 0, 0}, {"mvdnewstr", PF_newstring, 0, 0, 0, 0}, {"mvdfreestr", PF_forgetstring, 0, 0, 0, 0}, - {"conprint", PF_conprint, 0, 0, 0, 95}, - {"readcmd", PF_readcmd, 0, 0, 0, 96}, + {"conprint", PF_conprint, 0, 0, 0, 0}, + {"readcmd", PF_readcmd, 0, 0, 0, 0}, {"mvdstrcpy", PF_MVDSV_strcpy, 0, 0, 0, 0}, - {"strstr", PF_strstr, 0, 0, 0, 98}, + {"strstr", PF_strstr, 0, 0, 0, 0}, {"mvdstrncpy", PF_MVDSV_strncpy, 0, 0, 0, 0}, - {"log", PF_log, 0, 0, 0, 100}, + {"log", PF_log, 0, 0, 0, 0}, // {"redirectcmd", PF_redirectcmd, 0, 0, 0, 101}, {"calltimeofday", PF_calltimeofday, 0, 0, 0, 102}, {"forcedemoframe", PF_forcedemoframe, 0, 0, 0, 103}, @@ -7601,23 +7601,23 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any if (type == PROG_QW && pr_imitatemvdsv.value>0) //pretend to be mvdsv for a bit. { - if (PR_EnableEBFSBuiltin("teamfield", 0) != 87 || - PR_EnableEBFSBuiltin("substr", 0) != 88 || - PR_EnableEBFSBuiltin("mvdstrcat", 0) != 89 || - PR_EnableEBFSBuiltin("mvdstrlen", 0) != 90 || - PR_EnableEBFSBuiltin("str2byte", 0) != 91 || - PR_EnableEBFSBuiltin("str2short", 0) != 92 || - PR_EnableEBFSBuiltin("mvdnewstr", 93)!= 93 || - PR_EnableEBFSBuiltin("mvdfreestr", 94)!= 94 || - PR_EnableEBFSBuiltin("conprint", 0) != 95 || - PR_EnableEBFSBuiltin("readcmd", 0) != 96 || - PR_EnableEBFSBuiltin("mvdstrcpy", 97)!= 97 || - PR_EnableEBFSBuiltin("strstr", 0) != 98 || - PR_EnableEBFSBuiltin("mvdstrncpy", 99)!= 99 || - PR_EnableEBFSBuiltin("log", 0)!= 100 || -// PR_EnableEBFSBuiltin("redirectcmd", 0)!= 101 || - PR_EnableEBFSBuiltin("calltimeofday", 0)!= 102 || - PR_EnableEBFSBuiltin("forcedemoframe", 0)!= 103) + if (PR_EnableEBFSBuiltin("teamfield", 87) != 87 || + PR_EnableEBFSBuiltin("substr", 88) != 88 || + PR_EnableEBFSBuiltin("mvdstrcat", 89) != 89 || + PR_EnableEBFSBuiltin("mvdstrlen", 90) != 90 || + PR_EnableEBFSBuiltin("str2byte", 91) != 91 || + PR_EnableEBFSBuiltin("str2short", 92) != 92 || + PR_EnableEBFSBuiltin("mvdnewstr", 93) != 93 || + PR_EnableEBFSBuiltin("mvdfreestr", 94) != 94 || + PR_EnableEBFSBuiltin("conprint", 95) != 95 || + PR_EnableEBFSBuiltin("readcmd", 96) != 96 || + PR_EnableEBFSBuiltin("mvdstrcpy", 97) != 97 || + PR_EnableEBFSBuiltin("strstr", 98) != 98 || + PR_EnableEBFSBuiltin("mvdstrncpy", 99) != 99 || + PR_EnableEBFSBuiltin("log", 100)!= 100 || +// PR_EnableEBFSBuiltin("redirectcmd", 101)!= 101 || + PR_EnableEBFSBuiltin("calltimeofday", 102)!= 102 || + PR_EnableEBFSBuiltin("forcedemoframe", 103)!= 103) Con_Printf("Failed to register all MVDSV builtins\n"); else Con_Printf("Be aware that MVDSV does not follow standards. Please encourage your mod developers to not require pr_imitatemvdsv to be set.\n"); diff --git a/engine/server/server.h b/engine/server/server.h index ba2178d7e..50fc0fbfa 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -433,6 +433,9 @@ typedef struct client_s struct client_s *controller; struct client_s *controlled; + + int rate; + int drate; } client_t; // a client can leave the server in one of four ways: @@ -1040,6 +1043,8 @@ void SV_FlushDemoSignon (void); // savegame.c void SV_FlushLevelCache(void); +int SV_RateForClient(client_t *cl); + void SVVC_Frame (qboolean enabled); void SV_CalcPHS (void); diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 6d8eed1f6..63d3622fc 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -81,6 +81,7 @@ cvar_t sv_public = {"sv_public", "1"}; cvar_t sv_highchars = {"sv_highchars", "1"}; cvar_t sv_loadentfiles = {"sv_loadentfiles", "1"}; cvar_t sv_maxrate = {"sv_maxrate", "10000"}; +cvar_t sv_maxdrate = {"sv_maxdrate", "10000"}; cvar_t sv_phs = {"sv_phs", "1"}; cvar_t sv_resetparms = {"sv_resetparms", "0"}; @@ -264,7 +265,7 @@ void SV_FinalMessage (char *message) for (i=0, cl = svs.clients ; istate >= cs_spawned) Netchan_Transmit (&cl->netchan, sv.datagram.cursize - , sv.datagram.data); + , sv.datagram.data, 10000); } @@ -374,7 +375,7 @@ void SV_DropClient (client_t *drop) #ifndef SERVERONLY if (drop->netchan.remote_address.type == NA_LOOPBACK) { - Netchan_Transmit(&drop->netchan, 0, ""); + Netchan_Transmit(&drop->netchan, 0, "", SV_RateForClient(drop)); CL_Disconnect(); drop->state = cs_free; //don't do zombie stuff } @@ -2546,6 +2547,27 @@ void SV_GetConsoleCommands (void) } } + +int SV_RateForClient(client_t *cl) +{ + int rate; + if (cl->download) + { + rate = cl->drate; + if (rate > sv_maxdrate.value) + rate = sv_maxdrate.value; + } + else + { + rate = cl->rate; + if (rate > sv_maxrate.value) + rate = sv_maxrate.value; + } + if (rate < 500) + rate = 500; + + return rate; +} /* =================== SV_CheckVars @@ -3291,14 +3313,15 @@ void SV_ExtractFromUserinfo (client_t *cl) // rate command val = Info_ValueForKey (cl->userinfo, "rate"); if (strlen(val)) - { - i = atoi(val); - if (i < 500) - i = 500; - if (i > sv_maxrate.value) - i = sv_maxrate.value; - cl->netchan.rate = 1.0/i; - } + cl->rate = atoi(val); + else + cl->rate = 2500; + + val = Info_ValueForKey (cl->userinfo, "drate"); + if (strlen(val)) + cl->drate = atoi(val); + else + cl->drate = 2500; // msg command val = Info_ValueForKey (cl->userinfo, "msg"); diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 860fa9e71..ed80b60d8 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -2081,6 +2081,11 @@ void SV_MVDInit(void) { MVD_Init(); +#ifdef SERVERONLY //client command would conflict otherwise. + Cmd_AddCommand ("record", SV_MVD_Record_f); + Cmd_AddCommand ("stop", SV_MVDStop_f); + Cmd_AddCommand ("cancel", SV_MVD_Cancel_f); +#endif Cmd_AddCommand ("mvdrecord", SV_MVD_Record_f); Cmd_AddCommand ("easyrecord", SV_MVDEasyRecord_f); Cmd_AddCommand ("mvdstop", SV_MVDStop_f); diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 225ca5518..911afe3fa 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -1288,7 +1288,7 @@ qboolean SV_SendClientDatagram (client_t *client) // send deltas over reliable stream if (sv.worldmodel) - if (!client->isq2client && Netchan_CanReliable (&client->netchan)) + if (!client->isq2client && Netchan_CanReliable (&client->netchan, SV_RateForClient(client))) { int pnum=1; client_t *c; @@ -1305,7 +1305,7 @@ qboolean SV_SendClientDatagram (client_t *client) } // send the datagram - Netchan_Transmit (&client->netchan, msg.cursize, buf); + Netchan_Transmit (&client->netchan, msg.cursize, buf, SV_RateForClient(client)); return true; } @@ -1614,7 +1614,7 @@ void SV_SendClientMessages (void) if (!c->send_message) continue; c->send_message = false; // try putting this after choke? - if (!sv.paused && !Netchan_CanPacket (&c->netchan)) + if (!sv.paused && !Netchan_CanPacket (&c->netchan, SV_RateForClient(c))) { c->chokecount++; continue; // bandwidth choke @@ -1623,7 +1623,7 @@ void SV_SendClientMessages (void) if (c->state == cs_spawned) SV_SendClientDatagram (c); else - Netchan_Transmit (&c->netchan, 0, NULL); // just update reliable + Netchan_Transmit (&c->netchan, 0, NULL, SV_RateForClient(c)); // just update reliable } diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index dfae31da8..1730a83fc 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -1951,23 +1951,24 @@ Change the bandwidth estimate for a client */ void SV_Rate_f (void) { + extern cvar_t sv_maxrate; int rate; if (Cmd_Argc() != 2) { SV_ClientTPrintf (host_client, PRINT_HIGH, STL_CURRENTRATE, - (int)(1.0/host_client->netchan.rate + 0.5)); + host_client->rate); return; } rate = atoi(Cmd_Argv(1)); if (rate < 500) rate = 500; - if (rate > 10000) - rate = 10000; + if (rate > sv_maxrate.value) + rate = sv_maxrate.value; SV_ClientTPrintf (host_client, PRINT_HIGH, STL_RATESETTO, rate); - host_client->netchan.rate = 1.0/rate; + host_client->rate = rate; }