- use FMaterial.

This commit is contained in:
Christoph Oelckers 2020-05-30 21:45:17 +02:00
parent 423f758314
commit 58c62e071c
5 changed files with 127 additions and 107 deletions

View file

@ -307,7 +307,11 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
// Bind it to the system. // Bind it to the system.
if (!Bind(texunit, needmipmap)) if (!Bind(texunit, needmipmap))
{ {
if (flags & CTF_Indexed)
{
glTextureBytes = 1;
forcenofilter = true;
}
int w = 0, h = 0; int w = 0, h = 0;
// Create this texture // Create this texture
@ -331,7 +335,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
return false; return false;
} }
} }
if (forcenofilter) clampmode += CLAMP_NOFILTER - CLAMP_NONE; if (forcenofilter && clampmode <= CLAMP_XY) clampmode += CLAMP_NOFILTER - CLAMP_NONE;
GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255); GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255);
return true; return true;
} }

View file

@ -70,6 +70,23 @@ struct FDepthBiasState
} }
}; };
struct FMaterialState
{
FMaterial* mMaterial;
int mClampMode;
int mTranslation;
int mOverrideShader;
bool mChanged;
void Reset()
{
mMaterial = nullptr;
mTranslation = 0;
mClampMode = CLAMP_NONE;
mOverrideShader = -1;
mChanged = false;
}
};
struct PolymostRenderState struct PolymostRenderState
{ {
@ -89,6 +106,7 @@ struct PolymostRenderState
PalEntry fullscreenTint = 0xffffff, hictint = 0xffffff, hictint_overlay = 0xffffff; PalEntry fullscreenTint = 0xffffff, hictint = 0xffffff, hictint_overlay = 0xffffff;
int hictint_flags = -1; int hictint_flags = -1;
FDepthBiasState mBias{ }; FDepthBiasState mBias{ };
FMaterialState mMaterial;
OpenGLRenderer::FHardwareTexture* PaletteTexture = nullptr, * LookupTexture = nullptr; OpenGLRenderer::FHardwareTexture* PaletteTexture = nullptr, * LookupTexture = nullptr;
int StateFlags = STF_COLORMASK|STF_DEPTHMASK; int StateFlags = STF_COLORMASK|STF_DEPTHMASK;
@ -97,9 +115,9 @@ struct PolymostRenderState
PalEntry ClearColor = 0; PalEntry ClearColor = 0;
short vp_x, vp_y, vp_w, vp_h; short vp_x, vp_y, vp_w, vp_h;
short sc_x = SHRT_MIN, sc_y, sc_w, sc_h; short sc_x = SHRT_MIN, sc_y, sc_w, sc_h;
int texIds[4], samplerIds[4];
PalEntry FogColor; PalEntry FogColor;
void ApplyMaterial(FMaterial* mat, int clampmode, int translation, int overrideshader);
void Apply(PolymostShader *shader, GLState &oldstate); void Apply(PolymostShader *shader, GLState &oldstate);
}; };

View file

@ -63,113 +63,39 @@ OpenGLRenderer::FHardwareTexture* GLInstance::LoadTexture(FTexture *tex, int tex
bool GLInstance::SetTexture(int picnum, FGameTexture* tex, int paletteid, int method, int sampleroverride) bool GLInstance::SetTexture(int picnum, FGameTexture* tex, int paletteid, int method, int sampleroverride)
{ {
TexturePick pick; TexturePick texpick;
if (!PickTexture(picnum, tex, paletteid, pick)) return false; if (!PickTexture(picnum, tex, paletteid, texpick)) return false;
GLInterface.SetPalette(GetTranslationType(pick.translation & 0x7fffffff) - Translation_Remap); int TextureType = (texpick.translation & 0x80000000) ? TT_INDEXED : TT_TRUECOLOR;
GLInterface.SetPalswap(GetTranslationIndex(pick.translation));
GLInterface.SetBasepalTint(pick.basepalTint);
bool texbound[3] = {};
//int MatrixChange = 0;
//VSMatrix texmat;
// This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors.
GLInterface.SetTinting(pick.tintFlags, pick.tintColor, pick.tintColor);
// Load the main texture
int TextureType = (pick.translation & 0x80000000) ? TT_INDEXED : TT_TRUECOLOR;
int lookuppal = pick.translation & 0x7fffffff;
int bindflags = 0;
auto mtex = LoadTexture(tex->GetTexture(), TextureType, lookuppal);
if (mtex)
{
auto sampler = (method & DAMETH_CLAMPED) ? (sampleroverride != -1 ? sampleroverride : SamplerClampXY) : SamplerRepeat; auto sampler = (method & DAMETH_CLAMPED) ? (sampleroverride != -1 ? sampleroverride : SamplerClampXY) : SamplerRepeat;
if (TextureType == TT_INDEXED) if (TextureType == TT_INDEXED)
{ {
sampler = sampler + SamplerNoFilterRepeat - SamplerRepeat; sampler = sampler + SamplerNoFilterRepeat - SamplerRepeat;
bindflags = CTF_Indexed;
} }
else if (tex->isHardwareCanvas()) else if (tex->isHardwareCanvas())
{ {
sampler = CLAMP_CAMTEX; sampler = CLAMP_CAMTEX;
} }
UseDetailMapping(false);
UseGlowMapping(false);
UseBrightmaps(false);
mtex->BindOrCreate(tex->GetTexture(), 0, sampler, lookuppal, bindflags); int lookuppal = texpick.translation & 0x7fffffff;
BindTexture(0, mtex, sampler);
// Needs a) testing and b) verification for correctness. This doesn't look like it makes sense.
#if 0
if (rep && (rep->scale.x != 1.0f || rep->scale.y != 1.0f))
{
//texmat.loadIdentity();
//texmat.scale(rep->scale.x, rep->scale.y, 1.0f);
//GLInterface.SetMatrix(Matrix_Texture, &texmat);
}
#endif
// Also load additional layers needed for this texture.
if (hw_detailmapping)
{
auto det = tex->GetDetailmap();
auto detscale = tex->GetDetailScale();
if (det)
{
auto htex = LoadTexture(det, TT_TRUECOLOR, 0);
UseDetailMapping(true);
htex->BindOrCreate(det, 2, CLAMP_NONE, 0, 0);
BindTexture(2, htex, SamplerRepeat);
texbound[0] = true;
/* todo:
GLInterface.SetDetailScale(detscale);
*/
}
}
if (hw_glowmapping)
{
auto glow = tex->GetGlowmap();
if (glow)
{
auto htex = LoadTexture(glow, TT_TRUECOLOR, 0);
UseGlowMapping(true);
htex->BindOrCreate(glow, 3, sampler, 0, CTF_Upscale);
BindTexture(3, htex, SamplerRepeat);
texbound[1] = true;
}
}
if (!(globalflags & GLOBAL_NO_GL_FULLBRIGHT))
{
auto btex = tex->GetBrightmap();
if (btex)
{
auto htex = LoadTexture(btex, TT_TRUECOLOR, lookuppal);
if (htex != nullptr)
{
UseBrightmaps(true);
htex->BindOrCreate(btex, 1, sampler, 0, CTF_Upscale);
BindTexture(1, htex, sampler);
texbound[2] = true;
}
}
}
if (!texbound[0]) UnbindTexture(2);
if (!texbound[1]) UnbindTexture(3);
if (!texbound[2]) UnbindTexture(1);
}
else return false;
// This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors.
GLInterface.SetTinting(texpick.tintFlags, texpick.tintColor, texpick.tintColor);
GLInterface.SetPalette(GetTranslationType(lookuppal) - Translation_Remap);
GLInterface.SetPalswap(GetTranslationIndex(lookuppal));
GLInterface.SetBasepalTint(texpick.basepalTint);
auto &mat = renderState.mMaterial;
mat.mMaterial = FMaterial::ValidateTexture(tex, 0); // todo allow scaling
mat.mClampMode = sampler;
mat.mTranslation = texpick.translation;
mat.mOverrideShader = 0;
mat.mChanged = true;
if (TextureType == TT_INDEXED) renderState.Flags |= RF_UsePalette;
else renderState.Flags &= ~RF_UsePalette;
GLInterface.SetAlphaThreshold(tex->alphaThreshold); GLInterface.SetAlphaThreshold(tex->alphaThreshold);
return true; return true;
} }
//=========================================================================== //===========================================================================
// //
// stand-ins for the texture system. Nothing of this is used right now, but needs to be present to satisfy the linker // stand-ins for the texture system. Nothing of this is used right now, but needs to be present to satisfy the linker

View file

@ -284,26 +284,78 @@ void GLInstance::DrawImGui(ImDrawData* data)
} }
//===========================================================================
//
// Binds a texture to the renderer
//
//===========================================================================
void PolymostRenderState::ApplyMaterial(FMaterial* mat, int clampmode, int translation, int overrideshader)
{
auto tex = mat->Source();
//mEffectState = overrideshader >= 0 ? overrideshader : mat->GetShaderIndex();
//mShaderTimer = tex->GetShaderSpeed();
//SetSpecular(tex->GetGlossiness(), tex->GetSpecularLevel());
//if (tex->isHardwareCanvas()) static_cast<FCanvasTexture*>(tex->GetTexture())->NeedUpdate();
clampmode = tex->GetClampMode(clampmode);
// avoid rebinding the same texture multiple times.
//if (mat == lastMaterial && lastClamp == clampmode && translation == lastTranslation) return;
#if 0
lastMaterial = mat;
lastClamp = clampmode;
lastTranslation = translation;
#endif
int scf = 0;
if (Flags & RF_UsePalette)
{
scf |= CTF_Indexed;
translation = -1;
}
int usebright = false;
int maxbound = 0;
int numLayers = mat->NumLayers();
MaterialLayerInfo* layer;
auto base = static_cast<OpenGLRenderer::FHardwareTexture*>(mat->GetLayer(0, translation, &layer));
scf |= layer->scaleFlags;
if (base->BindOrCreate(layer->layerTexture, 0, clampmode, translation, scf))
{
for (int i = 1; i < numLayers; i++)
{
auto systex = static_cast<OpenGLRenderer::FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
// fixme: Upscale flags must be disabled for certain layers.
systex->BindOrCreate(layer->layerTexture, i, clampmode, 0, layer->scaleFlags);
maxbound = i;
}
}
// The palette lookup must be done manually.
#if 0
// unbind everything from the last texture that's still active
for (int i = maxbound + 1; i <= 16/*maxBoundMaterial*/; i++)
{
OpenGLRenderer::FHardwareTexture::Unbind(i);
//maxBoundMaterial = maxbound;
}
#endif
}
void PolymostRenderState::Apply(PolymostShader* shader, GLState &oldState) void PolymostRenderState::Apply(PolymostShader* shader, GLState &oldState)
{ {
if (!OpenGLRenderer::GLRenderer) return; if (!OpenGLRenderer::GLRenderer) return;
auto sm = OpenGLRenderer::GLRenderer->mSamplerManager; auto sm = OpenGLRenderer::GLRenderer->mSamplerManager;
bool reset = false; bool reset = false;
for (int i = 0; i < MAX_TEXTURES; i++) if (mMaterial.mChanged)
{ {
if ( texIds[i] != oldState.TexId[i] || samplerIds[i] != oldState.SamplerId[i]) mMaterial.mChanged = false;
{ ApplyMaterial(mMaterial.mMaterial, mMaterial.mClampMode, mMaterial.mTranslation, mMaterial.mOverrideShader);
if (i != 0)
{
glActiveTexture(GL_TEXTURE0 + i);
reset = true;
}
glBindTexture(GL_TEXTURE_2D, texIds[i]);
sm->Bind(i, samplerIds[i], -1);
oldState.TexId[i] = texIds[i];
oldState.SamplerId[i] = samplerIds[i];
}
} }
if (PaletteTexture != nullptr) if (PaletteTexture != nullptr)
{ {
PaletteTexture->Bind(4, false); PaletteTexture->Bind(4, false);

View file

@ -9,6 +9,7 @@
#include "matrix.h" #include "matrix.h"
#include "palentry.h" #include "palentry.h"
#include "renderstyle.h" #include "renderstyle.h"
#include "hw_material.h"
class FShader; class FShader;
class PolymostShader; class PolymostShader;
@ -352,6 +353,24 @@ public:
SetColor(r * (1 / 255.f), g * (1 / 255.f), b * (1 / 255.f), a * (1 / 255.f)); SetColor(r * (1 / 255.f), g * (1 / 255.f), b * (1 / 255.f), a * (1 / 255.f));
} }
void SetMaterial(FMaterial* mat, int clampmode, int translation, int overrideshader)
{
assert(mat);
renderState.mMaterial.mMaterial = mat;
renderState.mMaterial.mClampMode = clampmode;
renderState.mMaterial.mTranslation = translation;
renderState.mMaterial.mOverrideShader = overrideshader;
renderState.mMaterial.mChanged = true;
//mTextureModeFlags = mat->GetLayerFlags();
}
void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader)
{
assert(tex);
if (shouldUpscale(tex, upscalemask)) scaleflags |= CTF_Upscale;
SetMaterial(FMaterial::ValidateTexture(tex, scaleflags), clampmode, translation, overrideshader);
}
#if 0
void BindTexture(int texunit, OpenGLRenderer::FHardwareTexture* tex, int sampler) void BindTexture(int texunit, OpenGLRenderer::FHardwareTexture* tex, int sampler)
{ {
if (!tex) return; if (!tex) return;
@ -379,6 +398,7 @@ public:
UnbindTexture(texunit); UnbindTexture(texunit);
} }
} }
#endif
void UseColorOnly(bool yes) void UseColorOnly(bool yes)
{ {