Merge branch 'opengl-is-a-bad-renderer' into 'master'

OpenGL fixes

See merge request STJr/SRB2!519
This commit is contained in:
James R 2019-12-14 16:48:50 -05:00
commit 14674223e8
22 changed files with 595 additions and 476 deletions

View File

@ -1193,6 +1193,13 @@ void D_SRB2Main(void)
CONS_Printf("I_StartupGraphics()...\n"); CONS_Printf("I_StartupGraphics()...\n");
I_StartupGraphics(); I_StartupGraphics();
#ifdef HWRENDER
// Lactozilla: Add every hardware mode CVAR and CCMD.
// Has to be done before the configuration file loads,
// but after the OpenGL library loads.
HWR_AddCommands();
#endif
//--------------------------------------------------------- CONSOLE //--------------------------------------------------------- CONSOLE
// setup loading screen // setup loading screen
SCR_Startup(); SCR_Startup();

View File

@ -760,15 +760,15 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
// CACHING HANDLING // CACHING HANDLING
// ================================================= // =================================================
static size_t gr_numtextures; static size_t gr_numtextures; // Texture count
static GLTexture_t *gr_textures; // for ALL Doom textures static GLTexture_t *gr_textures; // For all textures
static GLTexture_t *gr_textures2; static GLTexture_t *gr_flats; // For all (texture) flats, as normal flats don't need to be cached
void HWR_InitTextureCache(void) void HWR_InitTextureCache(void)
{ {
gr_numtextures = 0; gr_numtextures = 0;
gr_textures = NULL; gr_textures = NULL;
gr_textures2 = NULL; gr_flats = NULL;
} }
// Callback function for HWR_FreeTextureCache. // Callback function for HWR_FreeTextureCache.
@ -776,29 +776,45 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch)
{ {
GLPatch_t* const pat = patch; GLPatch_t* const pat = patch;
(void)patchnum; //unused (void)patchnum; //unused
while (pat->mipmap && pat->mipmap->nextcolormap) // The mipmap must be valid, obviously
// The patch must be valid, obviously
if (!pat)
return;
// The mipmap must be valid, obviously
while (pat->mipmap)
{ {
// Confusing at first, but pat->mipmap->nextcolormap // Confusing at first, but pat->mipmap->nextcolormap
// at the beginning of the loop is the first colormap // at the beginning of the loop is the first colormap
// from the linked list of colormaps // from the linked list of colormaps.
GLMipmap_t *next = pat->mipmap; GLMipmap_t *next = NULL;
if (!next) // No mipmap in this patch, break out of loop.
// No mipmap in this patch, break out of the loop.
if (!pat->mipmap)
break; break;
// Set the first colormap
// to the one that comes after it // No colormap mipmap either.
next = next->nextcolormap; if (!pat->mipmap->nextcolormap)
break;
// Set the first colormap to the one that comes after it.
next = pat->mipmap->nextcolormap;
pat->mipmap->nextcolormap = next->nextcolormap; pat->mipmap->nextcolormap = next->nextcolormap;
// Free image data from memory
// Free image data from memory.
if (next->grInfo.data) if (next->grInfo.data)
Z_Free(next->grInfo.data); Z_Free(next->grInfo.data);
// Free the old colormap from memory next->grInfo.data = NULL;
// Free the old colormap mipmap from memory.
free(next); free(next);
} }
} }
void HWR_FreeTextureCache(void) void HWR_FreeMipmapCache(void)
{ {
INT32 i; INT32 i;
// free references to the textures // free references to the textures
HWD.pfnClearMipMapCache(); HWD.pfnClearMipMapCache();
@ -808,51 +824,46 @@ void HWR_FreeTextureCache(void)
Z_FreeTag(PU_HWRCACHE_UNLOCKED); Z_FreeTag(PU_HWRCACHE_UNLOCKED);
// Alam: free the Z_Blocks before freeing it's users // Alam: free the Z_Blocks before freeing it's users
// free all patch colormaps after each level: must be done after ClearMipMapCache! // free all patch colormaps after each level: must be done after ClearMipMapCache!
for (i = 0; i < numwadfiles; i++) for (i = 0; i < numwadfiles; i++)
M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap);
}
void HWR_FreeTextureCache(void)
{
// free references to the textures
HWR_FreeMipmapCache();
// now the heap don't have any 'user' pointing to our // now the heap don't have any 'user' pointing to our
// texturecache info, we can free it // texturecache info, we can free it
if (gr_textures) if (gr_textures)
free(gr_textures); free(gr_textures);
if (gr_textures2) if (gr_flats)
free(gr_textures2); free(gr_flats);
gr_textures = NULL; gr_textures = NULL;
gr_textures2 = NULL; gr_flats = NULL;
gr_numtextures = 0; gr_numtextures = 0;
} }
void HWR_PrepLevelCache(size_t pnumtextures) void HWR_LoadTextures(size_t pnumtextures)
{ {
// problem: the mipmap cache management hold a list of mipmaps.. but they are
// reallocated on each level..
//sub-optimal, but 1) just need re-download stuff in hardware cache VERY fast
// 2) sprite/menu stuff mixed with level textures so can't do anything else
// we must free it since numtextures changed // we must free it since numtextures changed
HWR_FreeTextureCache(); HWR_FreeTextureCache();
// Why not Z_Malloc?
gr_numtextures = pnumtextures; gr_numtextures = pnumtextures;
gr_textures = calloc(pnumtextures, sizeof (*gr_textures)); gr_textures = calloc(gr_numtextures, sizeof(*gr_textures));
if (gr_textures == NULL) gr_flats = calloc(gr_numtextures, sizeof(*gr_flats));
I_Error("3D can't alloc gr_textures");
gr_textures2 = calloc(pnumtextures, sizeof (*gr_textures2)); // Doesn't tell you which it _is_, but hopefully
if (gr_textures2 == NULL) // should never ever happen (right?!)
I_Error("3D can't alloc gr_textures2"); if ((gr_textures == NULL) || (gr_flats == NULL))
I_Error("HWR_LoadTextures: ran out of memory for OpenGL textures. Sad!");
} }
void HWR_SetPalette(RGBA_t *palette) void HWR_SetPalette(RGBA_t *palette)
{ {
//Hudler: 16/10/99: added for OpenGL gamma correction HWD.pfnSetPalette(palette);
RGBA_t gamma_correction = {0x7F7F7F7F};
//Hurdler 16/10/99: added for OpenGL gamma correction
gamma_correction.s.red = (UINT8)cv_grgammared.value;
gamma_correction.s.green = (UINT8)cv_grgammagreen.value;
gamma_correction.s.blue = (UINT8)cv_grgammablue.value;
HWD.pfnSetPalette(palette, &gamma_correction);
// hardware driver will flush there own cache if cache is non paletized // hardware driver will flush there own cache if cache is non paletized
// now flush data texture cache so 32 bit texture are recomputed // now flush data texture cache so 32 bit texture are recomputed
@ -873,11 +884,16 @@ GLTexture_t *HWR_GetTexture(INT32 tex)
if ((unsigned)tex >= gr_numtextures) if ((unsigned)tex >= gr_numtextures)
I_Error("HWR_GetTexture: tex >= numtextures\n"); I_Error("HWR_GetTexture: tex >= numtextures\n");
#endif #endif
// Every texture in memory, stored in the
// hardware renderer's bit depth format. Wow!
grtex = &gr_textures[tex]; grtex = &gr_textures[tex];
// Generate texture if missing from the cache
if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded)
HWR_GenerateTexture(tex, grtex); HWR_GenerateTexture(tex, grtex);
// Tell the hardware driver to bind the current texture to the flat's mipmap
HWD.pfnSetTexture(&grtex->mipmap); HWD.pfnSetTexture(&grtex->mipmap);
// The system-memory data can be purged now. // The system-memory data can be purged now.
@ -989,13 +1005,19 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
if ((unsigned)texturenum >= gr_numtextures) if ((unsigned)texturenum >= gr_numtextures)
I_Error("HWR_GetLevelFlat: texturenum >= numtextures\n"); I_Error("HWR_GetLevelFlat: texturenum >= numtextures\n");
#endif #endif
// Who knows?
if (texturenum == 0 || texturenum == -1) if (texturenum == 0 || texturenum == -1)
return; return;
grtex = &gr_textures2[texturenum];
// Every texture in memory, stored as a 8-bit flat. Wow!
grtex = &gr_flats[texturenum];
// Generate flat if missing from the cache
if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded)
HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum); HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum);
// Tell the hardware driver to bind the current texture to the flat's mipmap
HWD.pfnSetTexture(&grtex->mipmap); HWD.pfnSetTexture(&grtex->mipmap);
// The system-memory data can be purged now. // The system-memory data can be purged now.
@ -1019,6 +1041,7 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
HWR_MakePatch(patch, gpatch, grmip, true); HWR_MakePatch(patch, gpatch, grmip, true);
// You can't free rawpatch for some reason? // You can't free rawpatch for some reason?
// (Obviously I can't, sprite rotation needs that...)
if (!gpatch->rawpatch) if (!gpatch->rawpatch)
Z_Free(patch); Z_Free(patch);
} }
@ -1046,7 +1069,6 @@ void HWR_GetPatch(GLPatch_t *gpatch)
// this is inefficient.. but the hardware patch in heap is purgeable so it should // this is inefficient.. but the hardware patch in heap is purgeable so it should
// not fragment memory, and besides the REAL cache here is the hardware memory // not fragment memory, and besides the REAL cache here is the hardware memory
// You can't free rawpatch for some reason?
if (!gpatch->rawpatch) if (!gpatch->rawpatch)
Z_Free(ptr); Z_Free(ptr);
} }

View File

@ -48,6 +48,7 @@ struct GLMipmap_s
struct GLMipmap_s *nextcolormap; struct GLMipmap_s *nextcolormap;
const UINT8 *colormap; const UINT8 *colormap;
INT32 tcindex;
// opengl // opengl
struct GLMipmap_s *nextmipmap; // opengl : liste of all texture in opengl driver struct GLMipmap_s *nextmipmap; // opengl : liste of all texture in opengl driver

View File

@ -220,11 +220,10 @@ typedef struct FSurfaceInfo FSurfaceInfo;
//Hurdler: added for backward compatibility //Hurdler: added for backward compatibility
enum hwdsetspecialstate enum hwdsetspecialstate
{ {
HWD_SET_FOG_TABLE = 1, HWD_SET_MODEL_LIGHTING = 1,
HWD_SET_FOG_MODE, HWD_SET_FOG_MODE,
HWD_SET_FOG_COLOR, HWD_SET_FOG_COLOR,
HWD_SET_FOG_DENSITY, HWD_SET_FOG_DENSITY,
HWD_SET_FOV,
HWD_SET_TEXTUREFILTERMODE, HWD_SET_TEXTUREFILTERMODE,
HWD_SET_TEXTUREANISOTROPICMODE, HWD_SET_TEXTUREANISOTROPICMODE,
HWD_NUMSTATE HWD_NUMSTATE

View File

@ -39,11 +39,7 @@ EXPORT void HWRAPI(Shutdown) (void);
#ifdef _WINDOWS #ifdef _WINDOWS
EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes); EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes);
#endif #endif
#if defined (PURESDL) || defined (macintosh) EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal);
EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma);
#else
EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal, RGBA_t *pgamma);
#endif
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);

View File

@ -100,6 +100,7 @@ void HWR_FreePolyPool(void);
// -------- // --------
void HWR_InitTextureCache(void); void HWR_InitTextureCache(void);
void HWR_FreeTextureCache(void); void HWR_FreeTextureCache(void);
void HWR_FreeMipmapCache(void);
void HWR_FreeExtraSubsectors(void); void HWR_FreeExtraSubsectors(void);
void HWR_GetLevelFlat(levelflat_t *levelflat); void HWR_GetLevelFlat(levelflat_t *levelflat);

View File

@ -85,62 +85,8 @@ static void HWR_RenderTransparentWalls(void);
static void HWR_FoggingOn(void); static void HWR_FoggingOn(void);
static UINT32 atohex(const char *s); static UINT32 atohex(const char *s);
static void CV_filtermode_ONChange(void);
static void CV_anisotropic_ONChange(void);
static void CV_FogDensity_ONChange(void);
static void CV_grFov_OnChange(void);
// ==========================================================================
// 3D ENGINE COMMANDS & CONSOLE VARS
// ==========================================================================
static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
{HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"},
{HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"},
{HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"},
{0, NULL}};
CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
boolean drawsky = true; boolean drawsky = true;
// needs fix: walls are incorrectly clipped one column less
#ifndef NEWCLIP
static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
//development variables for diverse uses
static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grFov_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned,
CV_FogDensity_ONChange, 0, NULL, NULL, 0, 0, NULL};
// Unfortunately, this can no longer be saved..
consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_cons_t,
CV_filtermode_ONChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t,
CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL};
//static consvar_t cv_grzbuffer = {"gr_zbuffer", "On", 0, CV_OnOff};
consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static void CV_FogDensity_ONChange(void)
{
HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value);
}
static void CV_filtermode_ONChange(void)
{
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_grfiltermode.value);
}
static void CV_anisotropic_ONChange(void)
{
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value);
}
/* /*
* lookuptable for lightvalues * lookuptable for lightvalues
* calculated as follow: * calculated as follow:
@ -2473,11 +2419,13 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
static cliprange_t * hw_newend; static cliprange_t * hw_newend;
static cliprange_t gr_solidsegs[MAXSEGS]; static cliprange_t gr_solidsegs[MAXSEGS];
// needs fix: walls are incorrectly clipped one column less
static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static void printsolidsegs(void) static void printsolidsegs(void)
{ {
cliprange_t * start; cliprange_t * start;
if (!hw_newend || cv_grbeta.value != 2) if (!hw_newend)
return; return;
for (start = gr_solidsegs;start != hw_newend;start++) for (start = gr_solidsegs;start != hw_newend;start++)
{ {
@ -3431,7 +3379,7 @@ static void HWR_AddPolyObjectPlanes(void)
{ {
HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic]); HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic]);
HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
(light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic], (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->ceilingpic],
polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap));
} }
} }
@ -5420,14 +5368,20 @@ static void HWR_DrawSprites(void)
if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
HWR_DrawSprite(spr); HWR_DrawSprite(spr);
else else
HWR_DrawModel(spr); {
if (!HWR_DrawModel(spr))
HWR_DrawSprite(spr);
}
} }
else else
{ {
if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f)
HWR_DrawSprite(spr); HWR_DrawSprite(spr);
else else
HWR_DrawModel(spr); {
if (!HWR_DrawModel(spr))
HWR_DrawSprite(spr);
}
} }
} }
} }
@ -5941,7 +5895,7 @@ static void HWR_DrawSkyBackground(player_t *player)
{ {
if (cv_grskydome.value) if (cv_grskydome.value)
{ {
FTransform transform; FTransform dometransform;
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
postimg_t *type; postimg_t *type;
@ -5950,27 +5904,27 @@ static void HWR_DrawSkyBackground(player_t *player)
else else
type = &postimgtype; type = &postimgtype;
memset(&transform, 0x00, sizeof(FTransform)); memset(&dometransform, 0x00, sizeof(FTransform));
//04/01/2000: Hurdler: added for T&L //04/01/2000: Hurdler: added for T&L
// It should replace all other gr_viewxxx when finished // It should replace all other gr_viewxxx when finished
transform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); dometransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
transform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
if (*type == postimg_flip) if (*type == postimg_flip)
transform.flip = true; dometransform.flip = true;
else else
transform.flip = false; dometransform.flip = false;
transform.scalex = 1; dometransform.scalex = 1;
transform.scaley = (float)vid.width/vid.height; dometransform.scaley = (float)vid.width/vid.height;
transform.scalez = 1; dometransform.scalez = 1;
transform.fovxangle = fpov; // Tails dometransform.fovxangle = fpov; // Tails
transform.fovyangle = fpov; // Tails dometransform.fovyangle = fpov; // Tails
transform.splitscreen = splitscreen; dometransform.splitscreen = splitscreen;
HWR_GetTexture(texturetranslation[skytexture]); HWR_GetTexture(texturetranslation[skytexture]);
HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, transform); HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, dometransform);
} }
else else
{ {
@ -6172,6 +6126,8 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
//04/01/2000: Hurdler: added for T&L //04/01/2000: Hurdler: added for T&L
// It should replace all other gr_viewxxx when finished // It should replace all other gr_viewxxx when finished
memset(&atransform, 0x00, sizeof(FTransform));
atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
@ -6390,6 +6346,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
//04/01/2000: Hurdler: added for T&L //04/01/2000: Hurdler: added for T&L
// It should replace all other gr_viewxxx when finished // It should replace all other gr_viewxxx when finished
memset(&atransform, 0x00, sizeof(FTransform));
atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
@ -6584,59 +6542,125 @@ static void HWR_FoggingOn(void)
// 3D ENGINE COMMANDS // 3D ENGINE COMMANDS
// ========================================================================== // ==========================================================================
static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}};
static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}};
static void CV_grFov_OnChange(void) static void CV_grmodellighting_OnChange(void);
static void CV_grfiltermode_OnChange(void);
static void CV_granisotropic_OnChange(void);
static void CV_grfogdensity_OnChange(void);
static void CV_grfov_OnChange(void);
static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
{HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"},
{HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"},
{HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"},
{0, NULL}};
CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#ifdef ALAM_LIGHTING
consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_grmodellighting_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned,
CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_SAVE|CV_CALL, grfiltermode_cons_t,
CV_grfiltermode_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t,
CV_granisotropic_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static void CV_grmodellighting_OnChange(void)
{
if (rendermode == render_opengl)
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value);
}
static void CV_grfogdensity_OnChange(void)
{
if (rendermode == render_opengl)
HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value);
}
static void CV_grfiltermode_OnChange(void)
{
if (rendermode == render_opengl)
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_grfiltermode.value);
}
static void CV_granisotropic_OnChange(void)
{
if (rendermode == render_opengl)
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value);
}
static void CV_grfov_OnChange(void)
{ {
if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT) if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT)
CV_Set(&cv_grfov, cv_grfov.defaultvalue); CV_Set(&cv_grfov, cv_grfov.defaultvalue);
} }
static void Command_GrStats_f(void)
{
Z_CheckHeap(9875); // debug
CONS_Printf(M_GetText("Patch info headers: %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
CONS_Printf(M_GetText("3D Texture cache : %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
CONS_Printf(M_GetText("Plane polygon : %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
}
// **************************************************************************
// 3D ENGINE SETUP
// **************************************************************************
// --------------------------------------------------------------------------
// Add hardware engine commands & consvars
// --------------------------------------------------------------------------
//added by Hurdler: console varibale that are saved //added by Hurdler: console varibale that are saved
void HWR_AddCommands(void) void HWR_AddCommands(void)
{ {
CV_RegisterVar(&cv_grrounddown); CV_RegisterVar(&cv_grfovchange);
CV_RegisterVar(&cv_grfov); CV_RegisterVar(&cv_grfov);
CV_RegisterVar(&cv_grfogdensity); CV_RegisterVar(&cv_grfogdensity);
CV_RegisterVar(&cv_grfogcolor);
CV_RegisterVar(&cv_grfog);
CV_RegisterVar(&cv_grsoftwarefog);
#ifdef ALAM_LIGHTING
CV_RegisterVar(&cv_grstaticlighting);
CV_RegisterVar(&cv_grdynamiclighting);
CV_RegisterVar(&cv_grcoronasize);
CV_RegisterVar(&cv_grcoronas);
#endif
CV_RegisterVar(&cv_grmodellighting);
CV_RegisterVar(&cv_grmodelinterpolation);
CV_RegisterVar(&cv_grmodels);
CV_RegisterVar(&cv_grskydome);
CV_RegisterVar(&cv_grspritebillboarding);
CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_grfiltermode);
CV_RegisterVar(&cv_granisotropicmode); CV_RegisterVar(&cv_grrounddown);
CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grcorrecttricks);
CV_RegisterVar(&cv_grsolvetjoin); CV_RegisterVar(&cv_grsolvetjoin);
}
static inline void HWR_AddEngineCommands(void)
{
// engine state variables
//CV_RegisterVar(&cv_grzbuffer);
#ifndef NEWCLIP #ifndef NEWCLIP
CV_RegisterVar(&cv_grclipwalls); CV_RegisterVar(&cv_grclipwalls);
#endif #endif
// engine development mode variables
// - usage may vary from version to version..
CV_RegisterVar(&cv_gralpha);
CV_RegisterVar(&cv_grbeta);
// engine commands
COM_AddCommand("gr_stats", Command_GrStats_f);
} }
void HWR_AddSessionCommands(void)
{
CV_RegisterVar(&cv_granisotropicmode);
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Setup the hardware renderer // Setup the hardware renderer
@ -6657,12 +6681,9 @@ void HWR_Startup(void)
{ {
CONS_Printf("HWR_Startup()...\n"); CONS_Printf("HWR_Startup()...\n");
HWR_InitPolyPool(); HWR_InitPolyPool();
// add console cmds & vars HWR_AddSessionCommands();
HWR_AddEngineCommands();
HWR_InitTextureCache(); HWR_InitTextureCache();
HWR_InitModels(); HWR_InitModels();
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
HWR_InitLight(); HWR_InitLight();
#endif #endif
@ -6683,6 +6704,7 @@ void HWR_Shutdown(void)
CONS_Printf("HWR_Shutdown()\n"); CONS_Printf("HWR_Shutdown()\n");
HWR_FreeExtraSubsectors(); HWR_FreeExtraSubsectors();
HWR_FreePolyPool(); HWR_FreePolyPool();
HWR_FreeMipmapCache();
HWR_FreeTextureCache(); HWR_FreeTextureCache();
HWD.pfnFlushScreenTextures(); HWD.pfnFlushScreenTextures();
} }

View File

@ -47,7 +47,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale
void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreatePlanePolygons(INT32 bspnum);
void HWR_CreateStaticLightmaps(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum);
void HWR_PrepLevelCache(size_t pnumtextures); void HWR_LoadTextures(size_t pnumtextures);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 actualcolor, UINT8 strength); void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 actualcolor, UINT8 strength);
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 actualcolor); // Lat: separate flags from color since color needs to be an uint to work right. void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 actualcolor); // Lat: separate flags from color since color needs to be an uint to work right.
@ -57,6 +57,7 @@ UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *pathname); boolean HWR_Screenshot(const char *pathname);
void HWR_AddCommands(void); void HWR_AddCommands(void);
void HWR_AddSessionCommands(void);
void HWR_CorrectSWTricks(void); void HWR_CorrectSWTricks(void);
void transform(float *cx, float *cy, float *cz); void transform(float *cx, float *cy, float *cz);
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
@ -85,13 +86,11 @@ extern consvar_t cv_grcoronasize;
extern consvar_t cv_grfov; extern consvar_t cv_grfov;
extern consvar_t cv_grmodels; extern consvar_t cv_grmodels;
extern consvar_t cv_grmodelinterpolation; extern consvar_t cv_grmodelinterpolation;
extern consvar_t cv_grmodellighting;
extern consvar_t cv_grfog; extern consvar_t cv_grfog;
extern consvar_t cv_grfogcolor; extern consvar_t cv_grfogcolor;
extern consvar_t cv_grfogdensity; extern consvar_t cv_grfogdensity;
extern consvar_t cv_grsoftwarefog; extern consvar_t cv_grsoftwarefog;
extern consvar_t cv_grgammared;
extern consvar_t cv_grgammagreen;
extern consvar_t cv_grgammablue;
extern consvar_t cv_grfiltermode; extern consvar_t cv_grfiltermode;
extern consvar_t cv_granisotropicmode; extern consvar_t cv_granisotropicmode;
extern consvar_t cv_grcorrecttricks; extern consvar_t cv_grcorrecttricks;

View File

@ -239,7 +239,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
{ {
png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr); png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr);
png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->grInfo.data); png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRMODELTEXTURE, &grpatch->mipmap->grInfo.data);
png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep)); png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep));
for (i = 0; i < height; i++) for (i = 0; i < height; i++)
row_pointers[i] = PNG_image + i*pitch; row_pointers[i] = PNG_image + i*pitch;
@ -313,7 +313,7 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
pw = *w = header.xmax - header.xmin + 1; pw = *w = header.xmax - header.xmin + 1;
ph = *h = header.ymax - header.ymin + 1; ph = *h = header.ymax - header.ymin + 1;
image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->grInfo.data); image = Z_Malloc(pw*ph*4, PU_HWRMODELTEXTURE, &grpatch->mipmap->grInfo.data);
if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE) if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE)
{ {
@ -373,6 +373,9 @@ static void md2_loadTexture(md2_t *model)
if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data) if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data)
{ {
int w = 0, h = 0; int w = 0, h = 0;
UINT32 size;
RGBA_t *image;
#ifdef HAVE_PNG #ifdef HAVE_PNG
grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch); grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->grInfo.format == 0) if (grpatch->mipmap->grInfo.format == 0)
@ -389,6 +392,15 @@ static void md2_loadTexture(md2_t *model)
grpatch->mipmap->width = (UINT16)w; grpatch->mipmap->width = (UINT16)w;
grpatch->mipmap->height = (UINT16)h; grpatch->mipmap->height = (UINT16)h;
// Lactozilla: Apply colour cube
image = grpatch->mipmap->grInfo.data;
size = w*h;
while (size--)
{
V_CubeApply(&image->s.red, &image->s.green, &image->s.blue);
image++;
}
#ifdef GLIDE_API_COMPATIBILITY #ifdef GLIDE_API_COMPATIBILITY
// not correct! // not correct!
grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256;
@ -397,7 +409,6 @@ static void md2_loadTexture(md2_t *model)
#endif #endif
} }
HWD.pfnSetTexture(grpatch->mipmap); HWD.pfnSetTexture(grpatch->mipmap);
HWR_UnlockCachedPatch(grpatch);
} }
// -----------------+ // -----------------+
@ -453,7 +464,6 @@ static void md2_loadBlendTexture(md2_t *model)
#endif #endif
} }
HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(grpatch);
Z_Free(filename); Z_Free(filename);
} }
@ -637,18 +647,20 @@ spritemd2found:
// 0.7152 to green // 0.7152 to green
// 0.0722 to blue // 0.0722 to blue
#define SETBRIGHTNESS(brightness,r,g,b) \ #define SETBRIGHTNESS(brightness,r,g,b) \
brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000))
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color)
{ {
UINT8 i;
UINT16 w = gpatch->width, h = gpatch->height; UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h; UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor; RGBA_t *image, *blendimage, *cur, blendcolor;
// vanilla port
UINT8 translation[16];
memset(translation, 0, sizeof(translation));
if (grmip->width == 0) if (grmip->width == 0)
{ {
grmip->width = gpatch->width; grmip->width = gpatch->width;
grmip->height = gpatch->height; grmip->height = gpatch->height;
@ -658,80 +670,58 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
grmip->grInfo.format = GR_RGBA; grmip->grInfo.format = GR_RGBA;
} }
Z_Free(grmip->grInfo.data); if (grmip->grInfo.data)
grmip->grInfo.data = NULL; {
Z_Free(grmip->grInfo.data);
grmip->grInfo.data = NULL;
}
cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->grInfo.data); cur = Z_Malloc(size*4, PU_HWRMODELTEXTURE, &grmip->grInfo.data);
memset(cur, 0x00, size*4); memset(cur, 0x00, size*4);
image = gpatch->mipmap->grInfo.data; image = gpatch->mipmap->grInfo.data;
blendimage = blendgpatch->mipmap->grInfo.data; blendimage = blendgpatch->mipmap->grInfo.data;
blendcolor = V_GetColor(0); // initialize
// Average all of the translation's colors if (color != SKINCOLOR_NONE)
if (color == SKINCOLOR_NONE || color >= MAXTRANSLATIONS) memcpy(&translation, &Color_Index[color - 1], 16);
blendcolor = V_GetColor(0xff);
else while (size--)
{ {
const UINT8 div = 6; if (skinnum == TC_BOSS)
const UINT8 start = 4;
UINT32 r, g, b;
blendcolor = V_GetColor(Color_Index[color-1][start]);
r = (UINT32)(blendcolor.s.red*blendcolor.s.red);
g = (UINT32)(blendcolor.s.green*blendcolor.s.green);
b = (UINT32)(blendcolor.s.blue*blendcolor.s.blue);
for (i = 1; i < div; i++)
{ {
RGBA_t nextcolor = V_GetColor(Color_Index[color-1][start+i]); // Turn everything below a certain threshold white
r += (UINT32)(nextcolor.s.red*nextcolor.s.red); if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue <= 82)
g += (UINT32)(nextcolor.s.green*nextcolor.s.green);
b += (UINT32)(nextcolor.s.blue*nextcolor.s.blue);
}
blendcolor.s.red = (UINT8)(FixedSqrt((r/div)<<FRACBITS)>>FRACBITS);
blendcolor.s.green = (UINT8)(FixedSqrt((g/div)<<FRACBITS)>>FRACBITS);
blendcolor.s.blue = (UINT8)(FixedSqrt((b/div)<<FRACBITS)>>FRACBITS);
}
// rainbow support, could theoretically support boss ones too
if (skinnum == TC_RAINBOW)
{
while (size--)
{
if (image->s.alpha == 0 && blendimage->s.alpha == 0)
{ {
// Don't bother with blending the pixel if the alpha of the blend pixel is 0 // Lactozilla: Invert the colors
cur->rgba = image->rgba; cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue);
} }
else else
{ {
UINT32 tempcolor; cur->s.red = image->s.red;
UINT16 imagebright, blendbright, finalbright, colorbright; cur->s.green = image->s.green;
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); cur->s.blue = image->s.blue;
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
finalbright = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
tempcolor = (finalbright*blendcolor.s.red)/colorbright;
tempcolor = min(255, tempcolor);
cur->s.red = (UINT8)tempcolor;
tempcolor = (finalbright*blendcolor.s.green)/colorbright;
tempcolor = min(255, tempcolor);
cur->s.green = (UINT8)tempcolor;
tempcolor = (finalbright*blendcolor.s.blue)/colorbright;
tempcolor = min(255, tempcolor);
cur->s.blue = (UINT8)tempcolor;
cur->s.alpha = image->s.alpha;
} }
cur++; image++; blendimage++; cur->s.alpha = image->s.alpha;
} }
} else if (skinnum == TC_METALSONIC)
else if (skinnum == TC_DASHMODE) {
{ // Turn everything below a certain blue threshold white
while (size--) if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82)
{
cur->s.red = cur->s.green = cur->s.blue = 255;
}
else
{
cur->s.red = image->s.red;
cur->s.green = image->s.green;
cur->s.blue = image->s.blue;
}
cur->s.alpha = image->s.alpha;
}
else if (skinnum == TC_DASHMODE)
{ {
if (image->s.alpha == 0 && blendimage->s.alpha == 0) if (image->s.alpha == 0 && blendimage->s.alpha == 0)
{ {
@ -761,45 +751,194 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255; cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255;
cur->s.alpha = image->s.alpha; cur->s.alpha = image->s.alpha;
} }
cur++; image++; blendimage++;
} }
} else if (skinnum == TC_ALLWHITE)
else
{
while (size--)
{ {
if (blendimage->s.alpha == 0) // Turn everything white
cur->s.red = cur->s.green = cur->s.blue = 255;
cur->s.alpha = image->s.alpha;
}
else
{
UINT16 brightness;
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
if (skinnum == TC_RAINBOW)
{ {
// Don't bother with blending the pixel if the alpha of the blend pixel is 0 if (image->s.alpha == 0 && blendimage->s.alpha == 0)
cur->rgba = image->rgba; {
cur->rgba = image->rgba;
cur++; image++; blendimage++;
continue;
}
else
{
UINT16 imagebright, blendbright;
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
}
} }
else else
{ {
INT32 tempcolor; if (blendimage->s.alpha == 0)
INT16 tempmult, tempalpha; {
tempalpha = -(abs(blendimage->s.red-127)-127)*2; cur->rgba = image->rgba;
if (tempalpha > 255) cur++; image++; blendimage++;
tempalpha = 255; continue;
else if (tempalpha < 0) }
tempalpha = 0; else
{
SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
}
}
tempmult = (blendimage->s.red-127)*2; // Calculate a sort of "gradient" for the skincolor
if (tempmult > 255) // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
tempmult = 255; {
else if (tempmult < 0) RGBA_t nextcolor;
tempmult = 0; UINT8 firsti, secondi, mul;
UINT32 r, g, b;
tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors.
// Ensue horrible mess.
if (skinnum == TC_RAINBOW)
{
UINT16 brightdif = 256;
UINT8 colorbrightnesses[16];
INT32 compare, m, d;
UINT8 i;
// Ignore pure white & pitch black
if (brightness > 253 || brightness < 2)
{
cur->rgba = image->rgba;
cur++; image++; blendimage++;
continue;
}
firsti = 0;
mul = 0;
for (i = 0; i < 16; i++)
{
RGBA_t tempc = V_GetColor(translation[i]);
SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison
}
for (i = 0; i < 16; i++)
{
if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is)
continue;
compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness));
if (compare < brightdif)
{
brightdif = (UINT16)compare;
firsti = i; // best matching color that's equal brightness or darker
}
}
secondi = firsti+1; // next color in line
if (secondi == 16)
{
m = (INT16)brightness; // - 0;
d = (INT16)colorbrightnesses[firsti]; // - 0;
}
else
{
m = (INT16)brightness - (INT16)colorbrightnesses[secondi];
d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi];
}
if (m >= d)
m = d-1;
// calculate the "gradient" multiplier based on how close this color is to the one next in line
if (m <= 0 || d <= 0)
mul = 0;
else
mul = 15 - ((m * 16) / d);
}
else
{
// Thankfully, it's normally way more simple.
// Just convert brightness to a skincolor value, use remainder to find the gradient multipler
firsti = ((UINT8)(255-brightness) / 16);
secondi = firsti+1;
mul = ((UINT8)(255-brightness) % 16);
}
blendcolor = V_GetColor(translation[firsti]);
if (mul > 0 // If it's 0, then we only need the first color.
&& translation[firsti] != translation[secondi]) // Some colors have duplicate colors in a row, so let's just save the process
{
if (secondi == 16) // blend to black
nextcolor = V_GetColor(31);
else
nextcolor = V_GetColor(translation[secondi]);
// Find difference between points
r = (UINT32)(nextcolor.s.red - blendcolor.s.red);
g = (UINT32)(nextcolor.s.green - blendcolor.s.green);
b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue);
// Find the gradient of the two points
r = ((mul * r) / 16);
g = ((mul * g) / 16);
b = ((mul * b) / 16);
// Add gradient value to color
blendcolor.s.red += r;
blendcolor.s.green += g;
blendcolor.s.blue += b;
}
}
if (skinnum == TC_RAINBOW)
{
UINT32 tempcolor;
UINT16 colorbright;
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
if (colorbright == 0)
colorbright = 1; // no dividing by 0 please
tempcolor = (brightness * blendcolor.s.red) / colorbright;
tempcolor = min(255, tempcolor);
cur->s.red = (UINT8)tempcolor; cur->s.red = (UINT8)tempcolor;
tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255;
tempcolor = (brightness * blendcolor.s.green) / colorbright;
tempcolor = min(255, tempcolor);
cur->s.green = (UINT8)tempcolor; cur->s.green = (UINT8)tempcolor;
tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255;
tempcolor = (brightness * blendcolor.s.blue) / colorbright;
tempcolor = min(255, tempcolor);
cur->s.blue = (UINT8)tempcolor; cur->s.blue = (UINT8)tempcolor;
cur->s.alpha = image->s.alpha; cur->s.alpha = image->s.alpha;
} }
else
{
// Color strength depends on image alpha
INT32 tempcolor;
cur++; image++; blendimage++; tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255);
tempcolor = min(255, tempcolor);
cur->s.red = (UINT8)tempcolor;
tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255);
tempcolor = min(255, tempcolor);
cur->s.green = (UINT8)tempcolor;
tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255);
tempcolor = min(255, tempcolor);
cur->s.blue = (UINT8)tempcolor;
cur->s.alpha = image->s.alpha;
}
} }
cur++; image++; blendimage++;
} }
return; return;
@ -812,24 +951,24 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
// mostly copied from HWR_GetMappedPatch, hence the similarities and comment // mostly copied from HWR_GetMappedPatch, hence the similarities and comment
GLMipmap_t *grmip, *newmip; GLMipmap_t *grmip, *newmip;
if (colormap == colormaps || colormap == NULL) if ((colormap == colormaps || colormap == NULL) && (skinnum > TC_DEFAULT))
{ {
// Don't do any blending // Don't do any blending
HWD.pfnSetTexture(gpatch->mipmap); HWD.pfnSetTexture(gpatch->mipmap);
return; return;
} }
// search for the mimmap // search for the mipmap
// skip the first (no colormap translated) // skip the first (no colormap translated)
for (grmip = gpatch->mipmap; grmip->nextcolormap; ) for (grmip = gpatch->mipmap; grmip->nextcolormap; )
{ {
grmip = grmip->nextcolormap; grmip = grmip->nextcolormap;
if (grmip->colormap == colormap) if (grmip->colormap == colormap || grmip->tcindex == skinnum)
{ {
if (grmip->downloaded && grmip->grInfo.data) if (grmip->downloaded && grmip->grInfo.data)
{ {
HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(grmip->grInfo.data, PU_HWRMODELTEXTURE);
return; return;
} }
} }
@ -847,16 +986,27 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
I_Error("%s: Out of memory", "HWR_GetMappedPatch"); I_Error("%s: Out of memory", "HWR_GetMappedPatch");
grmip->nextcolormap = newmip; grmip->nextcolormap = newmip;
newmip->colormap = colormap; newmip->colormap = colormap;
newmip->tcindex = skinnum;
HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color); HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color);
HWD.pfnSetTexture(newmip); HWD.pfnSetTexture(newmip);
Z_ChangeTag(newmip->grInfo.data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(newmip->grInfo.data, PU_HWRMODELTEXTURE);
} }
#define NORMALFOG 0x00000000 #define NORMALFOG 0x00000000
#define FADEFOG 0x19000000 #define FADEFOG 0x19000000
static boolean HWR_AllowModel(mobj_t *mobj)
{
// Signpost overlay. Not needed.
if (mobj->state-states == S_PLAY_SIGN)
return false;
// Otherwise, render the model.
return true;
}
static boolean HWR_CanInterpolateModel(mobj_t *mobj, model_t *model) static boolean HWR_CanInterpolateModel(mobj_t *mobj, model_t *model)
{ {
if (cv_grmodelinterpolation.value == 2) // Always interpolate if (cv_grmodelinterpolation.value == 2) // Always interpolate
@ -932,7 +1082,7 @@ static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t
// HWR_DrawModel // HWR_DrawModel
// //
void HWR_DrawModel(gr_vissprite_t *spr) boolean HWR_DrawModel(gr_vissprite_t *spr)
{ {
FSurfaceInfo Surf; FSurfaceInfo Surf;
@ -945,10 +1095,12 @@ void HWR_DrawModel(gr_vissprite_t *spr)
UINT8 color[4]; UINT8 color[4];
if (!cv_grmodels.value) if (!cv_grmodels.value)
return; return false;
if (spr->precip) if (spr->precip)
return; return false;
memset(&p, 0x00, sizeof(FTransform));
// MD2 colormap fix // MD2 colormap fix
// colormap test // colormap test
@ -1036,7 +1188,7 @@ void HWR_DrawModel(gr_vissprite_t *spr)
} }
if (md2->error) if (md2->error)
return; // we already failed loading this before :( return false; // we already failed loading this before :(
if (!md2->model) if (!md2->model)
{ {
//CONS_Debug(DBG_RENDER, "Loading model... (%s)", sprnames[spr->mobj->sprite]); //CONS_Debug(DBG_RENDER, "Loading model... (%s)", sprnames[spr->mobj->sprite]);
@ -1052,9 +1204,14 @@ void HWR_DrawModel(gr_vissprite_t *spr)
{ {
//CONS_Debug(DBG_RENDER, " FAILED\n"); //CONS_Debug(DBG_RENDER, " FAILED\n");
md2->error = true; // prevent endless fail md2->error = true; // prevent endless fail
return; return false;
} }
} }
// Lactozilla: Disallow certain models from rendering
if (!HWR_AllowModel(spr->mobj))
return false;
//HWD.pfnSetBlend(blend); // This seems to actually break translucency? //HWD.pfnSetBlend(blend); // This seems to actually break translucency?
finalscale = md2->scale; finalscale = md2->scale;
//Hurdler: arf, I don't like that implementation at all... too much crappy //Hurdler: arf, I don't like that implementation at all... too much crappy
@ -1069,11 +1226,10 @@ void HWR_DrawModel(gr_vissprite_t *spr)
if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
{ {
if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE && if (md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format
md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format
&& gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height)
{ {
INT32 skinnum = TC_DEFAULT; INT32 skinnum = INT32_MAX;
if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
{ {
if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized)
@ -1083,7 +1239,7 @@ void HWR_DrawModel(gr_vissprite_t *spr)
else else
skinnum = TC_BOSS; skinnum = TC_BOSS;
} }
else if (spr->mobj->color) else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE)
{ {
if (spr->mobj->colorized) if (spr->mobj->colorized)
skinnum = TC_RAINBOW; skinnum = TC_RAINBOW;
@ -1101,7 +1257,15 @@ void HWR_DrawModel(gr_vissprite_t *spr)
else else
skinnum = TC_DEFAULT; skinnum = TC_DEFAULT;
} }
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color);
// Translation or skin number found
if (skinnum != INT32_MAX)
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color);
else
{
// Sorry nothing
HWD.pfnSetTexture(gpatch->mipmap);
}
} }
else else
{ {
@ -1279,6 +1443,8 @@ void HWR_DrawModel(gr_vissprite_t *spr)
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color);
} }
return true;
} }
#endif //HWRENDER #endif //HWRENDER

View File

@ -45,8 +45,8 @@ extern md2_t md2_models[NUMSPRITES];
extern md2_t md2_playermodels[MAXSKINS]; extern md2_t md2_playermodels[MAXSKINS];
void HWR_InitModels(void); void HWR_InitModels(void);
void HWR_DrawModel(gr_vissprite_t *spr);
void HWR_AddPlayerModel(INT32 skin); void HWR_AddPlayerModel(INT32 skin);
void HWR_AddSpriteModel(size_t spritenum); void HWR_AddSpriteModel(size_t spritenum);
boolean HWR_DrawModel(gr_vissprite_t *spr);
#endif // _HW_MD2_H_ #endif // _HW_MD2_H_

View File

@ -564,20 +564,15 @@ EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl)
// : in OpenGL, we store values for conversion of paletted graphics when // : in OpenGL, we store values for conversion of paletted graphics when
// : they are downloaded to the 3D card. // : they are downloaded to the 3D card.
// -----------------+ // -----------------+
EXPORT void HWRAPI(SetPalette) (RGBA_t *pal, RGBA_t *gamma) EXPORT void HWRAPI(SetPalette) (RGBA_t *pal)
{ {
INT32 i; size_t palsize = (sizeof(RGBA_t) * 256);
for (i = 0; i < 256; i++)
{
myPaletteData[i].s.red = (UINT8)MIN((pal[i].s.red*gamma->s.red)/127, 255);
myPaletteData[i].s.green = (UINT8)MIN((pal[i].s.green*gamma->s.green)/127, 255);
myPaletteData[i].s.blue = (UINT8)MIN((pal[i].s.blue*gamma->s.blue)/127, 255);
myPaletteData[i].s.alpha = pal[i].s.alpha;
}
// on a palette change, you have to reload all of the textures // on a palette change, you have to reload all of the textures
Flush(); if (memcmp(&myPaletteData, pal, palsize))
{
memcpy(&myPaletteData, pal, palsize);
Flush();
}
} }
#endif #endif

View File

@ -85,7 +85,7 @@ static GLboolean MipMap = GL_FALSE;
static GLint min_filter = GL_LINEAR; static GLint min_filter = GL_LINEAR;
static GLint mag_filter = GL_LINEAR; static GLint mag_filter = GL_LINEAR;
static GLint anisotropic_filter = 0; static GLint anisotropic_filter = 0;
static FTransform md2_transform; static boolean model_lighting = true;
const GLubyte *gl_extensions = NULL; const GLubyte *gl_extensions = NULL;
@ -723,8 +723,8 @@ void Flush(void)
while (gr_cachehead) while (gr_cachehead)
{ {
// ceci n'est pas du tout necessaire vu que tu les a charger normalement et // this is not necessary at all, because you have loaded them normally,
// donc il sont dans ta liste ! // and so they already are in your list!
#if 0 #if 0
//Hurdler: 25/04/2000: now support colormap in hardware mode //Hurdler: 25/04/2000: now support colormap in hardware mode
FTextureInfo *tmp = gr_cachehead->nextskin; FTextureInfo *tmp = gr_cachehead->nextskin;
@ -1296,11 +1296,11 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
pTexInfo->nextmipmap = NULL; pTexInfo->nextmipmap = NULL;
if (gr_cachetail) if (gr_cachetail)
{ // insertion en fin de liste { // insertion at the tail
gr_cachetail->nextmipmap = pTexInfo; gr_cachetail->nextmipmap = pTexInfo;
gr_cachetail = pTexInfo; gr_cachetail = pTexInfo;
} }
else // initialisation de la liste else // initialization of the linked list
gr_cachetail = gr_cachehead = pTexInfo; gr_cachetail = gr_cachehead = pTexInfo;
} }
} }
@ -1659,16 +1659,9 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
{ {
switch (IdState) switch (IdState)
{ {
case HWD_SET_MODEL_LIGHTING:
#if 0 model_lighting = Value;
case 77:
{
//08/01/00: Hurdler this is a test for mirror
if (!Value)
ClearBuffer(false, true, 0); // clear depth buffer
break; break;
}
#endif
case HWD_SET_FOG_COLOR: case HWD_SET_FOG_COLOR:
{ {
@ -1681,6 +1674,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
pglFogfv(GL_FOG_COLOR, fogcolor); pglFogfv(GL_FOG_COLOR, fogcolor);
break; break;
} }
case HWD_SET_FOG_DENSITY: case HWD_SET_FOG_DENSITY:
pglFogf(GL_FOG_DENSITY, Value*1200/(500*1000000.0f)); pglFogf(GL_FOG_DENSITY, Value*1200/(500*1000000.0f));
break; break;
@ -2045,16 +2039,25 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
} }
#endif #endif
pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); if (model_lighting)
{
pglLightfv(GL_LIGHT0, GL_POSITION, LightPos);
pglShadeModel(GL_SMOOTH);
}
pglShadeModel(GL_SMOOTH);
if (color) if (color)
{ {
#ifdef GL_LIGHT_MODEL_AMBIENT #ifdef GL_LIGHT_MODEL_AMBIENT
pglEnable(GL_LIGHTING); if (model_lighting)
pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); {
pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); pglEnable(GL_LIGHTING);
pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
}
else
#endif #endif
pglColor4ubv((GLubyte*)color);
if (color[3] < 255) if (color[3] < 255)
SetBlend(PF_Translucent|PF_Modulated|PF_Clip); SetBlend(PF_Translucent|PF_Modulated|PF_Clip);
else else
@ -2225,8 +2228,6 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
if (stransform) if (stransform)
{ {
boolean fovx90; boolean fovx90;
// keep a trace of the transformation for md2
memcpy(&md2_transform, stransform, sizeof (md2_transform));
#ifdef USE_FTRANSFORM_MIRROR #ifdef USE_FTRANSFORM_MIRROR
// mirroring from Kart // mirroring from Kart

View File

@ -309,7 +309,7 @@ static void M_ChangeControl(INT32 choice);
// Video & Sound // Video & Sound
menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef; menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef;
#ifdef HWRENDER #ifdef HWRENDER
menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef; menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef;
#endif #endif
menu_t OP_SoundOptionsDef; menu_t OP_SoundOptionsDef;
menu_t OP_SoundAdvancedDef; menu_t OP_SoundAdvancedDef;
@ -355,7 +355,6 @@ static void M_DrawScreenshotMenu(void);
static void M_DrawMonitorToggles(void); static void M_DrawMonitorToggles(void);
#ifdef HWRENDER #ifdef HWRENDER
static void M_OGL_DrawFogMenu(void); static void M_OGL_DrawFogMenu(void);
static void M_OGL_DrawColorMenu(void);
#endif #endif
#ifndef NONET #ifndef NONET
static void M_DrawScreenshotMenu(void); static void M_DrawScreenshotMenu(void);
@ -1300,21 +1299,25 @@ static menuitem_t OP_ColorOptionsMenu[] =
#ifdef HWRENDER #ifdef HWRENDER
static menuitem_t OP_OpenGLOptionsMenu[] = static menuitem_t OP_OpenGLOptionsMenu[] =
{ {
{IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 10}, {IT_HEADER, NULL, "3D Models", NULL, 0},
{IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 20}, {IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 12},
{IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 22},
{IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32},
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 40}, {IT_HEADER, NULL, "General", NULL, 51},
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 50}, {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 62},
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 60}, {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 72},
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,70}, {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 82},
#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,92},
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 80},
#endif {IT_HEADER, NULL, "Miscellaneous", NULL, 111},
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 123},
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 100}, {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 133},
#endif
#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)))
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 143},
#endif #endif
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 110},
{IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 120},
}; };
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
@ -1334,13 +1337,6 @@ static menuitem_t OP_OpenGLFogMenu[] =
{IT_STRING|IT_CVAR, NULL, "Fog density", &cv_grfogdensity, 30}, {IT_STRING|IT_CVAR, NULL, "Fog density", &cv_grfogdensity, 30},
{IT_STRING|IT_CVAR, NULL, "Software Fog",&cv_grsoftwarefog,40}, {IT_STRING|IT_CVAR, NULL, "Software Fog",&cv_grsoftwarefog,40},
}; };
static menuitem_t OP_OpenGLColorMenu[] =
{
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "red", &cv_grgammared, 10},
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "green", &cv_grgammagreen, 20},
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "blue", &cv_grgammablue, 30},
};
#endif #endif
static menuitem_t OP_SoundOptionsMenu[] = static menuitem_t OP_SoundOptionsMenu[] =
@ -2027,18 +2023,6 @@ menu_t OP_OpenGLFogDef =
0, 0,
NULL NULL
}; };
menu_t OP_OpenGLColorDef =
{
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_COLOR << 18),
"M_VIDEO",
sizeof (OP_OpenGLColorMenu)/sizeof (menuitem_t),
&OP_OpenGLOptionsDef,
OP_OpenGLColorMenu,
M_OGL_DrawColorMenu,
60, 40,
0,
NULL
};
#endif #endif
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE( menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6), MN_OP_MAIN + (MN_OP_DATA << 6),
@ -11931,20 +11915,6 @@ static void M_OGL_DrawFogMenu(void)
my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_' | 0x80,false); my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_' | 0x80,false);
} }
// =====================
// M_OGL_DrawColorMenu()
// =====================
static void M_OGL_DrawColorMenu(void)
{
INT32 mx, my;
mx = currentMenu->x;
my = currentMenu->y;
M_DrawGenericMenu(); // use generic drawer for cursor, items and title
V_DrawString(mx, my + currentMenu->menuitems[0].alphaKey - 10,
V_YELLOWMAP, "Gamma correction");
}
//=================== //===================
// M_HandleFogColor() // M_HandleFogColor()
//=================== //===================

View File

@ -3019,8 +3019,15 @@ boolean P_SetupLevel(boolean skipprecip)
P_SpawnPrecipitation(); P_SpawnPrecipitation();
#ifdef HWRENDER // not win32 only 19990829 by Kin #ifdef HWRENDER // not win32 only 19990829 by Kin
if (rendermode != render_soft && rendermode != render_none) if (rendermode == render_opengl)
{ {
// Lactozilla (December 8, 2019)
// Level setup used to free EVERY mipmap from memory.
// Even mipmaps that aren't related to level textures.
// Presumably, the hardware render code used to store textures as level data.
// Meaning, they had memory allocated and marked with the PU_LEVEL tag.
// Level textures are only reloaded after R_LoadTextures, which is
// when the texture list is loaded.
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
// BP: reset light between levels (we draw preview frame lights on current frame) // BP: reset light between levels (we draw preview frame lights on current frame)
HWR_ResetLights(); HWR_ResetLights();
@ -3175,11 +3182,6 @@ boolean P_SetupLevel(boolean skipprecip)
if (!cv_analog2.changed) if (!cv_analog2.changed)
CV_SetValue(&cv_analog2, 0); CV_SetValue(&cv_analog2, 0);
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
CV_Set(&cv_grfov, cv_grfov.defaultvalue);
#endif
displayplayer = consoleplayer; // Start with your OWN view, please! displayplayer = consoleplayer; // Start with your OWN view, please!
} }
@ -3203,14 +3205,6 @@ boolean P_SetupLevel(boolean skipprecip)
// Fab : 19-07-98 : start cd music for this level (note: can be remapped) // Fab : 19-07-98 : start cd music for this level (note: can be remapped)
I_PlayCD((UINT8)(gamemap), false); I_PlayCD((UINT8)(gamemap), false);
// preload graphics
#ifdef HWRENDER // not win32 only 19990829 by Kin
if (rendermode != render_soft && rendermode != render_none)
{
HWR_PrepLevelCache(numtextures);
}
#endif
P_MapEnd(); P_MapEnd();
// Remove the loading shit from the screen // Remove the loading shit from the screen

View File

@ -32,6 +32,10 @@
#include <malloc.h> // alloca(sizeof) #include <malloc.h> // alloca(sizeof)
#endif #endif
#ifdef HWRENDER
#include "hardware/hw_main.h" // HWR_LoadTextures
#endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma pack(1) #pragma pack(1)
#endif #endif
@ -872,6 +876,11 @@ void R_LoadTextures(void)
i++; i++;
} }
} }
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_LoadTextures(numtextures);
#endif
} }
static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)

View File

@ -1210,30 +1210,4 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_maxportals); CV_RegisterVar(&cv_maxportals);
CV_RegisterVar(&cv_movebob); CV_RegisterVar(&cv_movebob);
#ifdef HWRENDER
// GL-specific Commands
CV_RegisterVar(&cv_grgammablue);
CV_RegisterVar(&cv_grgammagreen);
CV_RegisterVar(&cv_grgammared);
CV_RegisterVar(&cv_grfovchange);
CV_RegisterVar(&cv_grfog);
CV_RegisterVar(&cv_grfogcolor);
CV_RegisterVar(&cv_grsoftwarefog);
#ifdef ALAM_LIGHTING
CV_RegisterVar(&cv_grstaticlighting);
CV_RegisterVar(&cv_grdynamiclighting);
CV_RegisterVar(&cv_grcoronas);
CV_RegisterVar(&cv_grcoronasize);
#endif
CV_RegisterVar(&cv_grmodelinterpolation);
CV_RegisterVar(&cv_grmodels);
CV_RegisterVar(&cv_grspritebillboarding);
CV_RegisterVar(&cv_grskydome);
#endif
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
HWR_AddCommands();
#endif
} }

View File

@ -222,20 +222,15 @@ void OglSdlFinishUpdate(boolean waitvbl)
HWR_DrawScreenFinalTexture(realwidth, realheight); HWR_DrawScreenFinalTexture(realwidth, realheight);
} }
EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette)
{ {
INT32 i = -1; size_t palsize = (sizeof(RGBA_t) * 256);
UINT32 redgamma = pgamma->s.red, greengamma = pgamma->s.green, // on a palette change, you have to reload all of the textures
bluegamma = pgamma->s.blue; if (memcmp(&myPaletteData, palette, palsize))
for (i = 0; i < 256; i++)
{ {
myPaletteData[i].s.red = (UINT8)MIN((palette[i].s.red * redgamma) /127, 255); memcpy(&myPaletteData, palette, palsize);
myPaletteData[i].s.green = (UINT8)MIN((palette[i].s.green * greengamma)/127, 255); Flush();
myPaletteData[i].s.blue = (UINT8)MIN((palette[i].s.blue * bluegamma) /127, 255);
myPaletteData[i].s.alpha = palette[i].s.alpha;
} }
Flush();
} }
#endif //HWRENDER #endif //HWRENDER

View File

@ -31,5 +31,5 @@ extern Uint16 realwidth;
extern Uint16 realheight; extern Uint16 realheight;
#ifdef _CREATE_DLL_ #ifdef _CREATE_DLL_
EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette, RGBA_t *pgamma); EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette);
#endif #endif

View File

@ -84,39 +84,6 @@ static CV_PossibleValue_t constextsize_cons_t[] = {
static void CV_constextsize_OnChange(void); static void CV_constextsize_OnChange(void);
consvar_t cv_constextsize = {"con_textsize", "Medium", CV_SAVE|CV_CALL, constextsize_cons_t, CV_constextsize_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_constextsize = {"con_textsize", "Medium", CV_SAVE|CV_CALL, constextsize_cons_t, CV_constextsize_OnChange, 0, NULL, NULL, 0, 0, NULL};
#ifdef HWRENDER
static void CV_Gammaxxx_ONChange(void);
// Saved hardware mode variables
// - You can change them in software,
// but they won't do anything.
static CV_PossibleValue_t grgamma_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}};
static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}};
consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grgammared = {"gr_gammared", "127", CV_SAVE|CV_CALL, grgamma_cons_t,
CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grgammagreen = {"gr_gammagreen", "127", CV_SAVE|CV_CALL, grgamma_cons_t,
CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grgammablue = {"gr_gammablue", "127", CV_SAVE|CV_CALL, grgamma_cons_t,
CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL};
#ifdef ALAM_LIGHTING
consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
// local copy of the palette for V_GetColor() // local copy of the palette for V_GetColor()
RGBA_t *pLocalPalette = NULL; RGBA_t *pLocalPalette = NULL;
RGBA_t *pMasterPalette = NULL; RGBA_t *pMasterPalette = NULL;
@ -128,6 +95,7 @@ Please check it out if you're trying to maintain this.
toast 18/04/17 toast 18/04/17
*/ */
float Cubepal[2][2][2][3]; float Cubepal[2][2][2][3];
boolean Cubeapply = false;
// returns whether to apply cube, selectively avoiding expensive operations // returns whether to apply cube, selectively avoiding expensive operations
static boolean InitCube(void) static boolean InitCube(void)
@ -343,11 +311,12 @@ const UINT8 correctiontable[256] =
// keep a copy of the palette so that we can get the RGB value for a color index at any time. // keep a copy of the palette so that we can get the RGB value for a color index at any time.
static void LoadPalette(const char *lumpname) static void LoadPalette(const char *lumpname)
{ {
boolean cube = InitCube();
lumpnum_t lumpnum = W_GetNumForName(lumpname); lumpnum_t lumpnum = W_GetNumForName(lumpname);
size_t i, palsize = W_LumpLength(lumpnum)/3; size_t i, palsize = W_LumpLength(lumpnum)/3;
UINT8 *pal; UINT8 *pal;
Cubeapply = InitCube();
Z_Free(pLocalPalette); Z_Free(pLocalPalette);
Z_Free(pMasterPalette); Z_Free(pMasterPalette);
@ -369,43 +338,49 @@ static void LoadPalette(const char *lumpname)
pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF; pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF;
// lerp of colour cubing! if you want, make it smoother yourself // lerp of colour cubing! if you want, make it smoother yourself
if (cube) if (Cubeapply)
{ V_CubeApply(&pLocalPalette[i].s.red, &pLocalPalette[i].s.green, &pLocalPalette[i].s.blue);
float working[4][3]; }
float linear; }
UINT8 q;
linear = (pLocalPalette[i].s.red/255.0); void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue)
{
float working[4][3];
float linear;
UINT8 q;
if (!Cubeapply)
return;
linear = (*red/255.0);
#define dolerp(e1, e2) ((1 - linear)*e1 + linear*e2) #define dolerp(e1, e2) ((1 - linear)*e1 + linear*e2)
for (q = 0; q < 3; q++) for (q = 0; q < 3; q++)
{ {
working[0][q] = dolerp(Cubepal[0][0][0][q], Cubepal[1][0][0][q]); working[0][q] = dolerp(Cubepal[0][0][0][q], Cubepal[1][0][0][q]);
working[1][q] = dolerp(Cubepal[0][1][0][q], Cubepal[1][1][0][q]); working[1][q] = dolerp(Cubepal[0][1][0][q], Cubepal[1][1][0][q]);
working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]); working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]);
working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]); working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]);
} }
linear = (pLocalPalette[i].s.green/255.0); linear = (*green/255.0);
for (q = 0; q < 3; q++) for (q = 0; q < 3; q++)
{ {
working[0][q] = dolerp(working[0][q], working[1][q]); working[0][q] = dolerp(working[0][q], working[1][q]);
working[1][q] = dolerp(working[2][q], working[3][q]); working[1][q] = dolerp(working[2][q], working[3][q]);
} }
linear = (pLocalPalette[i].s.blue/255.0); linear = (*blue/255.0);
for (q = 0; q < 3; q++) for (q = 0; q < 3; q++)
{ {
working[0][q] = 255*dolerp(working[0][q], working[1][q]); working[0][q] = 255*dolerp(working[0][q], working[1][q]);
if (working[0][q] > 255.0) if (working[0][q] > 255.0)
working[0][q] = 255.0; working[0][q] = 255.0;
else if (working[0][q] < 0.0) else if (working[0][q] < 0.0)
working[0][q] = 0.0; working[0][q] = 0.0;
} }
#undef dolerp #undef dolerp
pLocalPalette[i].s.red = (UINT8)(working[0][0]); *red = (UINT8)(working[0][0]);
pLocalPalette[i].s.green = (UINT8)(working[0][1]); *green = (UINT8)(working[0][1]);
pLocalPalette[i].s.blue = (UINT8)(working[0][2]); *blue = (UINT8)(working[0][2]);
}
}
} }
const char *R_GetPalname(UINT16 num) const char *R_GetPalname(UINT16 num)
@ -473,16 +448,6 @@ static void CV_palette_OnChange(void)
V_SetPalette(0); V_SetPalette(0);
} }
// change the palette directly to see the change
#ifdef HWRENDER
static void CV_Gammaxxx_ONChange(void)
{
if (rendermode != render_soft && rendermode != render_none)
V_SetPalette(0);
}
#endif
#if defined (__GNUC__) && defined (__i386__) && !defined (NOASM) && !defined (__APPLE__) && !defined (NORUSEASM) #if defined (__GNUC__) && defined (__i386__) && !defined (NOASM) && !defined (__APPLE__) && !defined (NORUSEASM)
void VID_BlitLinearScreen_ASM(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes, void VID_BlitLinearScreen_ASM(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
size_t destrowbytes); size_t destrowbytes);

View File

@ -48,6 +48,8 @@ const char *GetPalette(void);
extern RGBA_t *pLocalPalette; extern RGBA_t *pLocalPalette;
extern RGBA_t *pMasterPalette; extern RGBA_t *pMasterPalette;
void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue);
// Retrieve the ARGB value from a palette color index // Retrieve the ARGB value from a palette color index
#define V_GetColor(color) (pLocalPalette[color&0xFF]) #define V_GetColor(color) (pLocalPalette[color&0xFF])

View File

@ -98,7 +98,7 @@ static loadfunc_t hwdFuncTable[] = {
{"Init@4", &hwdriver.pfnInit}, {"Init@4", &hwdriver.pfnInit},
{"Shutdown@0", &hwdriver.pfnShutdown}, {"Shutdown@0", &hwdriver.pfnShutdown},
{"GetModeList@8", &hwdriver.pfnGetModeList}, {"GetModeList@8", &hwdriver.pfnGetModeList},
{"SetPalette@8", &hwdriver.pfnSetPalette}, {"SetPalette@4", &hwdriver.pfnSetPalette},
{"FinishUpdate@4", &hwdriver.pfnFinishUpdate}, {"FinishUpdate@4", &hwdriver.pfnFinishUpdate},
{"Draw2DLine@12", &hwdriver.pfnDraw2DLine}, {"Draw2DLine@12", &hwdriver.pfnDraw2DLine},
{"DrawPolygon@16", &hwdriver.pfnDrawPolygon}, {"DrawPolygon@16", &hwdriver.pfnDrawPolygon},
@ -110,7 +110,7 @@ static loadfunc_t hwdFuncTable[] = {
{"GClipRect@20", &hwdriver.pfnGClipRect}, {"GClipRect@20", &hwdriver.pfnGClipRect},
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache}, {"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
{"SetSpecialState@8", &hwdriver.pfnSetSpecialState}, {"SetSpecialState@8", &hwdriver.pfnSetSpecialState},
{"DrawModel@16", &hwdriver.pfnDrawModel}, {"DrawModel@16", &hwdriver.pfnDrawModel},
{"SetTransform@4", &hwdriver.pfnSetTransform}, {"SetTransform@4", &hwdriver.pfnSetTransform},
{"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed}, {"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed},
{"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion}, {"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion},

View File

@ -46,6 +46,7 @@ enum
PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache
PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch
PU_HWRMODELTEXTURE = 23, // Hardware model texture
PU_HWRCACHE = 48, // static until unlocked PU_HWRCACHE = 48, // static until unlocked
PU_CACHE = 49, // static until unlocked PU_CACHE = 49, // static until unlocked