mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-11 18:50:46 +00:00
- texture creation WIP.
This commit is contained in:
parent
3da49ad20a
commit
c6514949e3
7 changed files with 208 additions and 194 deletions
|
@ -649,7 +649,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
|
|||
if (drawpoly_srepeat && drawpoly_trepeat) sampleroverride = SamplerRepeat;
|
||||
else if (drawpoly_srepeat) sampleroverride = SamplerClampY;
|
||||
else if (drawpoly_trepeat) sampleroverride = SamplerClampX;
|
||||
else sampleroverride = -1;
|
||||
else sampleroverride = SamplerClampXY;
|
||||
|
||||
|
||||
bool success = GLInterface.SetTexture(TileFiles.tiles[globalpicnum], globalpal, method, sampleroverride);
|
||||
|
|
|
@ -129,45 +129,7 @@ void copybufbyte(const void *s, void *d, int32_t c)
|
|||
// *and* x86_64, and the C version otherwise.
|
||||
// XXX: we don't honor NOASM in the x86_64 case.
|
||||
|
||||
#if defined(__GNUC__) && defined(__x86_64__)
|
||||
// NOTE: Almost CODEDUP from x86 GCC assembly version, except that
|
||||
// - %%esi -> %%rsi
|
||||
// - %%edi -> %%rdi
|
||||
// - (dec,inc,sub,add)l suffix removed where necessary
|
||||
void copybufreverse(const void *S, void *D, int32_t c)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"shrl $1, %%ecx\n\t"
|
||||
"jnc 0f\n\t" // jnc skipit1
|
||||
"movb (%%rsi), %%al\n\t"
|
||||
"dec %%rsi\n\t"
|
||||
"movb %%al, (%%rdi)\n\t"
|
||||
"inc %%rdi\n\t"
|
||||
"0:\n\t" // skipit1:
|
||||
"shrl $1, %%ecx\n\t"
|
||||
"jnc 1f\n\t" // jnc skipit2
|
||||
"movw -1(%%rsi), %%ax\n\t"
|
||||
"sub $2, %%rsi\n\t"
|
||||
"rorw $8, %%ax\n\t"
|
||||
"movw %%ax, (%%rdi)\n\t"
|
||||
"add $2, %%rdi\n\t"
|
||||
"1:\n\t" // skipit2
|
||||
"testl %%ecx, %%ecx\n\t"
|
||||
"jz 3f\n\t" // jz endloop
|
||||
"2:\n\t" // begloop
|
||||
"movl -3(%%rsi), %%eax\n\t"
|
||||
"sub $4, %%rsi\n\t"
|
||||
"bswapl %%eax\n\t"
|
||||
"movl %%eax, (%%rdi)\n\t"
|
||||
"add $4, %%rdi\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"jnz 2b\n\t" // jnz begloop
|
||||
"3:"
|
||||
: "+S"(S), "+D"(D), "+c"(c) :
|
||||
: "eax", "memory", "cc"
|
||||
);
|
||||
}
|
||||
#elif !defined pragmas_have_copybufreverse
|
||||
#if !defined pragmas_have_copybufreverse
|
||||
void copybufreverse(const void *s, void *d, int32_t c)
|
||||
{
|
||||
auto src = (const char *)s;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#ifdef USE_OPENGL
|
||||
|
||||
#include "baselayer.h"
|
||||
#include "build.h"
|
||||
|
@ -15,6 +14,9 @@
|
|||
#include "bitmap.h"
|
||||
#include "../../glbackend/glbackend.h"
|
||||
|
||||
extern int r_detailmapping, r_glowmapping, usehightile, r_useindexedcolortextures;
|
||||
extern int fixpalette, fixpalswap;
|
||||
|
||||
#if 0
|
||||
|
||||
void gltexinvalidate(int32_t dapicnum, int32_t dapalnum, int32_t dameth)
|
||||
|
@ -99,18 +101,6 @@ static void polymost_setupsampler(FHardwareTexture* tex, const int32_t dameth, i
|
|||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void FlipNonSquareBlock(T* dst, const T* src, int x, int y, int srcpitch)
|
||||
{
|
||||
for (int i = 0; i < x; ++i)
|
||||
{
|
||||
for (int j = 0; j < y; ++j)
|
||||
{
|
||||
dst[i * y + j] = src[i + j * srcpitch];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gloadtile_art(int32_t dapic, int32_t dameth, pthtyp* pth, int32_t doalloc)
|
||||
{
|
||||
vec2_16_t const& tsizart = tilesiz[dapic];
|
||||
|
@ -229,77 +219,8 @@ int32_t gloadtile_hi(int32_t dapic, int32_t dapalnum, int32_t facen, hicreplctyp
|
|||
|
||||
globaltexcache texcache;
|
||||
|
||||
static pthtyp *texcache_tryart(int32_t const dapicnum, int32_t const dapalnum, int32_t const dashade, int32_t dameth)
|
||||
{
|
||||
const int32_t j = dapicnum&(GLTEXCACHEADSIZ-1);
|
||||
pthtyp *pth;
|
||||
int32_t tintpalnum = -1;
|
||||
int32_t searchpalnum = dapalnum;
|
||||
polytintflags_t const tintflags = hictinting[dapalnum].f;
|
||||
|
||||
if (tintflags & (HICTINT_USEONART))
|
||||
{
|
||||
tintpalnum = dapalnum;
|
||||
if (!(tintflags & HICTINT_APPLYOVERPALSWAP))
|
||||
searchpalnum = 0;
|
||||
}
|
||||
|
||||
// load from art
|
||||
for (pth=texcache.list[j]; pth; pth=pth->next)
|
||||
if (pth->picnum == dapicnum && ((pth->flags & (PTH_INDEXED|PTH_HIGHTILE)) == PTH_INDEXED))
|
||||
{
|
||||
if (pth->flags & PTH_INVALIDATED)
|
||||
{
|
||||
pth->flags &= ~PTH_INVALIDATED;
|
||||
gloadtile_art(dapicnum, dameth, pth, 0);
|
||||
pth->palnum = dapalnum;
|
||||
}
|
||||
|
||||
return pth;
|
||||
}
|
||||
|
||||
pth = (pthtyp *)Xcalloc(1,sizeof(pthtyp));
|
||||
|
||||
gloadtile_art(dapicnum, dameth, pth, 1);
|
||||
|
||||
pth->palnum = dapalnum;
|
||||
pth->next = texcache.list[j];
|
||||
texcache.list[j] = pth;
|
||||
|
||||
return pth;
|
||||
}
|
||||
|
||||
#if 0
|
||||
pthtyp *texcache_fetchmulti(pthtyp *pth, hicreplctyp *si, int32_t dapicnum, int32_t dameth)
|
||||
{
|
||||
const int32_t j = dapicnum&(GLTEXCACHEADSIZ-1);
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i <= (GLTEXCACHEADSIZ - 1); i++)
|
||||
{
|
||||
const pthtyp *pth2;
|
||||
|
||||
for (pth2=texcache.list[i]; pth2; pth2=pth2->next)
|
||||
{
|
||||
if (pth2->hicr && pth2->hicr->filename && si->filename && filnamcmp(pth2->hicr->filename, si->filename) == 0)
|
||||
{
|
||||
Bmemcpy(pth, pth2, sizeof(pthtyp));
|
||||
pth->picnum = dapicnum;
|
||||
pth->flags = PTH_HIGHTILE | (drawingskybox>0)*PTH_SKYBOX;
|
||||
if (pth2->flags & PTH_HASALPHA)
|
||||
pth->flags |= PTH_HASALPHA;
|
||||
pth->hicr = si;
|
||||
|
||||
pth->next = texcache.list[j];
|
||||
texcache.list[j] = pth;
|
||||
|
||||
return pth;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// <dashade>: ignored if not in Polymost+r_usetileshades
|
||||
pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int32_t dameth)
|
||||
|
@ -379,94 +300,171 @@ pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int3
|
|||
|
||||
}
|
||||
|
||||
extern int r_detailmapping, r_glowmapping, usehightile;
|
||||
#endif
|
||||
|
||||
bool GLInstance::ApplyTextureProps()
|
||||
|
||||
template<class T>
|
||||
void FlipNonSquareBlock(T* dst, const T* src, int x, int y, int srcpitch)
|
||||
{
|
||||
int pal = palmanager.ActivePalswap();
|
||||
if (currentTexture == nullptr) return false;
|
||||
auto rep = currentTexture->FindReplacement(pal);
|
||||
VSMatrix texmat;
|
||||
bool changed = false;
|
||||
for (int i = 0; i < x; ++i)
|
||||
{
|
||||
for (int j = 0; j < y; ++j)
|
||||
{
|
||||
dst[i * y + j] = src[i + j * srcpitch];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// texture scale
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Create an indexed version of the requested texture
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FHardwareTexture* CreateIndexedTexture(FTexture* tex)
|
||||
{
|
||||
auto siz = tex->GetSize();
|
||||
bool npoty = false;
|
||||
|
||||
const uint8_t* p = tex->Get8BitPixels();
|
||||
TArray<uint8_t> store(siz.x * siz.y, true);
|
||||
if (!p)
|
||||
{
|
||||
tex->Create8BitPixels(store.Data());
|
||||
p = store.Data();
|
||||
}
|
||||
|
||||
auto glpic = GLInterface.NewTexture();
|
||||
glpic->CreateTexture(siz.x, siz.y, true, false);
|
||||
|
||||
TArray<uint8_t> flipped(siz.x * siz.y, true);
|
||||
FlipNonSquareBlock(flipped.Data(), p, siz.y, siz.x, siz.y);
|
||||
glpic->LoadTexture(flipped.Data());
|
||||
return glpic;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Retrieve the texture to be used.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid)
|
||||
{
|
||||
if (textype == TT_TRUECOLOR && palid == 0) textype = TT_HICREPLACE; // true color tiles with the base palette won't get processed.
|
||||
if (textype == TT_INDEXED)
|
||||
{
|
||||
auto hwtex = tex->GetHardwareTexture(-1);
|
||||
if (hwtex) return hwtex;
|
||||
else
|
||||
{
|
||||
hwtex = CreateIndexedTexture(tex);
|
||||
tex->SetHardwareTexture(-1, hwtex);
|
||||
return hwtex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Sets a texture for rendering
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool GLInstance::SetTexture(FTexture* tex, int palette, int method, int sampleroverride)
|
||||
{
|
||||
int usepalette = fixpalette >= 1 ? fixpalette - 1 : curbasepal;
|
||||
int usepalswap = fixpalswap >= 1 ? fixpalswap - 1 : palette;
|
||||
GLInterface.SetPalette(usepalette);
|
||||
GLInterface.SetPalswap(usepalswap);
|
||||
|
||||
TextureType = r_useindexedcolortextures? TT_INDEXED : TT_TRUECOLOR;
|
||||
|
||||
int lookuppal = 0;
|
||||
VSMatrix texmat;
|
||||
|
||||
auto rep = usehightile? currentTexture->FindReplacement(palette) : nullptr;
|
||||
if (rep)
|
||||
{
|
||||
// Hightile replacements have only one texture representation and it is always the base.
|
||||
tex = rep->faces[0];
|
||||
TextureType = TT_HICREPLACE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only look up the palette if we really want to use it (i.e. when creating a true color texture of an ART tile.)
|
||||
if (!r_useindexedcolortextures) lookuppal = palmanager.LookupPalette(usepalette, usepalswap);
|
||||
}
|
||||
|
||||
// Load the main texture
|
||||
auto mtex = LoadTexture(tex, TextureType, lookuppal);
|
||||
if (mtex)
|
||||
{
|
||||
auto sampler = (method & DAMETH_CLAMPED) ? (sampleroverride != -1 ? sampleroverride : SamplerClampXY) : SamplerRepeat;
|
||||
|
||||
BindTexture(0, mtex, sampler);
|
||||
if (rep && ((rep->scale.x != 1.0f) || (rep->scale.y != 1.0f)))
|
||||
{
|
||||
texmat.loadIdentity();
|
||||
texmat.scale(rep->scale.x, rep->scale.y, 1.0f);
|
||||
GLInterface.SetMatrix(Matrix_Texture, &texmat);
|
||||
MatrixChange |= 1;
|
||||
}
|
||||
|
||||
if (r_detailmapping)
|
||||
// Also load additional layers needed for this texture.
|
||||
if (r_detailmapping && usehightile)
|
||||
{
|
||||
auto detailrep = currentTexture->FindReplacement(DETAILPAL);
|
||||
if (detailrep)
|
||||
auto drep = currentTexture->FindReplacement(DETAILPAL);
|
||||
if (drep)
|
||||
{
|
||||
auto htex = LoadTexture(drep->faces[0], TT_HICREPLACE, 0);
|
||||
UseDetailMapping(true);
|
||||
//BindTexture(3, detailrep->faces[0], SamplerRepeat);
|
||||
BindTexture(3, htex, SamplerRepeat);
|
||||
|
||||
texmat.loadIdentity();
|
||||
bool scaled = false;
|
||||
|
||||
if (rep && ((rep->scale.x != 1.0f) || (rep->scale.y != 1.0f)))
|
||||
{
|
||||
texmat.scale(rep->scale.x, rep->scale.y, 1.0f);
|
||||
scaled = true;
|
||||
MatrixChange |= 2;
|
||||
}
|
||||
|
||||
if ((detailrep->scale.x != 1.0f) || (detailrep->scale.y != 1.0f))
|
||||
if ((drep->scale.x != 1.0f) || (drep->scale.y != 1.0f))
|
||||
{
|
||||
texmat.scale(detailrep->scale.x, detailrep->scale.y, 1.0f);
|
||||
scaled = true;
|
||||
texmat.scale(drep->scale.x, drep->scale.y, 1.0f);
|
||||
MatrixChange |= 2;
|
||||
}
|
||||
|
||||
if (scaled) GLInterface.SetMatrix(Matrix_Detail, &texmat);
|
||||
changed |= scaled;
|
||||
if (MatrixChange & 2) GLInterface.SetMatrix(Matrix_Detail, &texmat);
|
||||
}
|
||||
}
|
||||
|
||||
// glow texture
|
||||
if (r_glowmapping)
|
||||
if (r_glowmapping && usehightile)
|
||||
{
|
||||
auto glowrep = currentTexture->FindReplacement(GLOWPAL);
|
||||
if (glowrep)
|
||||
auto drep = currentTexture->FindReplacement(GLOWPAL);
|
||||
if (drep)
|
||||
{
|
||||
auto htex = LoadTexture(drep->faces[0], TT_HICREPLACE, 0);
|
||||
UseGlowMapping(true);
|
||||
//BindTexture(4, glowrep->faces[0], SamplerRepeat);
|
||||
}
|
||||
}
|
||||
BindTexture(4, htex, SamplerRepeat);
|
||||
|
||||
auto brightrep = currentTexture->FindReplacement(BRIGHTPAL);
|
||||
if (brightrep)
|
||||
}
|
||||
}
|
||||
auto brep = currentTexture->FindReplacement(BRIGHTPAL);
|
||||
if (brep)
|
||||
{
|
||||
//UseGlowMapping(true);
|
||||
//BindTexture(5, glowrep->faces[0], SamplerRepeat);
|
||||
auto htex = LoadTexture(brep->faces[0], TT_HICREPLACE, 0);
|
||||
BindTexture(5, mtex, sampler);
|
||||
}
|
||||
}
|
||||
|
||||
return false; // true if the matrices were changed, false otherwise
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLInstance::SetTexture(FTexture* tex, int palette, int method)
|
||||
float al = 0;
|
||||
if (TextureType == TT_HICREPLACE)
|
||||
{
|
||||
|
||||
GLInterface.SetPalswap(fixpalswap >= 1 ? fixpalswap - 1 : globalpal);
|
||||
GLInterface.SetPalette(fixpalette >= 1 ? fixpalette - 1 : curbasepal);
|
||||
|
||||
|
||||
pthtyp* pth = texcache_fetch(globalpicnum, globalpal, getpalookup(1, globalshade), method | PTH_INDEXED);
|
||||
GLInterface.BindTexture(0, pth->glpic, mSampler);
|
||||
|
||||
// Fixme: Alpha test on shaders must be done differently.
|
||||
// Also: Consider a texture's alpha threshold.
|
||||
float const al = alphahackarray[globalpicnum] != 0 ? alphahackarray[globalpicnum] * (1.f / 255.f) :
|
||||
(pth->hicr && pth->hicr->alphacut >= 0.f ? pth->hicr->alphacut : 0.f);
|
||||
|
||||
al = /*alphahackarray[globalpicnum] != 0 ? alphahackarray[globalpicnum] * (1.f / 255.f) :*/
|
||||
(tex->alphaThreshold >= 0.f ? tex->alphaThreshold : 0.f);
|
||||
}
|
||||
GLInterface.SetAlphaThreshold(al);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1188,6 +1188,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr)
|
|||
}
|
||||
VSMatrix identity(0);
|
||||
GLInterface.SetMatrix(Matrix_ModelView, &identity);
|
||||
GLInterface.SetTinting(0, 0, PalEntry(255, 255, 255));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
class FImageSource;
|
||||
class FTexture;
|
||||
class FHardwareTexture;
|
||||
|
||||
// picanm[].sf:
|
||||
// |bit(1<<7)
|
||||
|
@ -249,6 +250,16 @@ public:
|
|||
Hightiles.Clear();
|
||||
}
|
||||
|
||||
void SetHardwareTexture(int palid, FHardwareTexture* htex)
|
||||
{
|
||||
HardwareTextures.Insert(palid, htex);
|
||||
}
|
||||
FHardwareTexture* GetHardwareTexture(int palid)
|
||||
{
|
||||
auto k = HardwareTextures.CheckKey(palid);
|
||||
return k ? *k : nullptr;
|
||||
}
|
||||
|
||||
HightileReplacement * FindReplacement(int palnum, bool skybox = false);
|
||||
|
||||
int alphaThreshold = 128;
|
||||
|
@ -299,6 +310,8 @@ protected:
|
|||
intptr_t CacheHandle = 0; // For tiles that do not have a static image but get accessed by the software renderer.
|
||||
uint8_t CacheLock = 0;
|
||||
TArray<HightileReplacement> Hightiles;
|
||||
// Don't waste too much effort on efficient storage here. Polymost performs so many calculations on a single draw call that the minor map lookup hardly matters.
|
||||
TMap<int, FHardwareTexture*> HardwareTextures; // Note: These must be deleted by the backend. When the texture manager is taken down it may already be too late to delete them.
|
||||
|
||||
FTexture (const char *name = NULL);
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "baselayer.h"
|
||||
#include "resourcefile.h"
|
||||
#include "imagehelpers.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -168,6 +169,10 @@ void PaletteManager::SetPalette(int index, const uint8_t* data, bool transient)
|
|||
return;
|
||||
}
|
||||
palettemap[index] = FindPalette(data);
|
||||
if (index == 0)
|
||||
{
|
||||
ImageHelpers::SetPalette((PalEntry*)data); // Palette 0 is always the reference for downconverting images
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -251,3 +256,24 @@ void PaletteManager::BindPalswap(int index)
|
|||
|
||||
}
|
||||
|
||||
|
||||
int PaletteManager::LookupPalette(int palette, int palswap)
|
||||
{
|
||||
int realpal = palettemap[palette];
|
||||
int realswap = palswapmap[palswap];
|
||||
int combined = realpal * 0x10000 + realswap;
|
||||
int* combinedindex = swappedpalmap.CheckKey(combined);
|
||||
if (combinedindex) return *combinedindex;
|
||||
|
||||
PaletteData* paldata = &palettes[realpal];
|
||||
PalswapData* swapdata = &palswaps[realswap];
|
||||
PalEntry swappedpalette[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int swapi = swapdata->lookup[i];
|
||||
swappedpalette[i] = paldata->colors[swapi];
|
||||
}
|
||||
int palid = FindPalette((uint8_t*)swappedpalette);
|
||||
swappedpalmap.Insert(combined, palid);
|
||||
return palid;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ class PaletteManager
|
|||
// All data is being stored in contiguous blocks that can be used as uniform buffers as-is.
|
||||
TArray<PaletteData> palettes;
|
||||
TArray<PalswapData> palswaps;
|
||||
TMap<int, int> swappedpalmap;
|
||||
FHardwareTexture* palswapTexture = nullptr;
|
||||
GLInstance* const inst;
|
||||
|
||||
|
@ -81,6 +82,7 @@ public:
|
|||
void BindPalette(int index);
|
||||
void BindPalswap(int index);
|
||||
int ActivePalswap() const { return lastsindex; }
|
||||
int LookupPalette(int palette, int palswap);
|
||||
};
|
||||
|
||||
|
||||
|
@ -186,6 +188,14 @@ enum EWinding
|
|||
Winding_CCW,
|
||||
Winding_CW
|
||||
};
|
||||
|
||||
enum ETexType
|
||||
{
|
||||
TT_INDEXED,
|
||||
TT_TRUECOLOR,
|
||||
TT_HICREPLACE
|
||||
};
|
||||
|
||||
class GLInstance
|
||||
{
|
||||
enum
|
||||
|
@ -202,6 +212,8 @@ class GLInstance
|
|||
int lastPalswapIndex = -1;
|
||||
FHardwareTexture* texv;
|
||||
FTexture* currentTexture = nullptr;
|
||||
int TextureType;
|
||||
int MatrixChange = 0;
|
||||
|
||||
|
||||
VSMatrix matrices[NUMMATRICES];
|
||||
|
@ -279,7 +291,7 @@ public:
|
|||
void SetSurfaceShader();
|
||||
void SetVPXShader();
|
||||
void SetPalette(int palette);
|
||||
bool ApplyTextureProps();
|
||||
bool ApplyTextureProps(FTexture *tex, int pal);
|
||||
void RestoreTextureProps();
|
||||
|
||||
void ReadPixels(int w, int h, uint8_t* buffer);
|
||||
|
@ -365,6 +377,8 @@ public:
|
|||
// not yet implemented - only relevant for hires replacements.
|
||||
}
|
||||
|
||||
FHardwareTexture* CreateIndexedTexture(FTexture* tex);
|
||||
FHardwareTexture *LoadTexture(FTexture* tex, int texturetype, int palid);
|
||||
bool SetTexture(FTexture* tex, int palette, int method, int sampleroverride = -1);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue