diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dcaddff32..38cc45189 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index df6d8f88e..76835c737 100644 --- a/src/gl/models/gl_models_md2.cpp +++ b/src/gl/models/gl_models_md2.cpp @@ -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); diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index cb9bb6c25..d3f71af5c 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -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); diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index ffd2a65de..0ce907aa5 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -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); diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index effbec942..ec0680bbc 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -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); - u2=1.f; - v2=-1.f; - u1 = v1 = 0.f; + gltex->Bind(CLAMP_XY_NOMIP, 0, -1, false); + u1 = 0.f; + v1 = 1.f; + u2 = 1.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)); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 15c8a2e16..aee400def 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -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; diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 98101c987..db6d1ad7c 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -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 diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 8461a90eb..2cda1e396 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -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); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index f997e69da..0df465caf 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -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()) { diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 7c7efc91d..5e82dbd7b 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -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); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index afd9259f2..fb4de22ea 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -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(); } diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index b236f45d8..d208e6875 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -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; } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 583c6fc62..b12ada3fc 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -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(); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 4aa0f90bc..502264e20 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -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); } } diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index bcf0080d0..1a9e30a72 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -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)<TextureHeight()<GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling))+rowoffset; - texturebottom=texturetop-(gltexture->TextureHeight(GLUSE_TEXTURE)<TextureHeight()<>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) { diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 51bf5de18..5bb81fbe5 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -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; diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index d0f2ab370..67e2f9576 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -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))<GetScaledLeftOffset())<>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<GetScaledTopOffset(GLUSE_PATCH)<GetScaledTopOffset()<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) { diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 12e7c9e02..57ad3ba89 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -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); diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 697bcda4d..d076f6a3e 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -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;iglTexID != 0) { - if (lastbound[texunit]==*pTexID) return *pTexID; - lastbound[texunit]=*pTexID; - if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); - glBindTexture(GL_TEXTURE_2D, *pTexID); + if (lastbound[texunit] == pTex->glTexID) return pTex->glTexID; + lastbound[texunit] = pTex->glTexID; + if (texunit != 0) glActiveTexture(GL_TEXTURE0 + texunit); + 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; -} - - diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 4e13bc841..eabc7a6ef 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -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 glTexID_Translated; + TranslatedTexture glDefTex; + TArray 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); }; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 9ec948b37..443560c7f 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -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; - HiresLump=-1; + 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); - else - { - delete gltexture[i]; - gltexture[i]=NULL; - } - } - } - if (glpatch) - { - if (!all) glpatch->Clean(false); + if (!all) mHwTexture->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; - - if (gltexture[4] != NULL && clampmode < 4 && gltexture[clampmode] == NULL) - { - hwtex = gltexture[clampmode] = gltexture[4]; - gltexture[4] = NULL; + bool needmipmap = (clampmode <= CLAMP_XY); - 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(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::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;iid; 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; - 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; igl_info.SystemTexture; - if (systex != NULL) + for (int j = 0; j < 2; j++) { - int cnt = systex->Dump(i); - cnth+=cnt; - cntt++; - pix += cnt * tex->GetWidth() * tex->GetHeight(); + FGLTexture *gltex = TexMan.ByIndex(i)->gl_info.SystemTexture[j]; + if (gltex != NULL) gltex->Clean(true); } } - Printf(PRINT_LOG, "%d system textures, %d hardware textures, %d pixels\n", cntt, cnth, pix); } diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 259f881b4..714ab5a03 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -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 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); }; diff --git a/src/gl/textures/gl_samplers.cpp b/src/gl/textures/gl_samplers.cpp new file mode 100644 index 000000000..1eb54ff10 --- /dev/null +++ b/src/gl/textures/gl_samplers.cpp @@ -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); +} + + diff --git a/src/gl/textures/gl_samplers.h b/src/gl/textures/gl_samplers.h new file mode 100644 index 000000000..a9802674f --- /dev/null +++ b/src/gl/textures/gl_samplers.h @@ -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 + diff --git a/src/gl/textures/gl_skyboxtexture.cpp b/src/gl/textures/gl_skyboxtexture.cpp index 658eb2004..71f5be8f4 100644 --- a/src/gl/textures/gl_skyboxtexture.cpp +++ b/src/gl/textures/gl_skyboxtexture.cpp @@ -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); + } + } } //----------------------------------------------------------------------------- diff --git a/src/gl/textures/gl_skyboxtexture.h b/src/gl/textures/gl_skyboxtexture.h index a85e14190..ce58308a1 100644 --- a/src/gl/textures/gl_skyboxtexture.h +++ b/src/gl/textures/gl_skyboxtexture.h @@ -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() { diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index a864c7e3e..5725f831c 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -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,12 +317,21 @@ void FTexture::CreateDefaultBrightmap() // //========================================================================== -void FTexture::PrecacheGL() +void FTexture::PrecacheGL(int cache) { if (gl_precache) { - FMaterial * gltex = FMaterial::ValidateTexture(this); - if (gltex) gltex->Precache(); + 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); +} + diff --git a/src/gl/textures/gl_texture.h b/src/gl/textures/gl_texture.h index afb812ff0..a70ccebc5 100644 --- a/src/gl/textures/gl_texture.h +++ b/src/gl/textures/gl_texture.h @@ -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); diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index b8256bc65..b4df6a045 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1239,6 +1239,8 @@ void FTextureManager::PrecacheLevel (void) if (demoplayback) return; + precacheTime = I_MSTime(); + hitlist = new BYTE[cnt]; memset (hitlist, 0, cnt); diff --git a/src/textures/textures.h b/src/textures/textures.h index ff0e22c0c..df2707401 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -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 diff --git a/src/v_video.cpp b/src/v_video.cpp index fa94cd49f..c6994d974 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -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; } }