- refactored texture setup to use an intermediate layer.

This commit is contained in:
Christoph Oelckers 2019-09-18 20:44:21 +02:00
parent 155f093bd5
commit e0f823a492
19 changed files with 245 additions and 694 deletions

View file

@ -288,7 +288,6 @@
<ClCompile Include="..\..\source\build\src\softsurface.cpp" /> <ClCompile Include="..\..\source\build\src\softsurface.cpp" />
<ClCompile Include="..\..\source\build\src\texcache.cpp" /> <ClCompile Include="..\..\source\build\src\texcache.cpp" />
<ClCompile Include="..\..\source\build\src\textfont.cpp" /> <ClCompile Include="..\..\source\build\src\textfont.cpp" />
<ClCompile Include="..\..\source\build\src\tilepacker.cpp" />
<ClCompile Include="..\..\source\build\src\tiles.cpp" /> <ClCompile Include="..\..\source\build\src\tiles.cpp" />
<ClCompile Include="..\..\source\build\src\vfs.cpp" /> <ClCompile Include="..\..\source\build\src\vfs.cpp" />
<ClCompile Include="..\..\source\build\src\voxmodel.cpp" /> <ClCompile Include="..\..\source\build\src\voxmodel.cpp" />
@ -369,7 +368,6 @@
<ClInclude Include="..\..\source\build\include\sdl_inc.h" /> <ClInclude Include="..\..\source\build\include\sdl_inc.h" />
<ClInclude Include="..\..\source\build\include\softsurface.h" /> <ClInclude Include="..\..\source\build\include\softsurface.h" />
<ClInclude Include="..\..\source\build\include\texcache.h" /> <ClInclude Include="..\..\source\build\include\texcache.h" />
<ClInclude Include="..\..\source\build\include\tilepacker.h" />
<ClInclude Include="..\..\source\build\include\tracker.hpp" /> <ClInclude Include="..\..\source\build\include\tracker.hpp" />
<ClInclude Include="..\..\source\build\include\tracker_operator.hpp" /> <ClInclude Include="..\..\source\build\include\tracker_operator.hpp" />
<ClInclude Include="..\..\source\build\include\tracker_operators.hpp" /> <ClInclude Include="..\..\source\build\include\tracker_operators.hpp" />

View file

@ -158,9 +158,6 @@
<ClCompile Include="..\..\source\build\src\textfont.cpp"> <ClCompile Include="..\..\source\build\src\textfont.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\source\build\src\tilepacker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\source\build\src\tiles.cpp"> <ClCompile Include="..\..\source\build\src\tiles.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@ -370,9 +367,6 @@
<ClInclude Include="..\..\source\build\include\texcache.h"> <ClInclude Include="..\..\source\build\include\texcache.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\source\build\include\tilepacker.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\source\build\include\tracker.hpp"> <ClInclude Include="..\..\source\build\include\tracker.hpp">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View file

@ -12,7 +12,7 @@ extern "C" {
#define SHARED_MODEL_DATA int32_t mdnum, shadeoff; \ #define SHARED_MODEL_DATA int32_t mdnum, shadeoff; \
float scale, bscale, zadd, yoffset; \ float scale, bscale, zadd, yoffset; \
GLuint *texid; \ FHardwareTexture **texid; \
int32_t flags; int32_t flags;
#define IDMODEL_SHARED_DATA int32_t numframes, cframe, nframe, fpssc, usesalpha; \ #define IDMODEL_SHARED_DATA int32_t numframes, cframe, nframe, fpssc, usesalpha; \
@ -24,6 +24,8 @@ extern "C" {
#define IDP2_MAGIC 0x32504449 #define IDP2_MAGIC 0x32504449
#define IDP3_MAGIC 0x33504449 #define IDP3_MAGIC 0x33504449
class FHardwareTexture;
typedef struct typedef struct
{ {
SHARED_MODEL_DATA; SHARED_MODEL_DATA;
@ -44,7 +46,7 @@ typedef struct _mdskinmap_t
uint8_t palette, flags, filler[2]; // Build palette number, flags the same as hicreplctyp uint8_t palette, flags, filler[2]; // Build palette number, flags the same as hicreplctyp
int32_t skinnum, surfnum; // Skin identifier, surface number int32_t skinnum, surfnum; // Skin identifier, surface number
char *fn; // Skin filename char *fn; // Skin filename
GLuint texid[HICTINT_MEMORY_COMBINATIONS]; // OpenGL texture numbers for effect variations FHardwareTexture *texid[HICTINT_MEMORY_COMBINATIONS]; // OpenGL texture numbers for effect variations
struct _mdskinmap_t *next; struct _mdskinmap_t *next;
float param, specpower, specfactor; float param, specpower, specfactor;
} mdskinmap_t; } mdskinmap_t;
@ -192,7 +194,7 @@ typedef struct
int32_t mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! int32_t mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure!
int32_t shadeoff; int32_t shadeoff;
float scale, bscale, zadd; float scale, bscale, zadd;
uint32_t *texid; // skins for palettes FHardwareTexture **texid; // skins for palettes
int32_t flags; int32_t flags;
//VOX specific stuff: //VOX specific stuff:
@ -206,7 +208,7 @@ typedef struct
EXTERN mdmodel_t **models; EXTERN mdmodel_t **models;
void updateanimation(md2model_t *m, const uspritetype *tspr, uint8_t lpal); void updateanimation(md2model_t *m, const uspritetype *tspr, uint8_t lpal);
int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf); FHardwareTexture *mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf);
void mdinit(void); void mdinit(void);
void freeallmodels(void); void freeallmodels(void);
void clearskins(int32_t type); void clearskins(int32_t type);

View file

@ -13,6 +13,7 @@ void Polymost_CacheHitList(uint8_t* hash);
extern "C" { extern "C" {
#endif #endif
class FHardwareTexture;
typedef struct { uint8_t r, g, b, a; } coltype; typedef struct { uint8_t r, g, b, a; } coltype;
typedef struct { float r, g, b, a; } coltypef; typedef struct { float r, g, b, a; } coltypef;
@ -33,11 +34,9 @@ extern struct glfiltermodes glfiltermodes[NUMGLFILTERMODES];
extern void Polymost_prepare_loadboard(void); extern void Polymost_prepare_loadboard(void);
void GetTextureHandle(GLuint *handle);
//void phex(char v, char *s); //void phex(char v, char *s);
void uploadtexture(int32_t doalloc, vec2_t siz, int32_t texfmt, coltype *pic, vec2_t tsiz, int32_t dameth); void uploadtexture(FHardwareTexture *tex, int32_t doalloc, vec2_t siz, int32_t texfmt, coltype *pic, vec2_t tsiz, int32_t dameth);
void uploadtextureindexed(int32_t doalloc, vec2_t offset, vec2_t siz, intptr_t tile);
void uploadbasepalette(int32_t basepalnum); void uploadbasepalette(int32_t basepalnum);
void uploadpalswap(int32_t palookupnum); void uploadpalswap(int32_t palookupnum);
void polymost_drawsprite(int32_t snum); void polymost_drawsprite(int32_t snum);
@ -57,16 +56,8 @@ void polymost_useColorOnly(char useColorOnly);
void polymost_usePaletteIndexing(char usePaletteIndexing); void polymost_usePaletteIndexing(char usePaletteIndexing);
void polymost_useDetailMapping(char useDetailMapping); void polymost_useDetailMapping(char useDetailMapping);
void polymost_useGlowMapping(char useGlowMapping); void polymost_useGlowMapping(char useGlowMapping);
void polymost_activeTexture(GLenum texture);
void polymost_bindTexture(GLenum target, uint32_t textureID);
void useShaderProgram(uint32_t shaderID); void useShaderProgram(uint32_t shaderID);
//POGOTODO: these wrappers won't be needed down the line -- remove them once proper draw call organization is finished
#undef glActiveTexture
#undef glBindTexture
#define glActiveTexture polymost_activeTexture
#define glBindTexture polymost_bindTexture
void polymost_glinit(void); void polymost_glinit(void);
void polymost_glreset(void); void polymost_glreset(void);
@ -225,8 +216,7 @@ EDUKE32_STATIC_ASSERT(TO_DAMETH_ARTIMMUNITY(HICR_ARTIMMUNITY) == DAMETH_ARTIMMUN
// Do we want a NPOT-y-as-classic texture for this <dameth> and <ysiz>? // Do we want a NPOT-y-as-classic texture for this <dameth> and <ysiz>?
static FORCE_INLINE int polymost_want_npotytex(int32_t dameth, int32_t ysiz) static FORCE_INLINE int polymost_want_npotytex(int32_t dameth, int32_t ysiz)
{ {
return videoGetRenderMode() != REND_POLYMER && // r_npotwallmode NYI in Polymer return polymost_is_npotmode() && (dameth&DAMETH_WALL) && check_nonpow2(ysiz);
polymost_is_npotmode() && (dameth&DAMETH_WALL) && check_nonpow2(ysiz);
} }
// pthtyp pth->flags bits // pthtyp pth->flags bits
@ -252,7 +242,7 @@ typedef struct pthtyp_t
struct pthtyp_t *ofb; // fullbright pixels struct pthtyp_t *ofb; // fullbright pixels
hicreplctyp *hicr; hicreplctyp *hicr;
uint32_t glpic; FHardwareTexture * glpic;
vec2f_t scale; vec2f_t scale;
vec2_t siz; vec2_t siz;
int16_t picnum; int16_t picnum;
@ -288,8 +278,8 @@ extern hitdata_t polymost_hitdata;
#include "texcache.h" #include "texcache.h"
extern void polymost_setupglowtexture(int32_t texunits, int32_t tex); extern void polymost_setupglowtexture(int32_t texunits, FHardwareTexture *tex);
extern void polymost_setupdetailtexture(int32_t texunits, int32_t tex); extern void polymost_setupdetailtexture(int32_t texunits, FHardwareTexture* tex);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -93,13 +93,6 @@ static void drawlinegl(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
glOrtho(0, xdim, ydim, 0, -1, 1); glOrtho(0, xdim, ydim, 0, -1, 1);
if (videoGetRenderMode() == REND_POLYMER)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
}
gloy1 = -1; gloy1 = -1;
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
@ -1366,14 +1359,6 @@ void polymostSet2dView(void)
glLoadIdentity(); glLoadIdentity();
glOrtho(0, xdim, ydim, 0, -1, 1); glOrtho(0, xdim, ydim, 0, -1, 1);
if (videoGetRenderMode() == REND_POLYMER)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
}
gloy1 = -1; gloy1 = -1;
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);

View file

@ -295,8 +295,7 @@ read_ivf_frame:
const int32_t ustride = img->stride[VPX_PLANE_U]; const int32_t ustride = img->stride[VPX_PLANE_U];
const int32_t vstride = img->stride[VPX_PLANE_V]; const int32_t vstride = img->stride[VPX_PLANE_V];
if (glinfo.glsl) /*** 3 planes --> packed conversion ***/ /*** 3 planes --> packed conversion ***/
{
vec2u_t const dim = { img->d_w, img->d_h }; vec2u_t const dim = { img->d_w, img->d_h };
for (unsigned int y = 0; y < dim.y; y += 2) for (unsigned int y = 0; y < dim.y; y += 2)
@ -326,33 +325,6 @@ read_ivf_frame:
dstpic[((wy1 + x + 1) << 2) + 2] = v; dstpic[((wy1 + x + 1) << 2) + 2] = v;
} }
} }
}
else /*** 3 planes --> packed conversion (RGB) ***/
{
int i = 0;
for (unsigned int imgY = 0; imgY < img->d_h; imgY++)
{
for (unsigned int imgX = 0; imgX < img->d_w; imgX++)
{
uint8_t const y = yplane[imgY * ystride + imgX];
uint8_t const u = uplane[(imgY >> 1) * ustride + (imgX >> 1)];
uint8_t const v = vplane[(imgY >> 1) * vstride + (imgX >> 1)];
int const c = y - 16;
int const d = (u + -128);
int const e = (v + -128);
int const c298 = c * 298;
dstpic[i + 0] = (uint8_t)clamp((c298 + 409 * e - -128) >> 8, 0, 255);
dstpic[i + 1] = (uint8_t)clamp((c298 - 100 * d - 208 * e - -128) >> 8, 0, 255);
dstpic[i + 2] = (uint8_t)clamp((c298 + 516 * d - -128) >> 8, 0, 255);
i += 3;
}
}
}
t[2] = timerGetTicks(); t[2] = timerGetTicks();
codec->sumtimes[0] += t[1]-t[0]; codec->sumtimes[0] += t[1]-t[0];
@ -367,7 +339,8 @@ read_ivf_frame:
/////////////// DRAWING! /////////////// /////////////// DRAWING! ///////////////
static GLuint texname = 0; static FHardwareTexture* texture;
static int sampler;
static int32_t texuploaded; static int32_t texuploaded;
#ifdef USE_GLEXT #ifdef USE_GLEXT
@ -458,26 +431,17 @@ void animvpx_setup_glstate(int32_t animvpx_flags)
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glEnable(GL_TEXTURE_2D);
#ifdef USE_GLEXT texture = GLInterface.NewTexture();
glActiveTexture(GL_TEXTURE0);
#endif
GetTextureHandle(&texname);
glBindTexture(GL_TEXTURE_2D, texname);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP);
if ((animvpx_flags & CUTSCENE_TEXTUREFILTER && gltexfiltermode == TEXFILTER_ON) || animvpx_flags & CUTSCENE_FORCEFILTER || if ((animvpx_flags & CUTSCENE_TEXTUREFILTER && gltexfiltermode == TEXFILTER_ON) || animvpx_flags & CUTSCENE_FORCEFILTER ||
(!(animvpx_flags & CUTSCENE_TEXTUREFILTER) && !(animvpx_flags & CUTSCENE_FORCENOFILTER))) // if no flags, then use filter for IVFs (!(animvpx_flags & CUTSCENE_TEXTUREFILTER) && !(animvpx_flags & CUTSCENE_FORCENOFILTER))) // if no flags, then use filter for IVFs
{ {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); sampler = Sampler2DFiltered;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} }
else else
{ {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); sampler = Sampler2DNoFilter;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
} }
texuploaded = 0; texuploaded = 0;
@ -499,8 +463,8 @@ void animvpx_restore_glstate(void)
// glPopAttrib(); // glPopAttrib();
glDeleteTextures(1, &texname); delete texture;
texname = 0; texture = nullptr;
texuploaded = 0; texuploaded = 0;
} }
@ -514,21 +478,13 @@ int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect)
if (codec->pic == NULL) if (codec->pic == NULL)
return 2; // shouldn't happen return 2; // shouldn't happen
int fmt = glinfo.glsl ? GL_RGBA : GL_RGB;
if (!texuploaded) if (!texuploaded)
{ {
glTexImage2D(GL_TEXTURE_2D, 0, fmt, codec->width,codec->height, texture->CreateTexture(codec->width, codec->height, false, false);
0, fmt, GL_UNSIGNED_BYTE, codec->pic);
if (glGetError() != GL_NO_ERROR) return 1;
texuploaded = 1; texuploaded = 1;
} }
else texture->LoadTexture(codec->pic);
{ GLInterface.BindTexture(0, texture, sampler);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, codec->width,codec->height,
fmt, GL_UNSIGNED_BYTE, codec->pic);
if (glGetError() != GL_NO_ERROR) return 1;
}
float vid_wbyh = ((float)codec->width)/codec->height; float vid_wbyh = ((float)codec->width)/codec->height;
if (animvpx_aspect > 0) if (animvpx_aspect > 0)

View file

@ -13,10 +13,10 @@
#include "../../glbackend/glbackend.h" #include "../../glbackend/glbackend.h"
static void* buffer; static void* buffer;
static GLuint bufferTexID; static FHardwareTexture* bufferTexture;
static vec2_t bufferRes; static vec2_t bufferRes;
static GLuint paletteTexID; static FHardwareTexture* paletteTexture;
static GLuint shaderProgramID = 0; static GLuint shaderProgramID = 0;
static GLint texSamplerLoc = -1; static GLint texSamplerLoc = -1;
@ -64,18 +64,10 @@ bool glsurface_initialize(vec2_t bufferResolution)
bufferRes = bufferResolution; bufferRes = bufferResolution;
buffer = Xaligned_alloc(16, bufferRes.x * bufferRes.y); buffer = Xaligned_alloc(16, bufferRes.x * bufferRes.y);
glActiveTexture(GL_TEXTURE0); bufferTexture = GLInterface.NewTexture();
GetTextureHandle(&bufferTexID); bufferTexture->CreateTexture(bufferRes.x, bufferRes.y, true, false);
glBindTexture(GL_TEXTURE_2D, bufferTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, bufferRes.x, bufferRes.y, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
GLInterface.Init();
glsurface_setPalette(curpalettefaded); glsurface_setPalette(curpalettefaded);
const char* const VERTEX_SHADER_CODE = const char* const VERTEX_SHADER_CODE =
@ -147,10 +139,10 @@ void glsurface_destroy()
ALIGNED_FREE_AND_NULL(buffer); ALIGNED_FREE_AND_NULL(buffer);
glDeleteTextures(1, &bufferTexID); delete bufferTexture;
bufferTexID = 0; bufferTexture = nullptr;
glDeleteTextures(1, &paletteTexID); delete paletteTexture;
paletteTexID = 0; paletteTexture = nullptr;
glUseProgram(0); glUseProgram(0);
glDeleteProgram(shaderProgramID); glDeleteProgram(shaderProgramID);
@ -164,25 +156,13 @@ void glsurface_setPalette(void* pPalette)
if (!pPalette) if (!pPalette)
return; return;
glActiveTexture(GL_TEXTURE1); if (!paletteTexture)
if (paletteTexID)
{ {
// assume the texture is already bound to GL_TEXTURE1 paletteTexture = GLInterface.NewTexture();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*) pPalette); paletteTexture->CreateTexture(256, 1, false, false);
}
else
{
GetTextureHandle(&paletteTexID);
glBindTexture(GL_TEXTURE_2D, paletteTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPalette);
} }
paletteTexture->LoadTexture(palette);
GLInterface.BindTexture(1, paletteTexture, Sampler2DNoFilter);
} }
void* glsurface_getBuffer() void* glsurface_getBuffer()
@ -200,8 +180,8 @@ void glsurface_blitBuffer()
if (!buffer) if (!buffer)
return; return;
glActiveTexture(GL_TEXTURE0); bufferTexture->LoadTexture((uint8_t*)buffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bufferRes.x, bufferRes.y, GL_RED, GL_UNSIGNED_BYTE, (void*) buffer); GLInterface.BindTexture(0, bufferTexture, Sampler2DNoFilter);
auto data = GLInterface.AllocVertices(4); auto data = GLInterface.AllocVertices(4);
auto vt = data.second; auto vt = data.second;

View file

@ -126,7 +126,7 @@ void freeallmodels()
// Skin texture names can be aliased! This is ugly, but at least correct. // Skin texture names can be aliased! This is ugly, but at least correct.
static void nullskintexids(GLuint texid) static void nullskintexids(FHardwareTexture *texid)
{ {
int32_t i, j; int32_t i, j;
@ -141,12 +141,12 @@ static void nullskintexids(GLuint texid)
for (j=0; j < m2->numskins * HICTINT_MEMORY_COMBINATIONS; j++) for (j=0; j < m2->numskins * HICTINT_MEMORY_COMBINATIONS; j++)
if (m2->texid[j] == texid) if (m2->texid[j] == texid)
m2->texid[j] = 0; m2->texid[j] = nullptr;
for (sk=m2->skinmap; sk; sk=sk->next) for (sk=m2->skinmap; sk; sk=sk->next)
for (j=0; j < HICTINT_MEMORY_COMBINATIONS; j++) for (j=0; j < HICTINT_MEMORY_COMBINATIONS; j++)
if (sk->texid[j] == texid) if (sk->texid[j] == texid)
sk->texid[j] = 0; sk->texid[j] = nullptr;
} }
} }
} }
@ -166,8 +166,8 @@ void clearskins(int32_t type)
for (j=0; j<MAXPALOOKUPS; j++) for (j=0; j<MAXPALOOKUPS; j++)
if (v->texid[j]) if (v->texid[j])
{ {
glDeleteTextures(1, &v->texid[j]); delete v->texid[j];
v->texid[j] = 0; v->texid[j] = nullptr;
} }
} }
else if ((m->mdnum == 2 || m->mdnum == 3) && type == INVALIDATE_ALL) else if ((m->mdnum == 2 || m->mdnum == 3) && type == INVALIDATE_ALL)
@ -178,10 +178,10 @@ void clearskins(int32_t type)
for (j=0; j < m2->numskins * HICTINT_MEMORY_COMBINATIONS; j++) for (j=0; j < m2->numskins * HICTINT_MEMORY_COMBINATIONS; j++)
if (m2->texid[j]) if (m2->texid[j])
{ {
GLuint otexid = m2->texid[j]; auto otexid = m2->texid[j];
glDeleteTextures(1, &m2->texid[j]); delete m2->texid[j];
m2->texid[j] = 0; m2->texid[j] = nullptr;
nullskintexids(otexid); nullskintexids(otexid);
} }
@ -190,10 +190,10 @@ void clearskins(int32_t type)
for (j=0; j < HICTINT_MEMORY_COMBINATIONS; j++) for (j=0; j < HICTINT_MEMORY_COMBINATIONS; j++)
if (sk->texid[j]) if (sk->texid[j])
{ {
GLuint otexid = sk->texid[j]; auto otexid = sk->texid[j];
glDeleteTextures(1, &sk->texid[j]); delete sk->texid[j];
sk->texid[j] = 0; sk->texid[j] = nullptr;
nullskintexids(otexid); nullskintexids(otexid);
} }
@ -208,8 +208,8 @@ void clearskins(int32_t type)
for (j=0; j<MAXPALOOKUPS; j++) for (j=0; j<MAXPALOOKUPS; j++)
if (v->texid[j]) if (v->texid[j])
{ {
glDeleteTextures(1, &v->texid[j]); delete v->texid[j];
v->texid[j] = 0; v->texid[j] = nullptr;
} }
} }
} }
@ -559,28 +559,28 @@ static inline int32_t hicfxid(size_t pal)
return globalnoeffect ? 0 : ((hictinting[pal].f & (HICTINT_GRAYSCALE|HICTINT_INVERT|HICTINT_COLORIZE)) | ((hictinting[pal].f & HICTINT_BLENDMASK)<<3)); return globalnoeffect ? 0 : ((hictinting[pal].f & (HICTINT_GRAYSCALE|HICTINT_INVERT|HICTINT_COLORIZE)) | ((hictinting[pal].f & HICTINT_BLENDMASK)<<3));
} }
static int32_t mdloadskin_notfound(char * const skinfile, char const * const fn) static FHardwareTexture *mdloadskin_notfound(char * const skinfile, char const * const fn)
{ {
OSD_Printf("Skin \"%s\" not found.\n", fn); OSD_Printf("Skin \"%s\" not found.\n", fn);
skinfile[0] = 0; skinfile[0] = 0;
return 0; return nullptr;
} }
static int32_t mdloadskin_failed(char * const skinfile, char const * const fn) static FHardwareTexture *mdloadskin_failed(char * const skinfile, char const * const fn)
{ {
OSD_Printf("Failed loading skin file \"%s\".\n", fn); OSD_Printf("Failed loading skin file \"%s\".\n", fn);
skinfile[0] = 0; skinfile[0] = 0;
return 0; return nullptr;
} }
//Note: even though it says md2model, it works for both md2model&md3model //Note: even though it says md2model, it works for both md2model&md3model
int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf) FHardwareTexture *mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
{ {
int32_t i; int32_t i;
char *skinfile = NULL, fn[BMAX_PATH]; char *skinfile = NULL, fn[BMAX_PATH];
GLuint *texidx = NULL; FHardwareTexture **texidx = NULL;
mdskinmap_t *sk, *skzero = NULL; mdskinmap_t *sk, *skzero = NULL;
int32_t doalloc = 1; int32_t doalloc = 1;
@ -624,21 +624,6 @@ int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
} }
else else
return 0; return 0;
#if 0
{
// fall back to the model-defined texture
if ((unsigned)number >= (unsigned)m->numskins)
number = 0;
// m->skinfn is undefined when md3model_t is cast to md2model_t --> crash
skinfile = m->skinfn + number*64;
texidx = &m->texid[number * HICTINT_MEMORY_COMBINATIONS + hicfxid(pal)];
Bstrncpyz(fn, m->basepath, BMAX_PATH);
if ((Bstrlen(fn) + Bstrlen(skinfile)) < BMAX_PATH)
Bstrcat(fn,skinfile);
//OSD_Printf("Using MD2/MD3 skin (%d) %s, pal=%d\n",number,skinfile,pal);
}
#endif
} }
if (skinfile == NULL || !skinfile[0]) if (skinfile == NULL || !skinfile[0])
@ -858,15 +843,15 @@ int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
if (pal < (MAXPALOOKUPS - RESERVEDPALS)) if (pal < (MAXPALOOKUPS - RESERVEDPALS))
m->usesalpha = hasalpha; m->usesalpha = hasalpha;
if ((doalloc & 3) == 1) if ((doalloc & 3) == 1)
GetTextureHandle(texidx); {
*texidx = GLInterface.NewTexture();
glBindTexture(GL_TEXTURE_2D, *texidx); }
//gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,xsiz,ysiz,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(char *)fptr); //gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,xsiz,ysiz,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(char *)fptr);
int32_t const texfmt = glinfo.bgra ? GL_BGRA : GL_RGBA; int32_t const texfmt = glinfo.bgra ? GL_BGRA : GL_RGBA;
uploadtexture((doalloc&1), siz, texfmt, pic, tsiz, uploadtexture(*texidx, (doalloc&1), siz, texfmt, pic, tsiz,
DAMETH_HI | DAMETH_MASK | DAMETH_HI | DAMETH_MASK |
TO_DAMETH_NODOWNSIZE(sk->flags) | TO_DAMETH_NODOWNSIZE(sk->flags) |
TO_DAMETH_NOTEXCOMPRESS(sk->flags) | TO_DAMETH_NOTEXCOMPRESS(sk->flags) |
@ -913,17 +898,10 @@ int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf)
m->skinloaded = 1+number; m->skinloaded = 1+number;
} }
int32_t const filter = (sk->flags & HICR_FORCEFILTER) ? TEXFILTER_ON : gltexfiltermode; if (*texidx)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,glfiltermodes[filter].mag); (*texidx)->SetSampler(SamplerRepeat);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,glfiltermodes[filter].min); }
#ifdef USE_GLEXT
if (glinfo.maxanisotropy > 1.0)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,glanisotropy);
#endif
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
if (willprint) if (willprint)
{ {
int32_t etime = timerGetTicks()-startticks; int32_t etime = timerGetTicks()-startticks;
@ -1215,7 +1193,7 @@ static md2model_t *md2load(buildvfs_kfd fil, const char *filnam)
{ Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return 0; } { Bfree(m->glcmds); Bfree(m->frames); Bfree(m); return 0; }
} }
m->texid = (GLuint *)Xcalloc(ournumskins, sizeof(GLuint) * HICTINT_MEMORY_COMBINATIONS); m->texid = (FHardwareTexture **)Xcalloc(ournumskins, sizeof(FHardwareTexture*) * HICTINT_MEMORY_COMBINATIONS);
maxmodelverts = max(maxmodelverts, m->numverts); maxmodelverts = max(maxmodelverts, m->numverts);
maxmodeltris = max(maxmodeltris, head.numtris); maxmodeltris = max(maxmodeltris, head.numtris);
@ -1225,7 +1203,7 @@ static md2model_t *md2load(buildvfs_kfd fil, const char *filnam)
// the MD2 is now loaded internally - let's begin the MD3 conversion process // the MD2 is now loaded internally - let's begin the MD3 conversion process
//OSD_Printf("Beginning md3 conversion.\n"); //OSD_Printf("Beginning md3 conversion.\n");
m3 = (md3model_t *)Xcalloc(1, sizeof(md3model_t)); m3 = (md3model_t *)Xcalloc(1, sizeof(md3model_t));
m3->mdnum = 3; m3->texid = 0; m3->scale = m->scale; m3->mdnum = 3; m3->texid = nullptr; m3->scale = m->scale;
m3->head.id = IDP3_MAGIC; m3->head.vers = 15; m3->head.id = IDP3_MAGIC; m3->head.vers = 15;
m3->head.flags = 0; m3->head.flags = 0;
@ -2041,8 +2019,6 @@ static int32_t polymost_md3draw(md3model_t *m, const uspritetype *tspr)
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glEnable(GL_TEXTURE_2D);
// tinting // tinting
pc[0] = pc[1] = pc[2] = ((float)numshades - min(max((globalshade * shadescale) + m->shadeoff, 0.f), (float)numshades)) / (float)numshades; pc[0] = pc[1] = pc[2] = ((float)numshades - min(max((globalshade * shadescale) + m->shadeoff, 0.f), (float)numshades)) / (float)numshades;
polytintflags_t const tintflags = hictinting[globalpal].f; polytintflags_t const tintflags = hictinting[globalpal].f;
@ -2164,11 +2140,11 @@ static int32_t polymost_md3draw(md3model_t *m, const uspritetype *tspr)
mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; glLoadMatrixf(mat); mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; glLoadMatrixf(mat);
// PLAG: End // PLAG: End
i = mdloadskin((md2model_t *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,globalpal,surfi); auto tex = mdloadskin((md2model_t *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,globalpal,surfi);
if (!i) if (!tex)
continue; continue;
//i = mdloadskin((md2model *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,surfi); //hack for testing multiple surfaces per MD3 //i = mdloadskin((md2model *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,surfi); //hack for testing multiple surfaces per MD3
glBindTexture(GL_TEXTURE_2D, i); GLInterface.BindTexture(0, tex);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
glLoadIdentity(); glLoadIdentity();
@ -2181,37 +2157,41 @@ static int32_t polymost_md3draw(md3model_t *m, const uspritetype *tspr)
//POGOTODO: if we add support for palette indexing on model skins, the texture for the palswap could be setup here //POGOTODO: if we add support for palette indexing on model skins, the texture for the palswap could be setup here
texunits += 4; texunits += 4;
i = r_detailmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, DETAILPAL, surfi) : 0; tex = r_detailmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, DETAILPAL, surfi) : nullptr;
if (i) if (tex)
{ {
mdskinmap_t *sk; mdskinmap_t *sk;
polymost_useDetailMapping(true); polymost_useDetailMapping(true);
polymost_setupdetailtexture(GL_TEXTURE3, i); polymost_setupdetailtexture(3, tex);
for (sk = m->skinmap; sk; sk = sk->next) for (sk = m->skinmap; sk; sk = sk->next)
if ((int32_t) sk->palette == DETAILPAL && sk->skinnum == tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum && sk->surfnum == surfi) if ((int32_t) sk->palette == DETAILPAL && sk->skinnum == tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum && sk->surfnum == surfi)
f = sk->param; f = sk->param;
glActiveTexture(GL_TEXTURE3);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
glLoadIdentity(); glLoadIdentity();
glTranslatef(xpanning, ypanning, 1.0f); glTranslatef(xpanning, ypanning, 1.0f);
glScalef(f, f, 1.0f); glScalef(f, f, 1.0f);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glActiveTexture(GL_TEXTURE0);
} }
i = r_glowmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, GLOWPAL, surfi) : 0; tex = r_glowmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, GLOWPAL, surfi) : 0;
if (i) if (i)
{ {
polymost_useGlowMapping(true); polymost_useGlowMapping(true);
polymost_setupglowtexture(GL_TEXTURE4, i); polymost_setupglowtexture(4, tex);
glActiveTexture(GL_TEXTURE4);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
glLoadIdentity(); glLoadIdentity();
glTranslatef(xpanning, ypanning, 1.0f); glTranslatef(xpanning, ypanning, 1.0f);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glActiveTexture(GL_TEXTURE0);
} }
#endif #endif
@ -2267,17 +2247,6 @@ static int32_t polymost_md3draw(md3model_t *m, const uspritetype *tspr)
} }
#ifdef USE_GLEXT #ifdef USE_GLEXT
{
while (texunits > GL_TEXTURE0)
{
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.0f);
glDisable(GL_TEXTURE_2D);
}
} // r_vertexarrays
polymost_useDetailMapping(false); polymost_useDetailMapping(false);
polymost_useGlowMapping(false); polymost_useGlowMapping(false);
#endif #endif

View file

@ -59,7 +59,6 @@ void fullscreen_tint_gl(uint8_t r, uint8_t g, uint8_t b, uint8_t f)
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);
polymost_setFogEnabled(false); polymost_setFogEnabled(false);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View file

@ -24,7 +24,6 @@ Ken Silverman's official web site: http://www.advsys.net/ken
#include "texcache.h" #include "texcache.h"
#include "common.h" #include "common.h"
#include "palette.h" #include "palette.h"
#include "tilepacker.h"
#include "../../glbackend/glbackend.h" #include "../../glbackend/glbackend.h"
#include "vfs.h" #include "vfs.h"
@ -107,7 +106,7 @@ int32_t r_glowmapping = 1;
int32_t gltexmaxsize = 0; // 0 means autodetection on first run int32_t gltexmaxsize = 0; // 0 means autodetection on first run
int32_t gltexmiplevel = 0; // discards this many mipmap levels int32_t gltexmiplevel = 0; // discards this many mipmap levels
int32_t glprojectionhacks = 1; int32_t glprojectionhacks = 1;
static GLuint polymosttext = 0; static FHardwareTexture *polymosttext = 0;
int32_t glrendmode = REND_POLYMOST; int32_t glrendmode = REND_POLYMOST;
// This variable, and 'shadeforfullbrightpass' control the drawing of // This variable, and 'shadeforfullbrightpass' control the drawing of
@ -145,12 +144,11 @@ static GLint fogColorLoc = -1;
#define PALSWAP_TEXTURE_SIZE 2048 #define PALSWAP_TEXTURE_SIZE 2048
int32_t r_useindexedcolortextures = -1; int32_t r_useindexedcolortextures = -1;
static GLuint tilesheetTexIDs[MAXTILESHEETS];
static GLint tilesheetSize = 0; static GLint tilesheetSize = 0;
static vec2f_t tilesheetHalfTexelSize = { 0.f, 0.f }; static vec2f_t tilesheetHalfTexelSize = { 0.f, 0.f };
static int32_t lastbasepal = -1; static int32_t lastbasepal = -1;
static GLuint paletteTextureIDs[MAXBASEPALS]; static FHardwareTexture *paletteTextureIDs[MAXBASEPALS];
static GLuint palswapTextureID = 0; static FHardwareTexture *palswapTextureID = nullptr;
static GLuint polymost1CurrentShaderProgramID = 0; static GLuint polymost1CurrentShaderProgramID = 0;
static GLuint polymost1BasicShaderProgramID = 0; static GLuint polymost1BasicShaderProgramID = 0;
static GLuint polymost1ExtendedShaderProgramID = 0; static GLuint polymost1ExtendedShaderProgramID = 0;
@ -217,22 +215,8 @@ int32_t r_parallaxskypanning = 1;
#define MIN_CACHETIME_PRINT 10 #define MIN_CACHETIME_PRINT 10
void GetTextureHandle(GLuint *handle)
{
*handle = GLInterface.GetTextureID();
}
// this was faster in MSVC but slower with GCC... currently unknown on ARM where both
// the FPU and possibly the optimization path in the compiler need improvement
#if 0
static inline int32_t __float_as_int(float f) { return *(int32_t *) &f; }
static inline float __int_as_float(int32_t d) { return *(float *) &d; }
static inline float Bfabsf(float f) { return __int_as_float(__float_as_int(f)&0x7fffffff); }
#else
#define Bfabsf fabsf #define Bfabsf fabsf
#endif
int32_t mdtims, omdtims; int32_t mdtims, omdtims;
uint8_t alphahackarray[MAXTILES]; uint8_t alphahackarray[MAXTILES];
@ -241,20 +225,6 @@ int32_t hicprecaching = 0;
hitdata_t polymost_hitdata; hitdata_t polymost_hitdata;
#if 0
static inline int32_t gltexmayhavealpha(int32_t dapicnum, int32_t dapalnum)
{
const int32_t j = (dapicnum&(GLTEXCACHEADSIZ-1));
pthtyp *pth;
for (pth=texcache.list[j]; pth; pth=pth->next)
if (pth->picnum == dapicnum && pth->palnum == dapalnum)
return ((pth->flags&PTH_HASALPHA) != 0);
return 1;
}
#endif
void gltexinvalidate(int32_t dapicnum, int32_t dapalnum, int32_t dameth) void gltexinvalidate(int32_t dapicnum, int32_t dapalnum, int32_t dameth)
{ {
const int32_t pic = (dapicnum&(GLTEXCACHEADSIZ-1)); const int32_t pic = (dapicnum&(GLTEXCACHEADSIZ-1));
@ -297,77 +267,22 @@ void gltexinvalidatetype(int32_t type)
#endif #endif
} }
static void bind_2d_texture(GLuint texture, int filter)
{
if (filter == -1)
filter = gltexfiltermode;
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glfiltermodes[filter].mag);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glfiltermodes[filter].min);
#ifdef USE_GLEXT
if (glinfo.maxanisotropy > 1.f)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, glanisotropy);
#endif
}
void gltexapplyprops(void) void gltexapplyprops(void)
{ {
if (videoGetRenderMode() == REND_CLASSIC) if (videoGetRenderMode() == REND_CLASSIC)
return; return;
GLInterface.mSamplers->SetTextureFilterMode(gltexfiltermode, glanisotropy);
if (glinfo.maxanisotropy > 1.f) if (glinfo.maxanisotropy > 1.f)
{ {
if (glanisotropy <= 0 || glanisotropy > glinfo.maxanisotropy) if (glanisotropy <= 0 || glanisotropy > glinfo.maxanisotropy)
glanisotropy = (int32_t)glinfo.maxanisotropy; glanisotropy = (int32_t)glinfo.maxanisotropy;
} }
GLInterface.mSamplers->SetTextureFilterMode(gltexfiltermode, glanisotropy);
gltexfiltermode = clamp(gltexfiltermode, 0, NUMGLFILTERMODES-1); gltexfiltermode = clamp(gltexfiltermode, 0, NUMGLFILTERMODES-1);
r_useindexedcolortextures = !gltexfiltermode; r_useindexedcolortextures = !gltexfiltermode;
for (bssize_t i=0; i<=GLTEXCACHEADSIZ-1; i++)
{
for (pthtyp *pth=texcache.list[i]; pth; pth=pth->next)
{
if (pth->flags & PTH_INDEXED)
{
//POGO: indexed textures should not be filtered
continue;
}
int32_t const filter = (pth->flags & PTH_FORCEFILTER) ? TEXFILTER_ON : -1;
bind_2d_texture(pth->glpic, filter);
if (r_fullbrights && pth->flags & PTH_HASFULLBRIGHT)
bind_2d_texture(pth->ofb->glpic, filter);
}
}
for (bssize_t i=0; i<nextmodelid; i++)
{
md2model_t *m = (md2model_t *)models[i];
if (m->mdnum < 2)
continue;
for (bssize_t j = 0; j < m->numskins * HICTINT_MEMORY_COMBINATIONS; j++)
{
if (!m->texid[j])
continue;
bind_2d_texture(m->texid[j], -1);
}
for (mdskinmap_t *sk = m->skinmap; sk; sk = sk->next)
for (bssize_t j = 0; j < HICTINT_MEMORY_COMBINATIONS; j++)
{
if (!sk->texid[j])
continue;
bind_2d_texture(sk->texid[j], (sk->flags & HICR_FORCEFILTER) ? TEXFILTER_ON : -1);
}
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -501,11 +416,11 @@ void polymost_glreset()
if (pth->flags & PTH_HASFULLBRIGHT) if (pth->flags & PTH_HASFULLBRIGHT)
{ {
glDeleteTextures(1, &pth->ofb->glpic); delete pth->ofb->glpic;
Bfree(pth->ofb); Bfree(pth->ofb);
} }
glDeleteTextures(1, &pth->glpic); delete pth->glpic;
Bfree(pth); Bfree(pth);
pth = next; pth = next;
} }
@ -517,8 +432,8 @@ void polymost_glreset()
} }
if (polymosttext) if (polymosttext)
glDeleteTextures(1,&polymosttext); delete polymosttext;
polymosttext=0; polymosttext=nullptr;
Bmemset(texcache.list,0,sizeof(texcache.list)); Bmemset(texcache.list,0,sizeof(texcache.list));
glox1 = -1; glox1 = -1;
@ -557,11 +472,8 @@ void polymost_resetProgram()
useShaderProgram(polymost1CurrentShaderProgramID); useShaderProgram(polymost1CurrentShaderProgramID);
// ensure that palswapTexture and paletteTexture[curbasepal] is bound // ensure that palswapTexture and paletteTexture[curbasepal] is bound
glActiveTexture(GL_TEXTURE1); GLInterface.BindTexture(1, palswapTextureID);
glBindTexture(GL_TEXTURE_2D, palswapTextureID); GLInterface.BindTexture(2, paletteTextureIDs[curbasepal]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, paletteTextureIDs[curbasepal]);
glActiveTexture(GL_TEXTURE0);
} }
static void polymost_setCurrentShaderProgram(uint32_t programID) static void polymost_setCurrentShaderProgram(uint32_t programID)
@ -759,50 +671,15 @@ void polymost_npotEmulation(char npotEmulation, float factor, float xOffset)
glUniform1f(polymost1NPOTEmulationXOffsetLoc, polymost1NPOTEmulationXOffset); glUniform1f(polymost1NPOTEmulationXOffsetLoc, polymost1NPOTEmulationXOffset);
} }
void polymost_activeTexture(GLenum texture) static void polymost_bindPth(pthtyp const * const pPth, int sampler)
{
currentActiveTexture = texture;
glad_glActiveTexture(texture);
}
//POGOTODO: replace this and polymost_activeTexture with proper draw call organization
void polymost_bindTexture(GLenum target, uint32_t textureID)
{
glBindSampler(currentActiveTexture - GL_TEXTURE0, 0);
glad_glBindTexture(target, textureID);
if (currentActiveTexture == GL_TEXTURE0)
{
currentTextureID = textureID;
}
}
static void polymost_bindPth(pthtyp const * const pPth)
{ {
Bassert(pPth); Bassert(pPth);
vec4f_t texturePosSize = { 0.f, 0.f, 1.f, 1.f }; vec4f_t texturePosSize = { 0.f, 0.f, 1.f, 1.f };
vec2f_t halfTexelSize = { 0.f, 0.f }; vec2f_t halfTexelSize = { 0.f, 0.f };
if ((pPth->flags & PTH_INDEXED) &&
!(pPth->flags & PTH_HIGHTILE))
{
Tile tile;
char tileIsPacked = tilepacker_getTile(waloff[pPth->picnum] ? pPth->picnum+1 : 0, &tile);
//POGO: check the width and height to ensure that the tile hasn't been changed for a user tile that has different dimensions
if (tileIsPacked &&
(!waloff[pPth->picnum] ||
(tile.rect.width == (uint32_t) tilesiz[pPth->picnum].y &&
tile.rect.height == (uint32_t) tilesiz[pPth->picnum].x)))
{
texturePosSize = { tile.rect.u/(float) tilesheetSize,
tile.rect.v/(float) tilesheetSize,
tile.rect.width/(float) tilesheetSize,
tile.rect.height/(float) tilesheetSize };
halfTexelSize = tilesheetHalfTexelSize;
}
}
polymost_setTexturePosSize(texturePosSize); polymost_setTexturePosSize(texturePosSize);
polymost_setHalfTexelSize(halfTexelSize); polymost_setHalfTexelSize(halfTexelSize);
glBindTexture(GL_TEXTURE_2D, pPth->glpic); GLInterface.BindTexture(0, pPth->glpic, sampler);
} }
void useShaderProgram(uint32_t shaderID) void useShaderProgram(uint32_t shaderID)
@ -814,6 +691,7 @@ void useShaderProgram(uint32_t shaderID)
// one-time initialization of OpenGL for polymost // one-time initialization of OpenGL for polymost
void polymost_glinit() void polymost_glinit()
{ {
glEnable(GL_TEXTURE_2D);
glHint(GL_FOG_HINT, GL_NICEST); glHint(GL_FOG_HINT, GL_NICEST);
glFogi(GL_FOG_MODE, (r_usenewshading < 2) ? GL_EXP2 : GL_LINEAR); glFogi(GL_FOG_MODE, (r_usenewshading < 2) ? GL_EXP2 : GL_LINEAR);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -844,37 +722,6 @@ void polymost_glinit()
tilesheetHalfTexelSize = { 0.5f/tilesheetSize, 0.5f/tilesheetSize }; tilesheetHalfTexelSize = { 0.5f/tilesheetSize, 0.5f/tilesheetSize };
vec2_t maxTexDimensions = { tilesheetSize, tilesheetSize }; vec2_t maxTexDimensions = { tilesheetSize, tilesheetSize };
char allPacked = false; char allPacked = false;
static uint32_t numTilesheets = 0;
//POGO: only pack the tilesheets once
if (numTilesheets == 0)
{
// add a blank texture for tileUID 0
tilepacker_addTile(0, 2, 2);
for (int picnum = 0; picnum < MAXTILES; ++picnum)
{
tilepacker_addTile(picnum+1, (uint32_t) tilesiz[picnum].y, (uint32_t) tilesiz[picnum].x);
}
do
{
tilepacker_initTilesheet(numTilesheets, tilesheetSize, tilesheetSize);
allPacked = tilepacker_pack(numTilesheets);
++numTilesheets;
} while (!allPacked && numTilesheets < MAXTILESHEETS);
}
for (uint32_t i = 0; i < numTilesheets; ++i)
{
GetTextureHandle(tilesheetTexIDs+i);
glBindTexture(GL_TEXTURE_2D, tilesheetTexIDs[i]);
uploadtextureindexed(true, {0, 0}, maxTexDimensions, (intptr_t) NULL);
}
const char blankTex[] = {255, 255,
255, 255};
Tile blankTile;
tilepacker_getTile(0, &blankTile);
glBindTexture(GL_TEXTURE_2D, tilesheetTexIDs[blankTile.tilesheetID]);
uploadtextureindexed(false, {(int32_t) blankTile.rect.u, (int32_t) blankTile.rect.v}, {2, 2}, (intptr_t) blankTex);
const char* const POLYMOST2_BASIC_VERTEX_SHADER_CODE = const char* const POLYMOST2_BASIC_VERTEX_SHADER_CODE =
"#version 110\n\ "#version 110\n\
@ -1448,7 +1295,6 @@ static void resizeglcheck(void)
{ {
glClearColor(1.0,1.0,1.0,0.0); glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D);
} }
#else #else
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
@ -1484,8 +1330,6 @@ static void resizeglcheck(void)
glLoadIdentity(); glLoadIdentity();
if (!nofog) polymost_setFogEnabled(true); if (!nofog) polymost_setFogEnabled(true);
//glEnable(GL_TEXTURE_2D);
} }
} }
@ -1535,44 +1379,17 @@ static void fixtransparency(coltype *dapic, vec2_t dasiz, vec2_t dasiz2, int32_t
} }
static void Polymost_SendTexToDriver(int32_t const doalloc, void uploadtexture(FHardwareTexture *tex, int32_t doalloc, vec2_t siz, int32_t texfmt,
vec2_t const siz,
int32_t const texfmt,
coltype const * const pic,
int32_t const intexfmt,
#if defined EDUKE32_GLES
int32_t const comprtexfmt,
int32_t const texcompress_ok,
#endif
int32_t const level)
{
#if B_BIG_ENDIAN
GLenum type = GL_UNSIGNED_INT_8_8_8_8;
#else
GLenum type = GL_UNSIGNED_INT_8_8_8_8_REV;
#endif
if (doalloc & 1)
glTexImage2D(GL_TEXTURE_2D, level, intexfmt, siz.x,siz.y, 0, texfmt, type, pic);
else
glTexSubImage2D(GL_TEXTURE_2D, level, 0,0, siz.x,siz.y, texfmt, type, pic);
glGenerateMipmap(GL_TEXTURE_2D);
}
void uploadtexture(int32_t doalloc, vec2_t siz, int32_t texfmt,
coltype* pic, vec2_t tsiz, int32_t dameth) coltype* pic, vec2_t tsiz, int32_t dameth)
{ {
int32_t intexfmt = GL_RGBA8;
#ifdef TIMING #ifdef TIMING
cycle_t clock; cycle_t clock;
clock.Reset(); clock.Reset();
clock.Clock(); clock.Clock();
#endif #endif
Polymost_SendTexToDriver(doalloc, siz, texfmt, pic,
intexfmt, tex->LoadTexture((uint8_t *)pic);
0);
#ifdef TIMING #ifdef TIMING
clock.Unclock(); clock.Unclock();
@ -1580,26 +1397,6 @@ void uploadtexture(int32_t doalloc, vec2_t siz, int32_t texfmt,
static int ttt; static int ttt;
OSD_Printf("%d: texture upload %d x %d took %2.3f ms\n", ttt++, siz.x, siz.y, clock.TimeMS()); OSD_Printf("%d: texture upload %d x %d took %2.3f ms\n", ttt++, siz.x, siz.y, clock.TimeMS());
#endif #endif
return;
}
void uploadtextureindexed(int32_t doalloc, vec2_t offset, vec2_t siz, intptr_t tile)
{
if (doalloc & 1)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, siz.y, siz.x, 0, GL_RED, GL_UNSIGNED_BYTE, (void*) tile);
}
else
{
glTexSubImage2D(GL_TEXTURE_2D, 0, offset.x, offset.y, siz.y, siz.x, GL_RED, GL_UNSIGNED_BYTE, (void*) tile);
}
} }
void uploadbasepalette(int32_t basepalnum) void uploadbasepalette(int32_t basepalnum)
@ -1624,27 +1421,14 @@ void uploadbasepalette(int32_t basepalnum)
basepalWFullBrightInfo[i*4+3] = 0-(IsPaletteIndexFullbright(i) != 0); basepalWFullBrightInfo[i*4+3] = 0-(IsPaletteIndexFullbright(i) != 0);
} }
char allocateTexture = !paletteTextureIDs[basepalnum]; if (!paletteTextureIDs[basepalnum])
if (allocateTexture)
{ {
GetTextureHandle(&paletteTextureIDs[basepalnum]); auto &p = paletteTextureIDs[basepalnum];
} p = GLInterface.NewTexture();
glBindTexture(GL_TEXTURE_2D, paletteTextureIDs[basepalnum]); p->CreateTexture(256, 1, false, false);
if (allocateTexture) p->SetSampler(Sampler2DNoFilter);
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, basepalWFullBrightInfo);
}
else
{
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, basepalWFullBrightInfo);
} }
paletteTextureIDs[basepalnum]->LoadTexture(basepalWFullBrightInfo); // RGBA
} }
void uploadpalswap(int32_t palookupnum) void uploadpalswap(int32_t palookupnum)
@ -1659,6 +1443,8 @@ void uploadpalswap(int32_t palookupnum)
return; return;
} }
// No point porting this, it's too much work for a short lived solution.
#if 0
char allocateTexture = !palswapTextureID; char allocateTexture = !palswapTextureID;
if (allocateTexture) if (allocateTexture)
{ {
@ -1686,54 +1472,21 @@ void uploadpalswap(int32_t palookupnum)
return; return;
} }
g lTexSubImage2D(GL_TEXTURE_2D, 0, 256*column, rowOffset, 256, numshades+1, GL_RED, GL_UNSIGNED_BYTE, palookup[palookupnum]); g lTexSubImage2D(GL_TEXTURE_2D, 0, 256*column, rowOffset, 256, numshades+1, GL_RED, GL_UNSIGNED_BYTE, palookup[palookupnum]);
}
#if 0
// TODO: make configurable
static int32_t tile_is_sky(int32_t tilenum)
{
return return (tilenum >= 78 /*CLOUDYOCEAN*/ && tilenum <= 99 /*REDSKY2*/);
}
# define clamp_if_tile_is_sky(x, y) (tile_is_sky(x) ? (y) : GL_REPEAT)
#else
# define clamp_if_tile_is_sky(x, y) (GL_REPEAT)
#endif #endif
static void polymost_setuptexture(const int32_t dameth, int filter)
{
const GLuint clamp_mode = glinfo.clamptoedge ? GL_CLAMP_TO_EDGE : GL_CLAMP;
gltexfiltermode = clamp(gltexfiltermode, 0, NUMGLFILTERMODES-1);
if (filter == -1)
filter = gltexfiltermode;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glfiltermodes[filter].mag);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glfiltermodes[filter].min);
#ifdef USE_GLEXT
if (glinfo.maxanisotropy > 1.f)
{
uint32_t i = (unsigned)Blrintf(glinfo.maxanisotropy);
if ((unsigned)glanisotropy > i)
glanisotropy = i;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, glanisotropy);
} }
#endif
static void polymost_setuptexture(FHardwareTexture *tex, const int32_t dameth, int filter)
{
if (!(dameth & DAMETH_CLAMPED)) if (!(dameth & DAMETH_CLAMPED))
{ {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp_if_tile_is_sky(dapic, clamp_mode)); tex->SetSampler(SamplerRepeat);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} }
else else
{ {
// For sprite textures, clamping looks better than wrapping // For sprite textures, clamping looks better than wrapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp_mode); tex->SetSampler(SamplerClampXY);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp_mode);
} }
} }
@ -1747,44 +1500,21 @@ static void gloadtile_art_indexed(int32_t dapic, int32_t dameth, pthtyp *pth, in
//POGOTODO: if !glinfo.texnpot, then we could allocate a texture of the pow2 size, and then populate the subportion using buffersubdata func //POGOTODO: if !glinfo.texnpot, then we could allocate a texture of the pow2 size, and then populate the subportion using buffersubdata func
//if (!glinfo.texnpot) //if (!glinfo.texnpot)
Tile tile = {};
if (waloff[dapic]) if (waloff[dapic])
{ {
char tileIsPacked = tilepacker_getTile(dapic+1, &tile);
if (tileIsPacked &&
tile.rect.width == (uint32_t) tsizart.y &&
tile.rect.height == (uint32_t) tsizart.x)
{
pth->glpic = tilesheetTexIDs[tile.tilesheetID];
doalloc = false;
}
else if (doalloc)
{
GetTextureHandle((GLuint *)&pth->glpic);
}
glBindTexture(GL_TEXTURE_2D, pth->glpic);
if (doalloc) if (doalloc)
{ {
const GLuint clamp_mode = glinfo.clamptoedge ? GL_CLAMP_TO_EDGE : GL_CLAMP; assert(pth->glpic == nullptr);
if (!(dameth & DAMETH_CLAMPED)) pth->glpic = GLInterface.NewTexture();
{ pth->glpic->CreateTexture(siz.x, siz.y, true, false);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp_if_tile_is_sky(dapic, clamp_mode)); pth->glpic->SetSampler(SamplerNoFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); polymost_setuptexture(pth->glpic, dameth, 0);
}
pth->glpic->LoadTexture((uint8_t*)waloff[dapic]); // Indexed
} }
else else
{ {
// For sprite textures, clamping looks better than wrapping assert(false);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp_mode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp_mode);
}
}
uploadtextureindexed(doalloc, {(int32_t) tile.rect.u, (int32_t) tile.rect.v}, siz, waloff[dapic]);
}
else
{
tilepacker_getTile(0, &tile);
pth->glpic = tilesheetTexIDs[tile.tilesheetID];
} }
pth->picnum = dapic; pth->picnum = dapic;
@ -1940,8 +1670,11 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t tintpalnum, int32_t das
} }
} }
if (doalloc) GetTextureHandle((GLuint *)&pth->glpic); //# of textures (make OpenGL allocate structure) if (doalloc)
glBindTexture(GL_TEXTURE_2D, pth->glpic); {
pth->glpic = GLInterface.NewTexture();
pth->glpic->CreateTexture(siz.x, siz.y, false, true);
}
fixtransparency(pic,tsiz,siz,dameth); fixtransparency(pic,tsiz,siz,dameth);
@ -1962,7 +1695,7 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t tintpalnum, int32_t das
npoty = 1; npoty = 1;
} }
uploadtexture(doalloc, siz, GL_BGRA, pic, tsiz, uploadtexture(pth->glpic, doalloc, siz, GL_BGRA, pic, tsiz,
dameth | DAMETH_ARTIMMUNITY | dameth | DAMETH_ARTIMMUNITY |
(dapic >= MAXUSERTILES ? (DAMETH_NOTEXCOMPRESS|DAMETH_NODOWNSIZE) : 0) | /* never process these short-lived tiles */ (dapic >= MAXUSERTILES ? (DAMETH_NOTEXCOMPRESS|DAMETH_NODOWNSIZE) : 0) | /* never process these short-lived tiles */
(hasfullbright ? DAMETH_HASFULLBRIGHT : 0) | (hasfullbright ? DAMETH_HASFULLBRIGHT : 0) |
@ -1972,7 +1705,7 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t tintpalnum, int32_t das
Bfree(pic); Bfree(pic);
} }
polymost_setuptexture(dameth, -1); polymost_setuptexture(pth->glpic, dameth, -1);
pth->picnum = dapic; pth->picnum = dapic;
pth->palnum = dapal; pth->palnum = dapal;
@ -2228,14 +1961,16 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp
hicr->flags |= HICR_ARTIMMUNITY; hicr->flags |= HICR_ARTIMMUNITY;
if ((doalloc & 3) == 1) if ((doalloc & 3) == 1)
GetTextureHandle(&pth->glpic); //# of textures (make OpenGL allocate structure) {
glBindTexture(GL_TEXTURE_2D, pth->glpic); pth->glpic = GLInterface.NewTexture();
pth->glpic->CreateTexture(siz.x, siz.y, false, true);
}
fixtransparency(pic,tsiz,siz,dameth); fixtransparency(pic,tsiz,siz,dameth);
int32_t const texfmt = glinfo.bgra ? GL_BGRA : GL_RGBA; int32_t const texfmt = glinfo.bgra ? GL_BGRA : GL_RGBA;
uploadtexture(doalloc,siz,texfmt,pic,tsiz, uploadtexture(pth->glpic, doalloc,siz,texfmt,pic,tsiz,
dameth | DAMETH_HI | DAMETH_NOFIX | dameth | DAMETH_HI | DAMETH_NOFIX |
TO_DAMETH_NODOWNSIZE(hicr->flags) | TO_DAMETH_NODOWNSIZE(hicr->flags) |
TO_DAMETH_NOTEXCOMPRESS(hicr->flags) | TO_DAMETH_NOTEXCOMPRESS(hicr->flags) |
@ -2258,7 +1993,7 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp
pth->scale.y = (float)tsiz.y / (float)tilesiz[dapic].y; pth->scale.y = (float)tsiz.y / (float)tilesiz[dapic].y;
} }
polymost_setuptexture(dameth, (hicr->flags & HICR_FORCEFILTER) ? TEXFILTER_ON : -1); polymost_setuptexture(pth->glpic, dameth, (hicr->flags & HICR_FORCEFILTER) ? TEXFILTER_ON : -1);
if (tsiz.x>>r_downsize <= tilesiz[dapic].x || tsiz.y>>r_downsize <= tilesiz[dapic].y) if (tsiz.x>>r_downsize <= tilesiz[dapic].x || tsiz.y>>r_downsize <= tilesiz[dapic].y)
hicr->flags |= HICR_ARTIMMUNITY; hicr->flags |= HICR_ARTIMMUNITY;
@ -2285,26 +2020,14 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp
} }
#ifdef USE_GLEXT #ifdef USE_GLEXT
void polymost_setupdetailtexture(const int32_t texunits, const int32_t tex) void polymost_setupdetailtexture(const int32_t texunits, FHardwareTexture *tex)
{ {
glActiveTexture(texunits); GLInterface.BindTexture(texunits, tex, SamplerRepeat);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} }
void polymost_setupglowtexture(const int32_t texunits, const int32_t tex) void polymost_setupglowtexture(const int32_t texunits, FHardwareTexture* tex)
{ {
glActiveTexture(texunits); GLInterface.BindTexture(texunits, tex, SamplerRepeat);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} }
#endif #endif
@ -2342,10 +2065,8 @@ static void polymost_updatePalette()
//POGO: only bind the base pal once when it's swapped //POGO: only bind the base pal once when it's swapped
if (curbasepal != lastbasepal) if (curbasepal != lastbasepal)
{ {
glActiveTexture(GL_TEXTURE2); GLInterface.BindTexture(2, paletteTextureIDs[curbasepal], Sampler2DNoFilter);
glBindTexture(GL_TEXTURE_2D, paletteTextureIDs[curbasepal]);
lastbasepal = curbasepal; lastbasepal = curbasepal;
glActiveTexture(GL_TEXTURE0);
} }
} }
@ -2521,16 +2242,23 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
// just submit the geometry and don't mess with textures. // just submit the geometry and don't mess with textures.
if (videoGetRenderMode() == REND_POLYMOST) if (videoGetRenderMode() == REND_POLYMOST)
{ {
polymost_bindPth(pth);
//POGOTODO: I could move this into bindPth //POGOTODO: I could move this into bindPth
if (!(pth->flags & PTH_INDEXED)) if (!(pth->flags & PTH_INDEXED))
polymost_usePaletteIndexing(false); polymost_usePaletteIndexing(false);
if (drawpoly_srepeat) // The entire logic here is just one lousy hack.
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); int mSampler = NoSampler;
if (drawpoly_trepeat) if (pth->glpic->GetSampler() != SamplerRepeat)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); {
if (drawpoly_srepeat && drawpoly_trepeat) mSampler = SamplerRepeat;
else if (drawpoly_srepeat) mSampler = SamplerClampY;
else if (drawpoly_trepeat) mSampler = SamplerClampX;
else mSampler = SamplerClampXY;
}
polymost_bindPth(pth, mSampler);
} }
// texture scale by parkar request // texture scale by parkar request
@ -2561,8 +2289,9 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
detailpth->hicr && detailpth->hicr->palnum == DETAILPAL) detailpth->hicr && detailpth->hicr->palnum == DETAILPAL)
{ {
polymost_useDetailMapping(true); polymost_useDetailMapping(true);
polymost_setupdetailtexture(videoGetRenderMode() == REND_POLYMOST ? GL_TEXTURE3 : ++texunits, detailpth->glpic); polymost_setupdetailtexture(3, detailpth->glpic);
glActiveTexture(GL_TEXTURE3);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
glLoadIdentity(); glLoadIdentity();
@ -2587,8 +2316,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
glowpth->hicr && (glowpth->hicr->palnum == GLOWPAL)) glowpth->hicr && (glowpth->hicr->palnum == GLOWPAL))
{ {
polymost_useGlowMapping(true); polymost_useGlowMapping(true);
polymost_setupglowtexture(videoGetRenderMode() == REND_POLYMOST ? GL_TEXTURE4 : ++texunits, glowpth->glpic); polymost_setupglowtexture(4, glowpth->glpic);
glActiveTexture(GL_TEXTURE0);
} }
} }
@ -2877,15 +2605,6 @@ do
// restore palette usage if we were just rendering a non-indexed color texture // restore palette usage if we were just rendering a non-indexed color texture
polymost_usePaletteIndexing(true); polymost_usePaletteIndexing(true);
} }
int const clamp_mode = glinfo.clamptoedge ? GL_CLAMP_TO_EDGE : GL_CLAMP;
if (drawpoly_srepeat)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp_mode);
if (drawpoly_trepeat)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp_mode);
if (fullbright_pass == 1) if (fullbright_pass == 1)
{ {
int32_t const shade = globalshade; int32_t const shade = globalshade;
@ -5359,7 +5078,6 @@ void polymost_drawrooms()
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS glDepthFunc(GL_ALWAYS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS
// glDepthRange(0.0, 1.0); //<- this is more widely supported than glPolygonOffset // glDepthRange(0.0, 1.0); //<- this is more widely supported than glPolygonOffset
@ -6775,7 +6493,6 @@ void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
glEnable(GL_TEXTURE_2D);
#if defined(POLYMER) #if defined(POLYMER)
# ifdef USE_GLEXT # ifdef USE_GLEXT
@ -7152,12 +6869,11 @@ void polymost_fillpolygon(int32_t npoints)
if (gloy1 != -1) polymostSet2dView(); //disables blending, texturing, and depth testing if (gloy1 != -1) polymostSet2dView(); //disables blending, texturing, and depth testing
glEnable(GL_ALPHA_TEST); glEnable(GL_ALPHA_TEST);
glEnable(GL_TEXTURE_2D);
pthtyp const * const pth = our_texcache_fetch(DAMETH_NOMASK | (videoGetRenderMode() == REND_POLYMOST && r_useindexedcolortextures ? PTH_INDEXED : 0)); pthtyp const * const pth = our_texcache_fetch(DAMETH_NOMASK | (videoGetRenderMode() == REND_POLYMOST && r_useindexedcolortextures ? PTH_INDEXED : 0));
if (pth) if (pth)
{ {
polymost_bindPth(pth); polymost_bindPth(pth, -1);
if (!(pth->flags & PTH_INDEXED)) if (!(pth->flags & PTH_INDEXED))
polymost_usePaletteIndexing(false); polymost_usePaletteIndexing(false);
@ -7193,8 +6909,7 @@ static int32_t gen_font_glyph_tex(void)
{ {
// construct a 256x128 texture for the font glyph matrix // construct a 256x128 texture for the font glyph matrix
GetTextureHandle(&polymosttext); polymosttext = GLInterface.NewTexture();
if (!polymosttext) return -1; if (!polymosttext) return -1;
char * const tbuf = (char *)Xmalloc(256*128*4); char * const tbuf = (char *)Xmalloc(256*128*4);
@ -7237,10 +6952,9 @@ static int32_t gen_font_glyph_tex(void)
} }
} }
glBindTexture(GL_TEXTURE_2D, polymosttext); polymosttext->CreateTexture(256, 128, false, false);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,256,128,0,GL_RGBA,GL_UNSIGNED_BYTE,(GLvoid *)tbuf); polymosttext->LoadTexture((uint8_t*)tbuf); // RGBA
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); polymosttext->SetSampler(Sampler2DNoFilter);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
Bfree(tbuf); Bfree(tbuf);
return 0; return 0;
@ -7262,7 +6976,7 @@ int32_t polymost_printext256(int32_t xpos, int32_t ypos, int16_t col, int16_t ba
if (videoGetRenderMode() < REND_POLYMOST || !in3dmode() || (!polymosttext && gen_font_glyph_tex() < 0)) if (videoGetRenderMode() < REND_POLYMOST || !in3dmode() || (!polymosttext && gen_font_glyph_tex() < 0))
return -1; return -1;
glBindTexture(GL_TEXTURE_2D, polymosttext); GLInterface.BindTexture(0, polymosttext);
polymost_setTexturePosSize({0, 0, 1, 1}); polymost_setTexturePosSize({0, 0, 1, 1});
polymost_usePaletteIndexing(false); polymost_usePaletteIndexing(false);
@ -7295,7 +7009,6 @@ int32_t polymost_printext256(int32_t xpos, int32_t ypos, int16_t col, int16_t ba
GLInterface.Draw(DT_TRIANGLE_FAN, data.first, 4); GLInterface.Draw(DT_TRIANGLE_FAN, data.first, 4);
} }
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glColor4ub(p.r,p.g,p.b,255); glColor4ub(p.r,p.g,p.b,255);

View file

@ -1298,7 +1298,6 @@ void sdlayer_setvideomode_opengl(void)
glsurface_destroy(); glsurface_destroy();
polymost_glreset(); polymost_glreset();
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // GL_FLAT glShadeModel(GL_SMOOTH); // GL_FLAT
glClearColor(0, 0, 0, 1.0); // Black Background glClearColor(0, 0, 0, 1.0); // Black Background
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Use FASTEST for ortho! glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Use FASTEST for ortho!
@ -1313,34 +1312,6 @@ void sdlayer_setvideomode_opengl(void)
glinfo.version = (const char *) glGetString(GL_VERSION); glinfo.version = (const char *) glGetString(GL_VERSION);
glinfo.extensions = (const char *) glGetString(GL_EXTENSIONS); glinfo.extensions = (const char *) glGetString(GL_EXTENSIONS);
#ifdef POLYMER
if (!Bstrcmp(glinfo.vendor, "ATI Technologies Inc."))
{
pr_ati_fboworkaround = 1;
initprintf("Enabling ATI FBO color attachment workaround.\n");
if (Bstrstr(glinfo.renderer, "Radeon X1"))
{
pr_ati_nodepthoffset = 1;
initprintf("Enabling ATI R520 polygon offset workaround.\n");
}
else
pr_ati_nodepthoffset = 0;
#ifdef __APPLE__
// See bug description at http://lists.apple.com/archives/mac-opengl/2005/Oct/msg00169.html
if (!Bstrncmp(glinfo.renderer, "ATI Radeon 9600", 15))
{
pr_ati_textureformat_one = 1;
initprintf("Enabling ATI Radeon 9600 texture format workaround.\n");
}
else
pr_ati_textureformat_one = 0;
#endif
}
else
pr_ati_fboworkaround = 0;
#endif // defined POLYMER
glinfo.maxanisotropy = 1.0; glinfo.maxanisotropy = 1.0;
glinfo.bgra = 0; glinfo.bgra = 0;
glinfo.clamptoedge = 1; glinfo.clamptoedge = 1;
@ -1356,20 +1327,9 @@ void sdlayer_setvideomode_opengl(void)
glinfo.shadow = !!Bstrstr(glinfo.extensions, "GL_ARB_shadow"); glinfo.shadow = !!Bstrstr(glinfo.extensions, "GL_ARB_shadow");
glinfo.fbos = !!Bstrstr(glinfo.extensions, "GL_EXT_framebuffer_object") || !!Bstrstr(glinfo.extensions, "GL_OES_framebuffer_object"); glinfo.fbos = !!Bstrstr(glinfo.extensions, "GL_EXT_framebuffer_object") || !!Bstrstr(glinfo.extensions, "GL_OES_framebuffer_object");
#if !defined EDUKE32_GLES
glinfo.texcompr = !!Bstrstr(glinfo.extensions, "GL_ARB_texture_compression") && Bstrcmp(glinfo.vendor, "ATI Technologies Inc.");
# ifdef DYNAMIC_GLEXT
if (glinfo.texcompr && (!glCompressedTexImage2D || !glGetCompressedTexImage))
{
// lacking the necessary extensions to do this
initprintf("Warning: the GL driver lacks necessary functions to use caching\n");
glinfo.texcompr = 0; glinfo.texcompr = 0;
} glinfo.bgra = 0;// !!Bstrstr(glinfo.extensions, "GL_EXT_bgra");
# endif glinfo.clamptoedge = true;
glinfo.bgra = !!Bstrstr(glinfo.extensions, "GL_EXT_bgra");
glinfo.clamptoedge = !!Bstrstr(glinfo.extensions, "GL_EXT_texture_edge_clamp") ||
!!Bstrstr(glinfo.extensions, "GL_SGIS_texture_edge_clamp");
glinfo.rect = glinfo.rect =
!!Bstrstr(glinfo.extensions, "GL_NV_texture_rectangle") || !!Bstrstr(glinfo.extensions, "GL_EXT_texture_rectangle"); !!Bstrstr(glinfo.extensions, "GL_NV_texture_rectangle") || !!Bstrstr(glinfo.extensions, "GL_EXT_texture_rectangle");
@ -1393,10 +1353,6 @@ void sdlayer_setvideomode_opengl(void)
initprintf("3dfx card detected: OpenGL fog disabled\n"); initprintf("3dfx card detected: OpenGL fog disabled\n");
warnonce |= 1; warnonce |= 1;
} }
#else
// don't bother checking because ETC2 et al. are not listed in extensions anyway
glinfo.texcompr = 1; // !!Bstrstr(glinfo.extensions, "GL_OES_compressed_ETC1_RGB8_texture");
#endif
// if (Bstrstr(glinfo.extensions, "GL_EXT_texture_filter_anisotropic")) // if (Bstrstr(glinfo.extensions, "GL_EXT_texture_filter_anisotropic"))
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glinfo.maxanisotropy); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glinfo.maxanisotropy);

View file

@ -608,6 +608,7 @@ bool tileLoad(int16_t tileNum)
tileLoadData(tileNum, dasiz, (char *) waloff[tileNum]); tileLoadData(tileNum, dasiz, (char *) waloff[tileNum]);
/*
#ifdef USE_OPENGL #ifdef USE_OPENGL
if (videoGetRenderMode() >= REND_POLYMOST && if (videoGetRenderMode() >= REND_POLYMOST &&
in3dmode()) in3dmode())
@ -620,6 +621,7 @@ bool tileLoad(int16_t tileNum)
} }
} }
#endif #endif
*/
tilePostLoad(tileNum); tilePostLoad(tileNum);

View file

@ -38,7 +38,7 @@ static voxmodel_t *gvox;
//pitch must equal xsiz*4 //pitch must equal xsiz*4
uint32_t gloadtex(const int32_t *picbuf, int32_t xsiz, int32_t ysiz, int32_t is8bit, int32_t dapal) FHardwareTexture *gloadtex(const int32_t *picbuf, int32_t xsiz, int32_t ysiz, int32_t is8bit, int32_t dapal)
{ {
const char *const cptr = &britable[gammabrightness ? 0 : curbrightness][0]; const char *const cptr = &britable[gammabrightness ? 0 : curbrightness][0];
@ -72,17 +72,13 @@ uint32_t gloadtex(const int32_t *picbuf, int32_t xsiz, int32_t ysiz, int32_t is8
} }
} }
uint32_t rtexid; auto tex = GLInterface.NewTexture();
tex->CreateTexture(xsiz, ysiz, false, false);
GetTextureHandle((GLuint *) &rtexid); tex->LoadTexture((uint8_t*)pic2); // RGBA
glBindTexture(GL_TEXTURE_2D, rtexid); tex->SetSampler(SamplerNoFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 4, xsiz, ysiz, 0, GL_RGBA, GL_UNSIGNED_BYTE, (char *) pic2);
Bfree(pic2); Bfree(pic2);
return rtexid; return tex;
} }
static int32_t getvox(int32_t x, int32_t y, int32_t z) static int32_t getvox(int32_t x, int32_t y, int32_t z)
@ -886,7 +882,7 @@ voxmodel_t *voxload(const char *filnam)
vm->piv.x = voxpiv.x; vm->piv.y = voxpiv.y; vm->piv.z = voxpiv.z; vm->piv.x = voxpiv.x; vm->piv.y = voxpiv.y; vm->piv.z = voxpiv.z;
vm->is8bit = is8bit; vm->is8bit = is8bit;
vm->texid = (uint32_t *)Xcalloc(MAXPALOOKUPS, sizeof(uint32_t)); vm->texid = (FHardwareTexture * *)Xcalloc(MAXPALOOKUPS, sizeof(FHardwareTexture*));
} }
DO_FREE_AND_NULL(shcntmal); DO_FREE_AND_NULL(shcntmal);
@ -975,8 +971,6 @@ int32_t polymost_voxdraw(voxmodel_t *m, const uspritetype *tspr)
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glEnable(GL_TEXTURE_2D);
float pc[4]; float pc[4];
pc[0] = pc[1] = pc[2] = ((float)numshades - min(max((globalshade * shadescale) + m->shadeoff, 0.f), (float)numshades)) / (float)numshades; pc[0] = pc[1] = pc[2] = ((float)numshades - min(max((globalshade * shadescale) + m->shadeoff, 0.f), (float)numshades)) / (float)numshades;
@ -1019,8 +1013,8 @@ int32_t polymost_voxdraw(voxmodel_t *m, const uspritetype *tspr)
if (!m->texid[globalpal]) if (!m->texid[globalpal])
m->texid[globalpal] = gloadtex(m->mytex, m->mytexx, m->mytexy, m->is8bit, globalpal); m->texid[globalpal] = gloadtex(m->mytex, m->mytexx, m->mytexy, m->is8bit, globalpal);
else
glBindTexture(GL_TEXTURE_2D, m->texid[globalpal]); GLInterface.BindTexture(0, m->texid[globalpal]);
polymost_usePaletteIndexing(false); polymost_usePaletteIndexing(false);
polymost_setTexturePosSize({ 0.f, 0.f, 1.f, 1.f }); polymost_setTexturePosSize({ 0.f, 0.f, 1.f, 1.f });

View file

@ -2745,7 +2745,6 @@ static int32_t SetupOpenGL(int32_t width, int32_t height, int32_t bitspp)
polymost_glreset(); polymost_glreset();
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); //GL_FLAT glShadeModel(GL_SMOOTH); //GL_FLAT
glClearColor(0,0,0,0.5); //Black Background glClearColor(0,0,0,0.5); //Black Background
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //Use FASTEST for ortho! glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //Use FASTEST for ortho!
@ -2836,11 +2835,13 @@ static int32_t SetupOpenGL(int32_t width, int32_t height, int32_t bitspp)
// supports GL_CLAMP_TO_EDGE or GL_CLAMP_TO_EDGE_SGIS // supports GL_CLAMP_TO_EDGE or GL_CLAMP_TO_EDGE_SGIS
glinfo.clamptoedge = 1; glinfo.clamptoedge = 1;
} }
/*
else if (!Bstrcmp((char *)p2, "GL_EXT_bgra")) else if (!Bstrcmp((char *)p2, "GL_EXT_bgra"))
{ {
// support bgra textures // support bgra textures
glinfo.bgra = 1; glinfo.bgra = 1;
} }
*/
else if (!Bstrcmp((char *)p2, "GL_ARB_texture_compression") && Bstrcmp(glinfo.vendor,"ATI Technologies Inc.")) else if (!Bstrcmp((char *)p2, "GL_ARB_texture_compression") && Bstrcmp(glinfo.vendor,"ATI Technologies Inc."))
{ {
// support texture compression // support texture compression

View file

@ -67,19 +67,20 @@ unsigned int FHardwareTexture::LoadTexture(unsigned char * buffer)
{ {
if (glTexID == 0) return 0; if (glTexID == 0) return 0;
int srcformat = glTextureBytes == 1? GL_R8 : GL_RGBA8;// TexFormat[gl_texture_format]; int dstformat = glTextureBytes == 1? GL_R8 : GL_RGBA8;// TexFormat[gl_texture_format];
GLenum srctype = glTextureBytes == 1 ? GL_UNSIGNED_BYTE : (B_BIG_ENDIAN? GL_UNSIGNED_INT_8_8_8_8 : GL_UNSIGNED_INT_8_8_8_8_REV); int srcformat = glTextureBytes == 1 ? GL_RED : GL_BGRA;// TexFormat[gl_texture_format];
glActiveTexture(GL_TEXTURE15); glActiveTexture(GL_TEXTURE15);
glBindTexture(GL_TEXTURE_2D, glTexID); glBindTexture(GL_TEXTURE_2D, glTexID);
if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mWidth, mHeight, srcformat, srctype, buffer); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mWidth, mHeight, srcformat, GL_UNSIGNED_BYTE, buffer);
if (mipmapped) glGenerateMipmap(GL_TEXTURE_2D); if (mipmapped) glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
return glTexID; return glTexID;
} }

View file

@ -9,6 +9,7 @@ public:
private: private:
int mSampler = 0;
unsigned int glTexID = 0; unsigned int glTexID = 0;
int glTextureBytes = 4; int glTextureBytes = 4;
bool mipmapped = true; bool mipmapped = true;
@ -18,12 +19,13 @@ public:
~FHardwareTexture(); ~FHardwareTexture();
unsigned int Bind(int texunit, bool needmipmap);
//bool BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags); //bool BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags);
unsigned int CreateTexture(int w, int h, bool eightbit, bool mipmapped); unsigned int CreateTexture(int w, int h, bool eightbit, bool mipmapped);
unsigned int LoadTexture(unsigned char * buffer); unsigned int LoadTexture(unsigned char * buffer);
unsigned int GetTextureHandle(); unsigned int GetTextureHandle();
int GetSampler() { return mSampler; }
void SetSampler(int sampler) { mSampler = sampler; }
}; };
#endif #endif

View file

@ -5,10 +5,13 @@
GLInstance GLInterface; GLInstance GLInterface;
void GLInstance::Init() void GLInstance::Init()
{
if (!mSamplers)
{ {
mSamplers = new FSamplerManager; mSamplers = new FSamplerManager;
memset(LastBoundTextures, 0, sizeof(LastBoundTextures)); memset(LastBoundTextures, 0, sizeof(LastBoundTextures));
} }
}
void GLInstance::Deinit() void GLInstance::Deinit()
{ {
@ -55,14 +58,19 @@ int GLInstance::GetTextureID()
return TextureHandleCache[currentindex]; return TextureHandleCache[currentindex];
} }
void GLInstance::BindTexture(int texunit, int tex, int sampler) FHardwareTexture* GLInstance::NewTexture()
{ {
return new FHardwareTexture;
}
void GLInstance::BindTexture(int texunit, FHardwareTexture *tex, int sampler)
{
if (!tex) return;
if (texunit != 0) glActiveTexture(GL_TEXTURE0 + texunit); if (texunit != 0) glActiveTexture(GL_TEXTURE0 + texunit);
glBindTexture(GL_TEXTURE_2D, tex); glBindTexture(GL_TEXTURE_2D, tex->GetTextureHandle());
if (sampler != NoSampler) mSamplers->Bind(texunit, sampler, 0); mSamplers->Bind(texunit, sampler == NoSampler? tex->GetSampler() : sampler, 0);
else glBindSampler(texunit, 0);
if (texunit != 0) glActiveTexture(GL_TEXTURE0); if (texunit != 0) glActiveTexture(GL_TEXTURE0);
LastBoundTextures[texunit] = tex; LastBoundTextures[texunit] = tex->GetTextureHandle();
} }
void GLInstance::UnbindTexture(int texunit) void GLInstance::UnbindTexture(int texunit)

View file

@ -74,7 +74,8 @@ public:
void Draw(EDrawType type, size_t start, size_t count); void Draw(EDrawType type, size_t start, size_t count);
int GetTextureID(); int GetTextureID();
void BindTexture(int texunit, int texid, int sampler = NoSampler); FHardwareTexture* NewTexture();
void BindTexture(int texunit, FHardwareTexture *texid, int sampler = NoSampler);
void UnbindTexture(int texunit); void UnbindTexture(int texunit);
void UnbindAllTextures(); void UnbindAllTextures();