From 4c11b0158881bb51118209730940ab7203f54f6a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 31 May 2020 23:37:11 +0200 Subject: [PATCH] - backend sync with Raze. --- src/common/rendering/gl/gl_framebuffer.cpp | 4 +- src/common/rendering/gl/gl_hwtexture.cpp | 10 +- src/common/rendering/gl/gl_samplers.cpp | 2 +- src/common/rendering/v_video.cpp | 5 - .../vulkan/textures/vk_hwtexture.cpp | 4 +- src/common/textures/gametexture.cpp | 2 +- src/common/textures/gametexture.h | 44 +++++++ src/common/textures/hw_material.cpp | 12 +- src/common/textures/hw_material.h | 5 + src/common/textures/hw_texcontainer.h | 1 + src/common/textures/texture.cpp | 122 ++++++++++-------- src/common/textures/texturemanager.cpp | 4 +- 12 files changed, 142 insertions(+), 73 deletions(-) diff --git a/src/common/rendering/gl/gl_framebuffer.cpp b/src/common/rendering/gl/gl_framebuffer.cpp index d91503c3c..a08969949 100644 --- a/src/common/rendering/gl/gl_framebuffer.cpp +++ b/src/common/rendering/gl/gl_framebuffer.cpp @@ -56,6 +56,7 @@ #include "gl_postprocessstate.h" #include "v_draw.h" #include "printf.h" +#include "gl_hwtexture.h" #include "flatvertices.h" #include "hw_cvars.h" @@ -87,9 +88,9 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, bool fullscreen) : // SetVSync needs to be at the very top to workaround a bug in Nvidia's OpenGL driver. // If wglSwapIntervalEXT is called after glBindFramebuffer in a frame the setting is not changed! Super::SetVSync(vid_vsync); + FHardwareTexture::InitGlobalState(); // Make sure all global variables tracking OpenGL context state are reset.. - FHardwareTexture::InitGlobalState(); gl_RenderState.Reset(); GLRenderer = nullptr; @@ -215,7 +216,6 @@ void OpenGLFrameBuffer::CopyScreenToBuffer(int width, int height, uint8_t* scr) //=========================================================================== void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function renderFunc) - { GLRenderer->StartOffscreen(); GLRenderer->BindToFrameBuffer(tex); diff --git a/src/common/rendering/gl/gl_hwtexture.cpp b/src/common/rendering/gl/gl_hwtexture.cpp index 31e104cfe..70c353082 100644 --- a/src/common/rendering/gl/gl_hwtexture.cpp +++ b/src/common/rendering/gl/gl_hwtexture.cpp @@ -42,6 +42,7 @@ #include "hw_cvars.h" #include "gl_debug.h" #include "gl_renderer.h" +#include "gl_renderstate.h" #include "gl_samplers.h" #include "gl_hwtexture.h" @@ -302,12 +303,16 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i { int usebright = false; - bool needmipmap = (clampmode <= CLAMP_XY); + bool needmipmap = (clampmode <= CLAMP_XY) && !forcenofilter; // Bind it to the system. if (!Bind(texunit, needmipmap)) { - + if (flags & CTF_Indexed) + { + glTextureBytes = 1; + forcenofilter = true; + } int w = 0, h = 0; // Create this texture @@ -331,6 +336,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i return false; } } + if (forcenofilter && clampmode <= CLAMP_XY) clampmode += CLAMP_NOFILTER - CLAMP_NONE; GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255); return true; } diff --git a/src/common/rendering/gl/gl_samplers.cpp b/src/common/rendering/gl/gl_samplers.cpp index caaedd6cc..a0573c468 100644 --- a/src/common/rendering/gl/gl_samplers.cpp +++ b/src/common/rendering/gl/gl_samplers.cpp @@ -93,7 +93,7 @@ FSamplerManager::~FSamplerManager() void FSamplerManager::UnbindAll() { - for (int i = 0; i < FHardwareTexture::MAX_TEXTURES; i++) + for (int i = 0; i < IHardwareTexture::MAX_TEXTURES; i++) { glBindSampler(i, 0); } diff --git a/src/common/rendering/v_video.cpp b/src/common/rendering/v_video.cpp index 7035e54cc..ce4dab80a 100644 --- a/src/common/rendering/v_video.cpp +++ b/src/common/rendering/v_video.cpp @@ -457,11 +457,6 @@ DEFINE_GLOBAL(CleanYfac_1) DEFINE_GLOBAL(CleanWidth_1) DEFINE_GLOBAL(CleanHeight_1) -IHardwareTexture* CreateHardwareTexture(int numchannels) -{ - return screen->CreateHardwareTexture(numchannels); -} - //========================================================================== // // CVAR transsouls diff --git a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp index aac018518..0a30a76e4 100644 --- a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp @@ -390,8 +390,8 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state) WriteDescriptors update; MaterialLayerInfo *layer; - auto systex = static_cast(GetLayer(0, state.mTranslation, &layer)); - update.addCombinedImageSampler(descriptor.get(), 0, systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout); + auto systex = static_cast(GetLayer(0, translation, &layer)); + update.addCombinedImageSampler(descriptor.get(), 0, systex->GetImage(layer->layerTexture, translation, layer->scaleFlags)->View.get(), sampler, systex->mImage.Layout); for (int i = 1; i < numLayers; i++) { auto systex = static_cast(GetLayer(i, 0, &layer)); diff --git a/src/common/textures/gametexture.cpp b/src/common/textures/gametexture.cpp index 3ab74a5c3..d47ffb733 100644 --- a/src/common/textures/gametexture.cpp +++ b/src/common/textures/gametexture.cpp @@ -187,7 +187,7 @@ void FGameTexture::AddAutoMaterials() void FGameTexture::CreateDefaultBrightmap() { auto tex = GetTexture(); - if (flags & GTexf_BrightmapChecked) + if (!(flags & GTexf_BrightmapChecked)) { flags |= GTexf_BrightmapChecked; // Check for brightmaps diff --git a/src/common/textures/gametexture.h b/src/common/textures/gametexture.h index 38c0908c6..4c717a8b9 100644 --- a/src/common/textures/gametexture.h +++ b/src/common/textures/gametexture.h @@ -92,6 +92,7 @@ class FGameTexture FMaterial* Material[4] = { }; // Material properties + FVector2 detailScale = { 1.f, 1.f }; float Glossiness = 10.f; float SpecularLevel = 0.1f; float shaderspeed = 1.f; @@ -305,6 +306,49 @@ public: } } + FVector2 GetDetailScale() const + { + return detailScale; + } + + void SetDetailScale(float x, float y) + { + detailScale.X = x; + detailScale.Y = y; + } + + FTexture* GetBrightmap() + { + if (Brightmap.get() || (flags & GTexf_BrightmapChecked)) return Brightmap.get(); + CreateDefaultBrightmap(); + return Brightmap.get(); + } + FTexture* GetGlowmap() + { + return Glowmap.get(); + } + FTexture* GetDetailmap() + { + return Detailmap.get(); + } + + void SetGlowmap(FTexture *T) + { + Glowmap = T; + } + void SetDetailmap(FTexture* T) + { + Detailmap = T; + } + void SetNormalmap(FTexture* T) + { + Normal = T; + } + void SetSpecularmap(FTexture* T) + { + Specular = T; + } + }; inline FGameTexture* MakeGameTexture(FTexture* tex, const char *name, ETextureType useType) diff --git a/src/common/textures/hw_material.cpp b/src/common/textures/hw_material.cpp index 4f5c301db..8df0b6298 100644 --- a/src/common/textures/hw_material.cpp +++ b/src/common/textures/hw_material.cpp @@ -83,30 +83,30 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags) auto placeholder = TexMan.GameByIndex(1); if (tx->Brightmap.get()) { - mTextureLayers.Push({ tx->Brightmap.get(), scaleflags }); + mTextureLayers.Push({ tx->Brightmap.get(), scaleflags, -1 }); mLayerFlags |= TEXF_Brightmap; } else { - mTextureLayers.Push({ placeholder->GetTexture(), 0 }); + mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 }); } if (tx->Detailmap.get()) { - mTextureLayers.Push({ tx->Detailmap.get(), 0 }); + mTextureLayers.Push({ tx->Detailmap.get(), 0, CLAMP_NONE }); mLayerFlags |= TEXF_Detailmap; } else { - mTextureLayers.Push({ placeholder->GetTexture(), 0 }); + mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 }); } if (tx->Glowmap.get()) { - mTextureLayers.Push({ tx->Glowmap.get(), scaleflags }); + mTextureLayers.Push({ tx->Glowmap.get(), scaleflags, -1 }); mLayerFlags |= TEXF_Glowmap; } else { - mTextureLayers.Push({ placeholder->GetTexture(), 0 }); + mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 }); } auto index = tx->GetShaderIndex(); diff --git a/src/common/textures/hw_material.h b/src/common/textures/hw_material.h index d7509cc94..e8c013d2b 100644 --- a/src/common/textures/hw_material.h +++ b/src/common/textures/hw_material.h @@ -12,6 +12,7 @@ struct MaterialLayerInfo { FTexture* layerTexture; int scaleFlags; + int clampflags; }; //=========================================================================== @@ -37,6 +38,10 @@ public: int GetShaderIndex() const { return mShaderIndex; } int GetScaleFlags() const { return mScaleFlags; } virtual void DeleteDescriptors() { } + FVector2 GetDetailScale() const + { + return sourcetex->GetDetailScale(); + } FGameTexture* Source() const { diff --git a/src/common/textures/hw_texcontainer.h b/src/common/textures/hw_texcontainer.h index c75d42278..a29fc6396 100644 --- a/src/common/textures/hw_texcontainer.h +++ b/src/common/textures/hw_texcontainer.h @@ -14,6 +14,7 @@ enum ECreateTexBufferFlags CTF_CreateMask = 3, // Flags that are relevant for hardware texture creation. CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures. + CTF_Indexed = 16 // Tell the backend to create an indexed texture. }; class FHardwareTextureContainer diff --git a/src/common/textures/texture.cpp b/src/common/textures/texture.cpp index e8626eaf7..20a8d9776 100644 --- a/src/common/textures/texture.cpp +++ b/src/common/textures/texture.cpp @@ -48,6 +48,8 @@ #include "formats/multipatchtexture.h" #include "texturemanager.h" #include "c_cvars.h" +#include "imagehelpers.h" +#include "v_video.h" // Wrappers to keep the definitions of these classes out of here. IHardwareTexture* CreateHardwareTexture(int numchannels); @@ -323,66 +325,82 @@ bool FTexture::ProcessData(unsigned char* buffer, int w, int h, bool ispatch) FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) { FTextureBuffer result; - - unsigned char* buffer = nullptr; - int W, H; - int isTransparent = -1; - bool checkonly = !!(flags & CTF_CheckOnly); - - int exx = !!(flags & CTF_Expand); - - W = GetWidth() + 2 * exx; - H = GetHeight() + 2 * exx; - - if (!checkonly) + if (flags & CTF_Indexed) { - buffer = new unsigned char[W * (H + 1) * 4]; - memset(buffer, 0, W * (H + 1) * 4); + // Indexed textures will never be translated and never be scaled. + int w = GetWidth(), h = GetHeight(); - auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation); - if (remap) translation = remap->Index; - FBitmap bmp(buffer, W * 4, W, H); + auto store = Get8BitPixels(false); + const uint8_t* p = store.Data(); - int trans; - auto Pixels = GetBgraBitmap(remap ? remap->Palette : nullptr, &trans); - bmp.Blit(exx, exx, Pixels); + result.mBuffer = new uint8_t[w * h]; + result.mWidth = w; + result.mHeight = h; + result.mContentId = 0; + ImageHelpers::FlipNonSquareBlock(result.mBuffer, p, h, w, h); + } + else + { + unsigned char* buffer = nullptr; + int W, H; + int isTransparent = -1; + bool checkonly = !!(flags & CTF_CheckOnly); - if (remap == nullptr) + int exx = !!(flags & CTF_Expand); + + W = GetWidth() + 2 * exx; + H = GetHeight() + 2 * exx; + + if (!checkonly) { - CheckTrans(buffer, W * H, trans); - isTransparent = bTranslucent; + buffer = new unsigned char[W * (H + 1) * 4]; + memset(buffer, 0, W * (H + 1) * 4); + + auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation); + if (remap) translation = remap->Index; + FBitmap bmp(buffer, W * 4, W, H); + + int trans; + auto Pixels = GetBgraBitmap(remap ? remap->Palette : nullptr, &trans); + bmp.Blit(exx, exx, Pixels); + + if (remap == nullptr) + { + CheckTrans(buffer, W * H, trans); + isTransparent = bTranslucent; + } + else + { + isTransparent = 0; + // A translated image is not conclusive for setting the texture's transparency info. + } } - else + + if (GetImage()) { - isTransparent = 0; - // A translated image is not conclusive for setting the texture's transparency info. + FContentIdBuilder builder; + builder.id = 0; + builder.imageID = GetImage()->GetId(); + builder.translation = MAX(0, translation); + builder.expand = exx; + result.mContentId = builder.id; + } + else result.mContentId = 0; // for non-image backed textures this has no meaning so leave it at 0. + + result.mBuffer = buffer; + result.mWidth = W; + result.mHeight = H; + + // Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.) + if (GetImage() && flags & CTF_ProcessData) + { + if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly); + + if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); } } - - if (GetImage()) - { - FContentIdBuilder builder; - builder.id = 0; - builder.imageID = GetImage()->GetId(); - builder.translation = MAX(0, translation); - builder.expand = exx; - result.mContentId = builder.id; - } - else result.mContentId = 0; // for non-image backed textures this has no meaning so leave it at 0. - - result.mBuffer = buffer; - result.mWidth = W; - result.mHeight = H; - - // Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.) - if (GetImage() && flags & CTF_ProcessData) - { - if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly); - - if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); - } - return result; + } //=========================================================================== @@ -514,7 +532,7 @@ IHardwareTexture* FTexture::GetHardwareTexture(int translation, int scaleflags) IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, scaleflags); if (hwtex == nullptr) { - hwtex = CreateHardwareTexture(4); + hwtex = screen->CreateHardwareTexture(4); SystemTextures.AddHardwareTexture(translation, scaleflags, hwtex); } return hwtex; @@ -535,7 +553,7 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits) Height = h; Format = bits; //bNoCompress = true; - auto hwtex = CreateHardwareTexture(4); + auto hwtex = screen->CreateHardwareTexture(4); // todo: Initialize here. SystemTextures.AddHardwareTexture(0, false, hwtex); } diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index c7cffd07c..80458a6ab 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -625,8 +625,8 @@ void FTextureManager::AddHiresTextures (int wadnum) auto gtex = MakeGameTexture(newtex, nullptr, ETextureType::Override); gtex->SetWorldPanning(true); gtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight()); - gtex->SetOffsets(0, xs_RoundToInt(oldtex->GetDisplayLeftOffset(0) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(0) * gtex->GetScaleY())); - gtex->SetOffsets(1, xs_RoundToInt(oldtex->GetDisplayLeftOffset(1) * gtex->GetScaleX()), xs_RoundToInt(oldtex->GetDisplayTopOffset(1) * gtex->GetScaleY())); + gtex->SetOffsets(0, oldtex->GetTexelLeftOffset(0), oldtex->GetTexelTopOffset(0)); + gtex->SetOffsets(1, oldtex->GetTexelLeftOffset(1), oldtex->GetTexelTopOffset(1)); ReplaceTexture(tlist[i], gtex, true); } }