Merge branch 'master' into next

This commit is contained in:
Alam Ed Arias 2018-04-03 15:48:06 -04:00
commit cf6a30a8ef
14 changed files with 990 additions and 572 deletions

View File

@ -233,11 +233,19 @@ static void F_SkyScroll(INT32 scrollspeed)
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode != render_none) else if (rendermode != render_none)
{ // if only software rendering could be this simple and retarded { // if only software rendering could be this simple and retarded
scrolled = animtimer; INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
if (scrolled > 0) INT32 y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz;
V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat); scrolled = animtimer * dupz;
for (x = 0; x < fakedwidth; x += SHORT(pat->width)) for (x = 0; x < vid.width; x += pw)
V_DrawScaledPatch(x + scrolled, 0, 0, pat); {
for (y = 0; y < vid.height; y += ph)
{
if (scrolled > 0)
V_DrawScaledPatch(scrolled - pw, y, V_NOSCALESTART, pat);
V_DrawScaledPatch(x + scrolled, y, V_NOSCALESTART, pat);
}
}
} }
#endif #endif
@ -999,7 +1007,7 @@ static const char *credits[] = {
"", "",
"\1Sprite Artists", "\1Sprite Artists",
"Odi \"Iceman404\" Atunzu", "Odi \"Iceman404\" Atunzu",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Jim \"MotorRoach\" DeMello", "Jim \"MotorRoach\" DeMello",
"Desmond \"Blade\" DesJardins", "Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins", "Sherman \"CoatRack\" DesJardins",

View File

@ -20,8 +20,8 @@
#define _HWR_DEFS_ #define _HWR_DEFS_
#include "../doomtype.h" #include "../doomtype.h"
#define ZCLIP_PLANE 4.0f #define ZCLIP_PLANE 4.0f // Used for the actual game drawing
#define NZCLIP_PLANE 0.9f #define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
// ========================================================================== // ==========================================================================
// SIMPLE TYPES // SIMPLE TYPES
@ -133,12 +133,13 @@ enum EPolyFlags
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture) PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture)
PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency
PF_Additive = 0x00000024, // Poly is added to the frame buffer PF_Additive = 0x00000004, // Poly is added to the frame buffer
PF_Environment = 0x00000008, // Poly should be drawn environment mapped. PF_Environment = 0x00000008, // Poly should be drawn environment mapped.
// Hurdler: used for text drawing // Hurdler: used for text drawing
PF_Substractive = 0x00000010, // for splat PF_Substractive = 0x00000010, // for splat
PF_NoAlphaTest = 0x00000020, // hiden param PF_NoAlphaTest = 0x00000020, // hiden param
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive)&~PF_NoAlphaTest, PF_Fog = 0x00000040, // Fog blocks
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest,
// other flag bits // other flag bits

View File

@ -147,10 +147,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; float dupx, dupy, fscale, fwidth, fheight;
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale);
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale);
if (alphalevel >= 10 && alphalevel < 13) if (alphalevel >= 10 && alphalevel < 13)
return; return;
@ -161,40 +158,108 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
else else
HWR_GetMappedPatch(gpatch, colormap); HWR_GetMappedPatch(gpatch, colormap);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
switch (option & V_SCALEPATCHMASK) switch (option & V_SCALEPATCHMASK)
{ {
case V_NOSCALEPATCH: case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f; dupx = dupy = 1.0f;
break; break;
case V_SMALLSCALEPATCH: case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); dupx = (float)vid.smalldupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); dupy = (float)vid.smalldupy;
break; break;
case V_MEDSCALEPATCH: case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); dupx = (float)vid.meddupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); dupy = (float)vid.meddupy;
break; break;
} }
if (option & V_NOSCALESTART) dupx = dupy = (dupx < dupy ? dupx : dupy);
sdupx = sdupy = 2.0f; fscale = FIXED_TO_FLOAT(pscale);
if (option & V_SPLITSCREEN) if (option & V_OFFSET)
sdupy /= 2.0f;
if (option & V_FLIP) // Need to flip both this and sow
{ {
v[0].x = v[3].x = (cx*sdupx-(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; cx -= (float)gpatch->leftoffset * dupx * fscale;
v[2].x = v[1].x = (cx*sdupx+gpatch->leftoffset*pdupx)/vid.width - 1; cy -= (float)gpatch->topoffset * dupy * fscale;
} }
else else
{ {
v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1; cy -= (float)gpatch->topoffset * fscale;
v[2].x = v[1].x = (cx*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; if (option & V_FLIP)
cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscale;
else
cx -= (float)gpatch->leftoffset * fscale;
} }
v[0].y = v[1].y = 1-(cy*sdupy-gpatch->topoffset*pdupy)/vid.height; if (option & V_SPLITSCREEN)
v[2].y = v[3].y = 1-(cy*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height; cy /= 2;
if (!(option & V_NOSCALESTART))
{
cx = cx * dupx;
cy = cy * dupy;
if (!(option & V_SCALEPATCHMASK))
{
// if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
Z_Free(realpatch);
}
// centre screen
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (vid.height != BASEVIDHEIGHT * vid.dupy)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
if (pscale != FRACUNIT)
{
fwidth = (float)gpatch->width * fscale * dupx;
fheight = (float)gpatch->height * fscale * dupy;
}
else
{
fwidth = (float)gpatch->width * dupx;
fheight = (float)gpatch->height * dupy;
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
v[2].x = v[1].x = cx + fwidth;
v[0].y = v[1].y = cy;
v[2].y = v[3].y = cy - fheight;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
@ -247,10 +312,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; float dupx, dupy, fscale, fwidth, fheight;
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale);
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale);
if (alphalevel >= 10 && alphalevel < 13) if (alphalevel >= 10 && alphalevel < 13)
return; return;
@ -258,28 +320,109 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// make patch ready in hardware cache // make patch ready in hardware cache
HWR_GetPatch(gpatch); HWR_GetPatch(gpatch);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
switch (option & V_SCALEPATCHMASK) switch (option & V_SCALEPATCHMASK)
{ {
case V_NOSCALEPATCH: case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f; dupx = dupy = 1.0f;
break; break;
case V_SMALLSCALEPATCH: case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); dupx = (float)vid.smalldupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); dupy = (float)vid.smalldupy;
break; break;
case V_MEDSCALEPATCH: case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); dupx = (float)vid.meddupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); dupy = (float)vid.meddupy;
break; break;
} }
if (option & V_NOSCALESTART) dupx = dupy = (dupx < dupy ? dupx : dupy);
sdupx = sdupy = 2.0f; fscale = FIXED_TO_FLOAT(pscale);
v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; cy -= (float)gpatch->topoffset * fscale;
v[2].x = v[1].x = (cx*sdupx + ((w-sx) - gpatch->leftoffset) * pdupx) / vid.width - 1; cx -= (float)gpatch->leftoffset * fscale;
v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height;
v[2].y = v[3].y = 1 - (cy*sdupy + ((h-sy) - gpatch->topoffset) * pdupy) / vid.height; if (!(option & V_NOSCALESTART))
{
cx = cx * dupx;
cy = cy * dupy;
if (!(option & V_SCALEPATCHMASK))
{
// if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
Z_Free(realpatch);
}
// centre screen
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (vid.height != BASEVIDHEIGHT * vid.dupy)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
fwidth = w;
fheight = h;
if (fwidth > w - sx)
fwidth = w - sx;
if (fheight > h - sy)
fheight = h - sy;
if (fwidth > gpatch->width)
fwidth = gpatch->width;
if (fheight > gpatch->height)
fheight = gpatch->height;
if (pscale != FRACUNIT)
{
fwidth *= fscale * dupx;
fheight *= fscale * dupy;
}
else
{
fwidth *= dupx;
fheight *= dupy;
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
v[2].x = v[1].x = cx + fwidth;
v[0].y = v[1].y = cy;
v[2].y = v[3].y = cy - fheight;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
@ -656,7 +799,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
{ {
FOutVector v[4]; FOutVector v[4];
FSurfaceInfo Surf; FSurfaceInfo Surf;
float sdupx, sdupy; float fx, fy, fw, fh;
if (w < 0 || h < 0) if (w < 0 || h < 0)
return; // consistency w/ software return; // consistency w/ software
@ -665,16 +808,79 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
if (color & V_NOSCALESTART) fx = (float)x;
sdupx = sdupy = 2.0f; fy = (float)y;
fw = (float)w;
fh = (float)h;
v[0].x = v[3].x = (x*sdupx)/vid.width - 1; if (!(color & V_NOSCALESTART))
v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1; {
v[0].y = v[1].y = 1-(y*sdupy)/vid.height; float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height;
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
HWD.pfnClearBuffer(true, false, &clearColour);
return;
}
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (color & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (vid.height != BASEVIDHEIGHT * dupy)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
}
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
fy = 0;
}
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = (float)vid.height - fy;
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
//Hurdler: do we still use this argb color? if not, we should remove it //Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;

View File

@ -79,6 +79,7 @@ EXPORT char *HWRAPI(GetRenderer) (void);
#define SCREENVERTS 10 #define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
#endif #endif
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(StartScreenWipe) (void);
EXPORT void HWRAPI(EndScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void);
EXPORT void HWRAPI(DoScreenWipe) (float alpha); EXPORT void HWRAPI(DoScreenWipe) (float alpha);
@ -124,6 +125,7 @@ struct hwdriver_s
#ifdef SHUFFLE #ifdef SHUFFLE
PostImgRedraw pfnPostImgRedraw; PostImgRedraw pfnPostImgRedraw;
#endif #endif
FlushScreenTextures pfnFlushScreenTextures;
StartScreenWipe pfnStartScreenWipe; StartScreenWipe pfnStartScreenWipe;
EndScreenWipe pfnEndScreenWipe; EndScreenWipe pfnEndScreenWipe;
DoScreenWipe pfnDoScreenWipe; DoScreenWipe pfnDoScreenWipe;

View File

@ -68,6 +68,7 @@ typedef struct gr_vissprite_s
struct gr_vissprite_s *prev; struct gr_vissprite_s *prev;
struct gr_vissprite_s *next; struct gr_vissprite_s *next;
float x1, x2; float x1, x2;
float z1, z2;
float tz, ty; float tz, ty;
lumpnum_t patchlumpnum; lumpnum_t patchlumpnum;
boolean flip; boolean flip;

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,7 @@ typedef struct GLRGBAFloat GLRGBAFloat;
#define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f)
#define ASPECT_RATIO (1.0f) //(320.0f/200.0f) #define ASPECT_RATIO (1.0f) //(320.0f/200.0f)
#define FAR_CLIPPING_PLANE 150000.0f // Draw further! Tails 01-21-2001 #define FAR_CLIPPING_PLANE 32768.0f // Draw further! Tails 01-21-2001
static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE;
// ************************************************************************** // **************************************************************************
@ -107,10 +107,19 @@ static GLint viewport[4];
#endif #endif
// Yay for arbitrary numbers! NextTexAvail is buggy for some reason. // Yay for arbitrary numbers! NextTexAvail is buggy for some reason.
static GLuint screentexture = 60000; // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing
static GLuint startScreenWipe = 60001; // flush all of the stored textures, leaving them unavailable at times such as between levels
static GLuint endScreenWipe = 60002; // These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs
static GLuint finalScreenTexture = 60003; // can know when the textures aren't there, as textures are always considered resident in their virtual memory
// TODO: Store them in a more normal way
#define SCRTEX_SCREENTEXTURE 65535
#define SCRTEX_STARTSCREENWIPE 65534
#define SCRTEX_ENDSCREENWIPE 65533
#define SCRTEX_FINALSCREENTEXTURE 65532
static GLuint screentexture = 0;
static GLuint startScreenWipe = 0;
static GLuint endScreenWipe = 0;
static GLuint finalScreenTexture = 0;
#if 0 #if 0
GLuint screentexture = FIRST_TEX_AVAIL; GLuint screentexture = FIRST_TEX_AVAIL;
#endif #endif
@ -263,6 +272,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
/* texture mapping */ //GL_EXT_copy_texture /* texture mapping */ //GL_EXT_copy_texture
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
#define pglCopyTexImage2D glCopyTexImage2D #define pglCopyTexImage2D glCopyTexImage2D
#define pglCopyTexSubImage2D glCopyTexSubImage2D
#endif #endif
#else //!STATIC_OPENGL #else //!STATIC_OPENGL
@ -387,6 +397,8 @@ static PFNglBindTexture pglBindTexture;
/* texture mapping */ //GL_EXT_copy_texture /* texture mapping */ //GL_EXT_copy_texture
typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
static PFNglCopyTexImage2D pglCopyTexImage2D; static PFNglCopyTexImage2D pglCopyTexImage2D;
typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
static PFNglCopyTexSubImage2D pglCopyTexSubImage2D;
#endif #endif
/* 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);
@ -503,6 +515,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglBindTexture , glBindTexture) GETOPENGLFUNC(pglBindTexture , glBindTexture)
GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D) GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D)
GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D)
#undef GETOPENGLFUNC #undef GETOPENGLFUNC
@ -654,6 +667,10 @@ void SetModelView(GLint w, GLint h)
{ {
// DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); // DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h);
// The screen textures need to be flushed if the width or height change so that they be remade for the correct size
if (screen_width != w || screen_height != h)
FlushScreenTextures();
screen_width = w; screen_width = w;
screen_height = h; screen_height = h;
@ -801,6 +818,7 @@ void Flush(void)
screentexture = FIRST_TEX_AVAIL; screentexture = FIRST_TEX_AVAIL;
} }
#endif #endif
tex_downloaded = 0; tex_downloaded = 0;
} }
@ -1056,30 +1074,56 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
switch (PolyFlags & PF_Blending) { switch (PolyFlags & PF_Blending) {
case PF_Translucent & PF_Blending: case PF_Translucent & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break; break;
case PF_Masked & PF_Blending: case PF_Masked & PF_Blending:
// Hurdler: does that mean lighting is only made by alpha src? // Hurdler: does that mean lighting is only made by alpha src?
// it sounds ok, but not for polygonsmooth // it sounds ok, but not for polygonsmooth
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_GREATER, 0.5f);
#endif
break; break;
case PF_Additive & PF_Blending: case PF_Additive & PF_Blending:
#ifdef ATI_RAGE_PRO_COMPATIBILITY #ifdef ATI_RAGE_PRO_COMPATIBILITY
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
#else #else
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
#endif
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif #endif
break; break;
case PF_Environment & PF_Blending: case PF_Environment & PF_Blending:
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break; break;
case PF_Substractive & PF_Blending: case PF_Substractive & PF_Blending:
// good for shadow // good for shadow
// not realy but what else ? // not realy but what else ?
pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break;
case PF_Fog & PF_Fog:
// Sryder: Fog
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break; break;
default : // must be 0, otherwise it's an error default : // must be 0, otherwise it's an error
// No blending // No blending
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_GREATER, 0.5f);
#endif
break; break;
} }
} }
@ -1339,6 +1383,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
tex[w*j+i].s.green = 0; tex[w*j+i].s.green = 0;
tex[w*j+i].s.blue = 0; tex[w*j+i].s.blue = 0;
tex[w*j+i].s.alpha = 0; tex[w*j+i].s.alpha = 0;
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
} }
else else
{ {
@ -1409,8 +1454,22 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
tex_downloaded = pTexInfo->downloaded; tex_downloaded = pTexInfo->downloaded;
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); if (pTexInfo->flags & TF_TRANSPARENT)
{
#ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NONE);
#else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif
}
else
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
}
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex); pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex);
@ -1864,12 +1923,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
ambient[1] = 0.75f; ambient[1] = 0.75f;
if (ambient[2] > 0.75f) if (ambient[2] > 0.75f)
ambient[2] = 0.75f; ambient[2] = 0.75f;
if (color[3] < 255)
{
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
pglDepthMask(GL_FALSE);
}
} }
pglEnable(GL_CULL_FACE); pglEnable(GL_CULL_FACE);
@ -1896,10 +1949,12 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
#endif #endif
if (color[3] < 255)
SetBlend(PF_Translucent|PF_Modulated|PF_Clip);
else
SetBlend(PF_Masked|PF_Modulated|PF_Occlude|PF_Clip);
} }
DrawPolygon(NULL, NULL, 0, PF_Masked|PF_Modulated|PF_Occlude|PF_Clip);
pglPushMatrix(); // should be the same as glLoadIdentity pglPushMatrix(); // should be the same as glLoadIdentity
//Hurdler: now it seems to work //Hurdler: now it seems to work
pglTranslatef(pos->x, pos->z, pos->y); pglTranslatef(pos->x, pos->z, pos->y);
@ -1907,14 +1962,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
scaley = -scaley; scaley = -scaley;
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
//pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
// Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?!
if (color && color[3] < 255)
{
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
pglDepthMask(GL_FALSE);
}
val = *gl_cmd_buffer++; val = *gl_cmd_buffer++;
@ -1982,7 +2029,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
if (color) if (color)
pglDisable(GL_LIGHTING); pglDisable(GL_LIGHTING);
pglShadeModel(GL_FLAT); pglShadeModel(GL_FLAT);
pglDepthMask(GL_TRUE);
pglDisable(GL_CULL_FACE); pglDisable(GL_CULL_FACE);
} }
@ -2135,10 +2181,25 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
} }
#endif //SHUFFLE #endif //SHUFFLE
// Sryder: This needs to be called whenever the screen changes resolution in order to reset the screen textures to use
// a new size
EXPORT void HWRAPI(FlushScreenTextures) (void)
{
pglDeleteTextures(1, &screentexture);
pglDeleteTextures(1, &startScreenWipe);
pglDeleteTextures(1, &endScreenWipe);
pglDeleteTextures(1, &finalScreenTexture);
screentexture = 0;
startScreenWipe = 0;
endScreenWipe = 0;
finalScreenTexture = 0;
}
// Create Screen to fade from // Create Screen to fade from
EXPORT void HWRAPI(StartScreenWipe) (void) EXPORT void HWRAPI(StartScreenWipe) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (startScreenWipe == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2147,27 +2208,38 @@ EXPORT void HWRAPI(StartScreenWipe) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
startScreenWipe = SCRTEX_STARTSCREENWIPE;
pglBindTexture(GL_TEXTURE_2D, startScreenWipe); pglBindTexture(GL_TEXTURE_2D, startScreenWipe);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else #else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif #endif
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = startScreenWipe;
} }
// Create Screen to fade to // Create Screen to fade to
EXPORT void HWRAPI(EndScreenWipe)(void) EXPORT void HWRAPI(EndScreenWipe)(void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (endScreenWipe == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2176,21 +2248,32 @@ EXPORT void HWRAPI(EndScreenWipe)(void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
endScreenWipe = SCRTEX_ENDSCREENWIPE;
pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else #else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif #endif
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
tex_downloaded = endScreenWipe;
} }
@ -2232,7 +2315,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void)
pglEnd(); pglEnd();
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = screentexture;
} }
// Do screen fades! // Do screen fades!
@ -2323,6 +2406,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit
pglActiveTexture(GL_TEXTURE0); pglActiveTexture(GL_TEXTURE0);
tex_downloaded = endScreenWipe;
} }
else else
{ {
@ -2348,11 +2432,10 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
pglTexCoord2f(xfix, 0.0f); pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1.0f, -1.0f, 1.0f); pglVertex3f(1.0f, -1.0f, 1.0f);
pglEnd(); pglEnd();
tex_downloaded = endScreenWipe;
#ifndef MINI_GL_COMPATIBILITY #ifndef MINI_GL_COMPATIBILITY
} }
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
} }
@ -2360,6 +2443,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
EXPORT void HWRAPI(MakeScreenTexture) (void) EXPORT void HWRAPI(MakeScreenTexture) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (screentexture == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2368,26 +2452,37 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
screentexture = SCRTEX_SCREENTEXTURE;
pglBindTexture(GL_TEXTURE_2D, screentexture); pglBindTexture(GL_TEXTURE_2D, screentexture);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else #else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif #endif
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = screentexture;
} }
EXPORT void HWRAPI(MakeScreenFinalTexture) (void) EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (finalScreenTexture == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2396,27 +2491,40 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
finalScreenTexture = SCRTEX_FINALSCREENTEXTURE;
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else #else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif #endif
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = finalScreenTexture;
} }
EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
{ {
float xfix, yfix; float xfix, yfix;
float origaspect, newaspect;
float xoff = 1, yoff = 1; // xoffset and yoffset for the polygon to have black bars around the screen
FRGBAFloat clearColour;
INT32 texsize = 2048; INT32 texsize = 2048;
if(screen_width <= 1024) if(screen_width <= 1024)
@ -2427,35 +2535,47 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
xfix = 1/((float)(texsize)/((float)((screen_width)))); xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height)))); yfix = 1/((float)(texsize)/((float)((screen_height))));
//pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); origaspect = (float)screen_width / screen_height;
newaspect = (float)width / height;
if (origaspect < newaspect)
{
xoff = origaspect / newaspect;
yoff = 1;
}
else if (origaspect > newaspect)
{
xoff = 1;
yoff = newaspect / origaspect;
}
pglViewport(0, 0, width, height); pglViewport(0, 0, width, height);
clearColour.red = clearColour.green = clearColour.blue = 0;
clearColour.alpha = 1;
ClearBuffer(true, false, &clearColour);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
pglBegin(GL_QUADS); pglBegin(GL_QUADS);
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Bottom left // Bottom left
pglTexCoord2f(0.0f, 0.0f); pglTexCoord2f(0.0f, 0.0f);
pglVertex3f(-1, -1, 1.0f); pglVertex3f(-xoff, -yoff, 1.0f);
// Top left // Top left
pglTexCoord2f(0.0f, yfix); pglTexCoord2f(0.0f, yfix);
pglVertex3f(-1, 1, 1.0f); pglVertex3f(-xoff, yoff, 1.0f);
// Top right // Top right
pglTexCoord2f(xfix, yfix); pglTexCoord2f(xfix, yfix);
pglVertex3f(1, 1, 1.0f); pglVertex3f(xoff, yoff, 1.0f);
// Bottom right // Bottom right
pglTexCoord2f(xfix, 0.0f); pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1, -1, 1.0f); pglVertex3f(xoff, -yoff, 1.0f);
pglEnd(); pglEnd();
SetModelView(screen_width, screen_height); tex_downloaded = finalScreenTexture;
SetStates();
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
} }
#endif //HWRENDER #endif //HWRENDER

View File

@ -94,6 +94,7 @@ void *hwSym(const char *funcName,void *handle)
#ifdef SHUFFLE #ifdef SHUFFLE
GETFUNC(PostImgRedraw); GETFUNC(PostImgRedraw);
#endif //SHUFFLE #endif //SHUFFLE
GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe); GETFUNC(StartScreenWipe);
GETFUNC(EndScreenWipe); GETFUNC(EndScreenWipe);
GETFUNC(DoScreenWipe); GETFUNC(DoScreenWipe);

View File

@ -1442,6 +1442,7 @@ void I_StartupGraphics(void)
#ifdef SHUFFLE #ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif #endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);

View File

@ -214,8 +214,11 @@ void OglSdlFinishUpdate(boolean waitvbl)
HWR_DrawScreenFinalTexture(sdlw, sdlh); HWR_DrawScreenFinalTexture(sdlw, sdlh);
SDL_GL_SwapWindow(window); SDL_GL_SwapWindow(window);
SetModelView(realwidth, realheight); GClipRect(0, 0, realwidth, realheight, NZCLIP_PLANE);
SetStates();
// Sryder: We need to draw the final screen texture again into the other buffer in the original position so that
// effects that want to take the old screen can do so after this
HWR_DrawScreenFinalTexture(realwidth, realheight);
} }
EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma)

View File

@ -100,6 +100,7 @@ void *hwSym(const char *funcName,void *handle)
#ifdef SHUFFLE #ifdef SHUFFLE
GETFUNC(PostImgRedraw); GETFUNC(PostImgRedraw);
#endif //SHUFFLE #endif //SHUFFLE
GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe); GETFUNC(StartScreenWipe);
GETFUNC(EndScreenWipe); GETFUNC(EndScreenWipe);
GETFUNC(DoScreenWipe); GETFUNC(DoScreenWipe);

View File

@ -1972,6 +1972,7 @@ void I_StartupGraphics(void)
#ifdef SHUFFLE #ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif #endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);

View File

@ -937,14 +937,6 @@ void V_DrawPatchFill(patch_t *pat)
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz;
#ifdef HWRENDER
if (rendermode == render_opengl)
{
pw = FixedMul(SHORT(pat->width)*FRACUNIT, vid.fdupx)>>FRACBITS;
ph = FixedMul(SHORT(pat->height)*FRACUNIT, vid.fdupy)>>FRACBITS;
}
#endif
for (x = 0; x < vid.width; x += pw) for (x = 0; x < vid.width; x += pw)
{ {
for (y = 0; y < vid.height; y += ph) for (y = 0; y < vid.height; y += ph)

View File

@ -117,6 +117,7 @@ static loadfunc_t hwdFuncTable[] = {
#ifdef SHUFFLE #ifdef SHUFFLE
{"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw}, {"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw},
#endif #endif
{"FlushScreenTextures@0",&hwdriver.pfnFlushScreenTextures},
{"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe}, {"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe},
{"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe}, {"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe},
{"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe}, {"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe},
@ -147,6 +148,7 @@ static loadfunc_t hwdFuncTable[] = {
#ifdef SHUFFLE #ifdef SHUFFLE
{"PostImgRedraw", &hwdriver.pfnPostImgRedraw}, {"PostImgRedraw", &hwdriver.pfnPostImgRedraw},
#endif #endif
{"FlushScreenTextures"},&hwdriver.pfnFlushScreenTextures},
{"StartScreenWipe", &hwdriver.pfnStartScreenWipe}, {"StartScreenWipe", &hwdriver.pfnStartScreenWipe},
{"EndScreenWipe", &hwdriver.pfnEndScreenWipe}, {"EndScreenWipe", &hwdriver.pfnEndScreenWipe},
{"DoScreenWipe", &hwdriver.pfnDoScreenWipe}, {"DoScreenWipe", &hwdriver.pfnDoScreenWipe},