major cleanup of the texture manager:

- use sampler objects to avoid creating up to 4 different system textures for one game texture just because of different clamping settings.
- avoids flushing all textures for change of texture filter mode.
- separate sprite and regular dimensions on the material level to have better control over which one gets used. It's now an explicit parameter of ValidateTexture. The main reason for this change is better handling of wall sprites which may not be subjected to such handling.
- create mipmaps based on use case, not texture type.
- allows removal of FCloneTexture hack for proper sharing of the same sprite for decals and other purposes.
- better precaching of skyboxes.
This commit is contained in:
Christoph Oelckers 2014-08-22 23:50:38 +02:00
parent 7a727b6807
commit 1050013017
31 changed files with 596 additions and 700 deletions

View File

@ -1042,6 +1042,7 @@ add_executable( zdoom WIN32
gl/textures/gl_material.cpp
gl/textures/gl_hirestex.cpp
gl/textures/gl_bitmap.cpp
gl/textures/gl_samplers.cpp
gl/textures/gl_translate.cpp
gl/textures/gl_hqresize.cpp
gl/textures/gl_skyboxtexture.cpp

View File

@ -301,9 +301,9 @@ void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double i
if (!skin) return;
}
FMaterial * tex = FMaterial::ValidateTexture(skin);
FMaterial * tex = FMaterial::ValidateTexture(skin, false);
tex->Bind(0, translation);
tex->Bind(CLAMP_NONE, translation, -1, false);
gl_RenderState.Apply();
GLRenderer->mModelVBO->SetupFrame(frames[frameno].vindex, frames[frameno2].vindex, inter);

View File

@ -265,9 +265,9 @@ void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double i
if (!surfaceSkin) return;
}
FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin);
FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin, false);
tex->Bind(0, translation);
tex->Bind(CLAMP_NONE, translation, -1, false);
gl_RenderState.Apply();
GLRenderer->mModelVBO->SetupFrame(surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, inter);

View File

@ -416,8 +416,8 @@ int FVoxelModel::FindFrame(const char * name)
void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation)
{
FMaterial * tex = FMaterial::ValidateTexture(skin);
tex->Bind(0, translation);
FMaterial * tex = FMaterial::ValidateTexture(skin, false);
tex->Bind(CLAMP_NOFILTER, translation, -1, false);
gl_RenderState.Apply();
GLRenderer->mModelVBO->SetupFrame(vindex, vindex, 0.f);

View File

@ -64,6 +64,7 @@
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_material.h"
#include "gl/textures/gl_samplers.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
#include "gl/models/gl_models.h"
@ -115,6 +116,7 @@ void FGLRenderer::Initialize()
mFBID = 0;
SetupLevel();
mShaderManager = new FShaderManager;
mSamplerManager = new FSamplerManager;
//mThreadManager = new FGLThreadManager;
}
@ -124,6 +126,7 @@ FGLRenderer::~FGLRenderer()
FMaterial::FlushAll();
//if (mThreadManager != NULL) delete mThreadManager;
if (mShaderManager != NULL) delete mShaderManager;
if (mSamplerManager != NULL) delete mSamplerManager;
if (mVBO != NULL) delete mVBO;
if (mModelVBO) delete mModelVBO;
if (mSkyVBO != NULL) delete mSkyVBO;
@ -243,7 +246,7 @@ void FGLRenderer::EndOffscreen()
unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h)
{
FMaterial * gltex = FMaterial::ValidateTexture(tex);
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
if (gltex)
{
return gltex->CreateTexBuffer(0, w, h);
@ -310,7 +313,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
float u1, v1, u2, v2;
int light = 255;
FMaterial * gltex = FMaterial::ValidateTexture(img);
FMaterial * gltex = FMaterial::ValidateTexture(img, false);
if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0)
{
@ -331,7 +334,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
}
}
gl_SetRenderStyle(parms.style, !parms.masked, false);
gltex->BindPatch(translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha));
gltex->Bind(CLAMP_XY_NOMIP, translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha));
u1 = gltex->GetUL();
v1 = gltex->GetVT();
@ -341,10 +344,11 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
}
else
{
gltex->Bind(0, 0);
gltex->Bind(CLAMP_XY_NOMIP, 0, -1, false);
u1 = 0.f;
v1 = 1.f;
u2 = 1.f;
v2=-1.f;
u1 = v1 = 0.f;
v2 = 0.f;
gl_RenderState.SetTextureMode(TM_OPAQUE);
}
@ -490,11 +494,11 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture *
{
float fU1,fU2,fV1,fV2;
FMaterial *gltexture=FMaterial::ValidateTexture(src);
FMaterial *gltexture=FMaterial::ValidateTexture(src, false);
if (!gltexture) return;
gltexture->Bind(0, 0);
gltexture->Bind(CLAMP_NONE, 0, -1, false);
// scaling is not used here.
if (!local_origin)
@ -575,7 +579,7 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint
return;
}
FMaterial *gltexture = FMaterial::ValidateTexture(texture);
FMaterial *gltexture = FMaterial::ValidateTexture(texture, false);
if (gltexture == NULL)
{
@ -587,7 +591,7 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint
gl_SetColor(lightlevel, 0, cm, 1.f);
gltexture->Bind();
gltexture->Bind(CLAMP_NONE, 0, -1, false);
int i;
float rot = float(rotation * M_PI / float(1u << 31));

View File

@ -18,6 +18,7 @@ class FShaderManager;
class GLPortal;
class FGLThreadManager;
class FLightBuffer;
class FSamplerManager;
enum SectorRenderFlags
{
@ -56,6 +57,7 @@ public:
float mCurrentFoV;
AActor *mViewActor;
FShaderManager *mShaderManager;
FSamplerManager *mSamplerManager;
FGLThreadManager *mThreadManager;
int gl_spriteindex;
unsigned int mFBID;

View File

@ -103,17 +103,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
FMaterial *tex;
if (texture->UseType == FTexture::TEX_MiscPatch)
{
// We need to create a clone of this texture where we can force the
// texture filtering offset in.
if (texture->gl_info.DecalTexture == NULL)
{
texture->gl_info.DecalTexture = new FCloneTexture(texture, FTexture::TEX_Decal);
}
tex = FMaterial::ValidateTexture(texture->gl_info.DecalTexture);
}
else tex = FMaterial::ValidateTexture(texture);
tex = FMaterial::ValidateTexture(texture, true);
// the sectors are only used for their texture origin coordinates
@ -192,10 +182,10 @@ void GLWall::DrawDecal(DBaseDecal *decal)
a = FIXED2FLOAT(decal->Alpha);
// now clip the decal to the actual polygon
float decalwidth = tex->TextureWidth(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleX);
float decalheight= tex->TextureHeight(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleY);
float decallefto = tex->GetLeftOffset(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleX);
float decaltopo = tex->GetTopOffset(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleY);
float decalwidth = tex->TextureWidth() * FIXED2FLOAT(decal->ScaleX);
float decalheight= tex->TextureHeight() * FIXED2FLOAT(decal->ScaleY);
float decallefto = tex->GetLeftOffset() * FIXED2FLOAT(decal->ScaleX);
float decaltopo = tex->GetTopOffset() * FIXED2FLOAT(decal->ScaleY);
float leftedge = glseg.fracleft * side->TexelLength;
@ -329,7 +319,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
gl_SetRenderStyle(decal->RenderStyle, false, false);
tex->BindPatch(decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha));
tex->Bind(CLAMP_XY, decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha));
// If srcalpha is one it looks better with a higher alpha threshold

View File

@ -1055,7 +1055,7 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
plane.GetFromSector(sec, ceiling);
gltexture=FMaterial::ValidateTexture(plane.texture, true);
gltexture=FMaterial::ValidateTexture(plane.texture, false, true);
if (!gltexture) return;
if (gl_fixedcolormap)
@ -1077,7 +1077,7 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
int rel = getExtraLight();
gl_SetColor(lightlevel, rel, Colormap, 1.0f);
gl_SetFog(lightlevel, rel, &Colormap, false);
gltexture->Bind();
gltexture->Bind(CLAMP_NONE, 0, -1, false);
float fviewx = FIXED2FLOAT(viewx);
float fviewy = FIXED2FLOAT(viewy);

View File

@ -77,11 +77,11 @@ void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
if (secplane->xoffs != 0 || secplane->yoffs != 0 ||
secplane->xscale != FRACUNIT || secplane->yscale != FRACUNIT ||
secplane->angle != 0 ||
gltexture->TextureWidth(GLUSE_TEXTURE) != 64 ||
gltexture->TextureHeight(GLUSE_TEXTURE) != 64)
gltexture->TextureWidth() != 64 ||
gltexture->TextureHeight() != 64)
{
float uoffs=FIXED2FLOAT(secplane->xoffs)/gltexture->TextureWidth(GLUSE_TEXTURE);
float voffs=FIXED2FLOAT(secplane->yoffs)/gltexture->TextureHeight(GLUSE_TEXTURE);
float uoffs=FIXED2FLOAT(secplane->xoffs)/gltexture->TextureWidth();
float voffs=FIXED2FLOAT(secplane->yoffs)/gltexture->TextureHeight();
float xscale1=FIXED2FLOAT(secplane->xscale);
float yscale1=FIXED2FLOAT(secplane->yscale);
@ -91,8 +91,8 @@ void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
}
float angle=-ANGLE_TO_FLOAT(secplane->angle);
float xscale2=64.f/gltexture->TextureWidth(GLUSE_TEXTURE);
float yscale2=64.f/gltexture->TextureHeight(GLUSE_TEXTURE);
float xscale2=64.f/gltexture->TextureWidth();
float yscale2=64.f/gltexture->TextureHeight();
gl_RenderState.mTextureMatrix.loadIdentity();
gl_RenderState.mTextureMatrix.scale(xscale1 ,yscale1,1.0f);
@ -341,7 +341,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
case GLPASS_ALL:
gl_SetColor(lightlevel, rel, Colormap,1.0f);
gl_SetFog(lightlevel, rel, &Colormap, false);
gltexture->Bind();
gltexture->Bind(CLAMP_NONE, 0, -1, false);
gl_SetPlaneTextureRotation(&plane, gltexture);
DrawSubsectors(pass, (pass == GLPASS_ALL || dynlightindex > -1), false);
gl_RenderState.EnableTextureMatrix(false);
@ -367,7 +367,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
}
else
{
gltexture->Bind();
gltexture->Bind(CLAMP_NONE, 0, -1, false);
gl_SetPlaneTextureRotation(&plane, gltexture);
DrawSubsectors(pass, true, true);
gl_RenderState.EnableTextureMatrix(false);
@ -424,7 +424,7 @@ void GLFlat::Process(sector_t * model, int whichplane, bool fog)
{
if (plane.texture==skyflatnum) return;
gltexture=FMaterial::ValidateTexture(plane.texture, true);
gltexture=FMaterial::ValidateTexture(plane.texture, false, true);
if (!gltexture) return;
if (gltexture->tex->isFullbright())
{

View File

@ -985,7 +985,7 @@ void GLHorizonPortal::DrawContents()
float z;
player_t * player=&players[consoleplayer];
gltexture=FMaterial::ValidateTexture(sp->texture, true);
gltexture=FMaterial::ValidateTexture(sp->texture, false, true);
if (!gltexture)
{
ClearScreen();
@ -1011,7 +1011,7 @@ void GLHorizonPortal::DrawContents()
}
gltexture->Bind();
gltexture->Bind(CLAMP_NONE, 0, -1, false);
gl_SetPlaneTextureRotation(sp, gltexture);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);

View File

@ -959,7 +959,7 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
{
if (cache)
{
tex->PrecacheGL();
tex->PrecacheGL(cache);
}
else
{
@ -1067,10 +1067,10 @@ extern TexFilter_s TexFilter[];
void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, int FOV)
{
FMaterial * gltex = FMaterial::ValidateTexture(tex);
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
int width = gltex->TextureWidth(GLUSE_TEXTURE);
int height = gltex->TextureHeight(GLUSE_TEXTURE);
int width = gltex->TextureWidth();
int height = gltex->TextureHeight();
gl_fixedcolormap=CM_DEFAULT;
gl_RenderState.SetFixedColormap(CM_DEFAULT);
@ -1102,15 +1102,15 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in
GL_IRECT bounds;
bounds.left=bounds.top=0;
bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth(GLUSE_TEXTURE));
bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight(GLUSE_TEXTURE));
bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth());
bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight());
GLRenderer->RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false);
if (!usefb)
{
glFlush();
gltex->Bind(0, 0);
gltex->Bind(0, 0, -1, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height);
}
else
@ -1118,8 +1118,6 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in
GLRenderer->EndOffscreen();
}
gltex->Bind(0, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter);
tex->SetUpdated();
}

View File

@ -111,7 +111,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
}
FTextureID texno = s->GetTexture(pos);
skyinfo.texture[0] = FMaterial::ValidateTexture(texno, true);
skyinfo.texture[0] = FMaterial::ValidateTexture(texno, false, true);
if (!skyinfo.texture[0] || skyinfo.texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky;
skyinfo.skytexno1 = texno;
skyinfo.x_offset[0] = ANGLE_TO_FLOAT(s->GetTextureXOffset(pos));
@ -123,7 +123,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
normalsky:
if (level.flags&LEVEL_DOUBLESKY)
{
skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, true);
skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, false, true);
skyinfo.x_offset[1] = GLRenderer->mSky1Pos;
skyinfo.doublesky = true;
}
@ -131,14 +131,14 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
if ((level.flags&LEVEL_SWAPSKIES || (sky1==PL_SKYFLAT) || (level.flags&LEVEL_DOUBLESKY)) &&
sky2texture!=sky1texture) // If both skies are equal use the scroll offset of the first!
{
skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, true);
skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, false, true);
skyinfo.skytexno1=sky2texture;
skyinfo.sky2 = true;
skyinfo.x_offset[0] = GLRenderer->mSky2Pos;
}
else
{
skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, true);
skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, false, true);
skyinfo.skytexno1=sky1texture;
skyinfo.x_offset[0] = GLRenderer->mSky1Pos;
}

View File

@ -268,9 +268,9 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in
if (tex)
{
tex->Bind(0, 0);
texw = tex->TextureWidth(GLUSE_TEXTURE);
texh = tex->TextureHeight(GLUSE_TEXTURE);
tex->Bind(CLAMP_NONE, 0, -1, false);
texw = tex->TextureWidth();
texh = tex->TextureHeight();
gl_RenderState.EnableModelMatrix(true);
gl_RenderState.mModelMatrix.loadIdentity();
@ -332,8 +332,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
faces=4;
// north
tex = FMaterial::ValidateTexture(sb->faces[0]);
tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0);
tex = FMaterial::ValidateTexture(sb->faces[0], false);
tex->Bind(CLAMP_XY, 0, -1, false);
gl_RenderState.Apply();
ptr = GLRenderer->mVBO->GetBuffer();
@ -348,8 +348,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
// east
tex = FMaterial::ValidateTexture(sb->faces[1]);
tex->Bind(GLT_CLAMPX | GLT_CLAMPY, 0);
tex = FMaterial::ValidateTexture(sb->faces[1], false);
tex->Bind(CLAMP_XY, 0, -1, false);
gl_RenderState.Apply();
ptr = GLRenderer->mVBO->GetBuffer();
@ -364,8 +364,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
// south
tex = FMaterial::ValidateTexture(sb->faces[2]);
tex->Bind(GLT_CLAMPX | GLT_CLAMPY, 0);
tex = FMaterial::ValidateTexture(sb->faces[2], false);
tex->Bind(CLAMP_XY, 0, -1, false);
gl_RenderState.Apply();
ptr = GLRenderer->mVBO->GetBuffer();
@ -380,8 +380,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
// west
tex = FMaterial::ValidateTexture(sb->faces[3]);
tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0);
tex = FMaterial::ValidateTexture(sb->faces[3], false);
tex->Bind(CLAMP_XY, 0, -1, false);
gl_RenderState.Apply();
ptr = GLRenderer->mVBO->GetBuffer();
@ -424,8 +424,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
}
// top
tex = FMaterial::ValidateTexture(sb->faces[faces]);
tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0);
tex = FMaterial::ValidateTexture(sb->faces[faces], false);
tex->Bind(CLAMP_XY, 0, -1, false);
gl_RenderState.Apply();
ptr = GLRenderer->mVBO->GetBuffer();
@ -440,8 +440,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
// bottom
tex = FMaterial::ValidateTexture(sb->faces[faces+1]);
tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0);
tex = FMaterial::ValidateTexture(sb->faces[faces+1], false);
tex->Bind(CLAMP_XY, 0, -1, false);
gl_RenderState.Apply();
ptr = GLRenderer->mVBO->GetBuffer();

View File

@ -214,7 +214,7 @@ void GLSprite::Draw(int pass)
gl_RenderState.SetFog(0, 0);
}
if (gltexture) gltexture->BindPatch(translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha));
if (gltexture) gltexture->Bind(CLAMP_XY, translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha));
else if (!modelframe) gl_RenderState.EnableTexture(false);
if (!modelframe)
@ -455,8 +455,9 @@ void GLSprite::PerformSpriteClipAdjustment(AActor *thing, fixed_t thingx, fixed_
if (top == -1000000.0f)
top = FIXED2FLOAT(thing->Sector->ceilingplane.ZatPoint(thingx, thingy));
float diffb = z2 - btm;
float difft = z1 - top;
// +/-1 to account for the one pixel empty frame around the sprite.
float diffb = (z2+1) - btm;
float difft = (z1-1) - top;
if (diffb >= 0 /*|| !gl_sprite_clip_to_floor*/) diffb = 0;
// Adjust sprites clipping into ceiling and adjust clipping adjustment for tall graphics
if (smarterclip)
@ -598,12 +599,13 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
bool mirror;
FTextureID patch = gl_GetSpriteFrame(spritenum, thing->frame, -1, ang - thing->angle, &mirror);
if (!patch.isValid()) return;
gltexture = FMaterial::ValidateTexture(patch, false);
int type = thing->renderflags & RF_SPRITETYPEMASK;
gltexture = FMaterial::ValidateTexture(patch, (type == RF_FACESPRITE), false);
if (!gltexture) return;
vt = gltexture->GetSpriteVT();
vb = gltexture->GetSpriteVB();
gltexture->GetRect(&r, GLUSE_SPRITE);
gltexture->GetSpriteRect(&r);
if (mirror)
{
r.left = -r.width - r.left; // mirror the sprite's x-offset
@ -624,7 +626,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
z1 = z - r.top;
z2 = z1 - r.height;
float spriteheight = FIXED2FLOAT(spritescaleY) * gltexture->GetScaledHeightFloat(GLUSE_SPRITE);
float spriteheight = FIXED2FLOAT(spritescaleY) * r.height;
// Tests show that this doesn't look good for many decorations and corpses
if (spriteheight > 0 && gl_spriteclip > 0 && (thing->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE)
@ -734,7 +736,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
translation=thing->Translation;
OverrideShader = 0;
OverrideShader = -1;
trans = FIXED2FLOAT(thing->alpha);
hw_styleflags = STYLEHW_Normal;
@ -923,7 +925,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
if (lump != NULL)
{
gltexture=FMaterial::ValidateTexture(lump);
gltexture = FMaterial::ValidateTexture(lump, true);
translation = 0;
ul = gltexture->GetUL();
@ -931,7 +933,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
vt = gltexture->GetVT();
vb = gltexture->GetVB();
FloatRect r;
gltexture->GetRect(&r, GLUSE_PATCH);
gltexture->GetSpriteRect(&r);
}
}

View File

@ -783,12 +783,12 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
if ( (seg->linedef->flags & ML_DONTPEGBOTTOM) >0)
{
texturebottom = MAX(realfront->GetPlaneTexZ(sector_t::floor),realback->GetPlaneTexZ(sector_t::floor))+rowoffset;
texturetop=texturebottom+(gltexture->TextureHeight(GLUSE_TEXTURE)<<FRACBITS);
texturetop=texturebottom+(gltexture->TextureHeight()<<FRACBITS);
}
else
{
texturetop = MIN(realfront->GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling))+rowoffset;
texturebottom=texturetop-(gltexture->TextureHeight(GLUSE_TEXTURE)<<FRACBITS);
texturebottom=texturetop-(gltexture->TextureHeight()<<FRACBITS);
}
}
else texturetop=texturebottom=0;
@ -915,8 +915,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
fixed_t textureoffset = tci.TextureOffset(t_ofs);
int righttex=(textureoffset>>FRACBITS)+seg->sidedef->TexelLength;
if ((textureoffset==0 && righttex<=gltexture->TextureWidth(GLUSE_TEXTURE)) ||
(textureoffset>=0 && righttex==gltexture->TextureWidth(GLUSE_TEXTURE)))
if ((textureoffset==0 && righttex<=gltexture->TextureWidth()) ||
(textureoffset>=0 && righttex==gltexture->TextureWidth()))
{
flags|=GLT_CLAMPX;
}
@ -1094,19 +1094,19 @@ void GLWall::BuildFFBlock(seg_t * seg, F3DFloor * rover,
if (rover->flags&FF_UPPERTEXTURE)
{
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), true);
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true);
if (!gltexture) return;
gltexture->GetTexCoordInfo(&tci, seg->sidedef->GetTextureXScale(side_t::top), seg->sidedef->GetTextureYScale(side_t::top));
}
else if (rover->flags&FF_LOWERTEXTURE)
{
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true);
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true);
if (!gltexture) return;
gltexture->GetTexCoordInfo(&tci, seg->sidedef->GetTextureXScale(side_t::bottom), seg->sidedef->GetTextureYScale(side_t::bottom));
}
else
{
gltexture = FMaterial::ValidateTexture(mastersd->GetTexture(side_t::mid), true);
gltexture = FMaterial::ValidateTexture(mastersd->GetTexture(side_t::mid), false, true);
if (!gltexture) return;
gltexture->GetTexCoordInfo(&tci, mastersd->GetTextureXScale(side_t::mid), mastersd->GetTextureYScale(side_t::mid));
}
@ -1558,7 +1558,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
SkyNormal(frontsector, v1, v2);
// normal texture
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), true);
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), false, true);
if (gltexture)
{
DoTexture(RENDERWALL_M1S, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
@ -1613,7 +1613,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
if (bch1a < fch1 || bch2a < fch2)
{
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), true);
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true);
if (gltexture)
{
DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0,
@ -1625,7 +1625,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
frontsector->GetTexture(sector_t::ceiling) != skyflatnum &&
backsector->GetTexture(sector_t::ceiling) != skyflatnum)
{
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), true);
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), false, true);
if (gltexture)
{
DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0,
@ -1650,7 +1650,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
{
tex = tex->GetRawTexture();
}
gltexture = FMaterial::ValidateTexture(tex);
gltexture = FMaterial::ValidateTexture(tex, false);
}
else gltexture = NULL;
@ -1675,7 +1675,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
if (bfh1>ffh1 || bfh2>ffh2)
{
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true);
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true);
if (gltexture)
{
DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
@ -1693,7 +1693,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
// render it anyway with the sector's floor texture. With a background sky
// there are ugly holes otherwise and slopes are simply not precise enough
// to mach in any case.
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), true);
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), false, true);
if (gltexture)
{
DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
@ -1756,7 +1756,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
zfloor[0] = zfloor[1] = FIXED2FLOAT(ffh);
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), true);
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), false, true);
if (gltexture)
{

View File

@ -273,8 +273,8 @@ void GLWall::RenderMirrorSurface()
gl_RenderState.AlphaFunc(GL_GREATER,0);
glDepthFunc(GL_LEQUAL);
FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture);
pat->BindPatch(0);
FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture, false);
pat->Bind(CLAMP_NONE, 0, -1, false);
flags &= ~GLWF_GLOW;
RenderWall(RWF_BLANK);
@ -326,7 +326,7 @@ void GLWall::RenderTranslucentWall()
if (gltexture)
{
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
gltexture->Bind(flags, 0);
gltexture->Bind(flags & 3, 0, -1, false);
extra = getExtraLight();
}
else
@ -390,7 +390,7 @@ void GLWall::Draw(int pass)
else gl_SetFog(255, 0, NULL, false);
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
gltexture->Bind(flags, 0);
gltexture->Bind(flags & 3, false, -1, false);
RenderWall(RWF_TEXTURED|RWF_GLOW);
gl_RenderState.EnableGlow(false);
break;

View File

@ -93,10 +93,10 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, &mirror);
if (!lump.isValid()) return;
FMaterial * tex = FMaterial::ValidateTexture(lump, false);
FMaterial * tex = FMaterial::ValidateTexture(lump, true, false);
if (!tex) return;
tex->BindPatch(0, OverrideShader, alphatexture);
tex->Bind(CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture);
int vw = viewwidth;
int vh = viewheight;
@ -104,18 +104,18 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
// calculate edges of the shape
scalex = xratio[WidescreenRatio] * vw / 320;
tx = sx - ((160 + tex->GetScaledLeftOffset(GLUSE_PATCH))<<FRACBITS);
tx = sx - ((160 + tex->GetScaledLeftOffset())<<FRACBITS);
x1 = (FixedMul(tx, scalex)>>FRACBITS) + (vw>>1);
if (x1 > vw) return; // off the right side
x1+=viewwindowx;
tx += tex->TextureWidth(GLUSE_PATCH) << FRACBITS;
tx += tex->TextureWidth() << FRACBITS;
x2 = (FixedMul(tx, scalex)>>FRACBITS) + (vw>>1);
if (x2 < 0) return; // off the left side
x2+=viewwindowx;
// killough 12/98: fix psprite positioning problem
texturemid = (100<<FRACBITS) - (sy-(tex->GetScaledTopOffset(GLUSE_PATCH)<<FRACBITS));
texturemid = (100<<FRACBITS) - (sy-(tex->GetScaledTopOffset()<<FRACBITS));
AWeapon * wi=player->ReadyWeapon;
if (wi && wi->YAdjust)
@ -132,7 +132,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
scale = ((SCREENHEIGHT*vw)/SCREENWIDTH) / 200.0f;
y1 = viewwindowy + (vh >> 1) - (int)(((float)texturemid / (float)FRACUNIT) * scale);
y2 = y1 + (int)((float)tex->TextureHeight(GLUSE_PATCH) * scale) + 1;
y2 = y1 + (int)((float)tex->TextureHeight() * scale) + 1;
if (!mirror)
{
@ -149,7 +149,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
fV2=tex->GetVB();
}
if (tex->GetTransparent() || OverrideShader != 0)
if (tex->GetTransparent() || OverrideShader != -1)
{
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
}
@ -207,7 +207,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, NULL);
if (lump.isValid())
{
FMaterial * tex=FMaterial::ValidateTexture(lump, false);
FMaterial * tex=FMaterial::ValidateTexture(lump, false, false);
if (tex)
disablefullbright = tex->tex->gl_info.bBrightmapDisablesFullbright;
}
@ -306,7 +306,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
// Set the render parameters
int OverrideShader = 0;
int OverrideShader = -1;
float trans = 0.f;
if (vis.RenderStyle.BlendOp >= STYLEOP_Fuzz && vis.RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub)
{

View File

@ -56,6 +56,7 @@
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_material.h"
#include "gl/textures/gl_samplers.h"
#include "gl/utility/gl_templates.h"
#include "gl/data/gl_vertexbuffer.h"
@ -146,13 +147,12 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
return false;
}
wipestartscreen = new FHardwareTexture(Width, Height, false, false, false, true);
wipestartscreen->CreateTexture(NULL, Width, Height, false, 0);
wipestartscreen = new FHardwareTexture(Width, Height, true);
wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false);
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER);
glFinish();
wipestartscreen->Bind(0);
wipestartscreen->Bind(0, false, false, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@ -169,10 +169,11 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
void OpenGLFrameBuffer::WipeEndScreen()
{
wipeendscreen = new FHardwareTexture(Width, Height, false, false, false, true);
wipeendscreen->CreateTexture(NULL, Width, Height, false, 0);
glFlush();
wipeendscreen->Bind(0);
wipeendscreen = new FHardwareTexture(Width, Height, true);
wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false);
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER);
glFinish();
wipeendscreen->Bind(0, false, false, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -283,7 +284,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb)
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.ResetColor();
gl_RenderState.Apply();
fb->wipestartscreen->Bind(0);
fb->wipestartscreen->Bind(0, 0, false, false);
FFlatVertex *ptr;
unsigned int offset, count;
@ -298,7 +299,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb)
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);
fb->wipeendscreen->Bind(0);
fb->wipeendscreen->Bind(0, 0, false, false);
gl_RenderState.SetColorAlpha(0xffffff, clamp(Clock/32.f, 0.f, 1.f));
gl_RenderState.Apply();
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
@ -345,7 +346,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
gl_RenderState.SetTextureMode(TM_OPAQUE);
gl_RenderState.ResetColor();
gl_RenderState.Apply();
fb->wipeendscreen->Bind(0);
fb->wipeendscreen->Bind(0, 0, false, false);
FFlatVertex *ptr;
ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(0, 0, 0, 0, vb);
@ -361,7 +362,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
int i, dy;
bool done = false;
fb->wipestartscreen->Bind(0);
fb->wipestartscreen->Bind(0, 0, false, false);
// Copy the old screen in vertical strips on top of the new one.
while (ticks--)
{
@ -468,7 +469,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
}
if (BurnTexture != NULL) delete BurnTexture;
BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, false, false, false, true);
BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, true);
// Update the burn texture with the new burn data
BYTE rgb_buffer[WIDTH*HEIGHT*4];
@ -493,7 +494,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.ResetColor();
gl_RenderState.Apply();
fb->wipestartscreen->Bind(0);
fb->wipestartscreen->Bind(0, 0, false, false);
FFlatVertex *ptr;
unsigned int offset, count;
ptr = GLRenderer->mVBO->GetBuffer();
@ -513,9 +514,9 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
gl_RenderState.Apply();
// Burn the new screen on top of it.
fb->wipeendscreen->Bind(1);
fb->wipeendscreen->Bind(1, 0, false, false);
BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0);
BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 0, false, 0, false);
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
gl_RenderState.SetEffect(EFF_NONE);

View File

@ -4,7 +4,7 @@
** containers for the various translations a texture can have.
**
**---------------------------------------------------------------------------
** Copyright 2004-2005 Christoph Oelckers
** Copyright 2004-2014 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
@ -173,6 +173,7 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un
}
//===========================================================================
//
// Loads the texture image into the hardware
@ -182,24 +183,27 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un
// strange crashes deep inside the GL driver when I didn't do it!
//
//===========================================================================
void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit)
unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, bool alphatexture)
{
int rh,rw;
int texformat=TexFormat[gl_texture_format];
bool deletebuffer=false;
bool use_mipmapping = TexFilter[gl_texture_filter].mipmapping;
if (alphatexture)
{
texformat = GL_R8;
translation = TRANS_Alpha;
}
else if (forcenocompression)
{
texformat = GL_RGBA8;
}
if (glTexID==0) glGenTextures(1,&glTexID);
glBindTexture(GL_TEXTURE_2D, glTexID);
lastbound[texunit]=glTexID;
TranslatedTexture * glTex=GetTexID(translation);
if (glTex->glTexID==0) glGenTextures(1,&glTex->glTexID);
if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit);
glBindTexture(GL_TEXTURE_2D, glTex->glTexID);
lastbound[texunit] = glTex->glTexID;
if (!buffer)
{
@ -209,7 +213,7 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
rh = GetTexDimension (h);
// The texture must at least be initialized if no data is present.
mipmap=false;
glTex->mipmapped = false;
buffer=(unsigned char *)calloc(4,rw * (rh+1));
deletebuffer=true;
//texheight=-h;
@ -235,42 +239,19 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
if (deletebuffer) free(buffer);
if (mipmap && use_mipmapping && !forcenofiltering) glGenerateMipmap(GL_TEXTURE_2D);
if (mipmap && TexFilter[gl_texture_filter].mipmapping)
{
glGenerateMipmap(GL_TEXTURE_2D);
glTex->mipmapped = true;
}
if (alphatexture)
{
static const GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
// When using separate samplers the stuff below is not needed.
// if (gl.flags & RFL_SAMPLER_OBJECTS) return;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapparam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapparam);
clampmode = wrapparam==GL_CLAMP_TO_EDGE? GLT_CLAMPX|GLT_CLAMPY : 0;
if (forcenofiltering)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
}
else
{
if (mipmap && use_mipmapping)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter);
if (gl_texture_filter_anisotropic)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic);
}
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter);
}
if (texunit != 0) glActiveTexture(GL_TEXTURE0);
return glTex->glTexID;
}
@ -279,17 +260,16 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
// Creates a texture
//
//===========================================================================
FHardwareTexture::FHardwareTexture(int _width, int _height, bool _mipmap, bool wrap, bool nofilter, bool nocompression)
FHardwareTexture::FHardwareTexture(int _width, int _height, bool nocompression)
{
forcenocompression = nocompression;
mipmap=_mipmap;
texwidth=_width;
texheight=_height;
glDefTexID = 0;
clampmode=0;
glDefTex.glTexID = 0;
glDefTex.translation = 0;
glDefTex.mipmapped = false;
glDepthID = 0;
forcenofiltering = nofilter;
}
@ -298,18 +278,20 @@ FHardwareTexture::FHardwareTexture(int _width, int _height, bool _mipmap, bool w
// Deletes a texture id and unbinds it from the texture units
//
//===========================================================================
void FHardwareTexture::DeleteTexture(unsigned int texid)
void FHardwareTexture::TranslatedTexture::Delete()
{
if (texid != 0)
if (glTexID != 0)
{
for(int i = 0; i < MAX_TEXTURES; i++)
{
if (lastbound[i] == texid)
if (lastbound[i] == glTexID)
{
lastbound[i] = 0;
}
}
glDeleteTextures(1, &texid);
glDeleteTextures(1, &glTexID);
glTexID = 0;
mipmapped = false;
}
}
@ -324,14 +306,13 @@ void FHardwareTexture::Clean(bool all)
if (all)
{
DeleteTexture(glDefTexID);
glDefTexID = 0;
glDefTex.Delete();
}
for(unsigned int i=0;i<glTexID_Translated.Size();i++)
for(unsigned int i=0;i<glTex_Translated.Size();i++)
{
DeleteTexture(glTexID_Translated[i].glTexID);
glTex_Translated[i].Delete();
}
glTexID_Translated.Clear();
glTex_Translated.Clear();
if (glDepthID != 0) glDeleteRenderbuffers(1, &glDepthID);
}
@ -352,27 +333,28 @@ FHardwareTexture::~FHardwareTexture()
//
//===========================================================================
unsigned * FHardwareTexture::GetTexID(int translation)
FHardwareTexture::TranslatedTexture *FHardwareTexture::GetTexID(int translation)
{
if (translation == 0)
{
return &glDefTexID;
return &glDefTex;
}
// normally there aren't more than very few different
// translations here so this isn't performance critical.
for(unsigned int i=0;i<glTexID_Translated.Size();i++)
for (unsigned int i = 0; i < glTex_Translated.Size(); i++)
{
if (glTexID_Translated[i].translation == translation)
if (glTex_Translated[i].translation == translation)
{
return &glTexID_Translated[i].glTexID;
return &glTex_Translated[i];
}
}
int add = glTexID_Translated.Reserve(1);
glTexID_Translated[add].translation=translation;
glTexID_Translated[add].glTexID=0;
return &glTexID_Translated[add].glTexID;
int add = glTex_Translated.Reserve(1);
glTex_Translated[add].translation = translation;
glTex_Translated[add].glTexID = 0;
glTex_Translated[add].mipmapped = false;
return &glTex_Translated[add];
}
//===========================================================================
@ -380,19 +362,25 @@ unsigned * FHardwareTexture::GetTexID(int translation)
// Binds this patch
//
//===========================================================================
unsigned int FHardwareTexture::Bind(int texunit, int translation, bool alphatexture)
unsigned int FHardwareTexture::Bind(int texunit, int translation, bool alphatexture, bool needmipmap)
{
if (alphatexture) translation = TRANS_Alpha;
unsigned int * pTexID=GetTexID(translation);
TranslatedTexture *pTex = GetTexID(translation);
if (*pTexID!=0)
if (pTex->glTexID != 0)
{
if (lastbound[texunit]==*pTexID) return *pTexID;
lastbound[texunit]=*pTexID;
if (lastbound[texunit] == pTex->glTexID) return pTex->glTexID;
lastbound[texunit] = pTex->glTexID;
if (texunit != 0) glActiveTexture(GL_TEXTURE0 + texunit);
glBindTexture(GL_TEXTURE_2D, *pTexID);
glBindTexture(GL_TEXTURE_2D, pTex->glTexID);
// Check if we need mipmaps on a texture that was creted without them.
if (needmipmap && !pTex->mipmapped && TexFilter[gl_texture_filter].mipmapping)
{
glGenerateMipmap(GL_TEXTURE_2D);
pTex->mipmapped = true;
}
if (texunit != 0) glActiveTexture(GL_TEXTURE0);
return *pTexID;
return pTex->glTexID;
}
return 0;
}
@ -445,25 +433,7 @@ int FHardwareTexture::GetDepthBuffer()
void FHardwareTexture::BindToFrameBuffer()
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTexID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTex.glTexID, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer());
}
//===========================================================================
//
// (re-)creates the texture
//
//===========================================================================
unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, bool wrap, int texunit, int translation, bool alphatexture)
{
if (alphatexture) translation = TRANS_Alpha;
unsigned int * pTexID=GetTexID(translation);
if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit);
LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP_TO_EDGE, alphatexture, texunit);
if (texunit != 0) glActiveTexture(GL_TEXTURE0);
return *pTexID;
}

View File

@ -33,23 +33,26 @@ enum
class FHardwareTexture
{
public:
enum
{
MAX_TEXTURES = 16
};
private:
struct TranslatedTexture
{
unsigned int glTexID;
int translation;
//int cm;
bool mipmapped;
void Delete();
};
public:
static unsigned int lastbound[MAX_TEXTURES];
static int lastactivetexture;
static bool supportsNonPower2;
static int max_texturesize;
static int GetTexDimension(int value);
@ -57,25 +60,20 @@ public:
private:
short texwidth, texheight;
//float scalexfac, scaleyfac;
bool mipmap;
BYTE clampmode;
bool forcenofiltering;
bool forcenocompression;
unsigned glDefTexID;
TArray<TranslatedTexture> glTexID_Translated;
TranslatedTexture glDefTex;
TArray<TranslatedTexture> glTex_Translated;
unsigned int glDepthID; // only used by camera textures
void LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit);
unsigned * GetTexID(int translation);
void LoadImage(unsigned char * buffer,int w, int h, TranslatedTexture *glTex, bool mipmap, bool alphatexture, int texunit);
TranslatedTexture * GetTexID(int translation);
int GetDepthBuffer();
void DeleteTexture(unsigned int texid);
void Resize(int width, int height, unsigned char *src_data, unsigned char *dst_data);
public:
FHardwareTexture(int w, int h, bool mip, bool wrap, bool nofilter, bool nocompress);
FHardwareTexture(int w, int h, bool nocompress);
~FHardwareTexture();
static void Unbind(int texunit);
@ -83,9 +81,8 @@ public:
void BindToFrameBuffer();
unsigned int Bind(int texunit, int translation=0, bool alphatexture = false);
unsigned int CreateTexture(unsigned char * buffer, int w, int h,bool wrap, int texunit, int translation=0, bool alphatexture = false);
void Resize(int _width, int _height) ;
unsigned int Bind(int texunit, int translation, bool alphatexture, bool needmipmap);
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, bool alphatexture);
void Clean(bool all);
};

View File

@ -53,11 +53,13 @@
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/data/gl_data.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_bitmap.h"
#include "gl/textures/gl_material.h"
#include "gl/textures/gl_samplers.h"
#include "gl/shaders/gl_shader.h"
EXTERN_CVAR(Bool, gl_render_precise)
@ -78,17 +80,16 @@ EXTERN_CVAR(Bool, gl_texture_usehires)
//===========================================================================
FGLTexture::FGLTexture(FTexture * tx, bool expandpatches)
{
assert(tx->gl_info.SystemTexture == NULL);
assert(tx->gl_info.SystemTexture[expandpatches] == NULL);
tex = tx;
glpatch=NULL;
for(int i=0;i<5;i++) gltexture[i]=NULL;
mHwTexture = NULL;
HiresLump = -1;
hirestexture = NULL;
bHasColorkey = false;
bIsTransparent = -1;
bExpand = expandpatches;
tex->gl_info.SystemTexture = this;
tex->gl_info.SystemTexture[expandpatches] = this;
}
//===========================================================================
@ -162,25 +163,13 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig
void FGLTexture::Clean(bool all)
{
for(int i=0;i<5;i++)
if (mHwTexture)
{
if (gltexture[i])
{
if (!all) gltexture[i]->Clean(false);
if (!all) mHwTexture->Clean(false);
else
{
delete gltexture[i];
gltexture[i]=NULL;
}
}
}
if (glpatch)
{
if (!all) glpatch->Clean(false);
else
{
delete glpatch;
glpatch=NULL;
delete mHwTexture;
mHwTexture = NULL;
}
}
}
@ -192,7 +181,7 @@ void FGLTexture::Clean(bool all)
//
//===========================================================================
unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, bool alphatexture)
unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool alphatexture)
{
unsigned char * buffer;
int W, H;
@ -209,8 +198,8 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b
}
}
W = w = tex->GetWidth() + expand*2;
H = h = tex->GetHeight() + expand*2;
W = w = tex->GetWidth() + bExpand*2;
H = h = tex->GetHeight() + bExpand*2;
buffer=new unsigned char[W*(H+1)*4];
@ -229,7 +218,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b
if (imgCreate.Create(W, H))
{
memset(imgCreate.GetPixels(), 0, W * H * 4);
int trans = tex->CopyTrueColorPixels(&imgCreate, expand, expand);
int trans = tex->CopyTrueColorPixels(&imgCreate, bExpand, bExpand);
bmp.CopyPixelDataRGB(0, 0, imgCreate.GetPixels(), W, H, 4, W * 4, 0, CF_BGRA);
tex->CheckTrans(buffer, W*H, trans);
bIsTransparent = tex->gl_info.mIsTransparent;
@ -237,7 +226,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b
}
else if (translation<=0)
{
int trans = tex->CopyTrueColorPixels(&bmp, expand, expand);
int trans = tex->CopyTrueColorPixels(&bmp, bExpand, bExpand);
tex->CheckTrans(buffer, W*H, trans);
bIsTransparent = tex->gl_info.mIsTransparent;
}
@ -246,7 +235,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b
// When using translations everything must be mapped to the base palette.
// Since FTexture's method is doing exactly that by calling GetPixels let's use that here
// to do all the dirty work for us. ;)
tex->FTexture::CopyTrueColorPixels(&bmp, expand, expand);
tex->FTexture::CopyTrueColorPixels(&bmp, bExpand, bExpand);
bIsTransparent = 0;
}
@ -262,64 +251,32 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b
//
//===========================================================================
FHardwareTexture *FGLTexture::CreateTexture(int clampmode)
FHardwareTexture *FGLTexture::CreateHwTexture()
{
if (tex->UseType==FTexture::TEX_Null) return NULL; // Cannot register a NULL texture
if (!gltexture[clampmode])
if (mHwTexture == NULL)
{
gltexture[clampmode] = new FHardwareTexture(tex->GetWidth(), tex->GetHeight(), true, true, false, tex->gl_info.bNoCompress);
mHwTexture = new FHardwareTexture(tex->GetWidth() + bExpand*2, tex->GetHeight() + bExpand*2, tex->gl_info.bNoCompress);
}
return gltexture[clampmode];
return mHwTexture;
}
//===========================================================================
//
// Create Hardware texture for patch use
//
//===========================================================================
bool FGLTexture::CreatePatch()
{
if (tex->UseType==FTexture::TEX_Null) return false; // Cannot register a NULL texture
if (!glpatch)
{
glpatch=new FHardwareTexture(tex->GetWidth() + bExpand, tex->GetHeight() + bExpand, false, false, tex->gl_info.bNoFilter, tex->gl_info.bNoCompress);
}
if (glpatch) return true;
return false;
}
//===========================================================================
//
// Binds a texture to the renderer
//
//===========================================================================
const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck)
const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, bool alphatexture, FTexture *hirescheck)
{
int usebright = false;
if (translation <= 0) translation = -translation;
else translation = GLTranslationPalette::GetInternalTranslation(translation);
FHardwareTexture *hwtex;
bool needmipmap = (clampmode <= CLAMP_XY);
if (gltexture[4] != NULL && clampmode < 4 && gltexture[clampmode] == NULL)
{
hwtex = gltexture[clampmode] = gltexture[4];
gltexture[4] = NULL;
if (hwtex->Bind(texunit, translation))
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (clampmode & GLT_CLAMPX)? GL_CLAMP_TO_EDGE : GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (clampmode & GLT_CLAMPY)? GL_CLAMP_TO_EDGE : GL_REPEAT);
}
}
else
{
hwtex = CreateTexture(clampmode);
}
FHardwareTexture *hwtex = CreateHwTexture();
if (hwtex)
{
@ -327,11 +284,11 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
if ((!tex->bHasCanvas && !tex->bWarped) && tex->CheckModified())
{
Clean(true);
hwtex = CreateTexture(clampmode);
hwtex = CreateHwTexture();
}
// Bind it to the system.
if (!hwtex->Bind(texunit, translation))
if (!hwtex->Bind(texunit, translation, alphatexture, needmipmap))
{
int w=0, h=0;
@ -341,73 +298,25 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
if (!tex->bHasCanvas)
{
buffer = CreateTexBuffer(translation, w, h, false, hirescheck);
buffer = CreateTexBuffer(translation, w, h, hirescheck, alphatexture);
tex->ProcessData(buffer, w, h, false);
}
if (!hwtex->CreateTexture(buffer, w, h, true, texunit, translation))
if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, alphatexture))
{
// could not create texture
delete[] buffer;
return NULL;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (clampmode & GLT_CLAMPX)? GL_CLAMP_TO_EDGE : GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (clampmode & GLT_CLAMPY)? GL_CLAMP_TO_EDGE : GL_REPEAT);
delete[] buffer;
}
if (tex->bHasCanvas) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
GLRenderer->mSamplerManager->Bind(texunit, clampmode);
return hwtex;
}
return NULL;
}
//===========================================================================
//
// Binds a sprite to the renderer
//
//===========================================================================
const FHardwareTexture * FGLTexture::BindPatch(int texunit, int translation, bool alphatexture)
{
bool usebright = false;
int transparm = translation;
if (translation <= 0) translation = -translation;
else translation = GLTranslationPalette::GetInternalTranslation(translation);
if (CreatePatch())
{
// Texture has become invalid - this is only for special textures, not the regular warping, which is handled above
if ((!tex->bHasCanvas && !tex->bWarped) && tex->CheckModified())
{
Clean(true);
CreatePatch();
}
// Bind it to the system.
if (!glpatch->Bind(texunit, translation, alphatexture))
{
int w, h;
// Create this texture
unsigned char * buffer = CreateTexBuffer(translation, w, h, bExpand, NULL, alphatexture);
tex->ProcessData(buffer, w, h, true);
if (!glpatch->CreateTexture(buffer, w, h, false, texunit, translation, alphatexture))
{
// could not create texture
delete[] buffer;
return NULL;
}
delete[] buffer;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
return glpatch;
}
return NULL;
}
//===========================================================================
//
//
@ -475,7 +384,7 @@ FGLTexture * FMaterial::ValidateSysTexture(FTexture * tex, bool expand)
{
if (tex && tex->UseType!=FTexture::TEX_Null)
{
FGLTexture *gltex = tex->gl_info.SystemTexture;
FGLTexture *gltex = tex->gl_info.SystemTexture[expand];
if (gltex == NULL)
{
gltex = new FGLTexture(tex, expand);
@ -493,15 +402,8 @@ FGLTexture * FMaterial::ValidateSysTexture(FTexture * tex, bool expand)
TArray<FMaterial *> FMaterial::mMaterials;
int FMaterial::mMaxBound;
FMaterial::FMaterial(FTexture * tx, bool forceexpand)
FMaterial::FMaterial(FTexture * tx, bool expanded)
{
assert(tx->gl_info.Material == NULL);
bool expanded = tx->UseType == FTexture::TEX_Sprite ||
tx->UseType == FTexture::TEX_SkinSprite ||
tx->UseType == FTexture::TEX_Decal ||
forceexpand;
mShaderIndex = 0;
// TODO: apply custom shader object here
@ -539,83 +441,62 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand)
}
}
}
assert(tx->gl_info.Material[expanded] == NULL);
mBaseLayer = ValidateSysTexture(tx, true);
for (int i=GLUSE_PATCH; i<=GLUSE_TEXTURE; i++)
{
Width[i] = tx->GetWidth();
Height[i] = tx->GetHeight();
LeftOffset[i] = tx->LeftOffset;
TopOffset[i] = tx->TopOffset;
RenderWidth[i] = tx->GetScaledWidth();
RenderHeight[i] = tx->GetScaledHeight();
}
Width[GLUSE_SPRITE] = Width[GLUSE_PATCH];
Height[GLUSE_SPRITE] = Height[GLUSE_PATCH];
LeftOffset[GLUSE_SPRITE] = LeftOffset[GLUSE_PATCH];
TopOffset[GLUSE_SPRITE] = TopOffset[GLUSE_PATCH];
SpriteU[0] = SpriteV[0] = 0;
spriteright = SpriteU[1] = Width[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Width[GLUSE_PATCH]);
spritebottom = SpriteV[1] = Height[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Height[GLUSE_PATCH]);
mWidth = tx->GetWidth();
mHeight = tx->GetHeight();
mLeftOffset = tx->LeftOffset;
mTopOffset = tx->TopOffset;
mRenderWidth = tx->GetScaledWidth();
mRenderHeight = tx->GetScaledHeight();
mSpriteU[0] = mSpriteV[0] = 0.f;
mSpriteU[1] = mSpriteV[1] = 1.f;
mTextureLayers.ShrinkToFit();
mMaxBound = -1;
mMaterials.Push(this);
tx->gl_info.Material = this;
if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0;
tex = tx;
tx->gl_info.mExpanded = expanded;
FTexture *basetex = tx->GetRedirect(false);
if (!expanded && !basetex->gl_info.mExpanded && basetex->UseType != FTexture::TEX_Sprite)
{
// check if the texture is just a simple redirect to a patch
// If so we should use the patch for texture creation to
// avoid eventual redundancies.
// This may only be done if both textures use the same expansion mode
// Redirects to sprites are not permitted because sprites get expanded, however, this won't have been set
// if the sprite hadn't been used yet.
mBaseLayer = ValidateSysTexture(basetex, false);
}
else if (!expanded)
{
// if we got a non-expanded texture that redirects to an expanded one
mBaseLayer = ValidateSysTexture(tx, false);
}
else
mBaseLayer = ValidateSysTexture(basetex, expanded);
// mSpriteRect is for positioning the sprite in the scene.
mSpriteRect.left = -mLeftOffset / FIXED2FLOAT(tx->xScale);
mSpriteRect.top = -mTopOffset / FIXED2FLOAT(tx->yScale);
mSpriteRect.width = mWidth / FIXED2FLOAT(tx->xScale);
mSpriteRect.height = mHeight / FIXED2FLOAT(tx->yScale);
if (expanded)
{
// a little adjustment to make sprites look better with texture filtering:
// create a 1 pixel wide empty frame around them.
RenderWidth[GLUSE_PATCH]+=2;
RenderHeight[GLUSE_PATCH]+=2;
Width[GLUSE_PATCH]+=2;
Height[GLUSE_PATCH]+=2;
LeftOffset[GLUSE_PATCH]+=1;
TopOffset[GLUSE_PATCH]+=1;
Width[GLUSE_SPRITE] += 2;
Height[GLUSE_SPRITE] += 2;
LeftOffset[GLUSE_SPRITE] += 1;
TopOffset[GLUSE_SPRITE] += 1;
spriteright = SpriteU[1] = Width[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Width[GLUSE_PATCH]);
spritebottom = SpriteV[1] = Height[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Height[GLUSE_PATCH]);
mBaseLayer = ValidateSysTexture(tx, true);
mWidth+=2;
mHeight+=2;
mLeftOffset+=1;
mTopOffset+=1;
mRenderWidth = mRenderWidth * mWidth / (mWidth-2);
mRenderHeight = mRenderHeight * mHeight / (mHeight-2);
int trim[4];
if (TrimBorders(trim))
{
Width[GLUSE_SPRITE] = trim[2] + 2;
Height[GLUSE_SPRITE] = trim[3] + 2;
LeftOffset[GLUSE_SPRITE] -= trim[0];
TopOffset[GLUSE_SPRITE] -= trim[1];
mSpriteRect.left = -(mLeftOffset - trim[0]) / FIXED2FLOAT(tx->xScale);
mSpriteRect.top = -(mTopOffset - trim[1]) / FIXED2FLOAT(tx->yScale);
mSpriteRect.width = (trim[2] + 2) / FIXED2FLOAT(tx->xScale);
mSpriteRect.height = (trim[3] + 2) / FIXED2FLOAT(tx->yScale);
SpriteU[0] = SpriteU[1] * (trim[0] / (float)Width[GLUSE_PATCH]);
SpriteV[0] = SpriteV[1] * (trim[1] / (float)Height[GLUSE_PATCH]);
SpriteU[1] *= (trim[0]+trim[2]+2) / (float)Width[GLUSE_PATCH];
SpriteV[1] *= (trim[1]+trim[3]+2) / (float)Height[GLUSE_PATCH];
mSpriteU[0] = trim[0] / (float)mWidth;
mSpriteV[0] = trim[1] / (float)mHeight;
mSpriteU[1] *= (trim[0]+trim[2]+2) / (float)mWidth;
mSpriteV[1] *= (trim[1]+trim[3]+2) / (float)mHeight;
}
}
mTextureLayers.ShrinkToFit();
mMaxBound = -1;
mMaterials.Push(this);
tx->gl_info.Material[expanded] = this;
if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0;
tex = tx;
mExpanded = expanded;
}
//===========================================================================
@ -657,7 +538,7 @@ bool FMaterial::TrimBorders(int *rect)
{
return false;
}
if (w != Width[GLUSE_TEXTURE] || h != Height[GLUSE_TEXTURE])
if (w != mWidth || h != mHeight)
{
// external Hires replacements cannot be trimmed.
delete [] buffer;
@ -730,20 +611,19 @@ outl:
//
//===========================================================================
void FMaterial::Bind(int clampmode, int translation, int overrideshader)
void FMaterial::Bind(int clampmode, int translation, int overrideshader, bool alphatexture)
{
int usebright = false;
int shaderindex = overrideshader > 0? overrideshader : mShaderIndex;
int maxbound = 0;
bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT;
bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT && clampmode <= CLAMP_XY && !mExpanded;
gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed);
if (tex->bHasCanvas || tex->bWarped) clampmode = 0;
else if (clampmode != -1) clampmode &= 3;
else clampmode = 4;
if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX;
else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL);
const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, alphatexture, allowhires? tex:NULL);
if (gltexture != NULL && shaderindex > 0 && overrideshader == 0)
{
for(unsigned i=0;i<mTextureLayers.Size();i++)
@ -753,13 +633,13 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader)
{
FTextureID id = mTextureLayers[i].texture->id;
layer = TexMan(id);
ValidateSysTexture(layer, false);
ValidateSysTexture(layer, mExpanded);
}
else
{
layer = mTextureLayers[i].texture;
}
layer->gl_info.SystemTexture->Bind(i+1, clampmode, 0, NULL);
layer->gl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, false, NULL);
maxbound = i+1;
}
}
@ -772,36 +652,6 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader)
}
//===========================================================================
//
// Binds a texture to the renderer
//
//===========================================================================
void FMaterial::BindPatch(int translation, int overrideshader, bool alphatexture)
{
int usebright = false;
int shaderindex = overrideshader > 0? overrideshader : mShaderIndex;
int maxbound = 0;
gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed);
const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, alphatexture);
// The only multitexture effect usable on sprites is the brightmap.
if (glpatch != NULL && shaderindex == 3)
{
mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, 0, false);
maxbound = 1;
}
// unbind everything from the last texture that's still active
for(int i=maxbound+1; i<=mMaxBound;i++)
{
FHardwareTexture::Unbind(i);
mMaxBound = maxbound;
}
}
//===========================================================================
//
//
@ -809,31 +659,12 @@ void FMaterial::BindPatch(int translation, int overrideshader, bool alphatexture
//===========================================================================
void FMaterial::Precache()
{
if (tex->UseType==FTexture::TEX_Sprite)
{
BindPatch(0);
}
else
{
int cached = 0;
for(int i=0;i<4;i++)
{
if (mBaseLayer->gltexture[i] != 0)
{
Bind (i, 0);
cached++;
}
if (cached == 0) Bind(-1, 0);
}
}
Bind(0, 0, 0, false);
}
//===========================================================================
//
// This function is needed here to temporarily manipulate the texture
// for per-wall scaling so that the coordinate functions return proper
// results. Doing this here is much easier than having the calling code
// make these calculations.
// Retrieve texture coordinate info for per-wall scaling
//
//===========================================================================
@ -841,14 +672,14 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const
{
if (x == FRACUNIT)
{
tci->mRenderWidth = RenderWidth[GLUSE_TEXTURE];
tci->mRenderWidth = mRenderWidth;
tci->mScaleX = tex->xScale;
tci->mTempScaleX = FRACUNIT;
}
else
{
fixed_t scale_x = FixedMul(x, tex->xScale);
int foo = (Width[GLUSE_TEXTURE] << 17) / scale_x;
int foo = (mWidth << 17) / scale_x;
tci->mRenderWidth = (foo >> 1) + (foo & 1);
tci->mScaleX = scale_x;
tci->mTempScaleX = x;
@ -856,14 +687,14 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const
if (y == FRACUNIT)
{
tci->mRenderHeight = RenderHeight[GLUSE_TEXTURE];
tci->mRenderHeight = mRenderHeight;
tci->mScaleY = tex->yScale;
tci->mTempScaleY = FRACUNIT;
}
else
{
fixed_t scale_y = FixedMul(y, tex->yScale);
int foo = (Height[GLUSE_TEXTURE] << 17) / scale_y;
int foo = (mHeight << 17) / scale_y;
tci->mRenderHeight = (foo >> 1) + (foo & 1);
tci->mScaleY = scale_y;
tci->mTempScaleY = y;
@ -874,7 +705,7 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const
tci->mRenderHeight = -tci->mRenderHeight;
}
tci->mWorldPanning = tex->bWorldPanning;
tci->mWidth = Width[GLUSE_TEXTURE];
tci->mWidth = mWidth;
}
//===========================================================================
@ -905,30 +736,15 @@ int FMaterial::GetAreas(FloatRect **pAreas) const
void FMaterial::BindToFrameBuffer()
{
if (mBaseLayer->gltexture[0] == NULL)
if (mBaseLayer->mHwTexture == NULL)
{
// must create the hardware texture first
mBaseLayer->Bind(0, 0, 0, NULL);
mBaseLayer->Bind(0, 0, 0, false, NULL);
FHardwareTexture::Unbind(0);
}
mBaseLayer->gltexture[0]->BindToFrameBuffer();
mBaseLayer->mHwTexture->BindToFrameBuffer();
}
//===========================================================================
//
// GetRect
//
//===========================================================================
void FMaterial::GetRect(FloatRect * r, ETexUse i) const
{
r->left = -GetScaledLeftOffsetFloat(i);
r->top = -GetScaledTopOffsetFloat(i);
r->width = GetScaledWidthFloat(i);
r->height = GetScaledHeightFloat(i);
}
//==========================================================================
//
// Gets a texture from the texture manager and checks its validity for
@ -936,24 +752,24 @@ void FMaterial::GetRect(FloatRect * r, ETexUse i) const
//
//==========================================================================
FMaterial * FMaterial::ValidateTexture(FTexture * tex)
FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand)
{
if (tex && tex->UseType!=FTexture::TEX_Null)
{
FMaterial *gltex = tex->gl_info.Material;
FMaterial *gltex = tex->gl_info.Material[expand];
if (gltex == NULL)
{
//@sync-tex
gltex = new FMaterial(tex, false);
gltex = new FMaterial(tex, expand);
}
return gltex;
}
return NULL;
}
FMaterial * FMaterial::ValidateTexture(FTextureID no, bool translate)
FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate)
{
return ValidateTexture(translate? TexMan(no) : TexMan[no]);
return ValidateTexture(translate? TexMan(no) : TexMan[no], expand);
}
@ -973,47 +789,11 @@ void FMaterial::FlushAll()
// so this will catch everything.
for(int i=TexMan.NumTextures()-1;i>=0;i--)
{
FGLTexture *gltex = TexMan.ByIndex(i)->gl_info.SystemTexture;
for (int j = 0; j < 2; j++)
{
FGLTexture *gltex = TexMan.ByIndex(i)->gl_info.SystemTexture[j];
if (gltex != NULL) gltex->Clean(true);
}
}
//==========================================================================
//
// Prints some texture info
//
//==========================================================================
int FGLTexture::Dump(int i)
{
int cnt = 0;
int lump = tex->GetSourceLump();
Printf(PRINT_LOG, "Texture '%s' (Index %d, Lump %d, Name '%s'):\n", tex->Name.GetChars(), i, lump, Wads.GetLumpFullName(lump));
if (hirestexture) Printf(PRINT_LOG, "\tHirestexture\n");
if (glpatch) Printf(PRINT_LOG, "\tPatch\n"),cnt++;
if (gltexture[0]) Printf(PRINT_LOG, "\tTexture (x:no, y:no )\n"),cnt++;
if (gltexture[1]) Printf(PRINT_LOG, "\tTexture (x:yes, y:no )\n"),cnt++;
if (gltexture[2]) Printf(PRINT_LOG, "\tTexture (x:no, y:yes)\n"),cnt++;
if (gltexture[3]) Printf(PRINT_LOG, "\tTexture (x:yes, y:yes)\n"),cnt++;
if (gltexture[4]) Printf(PRINT_LOG, "\tTexture precache\n"),cnt++;
return cnt;
}
CCMD(textureinfo)
{
int cnth = 0, cntt = 0, pix = 0;
for(int i=0; i<TexMan.NumTextures(); i++)
{
FTexture *tex = TexMan.ByIndex(i);
FGLTexture *systex = tex->gl_info.SystemTexture;
if (systex != NULL)
{
int cnt = systex->Dump(i);
cnth+=cnt;
cntt++;
pix += cnt * tex->GetWidth() * tex->GetHeight();
}
}
Printf(PRINT_LOG, "%d system textures, %d hardware textures, %d pixels\n", cntt, cnth, pix);
}

View File

@ -13,6 +13,17 @@ EXTERN_CVAR(Bool, gl_precache)
struct FRemapTable;
class FTextureShader;
enum
{
CLAMP_NONE = 0,
CLAMP_X = 1,
CLAMP_Y = 2,
CLAMP_XY = 3,
CLAMP_XY_NOMIP = 4,
CLAMP_NOFILTER = 5,
CLAMP_CAMTEX = 6,
};
struct FTexCoordInfo
@ -40,13 +51,6 @@ struct FTexCoordInfo
//===========================================================================
class FMaterial;
enum ETexUse
{
GLUSE_PATCH,
GLUSE_TEXTURE,
GLUSE_SPRITE,
};
class FGLTexture
{
@ -58,26 +62,23 @@ public:
int HiresLump;
private:
FHardwareTexture *gltexture[5];
FHardwareTexture *glpatch;
FHardwareTexture *mHwTexture;
bool bHasColorkey; // only for hires
bool bExpand;
unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture);
FHardwareTexture *CreateTexture(int clampmode);
//bool CreateTexture();
bool CreatePatch();
FHardwareTexture *CreateHwTexture();
const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck);
const FHardwareTexture *Bind(int texunit, int clamp, int translation, bool alphatexture, FTexture *hirescheck);
const FHardwareTexture *BindPatch(int texunit, int translation, bool alphatexture);
public:
FGLTexture(FTexture * tx, bool expandpatches);
~FGLTexture();
unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, bool alphatexture = false);
unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool alphatexture);
void Clean(bool all);
int Dump(int i);
@ -105,15 +106,16 @@ class FMaterial
TArray<FTextureLayer> mTextureLayers;
int mShaderIndex;
short LeftOffset[3];
short TopOffset[3];
short Width[3];
short Height[3];
short RenderWidth[2];
short RenderHeight[2];
short mLeftOffset;
short mTopOffset;
short mWidth;
short mHeight;
short mRenderWidth;
short mRenderHeight;
bool mExpanded;
float SpriteU[2], SpriteV[2];
float spriteright, spritebottom;
float mSpriteU[2], mSpriteV[2];
FloatRect mSpriteRect;
FGLTexture * ValidateSysTexture(FTexture * tex, bool expand);
bool TrimBorders(int *rect);
@ -129,12 +131,17 @@ public:
return !!mBaseLayer->tex->bMasked;
}
void Bind(int clamp = 0, int translation = 0, int overrideshader = 0);
void BindPatch(int translation = 0, int overrideshader = 0, bool alphatexture = false);
unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand = false, bool allowhires=true) const
int GetLayers() const
{
return mBaseLayer->CreateTexBuffer(translation, w, h, expand, allowhires? tex:NULL, 0);
return mTextureLayers.Size() + 1;
}
//void Bind(int clamp = 0, int translation = 0, int overrideshader = 0, bool alphatexture = false);
void Bind(int clamp, int translation, int overrideshader, bool alphatexture);
unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool allowhires=true) const
{
return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex:NULL, 0);
}
void Clean(bool f)
@ -145,78 +152,82 @@ public:
void BindToFrameBuffer();
// Patch drawing utilities
void GetRect(FloatRect *r, ETexUse i) const;
void GetSpriteRect(FloatRect * r) const
{
*r = mSpriteRect;
}
void GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const;
// This is scaled size in integer units as needed by walls and flats
int TextureHeight(ETexUse i) const { return RenderHeight[i]; }
int TextureWidth(ETexUse i) const { return RenderWidth[i]; }
int TextureHeight() const { return mRenderHeight; }
int TextureWidth() const { return mRenderWidth; }
int GetAreas(FloatRect **pAreas) const;
int GetWidth(ETexUse i) const
int GetWidth() const
{
return Width[i];
return mWidth;
}
int GetHeight(ETexUse i) const
int GetHeight() const
{
return Height[i];
return mHeight;
}
int GetLeftOffset(ETexUse i) const
int GetLeftOffset() const
{
return LeftOffset[i];
return mLeftOffset;
}
int GetTopOffset(ETexUse i) const
int GetTopOffset() const
{
return TopOffset[i];
return mTopOffset;
}
int GetScaledLeftOffset(ETexUse i) const
int GetScaledLeftOffset() const
{
return DivScale16(LeftOffset[i], tex->xScale);
return DivScale16(mLeftOffset, tex->xScale);
}
int GetScaledTopOffset(ETexUse i) const
int GetScaledTopOffset() const
{
return DivScale16(TopOffset[i], tex->yScale);
return DivScale16(mTopOffset, tex->yScale);
}
float GetScaledLeftOffsetFloat(ETexUse i) const
float GetScaledLeftOffsetFloat() const
{
return LeftOffset[i] / FIXED2FLOAT(tex->xScale);
return mLeftOffset / FIXED2FLOAT(tex->xScale);
}
float GetScaledTopOffsetFloat(ETexUse i) const
float GetScaledTopOffsetFloat() const
{
return TopOffset[i] / FIXED2FLOAT(tex->yScale);
return mTopOffset/ FIXED2FLOAT(tex->yScale);
}
// This is scaled size in floating point as needed by sprites
float GetScaledWidthFloat(ETexUse i) const
float GetScaledWidthFloat() const
{
return Width[i] / FIXED2FLOAT(tex->xScale);
return mWidth / FIXED2FLOAT(tex->xScale);
}
float GetScaledHeightFloat(ETexUse i) const
float GetScaledHeightFloat() const
{
return Height[i] / FIXED2FLOAT(tex->yScale);
return mHeight / FIXED2FLOAT(tex->yScale);
}
// Get right/bottom UV coordinates for patch drawing
float GetUL() const { return 0; }
float GetVT() const { return 0; }
float GetUR() const { return spriteright; }
float GetVB() const { return spritebottom; }
float GetU(float upix) const { return upix/(float)Width[GLUSE_PATCH] * spriteright; }
float GetV(float vpix) const { return vpix/(float)Height[GLUSE_PATCH] * spritebottom; }
float GetUR() const { return 1; }
float GetVB() const { return 1; }
float GetU(float upix) const { return upix/(float)mWidth; }
float GetV(float vpix) const { return vpix/(float)mHeight; }
float GetSpriteUL() const { return SpriteU[0]; }
float GetSpriteVT() const { return SpriteV[0]; }
float GetSpriteUR() const { return SpriteU[1]; }
float GetSpriteVB() const { return SpriteV[1]; }
float GetSpriteUL() const { return mSpriteU[0]; }
float GetSpriteVT() const { return mSpriteV[0]; }
float GetSpriteUR() const { return mSpriteU[1]; }
float GetSpriteVB() const { return mSpriteV[1]; }
@ -240,8 +251,8 @@ public:
static void DeleteAll();
static void FlushAll();
static FMaterial *ValidateTexture(FTexture * tex);
static FMaterial *ValidateTexture(FTextureID no, bool trans);
static FMaterial *ValidateTexture(FTexture * tex, bool expand);
static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans);
};

View File

@ -0,0 +1,112 @@
/*
** gl_samplers.cpp
**
**---------------------------------------------------------------------------
** Copyright 2014 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
** covered by the terms of the GNU Lesser General Public License as published
** by the Free Software Foundation; either version 2.1 of the License, or (at
** your option) any later version.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include "gl/system/gl_system.h"
#include "templates.h"
#include "c_cvars.h"
#include "c_dispatch.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_renderer.h"
#include "gl_samplers.h"
extern TexFilter_s TexFilter[];
FSamplerManager::FSamplerManager()
{
glGenSamplers(6, mSamplers);
SetTextureFilterMode();
glSamplerParameteri(mSamplers[5], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(mSamplers[5], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameterf(mSamplers[5], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameterf(mSamplers[4], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameterf(mSamplers[6], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
glSamplerParameteri(mSamplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[2], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
FSamplerManager::~FSamplerManager()
{
UnbindAll();
glDeleteSamplers(6, mSamplers);
}
void FSamplerManager::UnbindAll()
{
for (int i = 0; i < FHardwareTexture::MAX_TEXTURES; i++)
{
mLastBound[i] = 0;
glBindSampler(i, 0);
}
}
void FSamplerManager::Bind(int texunit, int num)
{
unsigned int samp = mSamplers[num];
//if (samp != mLastBound[texunit])
{
glBindSampler(texunit, samp);
mLastBound[texunit] = samp;
}
}
void FSamplerManager::SetTextureFilterMode()
{
UnbindAll();
for (int i = 0; i < 4; i++)
{
glSamplerParameteri(mSamplers[i], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter);
glSamplerParameteri(mSamplers[i], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter);
glSamplerParameterf(mSamplers[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic);
}
glSamplerParameteri(mSamplers[4], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter);
glSamplerParameteri(mSamplers[4], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter);
glSamplerParameteri(mSamplers[6], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter);
glSamplerParameteri(mSamplers[6], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter);
}

View File

@ -0,0 +1,28 @@
#ifndef __GL_SAMPLERS_H
#define __GL_SAMPLERS_H
#include "gl_hwtexture.h"
class FSamplerManager
{
// We need 6 different samplers: 4 for the different clamping modes,
// one for 2D-textures and one for voxel textures
unsigned int mSamplers[6];
unsigned int mLastBound[FHardwareTexture::MAX_TEXTURES];
void UnbindAll();
public:
FSamplerManager();
~FSamplerManager();
void Bind(int texunit, int num);
void SetTextureFilterMode();
};
#endif

View File

@ -132,9 +132,15 @@ void FSkyBox::Unload ()
//
//-----------------------------------------------------------------------------
void FSkyBox::PrecacheGL()
void FSkyBox::PrecacheGL(int cache)
{
//for(int i=0;i<6;i++) if (faces[i]) faces[i]->PrecacheGL();
for (int i = 0; i < 6; i++)
{
if (faces[i])
{
faces[i]->PrecacheGL(cache);
}
}
}
//-----------------------------------------------------------------------------

View File

@ -21,7 +21,7 @@ public:
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
bool UseBasePalette();
void Unload ();
void PrecacheGL();
void PrecacheGL(int cache);
void SetSize()
{

View File

@ -52,6 +52,7 @@
#include "gl/renderer/gl_renderer.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_material.h"
#include "gl/textures/gl_samplers.h"
//==========================================================================
//
@ -60,7 +61,7 @@
//==========================================================================
CUSTOM_CVAR(Float,gl_texture_filter_anisotropic,8.0f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
{
if (GLRenderer != NULL) GLRenderer->FlushTextures();
if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode();
}
CCMD(gl_flush)
@ -71,7 +72,7 @@ CCMD(gl_flush)
CUSTOM_CVAR(Int, gl_texture_filter, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
{
if (self < 0 || self > 5) self=4;
if (GLRenderer != NULL) GLRenderer->FlushTextures();
if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode();
}
CUSTOM_CVAR(Int, gl_texture_format, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
@ -235,37 +236,34 @@ FTexture::MiscGLInfo::MiscGLInfo() throw()
bBrightmapDisablesFullbright = false;
bNoFilter = false;
bNoCompress = false;
mExpanded = false;
areas = NULL;
areacount = 0;
mIsTransparent = -1;
shaderspeed = 1.f;
shaderindex = 0;
precacheTime = 0;
Material = NULL;
SystemTexture = NULL;
Material[1] = Material[0] = NULL;
SystemTexture[1] = SystemTexture[0] = NULL;
Brightmap = NULL;
DecalTexture = NULL;
}
FTexture::MiscGLInfo::~MiscGLInfo()
{
if (Material != NULL) delete Material;
Material = NULL;
for (int i = 0; i < 2; i++)
{
if (Material[i] != NULL) delete Material[i];
Material[i] = NULL;
if (SystemTexture != NULL) delete SystemTexture;
SystemTexture = NULL;
if (SystemTexture[i] != NULL) delete SystemTexture[i];
SystemTexture[i] = NULL;
}
// this is managed by the texture manager so it may not be deleted here.
//if (Brightmap != NULL) delete Brightmap;
// this is just a reference to another texture in the texture manager.
Brightmap = NULL;
if (areas != NULL) delete [] areas;
areas = NULL;
if (DecalTexture != NULL) delete DecalTexture;
DecalTexture = NULL;
}
//===========================================================================
@ -319,13 +317,22 @@ void FTexture::CreateDefaultBrightmap()
//
//==========================================================================
void FTexture::PrecacheGL()
void FTexture::PrecacheGL(int cache)
{
if (gl_precache)
{
FMaterial * gltex = FMaterial::ValidateTexture(this);
if (cache & 2)
{
FMaterial * gltex = FMaterial::ValidateTexture(this, false);
if (gltex) gltex->Precache();
}
if (cache & 4)
{
FMaterial * gltex = FMaterial::ValidateTexture(this, true);
if (gltex) gltex->Precache();
}
gl_info.precacheTime = TexMan.precacheTime;
}
}
//==========================================================================
@ -336,7 +343,12 @@ void FTexture::PrecacheGL()
void FTexture::UncacheGL()
{
if (gl_info.Material) gl_info.Material->Clean(true);
if (gl_info.precacheTime != TexMan.precacheTime)
{
if (gl_info.Material[0]) gl_info.Material[0]->Clean(true);
if (gl_info.Material[1]) gl_info.Material[1]->Clean(true);
gl_info.precacheTime = 0;
}
}
//==========================================================================
@ -640,49 +652,6 @@ int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotat
}
//===========================================================================
//
// A cloned texture. This is needed by the decal code which needs to assign
// a different texture type to some of its graphics.
//
//===========================================================================
FCloneTexture::FCloneTexture (FTexture *source, int usetype)
{
Name = "";
SourcePic = source;
CopySize(source);
bNoDecals = source->bNoDecals;
Rotations = source->Rotations;
UseType = usetype;
gl_info.bBrightmap = false;
id.SetInvalid();
SourceLump = -1;
}
FCloneTexture::~FCloneTexture ()
{
}
const BYTE *FCloneTexture::GetColumn (unsigned int column, const Span **spans_out)
{
return NULL;
}
const BYTE *FCloneTexture::GetPixels ()
{
return NULL;
}
void FCloneTexture::Unload ()
{
}
int FCloneTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
{
return SourcePic->CopyTrueColorPixels(bmp, x, y, rotate, inf);
}
//==========================================================================
//
// Parses a brightmap definition
@ -829,3 +798,42 @@ void gl_ParseDetailTexture(FScanner &sc)
}
}
//==========================================================================
//
// Prints some texture info
//
//==========================================================================
CCMD(textureinfo)
{
int cntt = 0;
for (int i = 0; i < TexMan.NumTextures(); i++)
{
FTexture *tex = TexMan.ByIndex(i);
if (tex->gl_info.SystemTexture[0] || tex->gl_info.SystemTexture[1] || tex->gl_info.Material[0] || tex->gl_info.Material[1])
{
int lump = tex->GetSourceLump();
Printf(PRINT_LOG, "Texture '%s' (Index %d, Lump %d, Name '%s'):\n", tex->Name, i, lump, Wads.GetLumpFullName(lump));
if (tex->gl_info.Material[0])
{
Printf(PRINT_LOG, "in use (normal)\n");
}
else if (tex->gl_info.SystemTexture[0])
{
Printf(PRINT_LOG, "referenced (normal)\n");
}
if (tex->gl_info.Material[1])
{
Printf(PRINT_LOG, "in use (expanded)\n");
}
else if (tex->gl_info.SystemTexture[1])
{
Printf(PRINT_LOG, "referenced (normal)\n");
}
cntt++;
}
}
Printf(PRINT_LOG, "%d system textures\n", cntt);
}

View File

@ -56,23 +56,6 @@ protected:
//Span **Spans;
};
class FCloneTexture : public FTexture
{
public:
FCloneTexture (FTexture *source, int usetype);
~FCloneTexture ();
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
const BYTE *GetPixels ();
void Unload ();
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
bool UseBasePalette() { return false; }
protected:
FTexture *SourcePic;
};
void gl_GenerateGlobalBrightmapFromColormap();
PalEntry averageColor(const DWORD *data, int size, fixed_t maxout);

View File

@ -1239,6 +1239,8 @@ void FTextureManager::PrecacheLevel (void)
if (demoplayback)
return;
precacheTime = I_MSTime();
hitlist = new BYTE[cnt];
memset (hitlist, 0, cnt);

View File

@ -329,10 +329,9 @@ public:
struct MiscGLInfo
{
FMaterial *Material;
FGLTexture *SystemTexture;
FMaterial *Material[2];
FGLTexture *SystemTexture[2];
FTexture *Brightmap;
FTexture *DecalTexture; // This is needed for decals of UseType TEX_MiscPatch-
PalEntry GlowColor;
PalEntry FloorSkyColor;
PalEntry CeilingSkyColor;
@ -340,6 +339,7 @@ public:
FloatRect *areas;
int areacount;
int shaderindex;
unsigned int precacheTime;
float shaderspeed;
int mIsTransparent:2;
bool bGlowing:1; // Texture glows
@ -351,14 +351,13 @@ public:
bool bBrightmapDisablesFullbright:1; // This disables fullbright display
bool bNoFilter:1;
bool bNoCompress:1;
bool mExpanded:1;
MiscGLInfo() throw ();
~MiscGLInfo();
};
MiscGLInfo gl_info;
virtual void PrecacheGL();
virtual void PrecacheGL(int cache);
virtual void UncacheGL();
void GetGlowColor(float *data);
PalEntry GetSkyCapColor(bool bottom);
@ -479,6 +478,8 @@ public:
FSwitchDef *FindSwitch (FTextureID texture);
FDoorAnimation *FindAnimatedDoor (FTextureID picnum);
unsigned int precacheTime;
private:
// texture counting

View File

@ -1245,7 +1245,7 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist)
FTextureID pic = frame->Texture[k];
if (pic.isValid())
{
hitlist[pic.GetIndex()] = 1;
hitlist[pic.GetIndex()] = 5;
}
}
}
@ -1264,7 +1264,7 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist)
{
hitlist[sides[i].GetTexture(side_t::top).GetIndex()] =
hitlist[sides[i].GetTexture(side_t::mid).GetIndex()] =
hitlist[sides[i].GetTexture(side_t::bottom).GetIndex()] |= 1;
hitlist[sides[i].GetTexture(side_t::bottom).GetIndex()] |= 3;
}
// Sky texture is always present.
@ -1276,11 +1276,11 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist)
if (sky1texture.isValid())
{
hitlist[sky1texture.GetIndex()] |= 1;
hitlist[sky1texture.GetIndex()] |= 3;
}
if (sky2texture.isValid())
{
hitlist[sky2texture.GetIndex()] |= 1;
hitlist[sky2texture.GetIndex()] |= 3;
}
}