Merge remote-tracking branch 'Sryder13/master'

This commit is contained in:
Alam Ed Arias 2014-11-02 01:30:46 -04:00
commit 21edc49ea4
9 changed files with 798 additions and 64 deletions

View file

@ -172,15 +172,6 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
*/ */
static void F_DoWipe(fademask_t *fademask) static void F_DoWipe(fademask_t *fademask)
{ {
#ifdef HWRENDER
/// \todo Mask wipes for OpenGL
if(rendermode != render_soft)
{
HWR_DoScreenWipe();
return;
}
#endif
// Software mask wipe -- optimized; though it might not look like it! // Software mask wipe -- optimized; though it might not look like it!
// Okay, to save you wondering *how* this is more optimized than the simpler // Okay, to save you wondering *how* this is more optimized than the simpler
// version that came before it... // version that came before it...
@ -344,6 +335,11 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
I_Sleep(); I_Sleep();
lastwipetic = nowtime; lastwipetic = nowtime;
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_DoWipe(wipetype, wipeframe-1); // send in the wipe type and wipeframe because we need to cache the graphic
else
#endif
F_DoWipe(fmask); F_DoWipe(fmask);
I_OsPolling(); I_OsPolling();
I_UpdateNoBlit(); I_UpdateNoBlit();

View file

@ -452,7 +452,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp[grtex->mipmap.grInfo.format]==4) if (format2bpp[grtex->mipmap.grInfo.format]==4)
{ {
for (i = 3; i < blocksize; i += 4) for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp
{ {
if (block[i] == 0) if (block[i] == 0)
{ {
@ -1002,4 +1002,108 @@ GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum)
return HWR_GetCachedGLPatchPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); return HWR_GetCachedGLPatchPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
} }
// Need to do this because they aren't powers of 2
static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 pblockheight,
lumpnum_t fademasklumpnum, UINT16 fmwidth, UINT16 fmheight)
{
INT32 i,j;
fixed_t posx, posy, stepx, stepy;
UINT8 *block = mipmap->grInfo.data; // places the data directly into here, it already has the space allocated from HWR_ResizeBlock
UINT8 *flat;
UINT8 *dest, *src, texel;
RGBA_t col;
// Place the flats data into flat
W_ReadLump(fademasklumpnum, Z_Malloc(W_LumpLength(fademasklumpnum),
PU_HWRCACHE, &flat));
stepy = ((INT32)SHORT(fmheight)<<FRACBITS)/pblockheight;
stepx = ((INT32)SHORT(fmwidth)<<FRACBITS)/pblockwidth;
posy = 0;
for (j = 0; j < pblockheight; j++)
{
posx = 0;
dest = &block[j*blockwidth]; // 1bpp
src = &flat[(posy>>FRACBITS)*SHORT(fmwidth)];
for (i = 0; i < pblockwidth;i++)
{
// fademask bpp is always 1, and is used just for alpha
texel = src[(posx)>>FRACBITS];
col = V_GetColor(texel);
*dest = col.s.red; // take the red level of the colour and use it for alpha, as fademasks do
dest++;
posx += stepx;
}
posy += stepy;
}
Z_Free(flat);
}
static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum)
{
size_t size;
UINT16 fmheight = 0, fmwidth = 0;
UINT8 *block; // The fade mask's pixels
// setup the texture info
grMipmap->grInfo.format = GR_TEXFMT_ALPHA_8; // put the correct alpha levels straight in so I don't need to convert it later
grMipmap->flags = 0;
size = W_LumpLength(fademasklumpnum);
switch (size)
{
// None of these are powers of 2, so I'll need to do what is done for textures and make them powers of 2 before they can be used
case 256000: // 640x400
fmwidth = 640;
fmheight = 400;
break;
case 64000: // 320x200
fmwidth = 320;
fmheight = 200;
break;
case 16000: // 160x100
fmwidth = 160;
fmheight = 100;
break;
case 4000: // 80x50 (minimum)
fmwidth = 80;
fmheight = 50;
break;
default: // Bad lump
CONS_Alert(CONS_WARNING, "Fade mask lump of incorrect size, ignored\n"); // I should avoid this by checking the lumpnum in HWR_RunWipe
break;
}
// Thankfully, this will still work for this scenario
HWR_ResizeBlock(fmwidth, fmheight, &grMipmap->grInfo);
grMipmap->width = blockwidth;
grMipmap->height = blockheight;
block = MakeBlock(grMipmap);
HWR_DrawFadeMaskInCache(grMipmap, blockwidth, blockheight, fademasklumpnum, fmwidth, fmheight);
// I DO need to convert this because it isn't power of 2 and we need the alpha
}
void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
{
GLMipmap_t *grmip;
grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
if (!grmip->downloaded && !grmip->grInfo.data)
HWR_CacheFadeMask(grmip, fademasklumpnum);
HWD.pfnSetTexture(grmip);
// The system-memory data can be purged now.
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
}
#endif //HWRENDER #endif //HWRENDER

View file

@ -106,6 +106,7 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum);
void HWR_SetPalette(RGBA_t *palette); void HWR_SetPalette(RGBA_t *palette);
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump); GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum); GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
// -------- // --------
// hw_draw.c // hw_draw.c

View file

@ -66,6 +66,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
#ifdef SORTING #ifdef SORTING
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight, void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
#else #else
static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight, static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector); INT32 lightlevel, INT32 alpha, sector_t *FOFSector);
@ -1286,6 +1288,25 @@ static void HWR_SplitFog(sector_t *sector, wallVert3D *wallVerts, FSurfaceInfo*
HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Translucent|PF_NoTexture, true, lightnum, colormap); HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Translucent|PF_NoTexture, true, lightnum, colormap);
} }
// HWR_DrawSkyWalls
// Draw walls into the depth buffer so that anything behind is culled properly
static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top)
{
HWD.pfnSetTexture(NULL);
// no texture
wallVerts[3].t = wallVerts[2].t = 0;
wallVerts[0].t = wallVerts[1].t = 0;
wallVerts[0].s = wallVerts[3].s = 0;
wallVerts[2].s = wallVerts[1].s = 0;
// set top/bottom coords
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall
HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL);
// PF_Invisible so it's not drawn into the colour buffer
// PF_NoTexture for no texture
// PF_Occlude is set in HWR_ProjectWall to draw into the depth buffer
}
// //
// HWR_StoreWallRange // HWR_StoreWallRange
// A portion or all of a wall segment will be drawn, from startfrac to endfrac, // A portion or all of a wall segment will be drawn, from startfrac to endfrac,
@ -1393,11 +1414,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
} }
// check TOP TEXTURE // check TOP TEXTURE
if (worldhigh < worldtop && texturetranslation[gr_sidedef->toptexture] if (worldhigh < worldtop && texturetranslation[gr_sidedef->toptexture])
#ifdef POLYOBJECTS // polyobjects don't have top textures, silly.
&& !gr_curline->polyseg
#endif
)
{ {
if (drawtextured) if (drawtextured)
{ {
@ -1435,11 +1452,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
} }
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
if (worldlow > worldbottom && texturetranslation[gr_sidedef->bottomtexture] if (worldlow > worldbottom && texturetranslation[gr_sidedef->bottomtexture]) //only if VISIBLE!!!
#ifdef POLYOBJECTS // polyobjects don't have bottom textures, silly.
&& !gr_curline->polyseg
#endif
) //only if VISIBLE!!!
{ {
if (drawtextured) if (drawtextured)
{ {
@ -1646,6 +1659,20 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
blendmode = PF_Masked; blendmode = PF_Masked;
break; break;
} }
#ifdef POLYOBJECTS
if (gr_curline->polyseg && gr_curline->polyseg->translucency > 0)
{
if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
{
Surf.FlatColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode
blendmode = PF_Masked;
}
else
blendmode = HWR_TranstableToAlpha(gr_curline->polyseg->translucency, &Surf);
}
#endif
if (grTex->mipmap.flags & TF_TRANSPARENT) if (grTex->mipmap.flags & TF_TRANSPARENT)
blendmode = PF_Translucent; blendmode = PF_Translucent;
@ -1668,6 +1695,85 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
Surf.FlatColor.rgba = 0xffffffff; Surf.FlatColor.rgba = 0xffffffff;
}*/ }*/
} }
// Isn't this just the most lovely mess
if (!gr_curline->polyseg) // Don't do it for polyobjects
{
if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum)
{
fixed_t depthwallheight;
if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn
depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
else
depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier
{
if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier
{
if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture
HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX);
else
HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX);
}
// behind sector is not a thok barrier
else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
// gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on
}
else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not
{
if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height
|| gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height
|| gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
}
else // neither sectors are thok barriers
{
if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower
|| gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
}
}
// And now for sky floors!
if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum)
{
fixed_t depthwallheight;
if (!gr_sidedef->bottomtexture)
depthwallheight = worldbottom > worldlow ? worldbottom : worldlow;
else
depthwallheight = worldbottom < worldlow ? worldbottom : worldlow;
if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier
{
if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier
{
if (!gr_sidedef->toptexture) // Only extend up if there's no texture
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh);
else
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh);
}
// behind sector is not a thok barrier
else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not
{
if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height
|| gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height
|| gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
else // neither sectors are thok barriers
{
if ((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher
|| gr_backsector->floorpic != skyflatnum) // behind sector is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
}
}
} }
else else
{ {
@ -1707,6 +1813,14 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
} }
} }
if (!gr_curline->polyseg)
{
if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector
HWR_DrawSkyWall(wallVerts, &Surf, worldtop, INT32_MAX);
if (gr_frontsector->floorpic == skyflatnum)
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldbottom);
}
} }
@ -2506,6 +2620,234 @@ static inline void HWR_AddPolyObjectSegs(void)
Z_Free(pv1); Z_Free(pv1);
Z_Free(gr_fakeline); Z_Free(gr_fakeline);
} }
#ifdef POLYOBJECTS_PLANES
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, fixed_t fixedheight,
FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector,
UINT8 alpha, extracolormap_t *planecolormap)
{
float height; //constant y for all points on the convex flat polygon
FOutVector *v3d;
INT32 i;
float flatxref,flatyref;
float fflatsize;
INT32 flatflag;
size_t len;
float scrollx = 0.0f, scrolly = 0.0f;
angle_t angle = 0;
FSurfaceInfo Surf;
fixed_t tempxsow, tempytow;
size_t nrPlaneVerts;
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
nrPlaneVerts = polysector->numVertices;
height = FIXED_TO_FLOAT(fixedheight);
if (nrPlaneVerts < 3) //not even a triangle ?
return;
if (nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size
{
CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX);
return;
}
// Allocate plane-vertex buffer if we need to
if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts)
{
numAllocedPlaneVerts = (UINT16)nrPlaneVerts;
Z_Free(planeVerts);
Z_Malloc(numAllocedPlaneVerts * sizeof (FOutVector), PU_LEVEL, &planeVerts);
}
len = W_LumpLength(lumpnum);
switch (len)
{
case 4194304: // 2048x2048 lump
fflatsize = 2048.0f;
flatflag = 2047;
break;
case 1048576: // 1024x1024 lump
fflatsize = 1024.0f;
flatflag = 1023;
break;
case 262144:// 512x512 lump
fflatsize = 512.0f;
flatflag = 511;
break;
case 65536: // 256x256 lump
fflatsize = 256.0f;
flatflag = 255;
break;
case 16384: // 128x128 lump
fflatsize = 128.0f;
flatflag = 127;
break;
case 1024: // 32x32 lump
fflatsize = 32.0f;
flatflag = 31;
break;
default: // 64x64 lump
fflatsize = 64.0f;
flatflag = 63;
break;
}
// reference point for flat texture coord for each vertex around the polygon
flatxref = (float)(((fixed_t)FIXED_TO_FLOAT(polysector->origVerts[0].x) & (~flatflag)) / fflatsize);
flatyref = (float)(((fixed_t)FIXED_TO_FLOAT(polysector->origVerts[0].y) & (~flatflag)) / fflatsize);
// transform
v3d = planeVerts;
if (FOFsector != NULL)
{
if (fixedheight == FOFsector->floorheight) // it's a floor
{
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
angle = FOFsector->floorpic_angle>>ANGLETOFINESHIFT;
}
else // it's a ceiling
{
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize;
angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT;
}
}
else if (gr_frontsector)
{
if (fixedheight < dup_viewz) // it's a floor
{
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT;
}
else // it's a ceiling
{
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize;
angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT;
}
}
if (angle) // Only needs to be done if there's an altered angle
{
// This needs to be done so that it scrolls in a different direction after rotation like software
tempxsow = FLOAT_TO_FIXED(scrollx);
tempytow = FLOAT_TO_FIXED(scrolly);
scrollx = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
scrolly = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
// This needs to be done so everything aligns after rotation
// It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does
tempxsow = FLOAT_TO_FIXED(flatxref);
tempytow = FLOAT_TO_FIXED(flatyref);
flatxref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
}
for (i = 0; i < nrPlaneVerts; i++,v3d++)
{
// Hurdler: add scrolling texture on floor/ceiling
v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatsize) - flatxref + scrollx); // Go from the polysector's original vertex locations
v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatsize) + scrolly); // Means the flat is offset based on the original vertex locations
// Need to rotate before translate
if (angle) // Only needs to be done if there's an altered angle
{
tempxsow = FLOAT_TO_FIXED(v3d->sow);
tempytow = FLOAT_TO_FIXED(v3d->tow);
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle))));
}
v3d->x = FIXED_TO_FLOAT(polysector->lines[i]->v1->x);
v3d->y = height;
v3d->z = FIXED_TO_FLOAT(polysector->lines[i]->v1->y);
}
if (planecolormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, planecolormap->rgba, planecolormap->fadergba, false, true);
else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, true);
if (blendmode & PF_Translucent)
{
Surf.FlatColor.s.alpha = (UINT8)alpha;
blendmode |= PF_Modulated|PF_Occlude|PF_Clip;
}
else
blendmode |= PF_Masked|PF_Modulated|PF_Clip;
HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode);
}
static void HWR_AddPolyObjectPlanes(void)
{
size_t i;
sector_t *polyobjsector;
// Polyobject Planes need their own function for drawing because they don't have extrasubsectors by themselves
// It should be okay because polyobjects should always be convex anyway
for (i = 0; i < numpolys; i++)
{
polyobjsector = po_ptrs[i]->lines[0]->backsector; // the in-level polyobject sector
if (!(po_ptrs[i]->flags & POF_RENDERPLANES)) // Only render planes when you should
continue;
if (po_ptrs[i]->translucency >= NUMTRANSMAPS)
continue;
if (polyobjsector->floorheight <= gr_frontsector->ceilingheight
&& polyobjsector->floorheight >= gr_frontsector->floorheight
&& (viewz < polyobjsector->floorheight))
{
if (po_ptrs[i]->translucency > 0)
{
FSurfaceInfo Surf;
FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], polyobjsector->floorheight,
polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
}
else
{
HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum);
HWR_RenderPolyObjectPlane(po_ptrs[i], polyobjsector->floorheight, PF_Occlude,
polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, NULL);
}
}
if (polyobjsector->ceilingheight >= gr_frontsector->floorheight
&& polyobjsector->ceilingheight <= gr_frontsector->ceilingheight
&& (viewz > polyobjsector->ceilingheight))
{
if (po_ptrs[i]->translucency > 0)
{
FSurfaceInfo Surf;
FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], polyobjsector->ceilingheight,
polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
}
else
{
HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum);
HWR_RenderPolyObjectPlane(po_ptrs[i], polyobjsector->ceilingheight, PF_Occlude,
polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, NULL);
}
}
}
}
#endif
#endif #endif
// -----------------+ // -----------------+
@ -2816,8 +3158,13 @@ static void HWR_Subsector(size_t num)
// Draw polyobject lines. // Draw polyobject lines.
HWR_AddPolyObjectSegs(); HWR_AddPolyObjectSegs();
// Draw polyobject planes #ifdef POLYOBJECTS_PLANES
//HWR_AddPolyObjectPlanes(); if (sub->validcount != validcount) // This validcount situation seems to let us know that the floors have already been drawn.
{
// Draw polyobject planes
HWR_AddPolyObjectPlanes();
}
#endif
} }
#endif #endif
@ -3698,6 +4045,22 @@ typedef struct
static size_t numplanes = 0; // a list of transparent floors to be drawn static size_t numplanes = 0; // a list of transparent floors to be drawn
static planeinfo_t *planeinfo = NULL; static planeinfo_t *planeinfo = NULL;
typedef struct
{
polyobj_t *polysector;
fixed_t fixedheight;
INT32 lightlevel;
lumpnum_t lumpnum;
INT32 alpha;
sector_t *FOFSector;
FBITFIELD blend;
extracolormap_t *planecolormap;
INT32 drawcount;
} polyplaneinfo_t;
static size_t numpolyplanes = 0; // a list of transparent poyobject floors to be drawn
static polyplaneinfo_t *polyplaneinfo = NULL;
#ifndef SORTING #ifndef SORTING
size_t numfloors = 0; size_t numfloors = 0;
#else #else
@ -3707,6 +4070,7 @@ size_t numfloors = 0;
typedef struct gr_drawnode_s typedef struct gr_drawnode_s
{ {
planeinfo_t *plane; planeinfo_t *plane;
polyplaneinfo_t *polyplane;
wallinfo_t *wall; wallinfo_t *wall;
gr_vissprite_t *sprite; gr_vissprite_t *sprite;
@ -3747,6 +4111,35 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub,
numplanes++; numplanes++;
} }
// Adding this for now until I can create extrasubsector info for polyobjects
// When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector,
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap)
{
static size_t allocedpolyplanes = 0;
// Force realloc if buffer has been freed
if (!polyplaneinfo)
allocedpolyplanes = 0;
if (allocedpolyplanes < numpolyplanes + 1)
{
allocedpolyplanes += MAX_TRANSPARENTFLOOR;
Z_Realloc(polyplaneinfo, allocedpolyplanes * sizeof (*polyplaneinfo), PU_LEVEL, &polyplaneinfo);
}
polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
polyplaneinfo[numpolyplanes].lightlevel = lightlevel;
polyplaneinfo[numpolyplanes].lumpnum = lumpnum;
polyplaneinfo[numpolyplanes].polysector = polysector;
polyplaneinfo[numpolyplanes].alpha = alpha;
polyplaneinfo[numpolyplanes].FOFSector = FOFSector;
polyplaneinfo[numpolyplanes].blend = blend;
polyplaneinfo[numpolyplanes].planecolormap = planecolormap;
polyplaneinfo[numpolyplanes].drawcount = drawcount++;
numpolyplanes++;
}
// //
// HWR_CreateDrawNodes // HWR_CreateDrawNodes
// Creates and sorts a list of drawnodes for the scene being rendered. // Creates and sorts a list of drawnodes for the scene being rendered.
@ -3759,12 +4152,13 @@ static void HWR_CreateDrawNodes(void)
// Could this be optimized into _AddTransparentWall/_AddTransparentPlane? // Could this be optimized into _AddTransparentWall/_AddTransparentPlane?
// Hell yes! But sort algorithm must be modified to use a linked list. // Hell yes! But sort algorithm must be modified to use a linked list.
gr_drawnode_t *sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) gr_drawnode_t *sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes)
+ (sizeof(polyplaneinfo_t)*numpolyplanes)
+ (sizeof(wallinfo_t)*numwalls) + (sizeof(wallinfo_t)*numwalls)
,PU_STATIC, NULL); ,PU_STATIC, NULL);
// todo: // todo:
// However, in reality we shouldn't be re-copying and shifting all this information // However, in reality we shouldn't be re-copying and shifting all this information
// that is already lying around. This should all be in some sort of linked list or lists. // that is already lying around. This should all be in some sort of linked list or lists.
size_t *sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numwalls), PU_STATIC, NULL); size_t *sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL);
// If true, swap the draw order. // If true, swap the draw order.
boolean shift = false; boolean shift = false;
@ -3775,6 +4169,12 @@ static void HWR_CreateDrawNodes(void)
sortindex[p] = p; sortindex[p] = p;
} }
for (i = 0; i < numpolyplanes; i++, p++)
{
sortnode[p].polyplane = &polyplaneinfo[i];
sortindex[p] = p;
}
for (i = 0; i < numwalls; i++, p++) for (i = 0; i < numwalls; i++, p++)
{ {
sortnode[p].wall = &wallinfo[i]; sortnode[p].wall = &wallinfo[i];
@ -3810,6 +4210,12 @@ static void HWR_CreateDrawNodes(void)
if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz)) if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz))
shift = true; shift = true;
} }
if (sortnode[sortindex[prev]].polyplane)
{
// Plane (i) is further away than polyplane (prev)
if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz))
shift = true;
}
else if (sortnode[sortindex[prev]].wall) else if (sortnode[sortindex[prev]].wall)
{ {
// Plane (i) is further than wall (prev) // Plane (i) is further than wall (prev)
@ -3817,6 +4223,28 @@ static void HWR_CreateDrawNodes(void)
shift = true; shift = true;
} }
} }
else if (sortnode[sortindex[i]].polyplane)
{
// What are we comparing it with?
if (sortnode[sortindex[prev]].plane)
{
// Plane (i) is further away than plane (prev)
if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz))
shift = true;
}
if (sortnode[sortindex[prev]].polyplane)
{
// Plane (i) is further away than polyplane (prev)
if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz))
shift = true;
}
else if (sortnode[sortindex[prev]].wall)
{
// Plane (i) is further than wall (prev)
if (sortnode[sortindex[i]].polyplane->drawcount > sortnode[sortindex[prev]].wall->drawcount)
shift = true;
}
}
else if (sortnode[sortindex[i]].wall) else if (sortnode[sortindex[i]].wall)
{ {
// What are we comparing it with? // What are we comparing it with?
@ -3826,6 +4254,12 @@ static void HWR_CreateDrawNodes(void)
if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].plane->drawcount) if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].plane->drawcount)
shift = true; shift = true;
} }
if (sortnode[sortindex[prev]].polyplane)
{
// Wall (i) is further than polyplane(prev)
if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].polyplane->drawcount)
shift = true;
}
else if (sortnode[sortindex[prev]].wall) else if (sortnode[sortindex[prev]].wall)
{ {
// Wall (i) is further than wall (prev) // Wall (i) is further than wall (prev)
@ -3862,6 +4296,16 @@ static void HWR_CreateDrawNodes(void)
HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel,
sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap); sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap);
} }
else if (sortnode[sortindex[i]].polyplane)
{
// We aren't traversing the BSP tree, so make gr_frontsector null to avoid crashes.
gr_frontsector = NULL;
if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture))
HWR_GetFlat(sortnode[sortindex[i]].polyplane->lumpnum);
HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel,
sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
}
else if (sortnode[sortindex[i]].wall) else if (sortnode[sortindex[i]].wall)
{ {
if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture)) if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture))
@ -3873,6 +4317,7 @@ static void HWR_CreateDrawNodes(void)
numwalls = 0; numwalls = 0;
numplanes = 0; numplanes = 0;
numpolyplanes = 0;
// No mem leaks, please. // No mem leaks, please.
Z_Free(sortnode); Z_Free(sortnode);
@ -4349,7 +4794,7 @@ static void HWR_DrawSkyBackground(player_t *player)
{ {
FOutVector v[4]; FOutVector v[4];
angle_t angle; angle_t angle;
float f; float dimensionmultiply;
// 3--2 // 3--2
// | /| // | /|
@ -4371,36 +4816,49 @@ static void HWR_DrawSkyBackground(player_t *player)
// X // X
if (textures[skytexture]->width > 256) // NOTE: This doesn't work right with texture widths greater than 1024
angle = (angle_t)((float)(dup_viewangle + gr_xtoviewangle[0]) // software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
/((float)textures[skytexture]->width/256.0f)) // The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
%(ANGLE_90-1);
else
angle = (dup_viewangle + gr_xtoviewangle[0])%(ANGLE_90-1);
f = (float)((textures[skytexture]->width/2) angle = (dup_viewangle + gr_xtoviewangle[0]);
* FIXED_TO_FLOAT(FINETANGENT((2048
- ((INT32)angle>>(ANGLETOFINESHIFT + 1))) & FINEMASK)));
v[0].sow = v[3].sow = 0.22f+(f)/(textures[skytexture]->width/2); dimensionmultiply = ((float)textures[skytexture]->width/256.0f);
v[2].sow = v[1].sow = 0.22f+(f+(127))/(textures[skytexture]->width/2);
v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*dimensionmultiply));
v[2].sow = v[1].sow = (-1.0f/dimensionmultiply)+((float) angle / ((ANGLE_90-1)*dimensionmultiply));
// Y // Y
angle = aimingangle;
float aspectratio = (float)vid.width/(float)vid.height;
dimensionmultiply = ((float)textures[skytexture]->height/(128.0f*aspectratio));
float angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
if (textures[skytexture]->height > 256) // Middle of the sky should always be at angle 0
angle = (angle_t)((float)(aimingangle) // need to keep correct aspect ratio with X
*(256.0f/(float)textures[skytexture]->height)) if (atransform.flip)
%(ANGLE_90-1); // Just so that looking up and down scales right {
// During vertical flip the sky should be flipped and it's y movement should also be flipped obviously
v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply));
v[0].tow = v[1].tow = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply));
}
else else
angle = (aimingangle); {
v[3].tow = v[2].tow = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply));
v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply));
}
f = (float)((textures[skytexture]->height/2) if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa
* FIXED_TO_FLOAT(FINETANGENT((2048 {
- ((INT32)angle>>(ANGLETOFINESHIFT + 1))) & FINEMASK))); angle = InvAngle(angle);
v[3].tow = v[2].tow += ((float) angle / angleturn);
v[3].tow = v[2].tow = 0.22f+(f)/(textures[skytexture]->height/2); v[0].tow = v[1].tow += ((float) angle / angleturn);
v[0].tow = v[1].tow = 0.22f+(f+(127))/(textures[skytexture]->height/2); }
else
{
v[3].tow = v[2].tow -= ((float) angle / angleturn);
v[0].tow = v[1].tow -= ((float) angle / angleturn);
}
HWD.pfnDrawPolygon(NULL, v, 4, 0); HWD.pfnDrawPolygon(NULL, v, 4, 0);
} }
@ -4649,7 +5107,7 @@ if (0)
#endif #endif
#ifdef SORTING #ifdef SORTING
if (numplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything
{ {
HWR_CreateDrawNodes(); HWR_CreateDrawNodes();
} }
@ -4879,12 +5337,12 @@ if (0)
#endif #endif
#ifdef SORTING #ifdef SORTING
if (numplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything
{ {
HWR_CreateDrawNodes(); HWR_CreateDrawNodes();
} }
#else #else
if (numfloors || numwalls) if (numfloors || numpolyplanes || numwalls)
{ {
HWD.pfnSetTransform(&atransform); HWD.pfnSetTransform(&atransform);
if (numfloors) if (numfloors)
@ -5413,7 +5871,7 @@ void HWR_StartScreenWipe(void)
void HWR_EndScreenWipe(void) void HWR_EndScreenWipe(void)
{ {
HWRWipeCounter = 1.0f; HWRWipeCounter = 0.0f;
//CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n"); //CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n");
HWD.pfnEndScreenWipe(); HWD.pfnEndScreenWipe();
} }
@ -5423,17 +5881,38 @@ void HWR_DrawIntermissionBG(void)
HWD.pfnDrawIntermissionBG(); HWD.pfnDrawIntermissionBG();
} }
void HWR_DoScreenWipe(void) void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
{ {
//CONS_Debug(DBG_RENDER, "In HWR_DoScreenWipe(). Alpha =%f\n", HWRWipeCounter); static char lumpname[9] = "FADEmmss";
lumpnum_t lumpnum;
size_t lsize;
HWD.pfnDoScreenWipe(HWRWipeCounter); if (wipenum > 99 || scrnnum > 99) // not a valid wipe number
return; // shouldn't end up here really, the loop should've stopped running beforehand
// This works for all the cases in vanilla until fade masks get done // puts the numbers into the lumpname
HWRWipeCounter -= 0.05f; // Go less opaque after sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
lumpnum = W_CheckNumForName(lumpname);
if (HWRWipeCounter < 0) if (lumpnum == LUMPERROR) // again, shouldn't be here really
HWRWipeCounter = 0; return;
lsize = W_LumpLength(lumpnum);
if (!(lsize == 256000 || lsize == 64000 || lsize == 16000 || lsize == 4000))
{
CONS_Alert(CONS_WARNING, "Fade mask lump %s of incorrect size, ignored\n", lumpname);
return; // again, shouldn't get here if it is a bad size
}
HWR_GetFadeMask(lumpnum);
HWD.pfnDoScreenWipe(HWRWipeCounter); // Still send in wipecounter since old stuff might not support multitexturing
HWRWipeCounter += 0.05f; // increase opacity of end screen
if (HWRWipeCounter > 1.0f)
HWRWipeCounter = 1.0f;
} }
#endif // HWRENDER #endif // HWRENDER

View file

@ -63,8 +63,8 @@ INT32 HWR_GetTextureUsed(void);
void HWR_DoPostProcessor(player_t *player); void HWR_DoPostProcessor(player_t *player);
void HWR_StartScreenWipe(void); void HWR_StartScreenWipe(void);
void HWR_EndScreenWipe(void); void HWR_EndScreenWipe(void);
void HWR_DoScreenWipe(void);
void HWR_DrawIntermissionBG(void); void HWR_DrawIntermissionBG(void);
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
// This stuff is put here so MD2's can use them // This stuff is put here so MD2's can use them
UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane); UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane);

View file

@ -1230,7 +1230,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
else else
p.z = FIXED_TO_FLOAT(spr->mobj->z); p.z = FIXED_TO_FLOAT(spr->mobj->z);
if (spr->mobj->skin) if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
sprdef = &((skin_t *)spr->mobj->skin)->spritedef; sprdef = &((skin_t *)spr->mobj->skin)->spritedef;
else else
sprdef = &sprites[spr->mobj->sprite]; sprdef = &sprites[spr->mobj->sprite];

View file

@ -366,6 +366,10 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
else else
maximumAnisotropy = 0; maximumAnisotropy = 0;
#ifndef MINI_GL_COMPATIBILITY
SetupGLFunc13();
#endif
screen_depth = (GLbyte)(lvid->bpp*8); screen_depth = (GLbyte)(lvid->bpp*8);
if (screen_depth > 16) if (screen_depth > 16)

View file

@ -157,6 +157,10 @@ float byteasfloat(UINT8 fbyte)
static I_Error_t I_Error_GL = NULL; static I_Error_t I_Error_GL = NULL;
#ifndef MINI_GL_COMPATIBILITY
static boolean gl13 = false; // whether we can use opengl 1.3 functions
#endif
// -----------------+ // -----------------+
// DBG_Printf : Output error messages to debug log if DEBUG_TO_FILE is defined, // DBG_Printf : Output error messages to debug log if DEBUG_TO_FILE is defined,
@ -263,6 +267,11 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
/* GLU functions */ /* GLU functions */
#define pgluBuild2DMipmaps gluBuild2DMipmaps #define pgluBuild2DMipmaps gluBuild2DMipmaps
#endif #endif
#ifndef MINI_GL_COMPATIBILITY
/* 1.3 functions for multitexturing */
#define pglActiveTexture, glActiveTexture;
#define pglMultiTexCoord2f, glMultiTexCoord2f;
#endif
#else //!STATIC_OPENGL #else //!STATIC_OPENGL
/* 1.0 functions */ /* 1.0 functions */
@ -387,6 +396,14 @@ static PFNglCopyTexImage2D pglCopyTexImage2D;
/* GLU functions */ /* GLU functions */
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
static PFNgluBuild2DMipmaps pgluBuild2DMipmaps; static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
#ifndef MINI_GL_COMPATIBILITY
/* 1.3 functions for multitexturing */
typedef void (APIENTRY *PFNGLACTIVETEXTUREPROC) (GLenum);
static PFNGLACTIVETEXTUREPROC pglActiveTexture;
typedef void (APIENTRY *PFNGLMULTITEXCOORD2FPROC) (GLenum, GLfloat, GLfloat);
static PFNGLMULTITEXCOORD2FPROC pglMultiTexCoord2f;
#endif
#endif #endif
#ifndef MINI_GL_COMPATIBILITY #ifndef MINI_GL_COMPATIBILITY
@ -402,6 +419,14 @@ static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
#define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_MAX_LOD 0x813B
#endif #endif
/* 1.3 GL_TEXTUREi */
#ifndef GL_TEXTURE0
#define GL_TEXTURE0 0x84C0
#endif
#ifndef GL_TEXTURE1
#define GL_TEXTURE1 0x84C1
#endif
#endif #endif
#ifdef MINI_GL_COMPATIBILITY #ifdef MINI_GL_COMPATIBILITY
@ -492,6 +517,39 @@ boolean SetupGLfunc(void)
return true; return true;
} }
#ifndef MINI_GL_COMPATIBILITY
// This has to be done after the context is created so the version number can be obtained
boolean SetupGLFunc13(void)
{
#ifndef STATIC_OPENGL
#define GETOPENGLFUNC(func, proc) \
func = GetGLFunc(#proc); \
if (!func) \
{ \
DBG_Printf("failed to get OpenGL function: %s", #proc); \
} \
const char *glversion = (const char *)pglGetString(GL_VERSION);
UINT32 majorversion = 0, minorversion = 0;
if (glversion != NULL && sscanf((char *)glversion, "%u.%u", &majorversion, &minorversion) == 2) // There is a version number I can identify
{
if (majorversion > 1 || (majorversion == 1 && minorversion >= 3)) // Version of OpenGL is equal to or greater than 1.3
{
// Get the functions
GETOPENGLFUNC(pglActiveTexture , glActiveTexture)
GETOPENGLFUNC(pglMultiTexCoord2f , glMultiTexCoord2f)
gl13 = true; // This is now true, so the new fade mask stuff can be done, if OpenGL version is less than 1.3, it still uses the old fade stuff.
}
}
#undef GETOPENGLFUNC
#endif
return true;
}
#endif
// -----------------+ // -----------------+
// SetNoTexture : Disable texture // SetNoTexture : Disable texture
// -----------------+ // -----------------+
@ -1234,6 +1292,23 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
} }
} }
} }
else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) // Used for fade masks
{
const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data;
INT32 i, j;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
{
tex[w*j+i] = (pImgData>>4)<<12;
tex[w*j+i] |= (255>>4)<<8;
tex[w*j+i] |= (255>>4)<<4;
tex[w*j+i] |= (255>>4);
pImgData++;
}
}
}
else else
DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format);
#else #else
@ -1299,6 +1374,23 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
} }
} }
} }
else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) // Used for fade masks
{
const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data;
INT32 i, j;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
{
tex[w*j+i].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't
tex[w*j+i].s.green = 255;
tex[w*j+i].s.blue = 255;
tex[w*j+i].s.alpha = *pImgData;
pImgData++;
}
}
}
else else
DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format);
#endif #endif
@ -2109,6 +2201,10 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
INT32 texsize = 2048; INT32 texsize = 2048;
float xfix, yfix; float xfix, yfix;
#ifndef MINI_GL_COMPATIBILITY
INT32 fademaskdownloaded = tex_downloaded; // the fade mask that has been set
#endif
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 1024) if(screen_width <= 1024)
texsize = 1024; texsize = 1024;
@ -2122,8 +2218,8 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
SetBlend(PF_Modulated|PF_NoDepthTest|PF_Clip|PF_NoZClip); SetBlend(PF_Modulated|PF_NoDepthTest|PF_Clip|PF_NoZClip);
// Draw the screen on bottom to fade to // Draw the original screen
pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglBindTexture(GL_TEXTURE_2D, startScreenWipe);
pglBegin(GL_QUADS); pglBegin(GL_QUADS);
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
@ -2142,12 +2238,56 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
// Bottom right // Bottom right
pglTexCoord2f(xfix, 0.0f); pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1.0f, -1.0f, 1.0f); pglVertex3f(1.0f, -1.0f, 1.0f);
pglEnd(); pglEnd();
SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest|PF_Clip|PF_NoZClip); SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest|PF_Clip|PF_NoZClip);
// Draw the screen on top that fades. #ifndef MINI_GL_COMPATIBILITY
pglBindTexture(GL_TEXTURE_2D, startScreenWipe); if (gl13)
{
// Draw the end screen that fades in
pglActiveTexture(GL_TEXTURE0);
pglEnable(GL_TEXTURE_2D);
pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
pglActiveTexture(GL_TEXTURE1);
pglEnable(GL_TEXTURE_2D);
pglBindTexture(GL_TEXTURE_2D, fademaskdownloaded);
pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
pglBegin(GL_QUADS);
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Bottom left
pglMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f);
pglMultiTexCoord2f(GL_TEXTURE1, 0.0f, 0.0f);
pglVertex3f(-1.0f, -1.0f, 1.0f);
// Top left
pglMultiTexCoord2f(GL_TEXTURE0, 0.0f, yfix);
pglMultiTexCoord2f(GL_TEXTURE1, 0.0f, 1.0f);
pglVertex3f(-1.0f, 1.0f, 1.0f);
// Top right
pglMultiTexCoord2f(GL_TEXTURE0, xfix, yfix);
pglMultiTexCoord2f(GL_TEXTURE1, 1.0f, 1.0f);
pglVertex3f(1.0f, 1.0f, 1.0f);
// Bottom right
pglMultiTexCoord2f(GL_TEXTURE0, xfix, 0.0f);
pglMultiTexCoord2f(GL_TEXTURE1, 1.0f, 0.0f);
pglVertex3f(1.0f, -1.0f, 1.0f);
pglEnd();
pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit
pglActiveTexture(GL_TEXTURE0);
}
else
{
#endif
// Draw the end screen that fades in
pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
pglBegin(GL_QUADS); pglBegin(GL_QUADS);
pglColor4f(1.0f, 1.0f, 1.0f, alpha); pglColor4f(1.0f, 1.0f, 1.0f, alpha);
@ -2166,8 +2306,10 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
// Bottom right // Bottom right
pglTexCoord2f(xfix, 0.0f); pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1.0f, -1.0f, 1.0f); pglVertex3f(1.0f, -1.0f, 1.0f);
pglEnd(); pglEnd();
#ifndef MINI_GL_COMPATIBILITY
}
#endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
} }

View file

@ -35,6 +35,13 @@
#else #else
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glu.h> #include <GL/glu.h>
#ifndef MINI_GL_COMPATIBILITY
#ifdef STATIC_OPENGL // Because of the 1.3 functions, you'll need GLext to compile it if static
#define GL_GLEXT_PROTOTYPES
#include <GL/glext.h>
#endif
#endif
#endif #endif
#define _CREATE_DLL_ // necessary for Unix AND Windows #define _CREATE_DLL_ // necessary for Unix AND Windows
@ -66,6 +73,7 @@
boolean LoadGL(void); boolean LoadGL(void);
void *GetGLFunc(const char *proc); void *GetGLFunc(const char *proc);
boolean SetupGLfunc(void); boolean SetupGLfunc(void);
boolean SetupGLFunc13(void);
void Flush(void); void Flush(void);
INT32 isExtAvailable(const char *extension, const GLubyte *start); INT32 isExtAvailable(const char *extension, const GLubyte *start);
boolean SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepthBits); boolean SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepthBits);