mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #2666
2666: Non divisible by 16 texture resize and warning r=heinrich5991 a=Jupeyy Co-authored-by: Jupeyy <jupjopjap@gmail.com>
This commit is contained in:
commit
3101747d46
|
@ -706,11 +706,31 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::
|
|||
p3DImageData = (uint8_t*)malloc(ImageColorChannels * Width * Height);
|
||||
int Image3DWidth, Image3DHeight;
|
||||
|
||||
if(IsSingleLayer || (Width != 0 && Width % 16 == 0 && Height != 0 && Height % 16 == 0 && Texture2DTo3D(pTexData, Width, Height, ImageColorChannels, 16, 16, p3DImageData, Image3DWidth, Image3DHeight)))
|
||||
int ConvertWidth = Width;
|
||||
int ConvertHeight = Height;
|
||||
|
||||
if(!IsSingleLayer)
|
||||
{
|
||||
if(ConvertWidth == 0 || (ConvertWidth % 16) != 0 || ConvertHeight == 0 || (ConvertHeight % 16) != 0)
|
||||
{
|
||||
dbg_msg("gfx", "3D/2D array texture was resized");
|
||||
int NewWidth = maximum<int>(HighestBit(ConvertWidth), 16);
|
||||
int NewHeight = maximum<int>(HighestBit(ConvertHeight), 16);
|
||||
uint8_t* pNewTexData = (uint8_t*)Resize(ConvertWidth, ConvertHeight, NewWidth, NewHeight, pCommand->m_Format, (const uint8_t*)pTexData);
|
||||
|
||||
ConvertWidth = NewWidth;
|
||||
ConvertHeight = NewHeight;
|
||||
|
||||
free(pTexData);
|
||||
pTexData = pNewTexData;
|
||||
}
|
||||
}
|
||||
|
||||
if(IsSingleLayer || (Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, ImageColorChannels, 16, 16, p3DImageData, Image3DWidth, Image3DHeight)))
|
||||
{
|
||||
if(IsSingleLayer)
|
||||
{
|
||||
glTexImage3D(Target, 0, StoreOglformat, Width, Height, 1, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
|
||||
glTexImage3D(Target, 0, StoreOglformat, ConvertWidth, ConvertHeight, 1, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2253,11 +2273,31 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Texture_Create(const CCommandBuffe
|
|||
p3DImageData = (uint8_t*)malloc(ImageColorChannels * Width * Height);
|
||||
int Image3DWidth, Image3DHeight;
|
||||
|
||||
if(IsSingleLayer || (Width != 0 && Width % 16 == 0 && Height != 0 && Height % 16 == 0 && Texture2DTo3D(pTexData, Width, Height, ImageColorChannels, 16, 16, p3DImageData, Image3DWidth, Image3DHeight)))
|
||||
int ConvertWidth = Width;
|
||||
int ConvertHeight = Height;
|
||||
|
||||
if(!IsSingleLayer)
|
||||
{
|
||||
if(ConvertWidth == 0 || (ConvertWidth % 16) != 0 || ConvertHeight == 0 || (ConvertHeight % 16) != 0)
|
||||
{
|
||||
dbg_msg("gfx", "3D/2D array texture was resized");
|
||||
int NewWidth = maximum<int>(HighestBit(ConvertWidth), 16);
|
||||
int NewHeight = maximum<int>(HighestBit(ConvertHeight), 16);
|
||||
uint8_t* pNewTexData = (uint8_t*)Resize(ConvertWidth, ConvertHeight, NewWidth, NewHeight, pCommand->m_Format, (const uint8_t*)pTexData);
|
||||
|
||||
ConvertWidth = NewWidth;
|
||||
ConvertHeight = NewHeight;
|
||||
|
||||
free(pTexData);
|
||||
pTexData = pNewTexData;
|
||||
}
|
||||
}
|
||||
|
||||
if(IsSingleLayer || (Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, ImageColorChannels, 16, 16, p3DImageData, Image3DWidth, Image3DHeight)))
|
||||
{
|
||||
if(IsSingleLayer)
|
||||
{
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, StoreOglformat, Width, Height, 1, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, StoreOglformat, ConvertWidth, ConvertHeight, 1, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -408,7 +408,7 @@ int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureID, int x, int y
|
|||
return 0;
|
||||
}
|
||||
|
||||
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags)
|
||||
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName)
|
||||
{
|
||||
// don't waste memory on texture if we are stress testing
|
||||
#ifdef CONF_DEBUG
|
||||
|
@ -448,6 +448,27 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(int Width, int Heig
|
|||
if((Flags&IGraphics::TEXLOAD_NO_2D_TEXTURE) != 0)
|
||||
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NO_2D_TEXTURE;
|
||||
|
||||
if((Flags&IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE) != 0 || (Flags&IGraphics::TEXLOAD_TO_3D_TEXTURE) != 0)
|
||||
{
|
||||
if(Width == 0 || (Width % 16) != 0 || Height == 0 || (Height % 16) != 0)
|
||||
{
|
||||
SGraphicsWarning NewWarning;
|
||||
char aText[128];
|
||||
if(pTexName && *pTexName)
|
||||
{
|
||||
str_format(aText, sizeof(aText), ":\n\"%s\"\n", pTexName);
|
||||
}
|
||||
else
|
||||
{
|
||||
aText[0] = ' ';
|
||||
aText[1] = 0;
|
||||
}
|
||||
str_format(NewWarning.m_aWarningMsg, sizeof(NewWarning.m_aWarningMsg), "The width and height of texture%sare not divisible by 16, which might cause visual bugs.", aText);
|
||||
|
||||
m_Warnings.emplace_back(NewWarning);
|
||||
}
|
||||
}
|
||||
|
||||
// copy texture data
|
||||
int MemSize = Width*Height*Cmd.m_PixelSize;
|
||||
void *pTmpData = malloc(MemSize);
|
||||
|
@ -479,7 +500,7 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTexture(const char *pFilename,
|
|||
if(StoreFormat == CImageInfo::FORMAT_AUTO)
|
||||
StoreFormat = Img.m_Format;
|
||||
|
||||
ID = LoadTextureRaw(Img.m_Width, Img.m_Height, Img.m_Format, Img.m_pData, StoreFormat, Flags);
|
||||
ID = LoadTextureRaw(Img.m_Width, Img.m_Height, Img.m_Format, Img.m_pData, StoreFormat, Flags, pFilename);
|
||||
free(Img.m_pData);
|
||||
if(ID != m_InvalidTexture && g_Config.m_Debug)
|
||||
dbg_msg("graphics/texture", "loaded %s", pFilename);
|
||||
|
@ -2318,6 +2339,15 @@ void CGraphics_Threaded::TakeCustomScreenshot(const char *pFilename)
|
|||
|
||||
void CGraphics_Threaded::Swap()
|
||||
{
|
||||
if(!m_Warnings.empty())
|
||||
{
|
||||
SGraphicsWarning* pCurWarning = GetCurWarning();
|
||||
if(pCurWarning->m_WasShown)
|
||||
{
|
||||
m_Warnings.erase(m_Warnings.begin());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: screenshot support
|
||||
if(m_DoScreenshot)
|
||||
{
|
||||
|
@ -2371,6 +2401,17 @@ void CGraphics_Threaded::WaitForIdle()
|
|||
m_pBackend->WaitForIdle();
|
||||
}
|
||||
|
||||
SGraphicsWarning *CGraphics_Threaded::GetCurWarning()
|
||||
{
|
||||
if(m_Warnings.empty())
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
SGraphicsWarning* pCurWarning = &m_Warnings[0];
|
||||
return pCurWarning;
|
||||
}
|
||||
}
|
||||
|
||||
int CGraphics_Threaded::GetVideoModes(CVideoMode *pModes, int MaxModes, int Screen)
|
||||
{
|
||||
if(g_Config.m_GfxDisplayAllModes)
|
||||
|
|
|
@ -663,6 +663,8 @@ class CGraphics_Threaded : public IEngineGraphics
|
|||
int m_FirstFreeTexture;
|
||||
int m_TextureMemoryUsage;
|
||||
|
||||
std::vector<SGraphicsWarning> m_Warnings;
|
||||
|
||||
struct SVertexArrayInfo
|
||||
{
|
||||
SVertexArrayInfo() : m_FreeIndex(-1) {}
|
||||
|
@ -742,7 +744,7 @@ public:
|
|||
virtual void LinesDraw(const CLineItem *pArray, int Num);
|
||||
|
||||
virtual int UnloadTexture(IGraphics::CTextureHandle Index);
|
||||
virtual IGraphics::CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags);
|
||||
virtual IGraphics::CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL);
|
||||
virtual int LoadTextureRawSub(IGraphics::CTextureHandle TextureID, int x, int y, int Width, int Height, int Format, const void *pData);
|
||||
|
||||
// simple uncompressed RGBA loaders
|
||||
|
@ -851,6 +853,8 @@ public:
|
|||
virtual bool IsIdle();
|
||||
virtual void WaitForIdle();
|
||||
|
||||
virtual SGraphicsWarning *GetCurWarning();
|
||||
|
||||
virtual bool IsTileBufferingEnabled() { return m_OpenGLTileBufferingEnabled; }
|
||||
virtual bool IsQuadBufferingEnabled() { return m_OpenGLQuadBufferingEnabled; }
|
||||
virtual bool IsTextBufferingEnabled() { return m_OpenGLTextBufferingEnabled; }
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "kernel.h"
|
||||
|
||||
#include <base/color.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <vector>
|
||||
#define GRAPHICS_TYPE_UNSIGNED_BYTE 0x1401
|
||||
|
@ -116,6 +117,13 @@ struct GL_SVertexTex3D
|
|||
GL_STexCoord3D m_Tex;
|
||||
};
|
||||
|
||||
struct SGraphicsWarning
|
||||
{
|
||||
SGraphicsWarning() : m_WasShown(false) {}
|
||||
char m_aWarningMsg[128];
|
||||
bool m_WasShown;
|
||||
};
|
||||
|
||||
typedef void(*WINDOW_RESIZE_FUNC)(void *pUser);
|
||||
|
||||
class IGraphics : public IInterface
|
||||
|
@ -186,7 +194,7 @@ public:
|
|||
virtual int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) = 0;
|
||||
|
||||
virtual int UnloadTexture(CTextureHandle Index) = 0;
|
||||
virtual CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags) = 0;
|
||||
virtual CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL) = 0;
|
||||
virtual int LoadTextureRawSub(CTextureHandle TextureID, int x, int y, int Width, int Height, int Format, const void *pData) = 0;
|
||||
virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) = 0;
|
||||
virtual void TextureSet(CTextureHandle Texture) = 0;
|
||||
|
@ -309,6 +317,7 @@ public:
|
|||
virtual void SetWindowGrab(bool Grab) = 0;
|
||||
virtual void NotifyWindow() = 0;
|
||||
|
||||
virtual SGraphicsWarning *GetCurWarning() = 0;
|
||||
protected:
|
||||
inline CTextureHandle CreateTextureHandle(int Index)
|
||||
{
|
||||
|
|
|
@ -116,6 +116,7 @@ MACRO_CONFIG_INT(GfxTextOverlay, gfx_text_overlay, 10, 1, 100, CFGFLAG_SAVE|CFGF
|
|||
MACRO_CONFIG_INT(GfxAsyncRenderOld, gfx_asyncrender_old, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Do rendering async from the the update")
|
||||
MACRO_CONFIG_INT(GfxTuneOverlay, gfx_tune_overlay, 20, 1, 100, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Stop rendering text overlay in tuning zone in editor: high value = less details = more speed")
|
||||
MACRO_CONFIG_INT(GfxQuadAsTriangle, gfx_quad_as_triangle, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Render quads as triangles (fixes quad coloring on some GPUs)")
|
||||
MACRO_CONFIG_INT(GfxShowWarnings, gfx_show_warnings, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Render gfx warnings to screen")
|
||||
|
||||
MACRO_CONFIG_INT(InpMousesens, inp_mousesens, 200, 1, 100000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Mouse sensitivity")
|
||||
MACRO_CONFIG_INT(InpMouseOld, inp_mouseold, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Use old mouse mode (warp mouse instead of raw input)")
|
||||
|
|
|
@ -90,7 +90,10 @@ void CMapImages::OnMapLoadImpl(class CLayers *pLayers, IMap *pMap)
|
|||
else
|
||||
{
|
||||
void *pData = pMap->GetData(pImg->m_ImageData);
|
||||
m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, LoadFlag);
|
||||
char *pName = (char *)pMap->GetData(pImg->m_ImageName);
|
||||
char aTexName[128];
|
||||
str_format(aTexName, sizeof(aTexName), "%s %s", "embedded:", pName);
|
||||
m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, LoadFlag, aTexName);
|
||||
pMap->UnloadData(pImg->m_ImageData);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -974,12 +974,33 @@ void CMenus::PopupMessage(const char *pTopic, const char *pBody, const char *pBu
|
|||
str_copy(m_aMessageTopic, pTopic, sizeof(m_aMessageTopic));
|
||||
str_copy(m_aMessageBody, pBody, sizeof(m_aMessageBody));
|
||||
str_copy(m_aMessageButton, pButton, sizeof(m_aMessageButton));
|
||||
m_Popup = POPUP_MESSAGE;
|
||||
}
|
||||
|
||||
void CMenus::PopupWarning(const char *pTopic, const char *pBody, const char *pButton, int64 Duration)
|
||||
{
|
||||
// reset active item
|
||||
UI()->SetActiveItem(0);
|
||||
|
||||
str_copy(m_aMessageTopic, pTopic, sizeof(m_aMessageTopic));
|
||||
str_copy(m_aMessageBody, pBody, sizeof(m_aMessageBody));
|
||||
str_copy(m_aMessageButton, pButton, sizeof(m_aMessageButton));
|
||||
m_Popup = POPUP_WARNING;
|
||||
SetActive(true);
|
||||
|
||||
m_PopupWarningDuration = Duration;
|
||||
m_PopupWarningLastTime = time_get_microseconds();
|
||||
}
|
||||
|
||||
bool CMenus::CanDisplayWarning()
|
||||
{
|
||||
return m_Popup == POPUP_NONE && (Client()->State() == IClient::STATE_DEMOPLAYBACK || Client()->State() == IClient::STATE_ONLINE);
|
||||
}
|
||||
|
||||
int CMenus::Render()
|
||||
{
|
||||
if(Client()->State() == IClient::STATE_DEMOPLAYBACK && m_Popup == POPUP_NONE)
|
||||
return 0;
|
||||
|
||||
CUIRect Screen = *UI()->Screen();
|
||||
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
|
||||
|
||||
|
@ -1008,7 +1029,7 @@ int CMenus::Render()
|
|||
ServerBrowser()->Refresh(IServerBrowser::TYPE_KOG);
|
||||
}
|
||||
|
||||
if(Client()->State() == IClient::STATE_ONLINE)
|
||||
if(Client()->State() >= IClient::STATE_ONLINE)
|
||||
{
|
||||
ms_ColorTabbarInactive = ms_ColorTabbarInactiveIngame;
|
||||
ms_ColorTabbarActive = ms_ColorTabbarActiveIngame;
|
||||
|
@ -1095,6 +1116,7 @@ int CMenus::Render()
|
|||
const char *pButtonText = "";
|
||||
int ExtraAlign = 0;
|
||||
|
||||
ColorRGBA BgColor = ColorRGBA{0.0f, 0.0f, 0.0f, 0.5f};
|
||||
if(m_Popup == POPUP_MESSAGE)
|
||||
{
|
||||
pTitle = m_aMessageTopic;
|
||||
|
@ -1213,6 +1235,14 @@ int CMenus::Render()
|
|||
pButtonText = Localize("Ok");
|
||||
ExtraAlign = -1;
|
||||
}
|
||||
else if(m_Popup == POPUP_WARNING)
|
||||
{
|
||||
BgColor = ColorRGBA{0.5f, 0.0f, 0.0f, 0.7f};
|
||||
pTitle = m_aMessageTopic;
|
||||
pExtraText = m_aMessageBody;
|
||||
pButtonText = m_aMessageButton;
|
||||
ExtraAlign = -1;
|
||||
}
|
||||
|
||||
CUIRect Box, Part;
|
||||
Box = Screen;
|
||||
|
@ -1223,7 +1253,7 @@ int CMenus::Render()
|
|||
}
|
||||
|
||||
// render the box
|
||||
RenderTools()->DrawUIRect(&Box, ColorRGBA(0,0,0,0.5f), CUI::CORNER_ALL, 15.0f);
|
||||
RenderTools()->DrawUIRect(&Box, BgColor, CUI::CORNER_ALL, 15.0f);
|
||||
|
||||
Box.HSplitTop(20.f/UI()->Scale(), &Part, &Box);
|
||||
Box.HSplitTop(24.f/UI()->Scale(), &Part, &Box);
|
||||
|
@ -1807,6 +1837,19 @@ int CMenus::Render()
|
|||
static float Offset = 0.0f;
|
||||
DoEditBox(&g_Config.m_PlayerName, &TextBox, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 12.0f, &Offset, false, CUI::CORNER_ALL, Client()->PlayerName());
|
||||
}
|
||||
else if(m_Popup == POPUP_WARNING)
|
||||
{
|
||||
Box.HSplitBottom(20.f, &Box, &Part);
|
||||
Box.HSplitBottom(24.f, &Box, &Part);
|
||||
Part.VMargin(120.0f, &Part);
|
||||
|
||||
static int s_Button = 0;
|
||||
if(DoButton_Menu(&s_Button, pButtonText, 0, &Part) || m_EscapePressed || m_EnterPressed || (time_get_microseconds() - m_PopupWarningLastTime >= m_PopupWarningDuration))
|
||||
{
|
||||
m_Popup = POPUP_NONE;
|
||||
SetActive(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Box.HSplitBottom(20.f, &Box, &Part);
|
||||
|
@ -1954,8 +1997,11 @@ void CMenus::OnStateChange(int NewState, int OldState)
|
|||
m_Popup = POPUP_CONNECTING;
|
||||
else if(NewState == IClient::STATE_ONLINE || NewState == IClient::STATE_DEMOPLAYBACK)
|
||||
{
|
||||
m_Popup = POPUP_NONE;
|
||||
SetActive(false);
|
||||
if(m_Popup != POPUP_WARNING)
|
||||
{
|
||||
m_Popup = POPUP_NONE;
|
||||
SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2025,8 +2071,7 @@ void CMenus::OnRender()
|
|||
UI()->Update(mx,my,mx*3.0f,my*3.0f,Buttons);
|
||||
|
||||
// render
|
||||
if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
Render();
|
||||
Render();
|
||||
|
||||
// render cursor
|
||||
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id);
|
||||
|
|
|
@ -396,6 +396,13 @@ public:
|
|||
void DeleteGhostItem(int Index);
|
||||
|
||||
void setPopup(int Popup) { m_Popup = Popup; }
|
||||
int GetCurPopup() { return m_Popup; }
|
||||
bool CanDisplayWarning();
|
||||
|
||||
void PopupWarning(const char *pTopic, const char *pBody, const char *pButton, int64 Duration);
|
||||
|
||||
int64 m_PopupWarningLastTime;
|
||||
int64 m_PopupWarningDuration;
|
||||
|
||||
int m_DemoPlayerState;
|
||||
char m_aDemoPlayerPopupHint[256];
|
||||
|
@ -420,6 +427,7 @@ public:
|
|||
POPUP_QUIT,
|
||||
POPUP_DISCONNECT,
|
||||
POPUP_DISCONNECT_DUMMY,
|
||||
POPUP_WARNING,
|
||||
|
||||
// demo player states
|
||||
DEMOPLAYER_NONE=0,
|
||||
|
|
|
@ -623,6 +623,21 @@ void CGameClient::OnRender()
|
|||
// update the local character and spectate position
|
||||
UpdatePositions();
|
||||
|
||||
// display gfx warnings
|
||||
if(g_Config.m_GfxShowWarnings == 1)
|
||||
{
|
||||
SGraphicsWarning* pWarning = Graphics()->GetCurWarning();
|
||||
if(pWarning != NULL)
|
||||
{
|
||||
if(m_pMenus->CanDisplayWarning())
|
||||
{
|
||||
m_pMenus->PopupWarning("Warning!", pWarning->m_aWarningMsg, "Ok", 10000000);
|
||||
|
||||
pWarning->m_WasShown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render all systems
|
||||
for(int i = 0; i < m_All.m_Num; i++)
|
||||
m_All.m_paComponents[i]->OnRender();
|
||||
|
|
Loading…
Reference in a new issue