Merge branch 'master' into modern

# Conflicts:
#	src/gl/renderer/gl_renderer.cpp
#	src/gl/renderer/gl_renderer.h
#	src/gl/renderer/gl_renderstate.h
#	src/gl/system/gl_framebuffer.cpp
#	src/gl/system/gl_framebuffer.h
This commit is contained in:
Christoph Oelckers 2018-07-14 13:18:34 +02:00
commit 33ee0f3c27
15 changed files with 205 additions and 138 deletions

View File

@ -260,6 +260,26 @@ sector_t *FGLRenderer::RenderView(player_t* player)
return retsec;
}
//===========================================================================
//
//
//
//===========================================================================
void FGLRenderer::BindToFrameBuffer(FMaterial *mat)
{
auto BaseLayer = static_cast<FHardwareTexture*>(mat->GetLayer(0));
if (BaseLayer == nullptr)
{
// must create the hardware texture first
BaseLayer->BindOrCreate(mat->sourcetex, 0, 0, 0, 0);
FHardwareTexture::Unbind(0);
gl_RenderState.ClearLastMaterial();
}
BaseLayer->BindToFrameBuffer(mat->GetWidth(), mat->GetHeight());
}
//===========================================================================
//
// Camera texture rendering
@ -274,7 +294,7 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
int height = gltex->TextureHeight();
StartOffscreen();
gltex->BindToFrameBuffer();
BindToFrameBuffer(gltex);
IntRect bounds;
bounds.left = bounds.top = 0;

View File

@ -116,9 +116,7 @@ public:
bool StartOffscreen();
void EndOffscreen();
void FillSimplePoly(FTexture *texture, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip);
void BindToFrameBuffer(FMaterial *mat);
};
#include "hwrenderer/scene/hw_fakeflat.h"

View File

@ -36,6 +36,7 @@
#include "gl/renderer/gl_renderer.h"
#include "gl/dynlights//gl_lightbuffer.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/textures/gl_hwtexture.h"
void gl_SetTextureMode(int type);
@ -288,3 +289,62 @@ void FRenderState::ApplyLightIndex(int index)
}
activeShader->muLightIndex.Set(index);
}
//===========================================================================
//
// Binds a texture to the renderer
//
//===========================================================================
void FRenderState::SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture)
{
if (mat->tex->bHasCanvas)
{
mTempTM = TM_OPAQUE;
}
else
{
mTempTM = TM_MODULATE;
}
mEffectState = overrideshader >= 0 ? overrideshader : mat->mShaderIndex;
mShaderTimer = mat->tex->shaderspeed;
SetSpecular(mat->tex->Glossiness, mat->tex->SpecularLevel);
// avoid rebinding the same texture multiple times.
if (mat == lastMaterial && lastClamp == clampmode && translation == lastTranslation) return;
lastMaterial = mat;
lastClamp = clampmode;
lastTranslation = translation;
int usebright = false;
int maxbound = 0;
auto tex = mat->tex;
if (tex->UseType == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER;
if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX;
else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0;
int numLayers = mat->GetLayers();
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0));
if (base->BindOrCreate(tex, 0, clampmode, translation, flags))
{
for (int i = 1; i<numLayers; i++)
{
FTexture *layer;
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, &layer));
systex->BindOrCreate(layer, i, clampmode, 0, mat->isExpanded() ? CTF_Expand : 0);
maxbound = i;
}
}
// unbind everything from the last texture that's still active
for (int i = maxbound + 1; i <= maxBoundMaterial; i++)
{
FHardwareTexture::Unbind(i);
maxBoundMaterial = maxbound;
}
}

View File

@ -124,6 +124,13 @@ class FRenderState
bool ApplyShader();
// Texture binding state
FMaterial *lastMaterial = nullptr;
int lastClamp = 0;
int lastTranslation = 0;
int maxBoundMaterial = -1;
public:
VSMatrix mModelMatrix;
@ -136,22 +143,13 @@ public:
void Reset();
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture)
void ClearLastMaterial()
{
if (mat->tex->bHasCanvas)
{
mTempTM = TM_OPAQUE;
}
else
{
mTempTM = TM_MODULATE;
}
mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex;
mShaderTimer = mat->tex->shaderspeed;
SetSpecular(mat->tex->Glossiness, mat->tex->SpecularLevel);
mat->Bind(clampmode, translation);
lastMaterial = nullptr;
}
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture);
void Apply();
void ApplyColorMask();
void ApplyLightIndex(int index);

View File

@ -488,6 +488,8 @@ static const FDefaultShader defaultshaders[]=
};
TArray<FString> usershaders;
TArray<FString> usermaterials;
TArray<FString> usershaderdefs;
struct FEffectShader
{
@ -609,7 +611,7 @@ void FShaderCollection::CompileShaders(EPassType passType)
FString name = ExtractFileBase(usershaders[i]);
FName sfn = name;
FShader *shc = Compile(sfn, usershaders[i], "shaders/glsl/material_normal.fp", "", true, passType);
FShader *shc = Compile(sfn, usershaders[i], usermaterials[i], usershaderdefs[i], true, passType);
mMaterialShaders.Push(shc);
}

View File

@ -73,7 +73,6 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, bool fullscreen) :
// Make sure all global variables tracking OpenGL context state are reset..
FHardwareTexture::InitGlobalState();
FMaterial::InitGlobalState();
gl_RenderState.Reset();
GLRenderer = new FGLRenderer(this);
@ -339,6 +338,11 @@ IHardwareTexture *OpenGLFrameBuffer::CreateHardwareTexture(FTexture *tex)
return new FHardwareTexture(tex->bNoCompress);
}
void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
{
gl_RenderState.SetMaterial(mat, CLAMP_NONE, translation, false, false);
}
FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli)
{
return new FGLModelRenderer(nullptr, mli);
@ -355,11 +359,6 @@ IShaderProgram *OpenGLFrameBuffer::CreateShaderProgram()
}
void OpenGLFrameBuffer::UnbindTexUnit(int no)
{
FHardwareTexture::Unbind(no);
}
void OpenGLFrameBuffer::TextureFilterChanged()
{
if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode();

View File

@ -35,8 +35,8 @@ public:
sector_t *RenderView(player_t *player) override;
void SetTextureFilterMode() override;
IHardwareTexture *CreateHardwareTexture(FTexture *tex) override;
void PrecacheMaterial(FMaterial *mat, int translation) override;
FModelRenderer *CreateModelRenderer(int mli) override;
void UnbindTexUnit(int no) override;
void TextureFilterChanged() override;
void BeginFrame() override;
void SetViewportRects(IntRect *bounds) override;

View File

@ -223,7 +223,7 @@ void OpenGLFrameBuffer::WipeCleanup()
delete wipeendscreen;
wipeendscreen = NULL;
}
FMaterial::ClearLastTexture();
gl_RenderState.ClearLastMaterial();
}
//==========================================================================

View File

@ -36,6 +36,7 @@
#include "hwrenderer/utility/hw_cvars.h"
#include "gl/system/gl_debug.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/textures/gl_samplers.h"
@ -469,7 +470,7 @@ void FHardwareTexture::UnbindAll()
{
Unbind(texunit);
}
FMaterial::ClearLastTexture();
gl_RenderState.ClearLastMaterial();
}
//===========================================================================

View File

@ -21,8 +21,6 @@ public:
IHardwareTexture() {}
virtual ~IHardwareTexture() {}
virtual void BindToFrameBuffer(int w, int h) = 0;
virtual bool BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags) = 0;
virtual void AllocateBuffer(int w, int h, int texelsize) = 0;
virtual uint8_t *MapBuffer() = 0;
virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) = 0;

View File

@ -154,6 +154,12 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
{
if (tx->shaderindex >= FIRST_USER_SHADER)
{
for (auto &texture : tx->CustomShaderTextures)
{
if(texture == nullptr) continue;
ValidateSysTexture(texture, expanded);
mTextureLayers.Push(texture);
}
mShaderIndex = tx->shaderindex;
}
else
@ -163,7 +169,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
for (auto &texture : { tx->Normal, tx->Specular })
{
ValidateSysTexture(texture, expanded);
mTextureLayers.Push({ texture, false });
mTextureLayers.Push(texture);
}
mShaderIndex = SHADER_Specular;
}
@ -172,7 +178,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
for (auto &texture : { tx->Normal, tx->Metallic, tx->Roughness, tx->AmbientOcclusion })
{
ValidateSysTexture(texture, expanded);
mTextureLayers.Push({ texture, false });
mTextureLayers.Push(texture);
}
mShaderIndex = SHADER_PBR;
}
@ -181,8 +187,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
if (tx->Brightmap != NULL)
{
ValidateSysTexture(tx->Brightmap, expanded);
FTextureLayer layer = {tx->Brightmap, false};
mTextureLayers.Push(layer);
mTextureLayers.Push(tx->Brightmap);
if (mShaderIndex == SHADER_Specular)
mShaderIndex = SHADER_SpecularBrightmap;
else if (mShaderIndex == SHADER_PBR)
@ -402,70 +407,6 @@ outl:
return true;
}
//===========================================================================
//
// Binds a texture to the renderer
//
//===========================================================================
static FMaterial *last;
static int lastclamp;
static int lasttrans;
void FMaterial::InitGlobalState()
{
last = nullptr;
lastclamp = 0;
lasttrans = 0;
}
void FMaterial::Bind(int clampmode, int translation)
{
// avoid rebinding the same texture multiple times.
if (this == last && lastclamp == clampmode && translation == lasttrans) return;
last = this;
lastclamp = clampmode;
lasttrans = translation;
int usebright = false;
int maxbound = 0;
if (tex->UseType == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER;
if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX;
else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
int flags = mExpanded? CTF_Expand : (gl_texture_usehires && tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY)? CTF_CheckHires : 0;
if (mBaseLayer->BindOrCreate(tex, 0, clampmode, translation, flags))
{
for(unsigned i=0;i<mTextureLayers.Size();i++)
{
FTexture *layer;
if (mTextureLayers[i].animated)
{
FTextureID id = mTextureLayers[i].texture->id;
layer = TexMan(id);
}
else
{
layer = mTextureLayers[i].texture;
}
auto systex = ValidateSysTexture(layer, mExpanded);
systex->BindOrCreate(layer, i+1, clampmode, 0, mExpanded ? CTF_Expand : 0);
maxbound = i+1;
}
}
// unbind everything from the last texture that's still active
for(int i=maxbound+1; i<=mMaxBound;i++)
{
screen->UnbindTexUnit(i);
mMaxBound = maxbound;
}
}
//===========================================================================
//
//
@ -473,7 +414,7 @@ void FMaterial::Bind(int clampmode, int translation)
//===========================================================================
void FMaterial::Precache()
{
Bind(0, 0);
screen->PrecacheMaterial(this, 0);
}
//===========================================================================
@ -486,7 +427,7 @@ void FMaterial::PrecacheList(SpriteHits &translations)
if (mBaseLayer != nullptr) mBaseLayer->CleanUnused(translations);
SpriteHits::Iterator it(translations);
SpriteHits::Pair *pair;
while(it.NextPair(pair)) Bind(0, pair->Key);
while(it.NextPair(pair)) screen->PrecacheMaterial(this, pair->Key);
}
//===========================================================================
@ -552,24 +493,6 @@ int FMaterial::GetAreas(FloatRect **pAreas) const
}
}
//===========================================================================
//
//
//
//===========================================================================
void FMaterial::BindToFrameBuffer()
{
if (mBaseLayer == nullptr)
{
// must create the hardware texture first
mBaseLayer->BindOrCreate(sourcetex, 0, 0, 0, 0);
screen->UnbindTexUnit(0);
ClearLastTexture();
}
mBaseLayer->BindToFrameBuffer(mWidth, mHeight);
}
//==========================================================================
//
// Gets a texture from the texture manager and checks its validity for
@ -641,11 +564,6 @@ void FMaterial::FlushAll()
}
}
void FMaterial::ClearLastTexture()
{
last = NULL;
}
void FMaterial::Clean(bool f)
{
// This somehow needs to deal with the other layers as well, but they probably need some form of reference counting to work properly...

View File

@ -52,12 +52,6 @@ class FMaterial
{
friend class FRenderState;
struct FTextureLayer
{
FTexture *texture;
bool animated;
};
// This array is needed because not all textures are managed by the texture manager
// but some code needs to discard all hardware dependent data attached to any created texture.
// Font characters are not, for example.
@ -65,7 +59,7 @@ class FMaterial
static int mMaxBound;
IHardwareTexture *mBaseLayer;
TArray<FTextureLayer> mTextureLayers;
TArray<FTexture*> mTextureLayers;
int mShaderIndex;
short mLeftOffset;
@ -81,7 +75,6 @@ class FMaterial
float mSpriteU[2], mSpriteV[2];
FloatRect mSpriteRect;
IHardwareTexture * ValidateSysTexture(FTexture * tex, bool expand);
bool TrimBorders(uint16_t *rect);
public:
@ -93,27 +86,44 @@ public:
void SetSpriteRect();
void Precache();
void PrecacheList(SpriteHits &translations);
IHardwareTexture * ValidateSysTexture(FTexture * tex, bool expand);
void AddTextureLayer(FTexture *tex)
{
FTextureLayer layer = { tex, false };
ValidateTexture(tex, false);
mTextureLayers.Push(layer);
mTextureLayers.Push(tex);
}
bool isMasked() const
{
return !!sourcetex->bMasked;
}
bool isExpanded() const
{
return mExpanded;
}
int GetLayers() const
{
return mTextureLayers.Size() + 1;
}
void Bind(int clamp, int translation);
IHardwareTexture *GetLayer(int i, FTexture **pLayer = nullptr)
{
if (i == 0)
{
if (pLayer) *pLayer = tex;
return mBaseLayer;
}
else
{
i--;
FTexture *layer = mTextureLayers[i];
if (pLayer) *pLayer = layer;
return ValidateSysTexture(layer, isExpanded());
}
}
void Clean(bool f);
void BindToFrameBuffer();
// Patch drawing utilities
void GetSpriteRect(FloatRect * r) const
@ -172,9 +182,6 @@ public:
static void FlushAll();
static FMaterial *ValidateTexture(FTexture * tex, bool expand);
static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans);
static void ClearLastTexture();
static void InitGlobalState();
};
#endif

View File

@ -51,6 +51,8 @@ void AddLightAssociation(const char *actor, const char *frame, const char *light
void InitializeActorLights(TArray<FLightAssociation> &LightAssociations);
extern TArray<FString> usershaders;
extern TArray<FString> usermaterials;
extern TArray<FString> usershaderdefs;
extern TDeletingArray<FLightDefaults *> LightDefaults;
@ -1378,6 +1380,9 @@ class GLDefsParser
bool iwad = false;
int maplump = -1;
FString maplumpname;
FString materiallumpname = "shaders/glsl/material_normal.fp";
FString texnameDefs = "";
TArray<FString> texNameList;
float speed = 1.f;
sc.MustGetString();
@ -1393,11 +1398,62 @@ class GLDefsParser
sc.MustGetString();
maplumpname = sc.String;
}
else if (sc.Compare("material"))
{
sc.MustGetString();
materiallumpname = sc.String;
}
else if (sc.Compare("speed"))
{
sc.MustGetFloat();
speed = float(sc.Float);
}
else if (sc.Compare("texture"))
{
sc.MustGetString();
FString textureName = sc.String;
for(FString &texName : texNameList)
{
if(!texName.Compare(textureName))
{
sc.ScriptError("Trying to redefine custom hardware shader texture '%s' in texture '%s'\n", textureName.GetChars(), tex? tex->Name.GetChars() : "(null)");
}
}
texNameList.Push(textureName);
sc.MustGetString();
bool okay = false;
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)
{
if (!tex->CustomShaderTextures[i])
{
tex->CustomShaderTextures[i] = TexMan.FindTexture(sc.String, ETextureType::Any, FTextureManager::TEXMAN_TryAny);
if (!tex->CustomShaderTextures[i])
{
sc.ScriptError("Custom hardware shader texture '%s' not found in texture '%s'\n", sc.String, tex? tex->Name.GetChars() : "(null)");
}
texnameDefs.AppendFormat("#define %s texture%d\n", textureName.GetChars(), i + 2);
okay = true;
break;
}
}
if(!okay)
{
sc.ScriptError("Error: out of texture units in texture '%s'", tex? tex->Name.GetChars() : "(null)");
}
}
else if(sc.Compare("define"))
{
sc.MustGetString();
FString defineName = sc.String;
FString defineValue = "";
if(sc.CheckToken('='))
{
sc.MustGetString();
defineValue = sc.String;
}
texnameDefs.AppendFormat("#define %s %s\n", defineName.GetChars(), defineValue.GetChars());
}
}
if (!tex)
{
@ -1414,13 +1470,17 @@ class GLDefsParser
tex->shaderspeed = speed;
for (unsigned i = 0; i < usershaders.Size(); i++)
{
if (!usershaders[i].CompareNoCase(maplumpname))
if (!usershaders[i].CompareNoCase(maplumpname) &&
!usermaterials[i].CompareNoCase(materiallumpname) &&
!usershaderdefs[i].Compare(texnameDefs))
{
tex->shaderindex = i + FIRST_USER_SHADER;
return;
}
}
tex->shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER;
usermaterials.Push(materiallumpname);
usershaderdefs.Push(texnameDefs);
}
}
}

View File

@ -44,6 +44,9 @@
#include "r_data/r_translate.h"
#include <vector>
// 15 because 0th texture is our texture
#define MAX_CUSTOM_HW_SHADER_TEXTURES 15
typedef TMap<int, bool> SpriteHits;
enum MaterialShaderIndex
@ -234,6 +237,8 @@ public:
FTexture *Metallic = nullptr; // Metalness texture for the physically based rendering (PBR) light model
FTexture *Roughness = nullptr; // Roughness texture for PBR
FTexture *AmbientOcclusion = nullptr; // Ambient occlusion texture for PBR
FTexture *CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES] = { nullptr }; // Custom texture maps for custom hardware shaders
FString Name;
ETextureType UseType; // This texture's primary purpose

View File

@ -417,6 +417,7 @@ public:
virtual void CleanForRestart() {}
virtual void SetTextureFilterMode() {}
virtual IHardwareTexture *CreateHardwareTexture(FTexture *tex) { return nullptr; }
virtual void PrecacheMaterial(FMaterial *mat, int translation) {}
virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; }
virtual void UnbindTexUnit(int no) {}
virtual void TextureFilterChanged() {}