Added cel shading.

Moved ARB warp distortion texture to glMedia struct.
This commit is contained in:
Knightmare66 2020-02-23 14:07:48 -05:00
parent 552fe17908
commit bdf3406328
13 changed files with 410 additions and 59 deletions

View file

@ -13,6 +13,8 @@ Changes as of v0.20 update 8:
- Added Windows DPI scaling detection from Yamagi Quake2.
- Added cel shading support. Uses cvars r_celshading to enable, and r_celshading_width for line width (1-10).
- Now compresses .sav and .sv2 savegame files into .savz files. It will still read savegames from earlier
KMQ2 versions (with the same game DLL). This should improve load and save times in multi-level units.

View file

@ -39,10 +39,10 @@ float aliasShadowAlpha;
/*
=================
R_LightAliasModel
R_LightAliasVertex
=================
*/
void R_LightAliasModel (vec3_t baselight, vec3_t normal, vec3_t lightOut, byte normalindex, qboolean shaded)
void R_LightAliasVertex (vec3_t baselight, vec3_t normal, vec3_t lightOut, byte normalindex, qboolean shaded)
{
int i;
float l;
@ -88,6 +88,70 @@ void R_LightAliasModel (vec3_t baselight, vec3_t normal, vec3_t lightOut, byte n
}
/*
=================
R_LightAliasVertexCel
Adds dlights only for cel shading
=================
*/
void R_LightAliasVertexCel (vec3_t baselight, vec3_t normal, vec3_t lightOut, byte normalindex)
{
int i;
float l;
if (r_fullbright->integer != 0) {
VectorSet (lightOut, 1.0f, 1.0f, 1.0f);
return;
}
VectorCopy(baselight, lightOut);
if (model_dlights_num)
for (i=0; i<model_dlights_num; i++)
{
l = 2.0 * VLight_GetLightValue (normal, model_dlights[i].direction,
currententity->angles[PITCH], currententity->angles[YAW], true);
VectorMA(lightOut, l, model_dlights[i].color, lightOut);
}
for (i=0; i<3; i++)
lightOut[i] = max(min(lightOut[i], 1.0f), 0.0f);
}
/*
=================
R_CelTexCoord
=================
*/
#define CEL_OUTLINEDROPOFF 1024.0f // distance for cel shading outline to disappear
#define CEL_TEX_MIN (0.5f/32.0f)
#define CEL_TEX_MAX (31.5f/32.0f)
float R_CelTexCoord (vec3_t meshlight, vec3_t normal, byte lightnormalindex)
{
float shadeCoord;
int i, highest = 0;
vec3_t lightColor;
R_LightAliasVertex (meshlight, normal, lightColor, lightnormalindex, true);
for (i=0; i<3; i++) {
if (lightColor[i] > lightColor[highest])
highest = i;
}
for (i=0; i<3; i++) {
lightColor[i] = min(max(lightColor[i], 0.0f), 1.0f);
}
shadeCoord = lightColor[highest];
shadeCoord = min(max(shadeCoord, CEL_TEX_MIN), CEL_TEX_MAX);
return shadeCoord;
}
/*
=================
R_AliasMeshesAreBatchable
@ -154,7 +218,7 @@ void RB_RenderAliasMesh (maliasmodel_t *paliashdr, unsigned meshnum, unsigned sk
{
entity_t *e = currententity;
maliasmesh_t *mesh;
renderparms_t skinParms;
renderparms_t *skinParms;
int i;
float thisalpha = colorArray[0][3];
qboolean shellModel = e->flags & RF_MASK_SHELL;
@ -168,25 +232,25 @@ void RB_RenderAliasMesh (maliasmodel_t *paliashdr, unsigned meshnum, unsigned sk
GL_Bind(skin->texnum);
// md3 skin scripting
skinParms = mesh->skins[skinnum].renderparms;
skinParms = &mesh->skins[skinnum].renderparms;
if (skinParms.twosided)
if (skinParms->twosided)
GL_Disable (GL_CULL_FACE);
else
GL_Enable (GL_CULL_FACE);
if (skinParms.alphatest && !shellModel)
if (skinParms->alphatest && !shellModel)
GL_Enable (GL_ALPHA_TEST);
else
GL_Disable (GL_ALPHA_TEST);
if (thisalpha < 1.0f || skinParms.blend)
if (thisalpha < 1.0f || skinParms->blend)
GL_Enable (GL_BLEND);
else
GL_Disable (GL_BLEND);
if (skinParms.blend && !shellModel)
GL_BlendFunc (skinParms.blendfunc_src, skinParms.blendfunc_dst);
if (skinParms->blend && !shellModel)
GL_BlendFunc (skinParms->blendfunc_src, skinParms->blendfunc_dst);
else if (shellModel)
GL_BlendFunc (GL_ONE, GL_ONE);
else
@ -200,7 +264,7 @@ void RB_RenderAliasMesh (maliasmodel_t *paliashdr, unsigned meshnum, unsigned sk
if (mesh->skins[skinnum].glowimage && !shellModel)
{
float glowcolor;
if (skinParms.glow.type > -1)
if (skinParms->glow.type > -1)
glowcolor = RB_CalcGlowColor (skinParms);
else
glowcolor = 1.0;
@ -219,7 +283,7 @@ void RB_RenderAliasMesh (maliasmodel_t *paliashdr, unsigned meshnum, unsigned sk
}
// envmap pass
if (skinParms.envmap > 0.0f && !shellModel)
if (skinParms->envmap > 0.0f && !shellModel)
{
GL_Enable (GL_BLEND);
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -228,7 +292,7 @@ void RB_RenderAliasMesh (maliasmodel_t *paliashdr, unsigned meshnum, unsigned sk
qglTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
// apply alpha to array
for (i=0; i<rb_vertex; i++)
colorArray[i][3] = thisalpha*skinParms.envmap;
colorArray[i][3] = thisalpha*skinParms->envmap;
GL_Bind(glMedia.envmappic->texnum);
@ -241,6 +305,51 @@ void RB_RenderAliasMesh (maliasmodel_t *paliashdr, unsigned meshnum, unsigned sk
qglDisable(GL_TEXTURE_GEN_T);
}
// cel shading
if ( r_celshading->integer && !(thisalpha < 1.0f || skinParms->blend) )
{
float strength, len;
vec3_t offset;
// blend cel shade texture
qglDepthMask (false);
GL_Enable (GL_BLEND);
GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_Bind (glMedia.celshadetexture->texnum);
qglTexCoordPointer (2, GL_FLOAT, sizeof(celTexCoordArray[0]), celTexCoordArray[0]);
qglDisableClientState (GL_COLOR_ARRAY);
qglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
RB_DrawArrays ();
qglTexCoordPointer (2, GL_FLOAT, sizeof(texCoordArray[0][0]), texCoordArray[0][0]);
// qglEnableClientState (GL_COLOR_ARRAY);
GL_Disable (GL_BLEND);
qglDepthMask (true);
// draw outlines
VectorSubtract (r_newrefdef.vieworg, currententity->origin, offset);
len = VectorNormalize(offset);
strength = (CEL_OUTLINEDROPOFF - len) / CEL_OUTLINEDROPOFF;
strength = min(max(strength, 0.0f), 1.0f);
qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
GL_CullFace(GL_BACK);
qglColor4f(0.0f, 0.0f, 0.0f, 1.0f);
qglLineWidth(r_celshading_width->value * strength);
RB_DrawArrays ();
qglLineWidth(1.0f);
qglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GL_CullFace(GL_FRONT);
qglEnableClientState (GL_COLOR_ARRAY);
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
RB_DrawMeshTris ();
rb_vertex = rb_index = 0;
@ -272,6 +381,7 @@ void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly
image_t *skin;
renderparms_t skinParms;
qboolean shellModel = e->flags & RF_MASK_SHELL;
qboolean meshCelShaded; // added for cel shading
frontlerp = 1.0 - backlerp;
@ -348,6 +458,9 @@ void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly
meshalpha = alpha * skinParms.basealpha;
// md3 skin scripting
// is this mesh cel shaded?
meshCelShaded = (r_celshading->integer && !(meshalpha < 1.0f || skinParms.blend));
v = mesh.vertexes + e->frame * mesh.num_verts;
ov = mesh.vertexes + e->oldframe * mesh.num_verts;
baseindex = rb_vertex;
@ -394,8 +507,10 @@ void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly
// calc lighting and alpha
if (shellModel)
VectorCopy(meshlight, lightcolor);
else if (meshCelShaded)
R_LightAliasVertexCel (meshlight, tempNormalsArray[i], lightcolor, v->lightnormalindex); // added for cel shading
else
R_LightAliasModel (meshlight, tempNormalsArray[i], lightcolor, v->lightnormalindex, !skinParms.nodiffuse);
R_LightAliasVertex (meshlight, tempNormalsArray[i], lightcolor, v->lightnormalindex, !skinParms.nodiffuse);
//thisalpha = R_CalcEntAlpha(meshalpha, tempVertexArray[meshnum][i]);
thisalpha = meshalpha;
@ -412,10 +527,13 @@ void R_DrawAliasMeshes (maliasmodel_t *paliashdr, entity_t *e, qboolean lerpOnly
VA_SetElem2(texCoordArray[0][rb_vertex], tempSkinCoord[0], tempSkinCoord[1]);
VA_SetElem3(vertexArray[rb_vertex], tempVertexArray[meshnum][i][0], tempVertexArray[meshnum][i][1], tempVertexArray[meshnum][i][2]);
VA_SetElem4(colorArray[rb_vertex], lightcolor[0], lightcolor[1], lightcolor[2], thisalpha);
if (meshCelShaded) {
VA_SetElem2(celTexCoordArray[rb_vertex], R_CelTexCoord(meshlight, tempNormalsArray[i], v->lightnormalindex), 0); // added for cel shading
}
rb_vertex++;
}
if (!shellModel)
RB_ModifyTextureCoords (&texCoordArray[0][baseindex][0], &vertexArray[baseindex][0], mesh.num_verts, skinParms);
RB_ModifyTextureCoords (&texCoordArray[0][baseindex][0], &vertexArray[baseindex][0], mesh.num_verts, &skinParms);
// compare renderparms for next mesh and check for overflow
if ( k < (paliashdr->num_meshes-1) ) {
@ -997,6 +1115,12 @@ void R_DrawAliasModel (entity_t *e)
mirrormodel = true;
// end mirroring support
// clamp r_celshading_width to >= 1.0
if (!r_celshading_width)
r_celshading_width = Cvar_Get("r_celshading_width", "4", 0);
if (r_celshading_width->value < 1.0f)
Cvar_SetValue( "r_celshading_width", 1.0f);
paliashdr = (maliasmodel_t *)currentmodel->extradata;
R_SetShadeLight ();

View file

@ -100,12 +100,12 @@ static char fragment_program_warp[] =
"ADD coord.y, fragment.texcoord[0].y, offset.w;\n"
"TEX dist, coord, texture[0], 2D;\n"
"MUL col, dist, fragment.color;\n"
// scale by rgbscale
"MUL result.color, col, rgbscale;\n"
"END\n";
#else
static char fragment_program_warp[] =
"!!ARBfp1.0\n"
//"OPTION ARB_precision_hint_fastest;\n"
@ -127,6 +127,36 @@ static char fragment_program_warp[] =
"END\n";
#endif
static char fragment_program_warp_lightmap[] =
"!!ARBfp1.0\n"
//"OPTION ARB_precision_hint_fastest;\n"
"OPTION ARB_precision_hint_nicest;\n"
"PARAM rgbscale = program.local[0];\n"
"TEMP offset, light, coord, dist, unlit, col;\n"
"TEX offset, fragment.texcoord[2], texture[2], 2D;\n"
"MUL offset, offset, 0.5;\n"
"TEX light, fragment.texcoord[1], texture[1], 2D;\n"
"MOV light.w, 1.0;\n"
// fetch the water texture
"ADD coord.x, fragment.texcoord[0].x, offset.z;\n"
"ADD coord.y, fragment.texcoord[0].y, offset.w;\n"
"TEX dist, coord, texture[0], 2D;\n"
"MUL unlit, dist, fragment.color;\n"
// blend lightmap
"MUL col, unlit, light;\n"
// scale by rgbscale
"MUL result.color, col, rgbscale;\n"
"END\n";
static char fragment_program_water_distort[] =
"!!ARBfp1.0\n"
@ -261,6 +291,7 @@ static char *fragment_progs[NUM_FRAGMENT_PROGRAM] =
{
fragment_program_heathazemask,
fragment_program_warp,
fragment_program_warp_lightmap,
fragment_program_water_distort
};

View file

@ -39,6 +39,7 @@ float texCoordArray[MAX_TEXTURE_UNITS][MAX_VERTICES][2];
float vertexArray[MAX_VERTICES][3];
float colorArray[MAX_VERTICES][4];
float inTexCoordArray[MAX_VERTICES][2];
float celTexCoordArray[MAX_VERTICES][2]; // for cel shading
unsigned rb_vertex, rb_index;
@ -120,15 +121,17 @@ void RB_InitBackend (void)
RB_CalcGlowColor
=================
*/
float RB_CalcGlowColor (renderparms_t parms)
float RB_CalcGlowColor (renderparms_t *parms)
{
float *table, rad, out=1.0f;
if (parms.glow.type > -1)
if (!parms) return 0.0f;
if (parms->glow.type > -1)
{
table = RB_TableForFunc(&parms.glow);
rad = parms.glow.params[2] + parms.glow.params[3] * r_newrefdef.time;
out = table[((int)(rad * TABLE_SIZE)) & TABLE_MASK] * parms.glow.params[1] + parms.glow.params[0];
table = RB_TableForFunc(&parms->glow);
rad = parms->glow.params[2] + parms->glow.params[3] * r_newrefdef.time;
out = table[((int)(rad * TABLE_SIZE)) & TABLE_MASK] * parms->glow.params[1] + parms->glow.params[0];
out = max(min(out, 1.0f), 0.0f); // clamp
}
return out;
@ -140,22 +143,25 @@ RB_ModifyTextureCoords
borrowed from EGL & Q2E
=================
*/
void RB_ModifyTextureCoords (float *inArray, float *inVerts, int numVerts, renderparms_t parms)
void RB_ModifyTextureCoords (float *inArray, float *inVerts, int numVerts, renderparms_t *parms)
{
int i;
float t1, t2, sint, cost, rad;
float *tcArray, *vertArray, *table;
if (parms.translate_x != 0.0f)
for (tcArray=inArray, i=0; i<numVerts; i++, tcArray+=2)
tcArray[0] += parms.translate_x;
if (parms.translate_y != 0.0f)
for (tcArray=inArray, i=0; i<numVerts; i++, tcArray+=2)
tcArray[1] += parms.translate_y;
if (!inArray || !inVerts || !parms)
return;
if (parms.rotate != 0.0f)
if (parms->translate_x != 0.0f)
for (tcArray=inArray, i=0; i<numVerts; i++, tcArray+=2)
tcArray[0] += parms->translate_x;
if (parms->translate_y != 0.0f)
for (tcArray=inArray, i=0; i<numVerts; i++, tcArray+=2)
tcArray[1] += parms->translate_y;
if (parms->rotate != 0.0f)
{
rad = -DEG2RAD(parms.rotate * r_newrefdef.time);
rad = -DEG2RAD(parms->rotate * r_newrefdef.time);
sint = sin(rad);
cost = cos(rad);
@ -167,11 +173,11 @@ void RB_ModifyTextureCoords (float *inArray, float *inVerts, int numVerts, rende
}
}
if (parms.stretch.type > -1)
if (parms->stretch.type > -1)
{
table = RB_TableForFunc(&parms.stretch);
rad = parms.stretch.params[2] + parms.stretch.params[3] * r_newrefdef.time;
t1 = table[((int)(rad * TABLE_SIZE)) & TABLE_MASK] * parms.stretch.params[1] + parms.stretch.params[0];
table = RB_TableForFunc(&parms->stretch);
rad = parms->stretch.params[2] + parms->stretch.params[3] * r_newrefdef.time;
t1 = table[((int)(rad * TABLE_SIZE)) & TABLE_MASK] * parms->stretch.params[1] + parms->stretch.params[0];
t1 = (t1) ? 1.0 / t1 : 1.0;
t2 = 0.5 - 0.5 * t1;
@ -182,31 +188,30 @@ void RB_ModifyTextureCoords (float *inArray, float *inVerts, int numVerts, rende
}
}
if (parms.scale_x != 1.0f)
if (parms->scale_x != 1.0f)
for (tcArray=inArray, i=0; i<numVerts; i++, tcArray+=2)
tcArray[0] = tcArray[0] / parms.scale_x;
if (parms.scale_y != 1.0f)
tcArray[0] = tcArray[0] / parms->scale_x;
if (parms->scale_y != 1.0f)
for (tcArray=inArray, i=0; i<numVerts; i++, tcArray+=2)
tcArray[1] = tcArray[1] / parms.scale_y;
tcArray[1] = tcArray[1] / parms->scale_y;
if (parms.turb.type > -1)
if (parms->turb.type > -1)
{
table = RB_TableForFunc(&parms.turb);
t1 = parms.turb.params[2] + parms.turb.params[3] * r_newrefdef.time;
table = RB_TableForFunc(&parms->turb);
t1 = parms->turb.params[2] + parms->turb.params[3] * r_newrefdef.time;
for (tcArray=inArray, vertArray=inVerts, i=0; i<numVerts; i++, tcArray+=2, vertArray+=3) {
tcArray[0] += (table[((int)(((vertArray[0] + vertArray[2]) * 1.0/128 * 0.125 + t1) * TABLE_SIZE)) & TABLE_MASK] * parms.turb.params[1] + parms.turb.params[0]);
tcArray[1] += (table[((int)(((vertArray[1]) * 1.0/128 * 0.125 + t1) * TABLE_SIZE)) & TABLE_MASK] * parms.turb.params[1] + parms.turb.params[0]);
tcArray[0] += (table[((int)(((vertArray[0] + vertArray[2]) * 1.0/128 * 0.125 + t1) * TABLE_SIZE)) & TABLE_MASK] * parms->turb.params[1] + parms->turb.params[0]);
tcArray[1] += (table[((int)(((vertArray[1]) * 1.0/128 * 0.125 + t1) * TABLE_SIZE)) & TABLE_MASK] * parms->turb.params[1] + parms->turb.params[0]);
}
}
if (parms.scroll_x != 0.0f)
if (parms->scroll_x != 0.0f)
for (tcArray=inArray, i=0; i<numVerts; i++, tcArray+=2)
tcArray[0] += r_newrefdef.time * parms.scroll_x;
if (parms.scroll_y != 0.0f)
tcArray[0] += r_newrefdef.time * parms->scroll_x;
if (parms->scroll_y != 0.0f)
for (tcArray=inArray, i=0; i<numVerts; i++, tcArray+=2)
tcArray[1] += r_newrefdef.time * parms.scroll_y;
tcArray[1] += r_newrefdef.time * parms->scroll_y;
}
/*

View file

@ -593,7 +593,7 @@ void R_DrawCameraEffect (void)
cameraParms.scale_y = texparms[i][1];
cameraParms.scroll_x = texparms[i][2];
cameraParms.scroll_y = texparms[i][3];
RB_ModifyTextureCoords (&texCoord[0][0], &verts[0][0], 4, cameraParms);
RB_ModifyTextureCoords (&texCoord[0][0], &verts[0][0], 4, &cameraParms);
for (j=0; j<4; j++) {
VA_SetElem2(texCoordArray[0][j], texCoord[j][0], texCoord[j][1]);
VA_SetElem3(vertexArray[j], verts[j][0], verts[j][1], verts[j][2]);

View file

@ -2387,15 +2387,17 @@ void R_FreeUnusedImages (void)
// never free notexture or particle textures
glMedia.notexture->registration_sequence = registration_sequence;
glMedia.whitetexture->registration_sequence = registration_sequence;
glMedia.distTextureARB->registration_sequence = registration_sequence;
#ifdef ROQ_SUPPORT
glMedia.rawtexture->registration_sequence = registration_sequence;
#endif // ROQ_SUPPORT
glMedia.envmappic->registration_sequence = registration_sequence;
glMedia.spheremappic->registration_sequence = registration_sequence;
glMedia.shelltexture->registration_sequence = registration_sequence;
glMedia.celshadetexture->registration_sequence = registration_sequence;
glMedia.causticwaterpic->registration_sequence = registration_sequence;
glMedia.causticslimepic->registration_sequence = registration_sequence;
glMedia.causticlavapic->registration_sequence = registration_sequence;
glMedia.shelltexture->registration_sequence = registration_sequence;
glMedia.particlebeam->registration_sequence = registration_sequence;
for (i=0; i<PARTICLE_TYPES; i++)

View file

@ -166,10 +166,12 @@ typedef enum {
typedef struct glmedia_s {
image_t *notexture; // used for bad textures
image_t *whitetexture; // used for solid colors
image_t *distTextureARB; // used for warp distortion
image_t *rawtexture; // used for cinematics
image_t *envmappic;
image_t *spheremappic;
image_t *shelltexture;
image_t *celshadetexture;
image_t *causticwaterpic;
image_t *causticslimepic;
image_t *causticlavapic;
@ -328,6 +330,10 @@ extern cvar_t *r_saturation; //** DMP
extern cvar_t *r_bloom;
// Discoloda's cel shading
extern cvar_t *r_celshading;
extern cvar_t *r_celshading_width;
extern cvar_t *vid_fullscreen;
extern cvar_t *vid_gamma;
@ -474,6 +480,7 @@ void R_SetPalette ( const unsigned char *palette);
void R_CreateDisplayLists (void);
void R_ClearDisplayLists (void);
void R_InitMedia (void);
void R_ShutdownMedia (void);
void R_ScreenShot_f (void);
void R_ScreenShot_Silent_f (void);
void R_ScreenShot_TGA_f (void);
@ -557,15 +564,16 @@ void R_DrawAliasModelBBox (vec3_t bbox[8], entity_t *e, float red, float green,
extern unsigned indexArray[MAX_INDICES];
extern float texCoordArray[MAX_TEXTURE_UNITS][MAX_VERTICES][2];
extern float inTexCoordArray[MAX_VERTICES][2];
extern float vertexArray[MAX_VERTICES][3];
extern float colorArray[MAX_VERTICES][4];
extern float inTexCoordArray[MAX_VERTICES][2];
extern float celTexCoordArray[MAX_VERTICES][2]; // for cel shading
extern unsigned rb_vertex, rb_index;
// end vertex array stuff
void RB_InitBackend (void);
float RB_CalcGlowColor (renderparms_t parms);
void RB_ModifyTextureCoords (float *inArray, float *vertexArray, int numVerts, renderparms_t parms);
float RB_CalcGlowColor (renderparms_t *parms);
void RB_ModifyTextureCoords (float *inArray, float *inVerts, int numVerts, renderparms_t *parms);
qboolean RB_CheckArrayOverflow (int numVerts, int numIndex);
void RB_RenderMeshGeneric (qboolean drawTris);
void RB_DrawArrays (void);
@ -581,6 +589,7 @@ typedef enum
{
F_PROG_HEATHAZEMASK = 0,
F_PROG_WARP,
F_PROG_WARP_LM,
F_PROG_WATER_DISTORT,
NUM_FRAGMENT_PROGRAM
} fr_progs;

View file

@ -192,6 +192,10 @@ cvar_t *vid_ref;
cvar_t *r_bloom; // BLOOMS
// Discoloda's cel shading
cvar_t *r_celshading;
cvar_t *r_celshading_width;
cvar_t *r_skydistance; // variable sky range
cvar_t *r_fog_skyratio; // variable sky fog ratio
cvar_t *r_saturation; //** DMP
@ -1039,6 +1043,9 @@ void R_Register (void)
r_bloom = Cvar_Get( "r_bloom", "0", CVAR_ARCHIVE ); // BLOOMS
r_celshading = Cvar_Get( "r_celshading", "0", CVAR_ARCHIVE );
r_celshading_width = Cvar_Get( "r_celshading_width", "4", CVAR_ARCHIVE );
r_skydistance = Cvar_Get("r_skydistance", "24000", CVAR_ARCHIVE); // variable sky range
r_fog_skyratio = Cvar_Get("r_fog_skyratio", "10", CVAR_ARCHIVE); // variable sky fog ratio
r_saturation = Cvar_Get( "r_saturation", "1.0", CVAR_ARCHIVE ); //** DMP saturation setting (.89 good for nvidia)
@ -1932,7 +1939,8 @@ void R_Shutdown (void)
Mod_FreeAll ();
R_ShutdownImages ();
R_ClearDisplayLists ();
// R_ClearDisplayLists ();
R_ShutdownMedia ();
//
// shut down OS specific OpenGL stuff like contexts, etc.

View file

@ -69,6 +69,116 @@ image_t * R_CreateNullTexture (void)
}
/*
==================
R_CreateDistTextureARB
==================
*/
#define DIST_SIZE 16
image_t *R_CreateDistTextureARB (void)
{
byte dist[DIST_SIZE][DIST_SIZE][4];
int x, y;
image_t *image;
srand(Sys_TickCount());
for (x=0; x<DIST_SIZE; x++)
for (y=0; y<DIST_SIZE; y++) {
dist[x][y][0] = rand()%255;
dist[x][y][1] = rand()%255;
dist[x][y][2] = rand()%48;
dist[x][y][3] = rand()%48;
}
image = R_LoadPic ("*disttexture", (byte *)dist, DIST_SIZE, DIST_SIZE, it_wall, 32);
qglBindTexture(GL_TEXTURE_2D, image->texnum);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
return image;
}
/*
==================
R_CreateCelShadeTexture
==================
*/
#define CEL_SHADE_SIZE 32
const byte cel_tex_colors[CEL_SHADE_SIZE][2] =
{
// + 3 = 3
0, 255,
0, 255,
0, 255,
// + 5 = 8
0, 170,
0, 170,
0, 170,
0, 170,
0, 170,
// + 8 = 16
0, 85,
0, 85,
0, 85,
0, 85,
0, 85,
0, 85,
0, 85,
0, 85,
// + 8 = 24
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
// + 8 = 32
255, 0,
255, 0,
255, 0,
255, 0,
255, 0,
255, 0,
255, 0,
255, 0,
};
image_t *R_CreateCelShadeTexture (void)
{
byte cel_tex[CEL_SHADE_SIZE][CEL_SHADE_SIZE][4];
int x, y;
image_t *image;
for (x=0; x<CEL_SHADE_SIZE; x++)
for (y=0; y<CEL_SHADE_SIZE; y++) {
cel_tex[x][y][0] = (byte)cel_tex_colors[y][0];
cel_tex[x][y][1] = (byte)cel_tex_colors[y][0];
cel_tex[x][y][2] = (byte)cel_tex_colors[y][0];
cel_tex[x][y][3] = (byte)cel_tex_colors[y][1];
}
image = R_LoadPic ("*celshadetexture", (byte *)cel_tex, CEL_SHADE_SIZE, CEL_SHADE_SIZE, it_pic, 32);
qglBindTexture(GL_TEXTURE_2D, image->texnum);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
return image;
}
/*
==================
LoadPartImg
@ -195,6 +305,8 @@ void R_InitMedia (void)
memset (whitetex, 255, sizeof(whitetex));
glMedia.whitetexture = R_LoadPic ("***whitetexture***", (byte *)whitetex, NULLTEX_SIZE, NULLTEX_SIZE, it_wall, 32);
glMedia.distTextureARB = R_CreateDistTextureARB (); // Generate warp distortion texture
#ifdef ROQ_SUPPORT
memset(data2D, 255, 256*256*4);
glMedia.rawtexture = R_LoadPic ("***rawtexture***", data2D, 256, 256, it_pic, 32);
@ -203,6 +315,9 @@ void R_InitMedia (void)
glMedia.envmappic = LoadPartImg ("gfx/effects/envmap.tga", it_wall);
glMedia.spheremappic = LoadPartImg ("gfx/effects/spheremap.tga", it_skin);
glMedia.shelltexture = LoadPartImg ("gfx/effects/shell_generic.tga", it_skin);
glMedia.celshadetexture = R_CreateCelShadeTexture ();
glMedia.causticwaterpic = LoadPartImg ("gfx/water/caustic_water.tga", it_wall);
glMedia.causticslimepic = LoadPartImg ("gfx/water/caustic_slime.tga", it_wall);
glMedia.causticlavapic = LoadPartImg ("gfx/water/caustic_lava.tga", it_wall);
@ -221,6 +336,37 @@ void R_InitMedia (void)
}
/*
==================
R_ShutdownMedia
==================
*/
void R_ShutdownMedia (void)
{
int i;
glMedia.notexture = NULL;
glMedia.whitetexture = NULL;
glMedia.distTextureARB = NULL;
glMedia.rawtexture = NULL;
glMedia.envmappic = NULL;
glMedia.spheremappic = NULL;
glMedia.shelltexture = NULL;
glMedia.celshadetexture = NULL;
glMedia.causticwaterpic = NULL;
glMedia.causticslimepic = NULL;
glMedia.causticlavapic = NULL;
glMedia.particlebeam = NULL;
for (i=0; i<PARTICLE_TYPES; i++)
glMedia.particletextures[i] = NULL;
R_ClearDisplayLists ();
}
/*
==============================================================================

View file

@ -871,8 +871,8 @@ void Mod_LoadFaces (lump_t *l)
out->flags |= SURF_DRAWTURB;
for (i=0; i<2; i++)
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
out->extents[i] = (WORLD_SIZE*2); // was 16384
out->texturemins[i] = -WORLD_SIZE; // was -8192
}
R_SubdivideSurface (out); // cut up polygon for warps
}

View file

@ -240,6 +240,7 @@ void CreateDSTTex_NV (void)
qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
#if 0
/*
===============
CreateDSTTex_ARB
@ -272,6 +273,7 @@ void CreateDSTTex_ARB (void)
qglHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
}
#endif
/*
===============
@ -283,9 +285,10 @@ Needed after a vid_restart.
*/
void R_InitDSTTex (void)
{
dst_texture_NV = dst_texture_ARB = 0;
dst_texture_NV = 0;
// dst_texture_ARB = 0;
CreateDSTTex_NV ();
CreateDSTTex_ARB ();
// CreateDSTTex_ARB ();
}
//end MrG
@ -335,7 +338,8 @@ void RB_RenderWarpSurface (msurface_t *fa)
GL_MBind(0, image->texnum);
GL_EnableTexture(1);
GL_MBind(1, dst_texture_ARB);
// GL_MBind(1, dst_texture_ARB);
GL_MBind(1, glMedia.distTextureARB->texnum);
GL_Enable (GL_FRAGMENT_PROGRAM_ARB);
qglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fragment_programs[F_PROG_WARP]);

View file

@ -126,6 +126,7 @@ static void ResetVideoDefaults ( void *unused )
Cvar_SetToDefault ("r_shadows");
Cvar_SetToDefault ("r_stencilTwoSide");
Cvar_SetToDefault ("r_shelltype");
Cvar_SetToDefault ("r_celshading");
// Cvar_SetToDefault ("r_screenshot_jpeg");
Cvar_SetToDefault ("r_screenshot_format");
Cvar_SetToDefault ("r_screenshot_jpeg_quality");

View file

@ -56,6 +56,7 @@ static menulist_s s_modelshading_box;
static menulist_s s_shadows_box;
static menulist_s s_two_side_stencil_box;
static menulist_s s_ent_shell_box;
static menulist_s s_celshading_box;
static menulist_s s_glass_envmap_box;
//static menulist_s s_screenshotjpeg_box;
static menulist_s s_screenshotformat_box;
@ -123,6 +124,9 @@ static void Video_Advanced_MenuSetValues ( void )
Cvar_SetValue( "r_shelltype", ClampCvar( 0, 2, Cvar_VariableValue("r_shelltype") ) );
s_ent_shell_box.curvalue = Cvar_VariableValue("r_shelltype");
Cvar_SetValue( "r_celshading", ClampCvar( 0, 1, Cvar_VariableValue("r_celshading") ) );
s_celshading_box.curvalue = Cvar_VariableValue("r_celshading");
// Cvar_SetValue( "r_screenshot_jpeg", ClampCvar( 0, 1, Cvar_VariableValue("r_screenshot_jpeg") ) );
// s_screenshotjpeg_box.curvalue = Cvar_VariableValue("r_screenshot_jpeg");
@ -226,6 +230,11 @@ static void EntShellCallback ( void *unused )
Cvar_SetValue( "r_shelltype", s_ent_shell_box.curvalue);
}
static void CelShadingCallback ( void *unused )
{
Cvar_SetValue( "r_celshading", s_celshading_box.curvalue);
}
/*
static void JPEGScreenshotCallback ( void *unused )
{
@ -482,6 +491,15 @@ void Menu_Video_Advanced_Init (void)
s_ent_shell_box.generic.callback = EntShellCallback;
s_ent_shell_box.itemnames = shell_names;
s_ent_shell_box.generic.statusbar = "envmap effect may cause instability on ATI cards";
s_celshading_box.generic.type = MTYPE_SPINCONTROL;
s_celshading_box.generic.x = 0;
s_celshading_box.generic.y = y += MENU_LINE_SIZE;
s_celshading_box.generic.name = "cel shading";
s_celshading_box.generic.callback = CelShadingCallback;
s_celshading_box.itemnames = yesno_names;
s_celshading_box.generic.statusbar = "cartoon-style rendering of models";
/*
s_screenshotjpeg_box.generic.type = MTYPE_SPINCONTROL;
s_screenshotjpeg_box.generic.x = 0;
@ -549,6 +567,7 @@ void Menu_Video_Advanced_Init (void)
Menu_AddItem( &s_video_advanced_menu, ( void * ) &s_shadows_box );
Menu_AddItem( &s_video_advanced_menu, ( void * ) &s_two_side_stencil_box );
Menu_AddItem( &s_video_advanced_menu, ( void * ) &s_ent_shell_box );
Menu_AddItem( &s_video_advanced_menu, ( void * ) &s_celshading_box );
// Menu_AddItem( &s_video_advanced_menu, ( void * ) &s_screenshotjpeg_box );
Menu_AddItem( &s_video_advanced_menu, ( void * ) &s_screenshotformat_box );
Menu_AddItem( &s_video_advanced_menu, ( void * ) &s_screenshotjpegquality_slider );