port pfnUpdateTexture

This commit is contained in:
Jaime Passos 2020-01-28 00:16:38 -03:00
parent c87119f18f
commit af7b4795b7
5 changed files with 212 additions and 173 deletions

View file

@ -40,6 +40,7 @@ EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data);
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
EXPORT void HWRAPI(ClearMipMapCache) (void);
@ -92,6 +93,7 @@ struct hwdriver_s
SetBlend pfnSetBlend;
ClearBuffer pfnClearBuffer;
SetTexture pfnSetTexture;
UpdateTexture pfnUpdateTexture;
ReadRect pfnReadRect;
GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache;

View file

@ -267,6 +267,7 @@ static void GL_MSG_Error(const char *format, ...)
#define pglTexEnvi glTexEnvi
#define pglTexParameteri glTexParameteri
#define pglTexImage2D glTexImage2D
#define pglTexSubImage2D glTexSubImage2D
/* Fog */
#define pglFogf glFogf
@ -381,6 +382,8 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint
static PFNglTexParameteri pglTexParameteri;
typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexImage2D pglTexImage2D;
typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexSubImage2D pglTexSubImage2D;
/* Fog */
typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param);
@ -518,6 +521,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglTexEnvi, glTexEnvi)
GETOPENGLFUNC(pglTexParameteri, glTexParameteri)
GETOPENGLFUNC(pglTexImage2D, glTexImage2D)
GETOPENGLFUNC(pglTexSubImage2D , glTexSubImage2D)
GETOPENGLFUNC(pglFogf, glFogf)
GETOPENGLFUNC(pglFogfv, glFogfv)
@ -1633,6 +1637,207 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
CurrentPolyFlags = PolyFlags;
}
// -----------------+
// UpdateTexture : Updates the texture data.
// -----------------+
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
{
// Download a mipmap
boolean updatemipmap = true;
static RGBA_t tex[2048*2048];
const GLvoid *ptex = tex;
INT32 w, h;
GLuint texnum = 0;
if (!pTexInfo->downloaded)
{
pglGenTextures(1, &texnum);
pTexInfo->downloaded = texnum;
updatemipmap = false;
}
else
texnum = pTexInfo->downloaded;
//GL_DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->grInfo.data);
w = pTexInfo->width;
h = pTexInfo->height;
if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) ||
(pTexInfo->grInfo.format == GR_TEXFMT_AP_88))
{
const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data;
INT32 i, j;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
{
if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) &&
(pTexInfo->flags & TF_CHROMAKEYED))
{
tex[w*j+i].s.red = 0;
tex[w*j+i].s.green = 0;
tex[w*j+i].s.blue = 0;
tex[w*j+i].s.alpha = 0;
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
}
else
{
tex[w*j+i].s.red = myPaletteData[*pImgData].s.red;
tex[w*j+i].s.green = myPaletteData[*pImgData].s.green;
tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue;
tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha;
}
pImgData++;
if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)
{
if (!(pTexInfo->flags & TF_CHROMAKEYED))
tex[w*j+i].s.alpha = *pImgData;
pImgData++;
}
}
}
}
else if (pTexInfo->grInfo.format == GR_RGBA)
{
// corona test : passed as ARGB 8888, which is not in glide formats
// Hurdler: not used for coronas anymore, just for dynamic lighting
ptex = pTexInfo->grInfo.data;
}
else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88)
{
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 = *pImgData;
tex[w*j+i].s.green = *pImgData;
tex[w*j+i].s.blue = *pImgData;
pImgData++;
tex[w*j+i].s.alpha = *pImgData;
pImgData++;
}
}
}
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
GL_MSG_Warning ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format);
// the texture number was already generated by pglGenTextures
pglBindTexture(GL_TEXTURE_2D, texnum);
tex_downloaded = texnum;
// disable texture filtering on any texture that has holes so there's no dumb borders or blending issues
if (pTexInfo->flags & TF_TRANSPARENT)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
}
if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88)
{
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
if (MipMap)
{
pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
if (updatemipmap)
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
else
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
}
else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8)
{
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
if (MipMap)
{
pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
if (updatemipmap)
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
else
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
}
else
{
if (MipMap)
{
pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
// Control the mipmap level of detail
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5);
}
else
{
if (updatemipmap)
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
else
pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
}
if (pTexInfo->flags & TF_WRAPX)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
else
Clamp2D(GL_TEXTURE_WRAP_S);
if (pTexInfo->flags & TF_WRAPY)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
else
Clamp2D(GL_TEXTURE_WRAP_T);
if (maximumAnisotropy)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_filter);
}
// -----------------+
// SetTexture : The mipmap becomes the current texture source
@ -1654,179 +1859,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
}
else
{
// Download a mipmap
static RGBA_t tex[2048*2048];
const GLvoid *ptex = tex;
INT32 w, h;
GLuint texnum = 0;
pglGenTextures(1, &texnum);
//GL_DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->grInfo.data);
w = pTexInfo->width;
h = pTexInfo->height;
if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) ||
(pTexInfo->grInfo.format == GR_TEXFMT_AP_88))
{
const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data;
INT32 i, j;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
{
if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) &&
(pTexInfo->flags & TF_CHROMAKEYED))
{
tex[w*j+i].s.red = 0;
tex[w*j+i].s.green = 0;
tex[w*j+i].s.blue = 0;
tex[w*j+i].s.alpha = 0;
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
}
else
{
tex[w*j+i].s.red = myPaletteData[*pImgData].s.red;
tex[w*j+i].s.green = myPaletteData[*pImgData].s.green;
tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue;
tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha;
}
pImgData++;
if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)
{
if (!(pTexInfo->flags & TF_CHROMAKEYED))
tex[w*j+i].s.alpha = *pImgData;
pImgData++;
}
}
}
}
else if (pTexInfo->grInfo.format == GR_RGBA)
{
// corona test : passed as ARGB 8888, which is not in glide formats
// Hurdler: not used for coronas anymore, just for dynamic lighting
ptex = pTexInfo->grInfo.data;
}
else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88)
{
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 = *pImgData;
tex[w*j+i].s.green = *pImgData;
tex[w*j+i].s.blue = *pImgData;
pImgData++;
tex[w*j+i].s.alpha = *pImgData;
pImgData++;
}
}
}
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
GL_MSG_Warning ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format);
// the texture number was already generated by pglGenTextures
pglBindTexture(GL_TEXTURE_2D, texnum);
pTexInfo->downloaded = texnum;
tex_downloaded = texnum;
// disable texture filtering on any texture that has holes so there's no dumb borders or blending issues
if (pTexInfo->flags & TF_TRANSPARENT)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
}
if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88)
{
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
if (MipMap)
{
pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
}
else
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8)
{
//pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
if (MipMap)
{
pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
}
else
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
else
{
if (MipMap)
{
pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
// Control the mipmap level of detail
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail
if (pTexInfo->flags & TF_TRANSPARENT)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5);
}
else
pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
}
if (pTexInfo->flags & TF_WRAPX)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
else
Clamp2D(GL_TEXTURE_WRAP_S);
if (pTexInfo->flags & TF_WRAPY)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
else
Clamp2D(GL_TEXTURE_WRAP_T);
if (maximumAnisotropy)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_filter);
UpdateTexture(pTexInfo);
pTexInfo->nextmipmap = NULL;
if (gr_cachetail)
{ // insertion at the tail

View file

@ -84,6 +84,7 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(SetBlend);
GETFUNC(ClearBuffer);
GETFUNC(SetTexture);
GETFUNC(UpdateTexture);
GETFUNC(ReadRect);
GETFUNC(GClipRect);
GETFUNC(ClearMipMapCache);

View file

@ -1769,6 +1769,7 @@ void I_StartupHardwareGraphics(void)
HWD.pfnSetBlend = hwSym("SetBlend",NULL);
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL);
HWD.pfnReadRect = hwSym("ReadRect",NULL);
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);

View file

@ -106,6 +106,7 @@ static loadfunc_t hwdFuncTable[] = {
{"SetBlend@4", &hwdriver.pfnSetBlend},
{"ClearBuffer@12", &hwdriver.pfnClearBuffer},
{"SetTexture@4", &hwdriver.pfnSetTexture},
{"UpdateTexture@4", &hwdriver.pfnUpdateTexture},
{"ReadRect@24", &hwdriver.pfnReadRect},
{"GClipRect@20", &hwdriver.pfnGClipRect},
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
@ -137,6 +138,7 @@ static loadfunc_t hwdFuncTable[] = {
{"SetBlend", &hwdriver.pfnSetBlend},
{"ClearBuffer", &hwdriver.pfnClearBuffer},
{"SetTexture", &hwdriver.pfnSetTexture},
{"UpdateTexture", &hwdriver.pfnUpdateTexture},
{"ReadRect", &hwdriver.pfnReadRect},
{"GClipRect", &hwdriver.pfnGClipRect},
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},