Remove manual memory management from graphics classes
parent
5d52214737
commit
93a06c0c23
|
@ -71,16 +71,6 @@ SDL_RWops* CSDLFileWrapper::GetHandler()
|
|||
return m_rwops;
|
||||
}
|
||||
|
||||
SDL_RWops* CSDLFileWrapper::ReleaseHandler()
|
||||
{
|
||||
SDL_RWops* rwops = m_rwops;
|
||||
m_rwops = nullptr;
|
||||
|
||||
// Destructor will not call SDL_FreeRW, so we must take care of it ourselves
|
||||
rwops->close = SDLCloseWithFreeRW;
|
||||
return rwops;
|
||||
}
|
||||
|
||||
bool CSDLFileWrapper::IsOpen() const
|
||||
{
|
||||
return m_rwops != nullptr;
|
||||
|
@ -91,23 +81,19 @@ int CSDLFileWrapper::SDLClose(SDL_RWops *context, bool freeRW)
|
|||
if (context == nullptr)
|
||||
return 0;
|
||||
|
||||
if (CheckSDLContext(context))
|
||||
if (!CheckSDLContext(context))
|
||||
return 1;
|
||||
|
||||
if (context->hidden.unknown.data1 != nullptr)
|
||||
{
|
||||
if (context->hidden.unknown.data1 != nullptr)
|
||||
{
|
||||
PHYSFS_close(static_cast<PHYSFS_File *>(context->hidden.unknown.data1));
|
||||
context->hidden.unknown.data1 = nullptr;
|
||||
}
|
||||
|
||||
if (freeRW)
|
||||
{
|
||||
SDL_FreeRW(context);
|
||||
}
|
||||
|
||||
return 0;
|
||||
PHYSFS_close(static_cast<PHYSFS_File *>(context->hidden.unknown.data1));
|
||||
context->hidden.unknown.data1 = nullptr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
if (freeRW)
|
||||
SDL_FreeRW(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CSDLFileWrapper::SDLCloseWithoutFreeRW(SDL_RWops *context)
|
||||
|
|
|
@ -36,9 +36,6 @@ public:
|
|||
bool IsOpen() const;
|
||||
SDL_RWops* GetHandler();
|
||||
|
||||
// TODO: this is kind of hacked for SDL_ttf, which keeps SDL_RWops open
|
||||
SDL_RWops* ReleaseHandler();
|
||||
|
||||
private:
|
||||
static int SDLSeek(SDL_RWops *context, int offset, int whence);
|
||||
static int SDLRead(SDL_RWops *context, void *ptr, int size, int maxnum);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "math/intpoint.h"
|
||||
#include "math/matrix.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
@ -245,6 +246,14 @@ enum RenderTarget
|
|||
RENDER_TARGET_STENCIL
|
||||
};
|
||||
|
||||
class CFrameBufferPixels
|
||||
{
|
||||
public:
|
||||
virtual ~CFrameBufferPixels() {}
|
||||
|
||||
virtual void* GetPixelsData() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CDevice
|
||||
* \brief Abstract interface of graphics device
|
||||
|
@ -408,7 +417,7 @@ public:
|
|||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) = 0;
|
||||
|
||||
//! Returns the pixels of the entire screen
|
||||
virtual void* GetFrameBufferPixels() const = 0;
|
||||
virtual std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const = 0;
|
||||
|
||||
//! Returns framebuffer with given name or nullptr if it doesn't exist
|
||||
virtual CFramebuffer* GetFramebuffer(std::string name) = 0;
|
||||
|
|
|
@ -359,7 +359,7 @@ void CNullDevice::CopyFramebufferToTexture(Texture& texture, int xOffset, int yO
|
|||
{
|
||||
}
|
||||
|
||||
void* CNullDevice::GetFrameBufferPixels() const
|
||||
std::unique_ptr<CFrameBufferPixels> CNullDevice::GetFrameBufferPixels() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ public:
|
|||
|
||||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height);
|
||||
|
||||
virtual void* GetFrameBufferPixels() const;
|
||||
virtual std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const;
|
||||
|
||||
virtual CFramebuffer* GetFramebuffer(std::string name);
|
||||
|
||||
|
|
|
@ -209,19 +209,6 @@ CEngine::CEngine(CApplication *app, CSystemUtils* systemUtils)
|
|||
|
||||
CEngine::~CEngine()
|
||||
{
|
||||
m_app = nullptr;
|
||||
m_sound = nullptr;
|
||||
m_device = nullptr;
|
||||
m_text = nullptr;
|
||||
m_lightMan = nullptr;
|
||||
m_particle = nullptr;
|
||||
m_water = nullptr;
|
||||
m_cloud = nullptr;
|
||||
m_lightning = nullptr;
|
||||
m_planet = nullptr;
|
||||
m_terrain = nullptr;
|
||||
m_pause = nullptr;
|
||||
|
||||
m_systemUtils->DestroyTimeStamp(m_lastFrameTime);
|
||||
m_lastFrameTime = nullptr;
|
||||
m_systemUtils->DestroyTimeStamp(m_currentFrameTime);
|
||||
|
@ -250,17 +237,17 @@ CPyroManager* CEngine::GetPyroManager()
|
|||
|
||||
CText* CEngine::GetText()
|
||||
{
|
||||
return m_text;
|
||||
return m_text.get();
|
||||
}
|
||||
|
||||
CLightManager* CEngine::GetLightManager()
|
||||
{
|
||||
return m_lightMan;
|
||||
return m_lightMan.get();
|
||||
}
|
||||
|
||||
CParticle* CEngine::GetParticle()
|
||||
{
|
||||
return m_particle;
|
||||
return m_particle.get();
|
||||
}
|
||||
|
||||
CTerrain* CEngine::GetTerrain()
|
||||
|
@ -270,22 +257,22 @@ CTerrain* CEngine::GetTerrain()
|
|||
|
||||
CWater* CEngine::GetWater()
|
||||
{
|
||||
return m_water;
|
||||
return m_water.get();
|
||||
}
|
||||
|
||||
CLightning* CEngine::GetLightning()
|
||||
{
|
||||
return m_lightning;
|
||||
return m_lightning.get();
|
||||
}
|
||||
|
||||
CPlanet* CEngine::GetPlanet()
|
||||
{
|
||||
return m_planet;
|
||||
return m_planet.get();
|
||||
}
|
||||
|
||||
CCloud* CEngine::GetCloud()
|
||||
{
|
||||
return m_cloud;
|
||||
return m_cloud.get();
|
||||
}
|
||||
|
||||
void CEngine::SetTerrain(CTerrain* terrain)
|
||||
|
@ -300,14 +287,14 @@ bool CEngine::Create()
|
|||
|
||||
m_modelManager = MakeUnique<COldModelManager>(this);
|
||||
m_pyroManager = MakeUnique<CPyroManager>();
|
||||
m_lightMan = new CLightManager(this);
|
||||
m_text = new CText(this);
|
||||
m_particle = new CParticle(this);
|
||||
m_water = new CWater(this);
|
||||
m_cloud = new CCloud(this);
|
||||
m_lightning = new CLightning(this);
|
||||
m_planet = new CPlanet(this);
|
||||
m_pause = new CPauseManager();
|
||||
m_lightMan = MakeUnique<CLightManager>(this);
|
||||
m_text = MakeUnique<CText>(this);
|
||||
m_particle = MakeUnique<CParticle>(this);
|
||||
m_water = MakeUnique<CWater>(this);
|
||||
m_cloud = MakeUnique<CCloud>(this);
|
||||
m_lightning = MakeUnique<CLightning>(this);
|
||||
m_planet = MakeUnique<CPlanet>(this);
|
||||
m_pause = MakeUnique<CPauseManager>();
|
||||
|
||||
m_lightMan->SetDevice(m_device);
|
||||
m_particle->SetDevice(m_device);
|
||||
|
@ -357,29 +344,14 @@ void CEngine::Destroy()
|
|||
m_shadowMap = Texture();
|
||||
}
|
||||
|
||||
delete m_pause;
|
||||
m_pause = nullptr;
|
||||
|
||||
delete m_lightMan;
|
||||
m_lightMan = nullptr;
|
||||
|
||||
delete m_text;
|
||||
m_text = nullptr;
|
||||
|
||||
delete m_particle;
|
||||
m_particle = nullptr;
|
||||
|
||||
delete m_water;
|
||||
m_water = nullptr;
|
||||
|
||||
delete m_cloud;
|
||||
m_cloud = nullptr;
|
||||
|
||||
delete m_lightning;
|
||||
m_lightning = nullptr;
|
||||
|
||||
delete m_planet;
|
||||
m_planet = nullptr;
|
||||
m_pause.reset();
|
||||
m_lightMan.reset();
|
||||
m_text.reset();
|
||||
m_particle.reset();
|
||||
m_water.reset();
|
||||
m_cloud.reset();
|
||||
m_lightning.reset();
|
||||
m_planet.reset();
|
||||
}
|
||||
|
||||
void CEngine::ResetAfterDeviceChanged()
|
||||
|
@ -490,7 +462,8 @@ void CEngine::WriteScreenShot(const std::string& fileName)
|
|||
auto data = MakeUnique<WriteScreenShotData>();
|
||||
data->img = MakeUnique<CImage>(Math::IntPoint(m_size.x, m_size.y));
|
||||
|
||||
data->img->SetDataPixels(m_device->GetFrameBufferPixels());
|
||||
auto pixels = m_device->GetFrameBufferPixels();
|
||||
data->img->SetDataPixels(pixels->GetPixelsData());
|
||||
data->img->FlipVertically();
|
||||
|
||||
data->fileName = fileName;
|
||||
|
|
|
@ -1308,16 +1308,16 @@ protected:
|
|||
CSystemUtils* m_systemUtils;
|
||||
CSoundInterface* m_sound;
|
||||
CDevice* m_device;
|
||||
std::unique_ptr<COldModelManager> m_modelManager;
|
||||
CText* m_text;
|
||||
CLightManager* m_lightMan;
|
||||
CParticle* m_particle;
|
||||
CWater* m_water;
|
||||
CCloud* m_cloud;
|
||||
CLightning* m_lightning;
|
||||
CPlanet* m_planet;
|
||||
CTerrain* m_terrain;
|
||||
CPauseManager* m_pause;
|
||||
std::unique_ptr<COldModelManager> m_modelManager;
|
||||
std::unique_ptr<CText> m_text;
|
||||
std::unique_ptr<CLightManager> m_lightMan;
|
||||
std::unique_ptr<CParticle> m_particle;
|
||||
std::unique_ptr<CWater> m_water;
|
||||
std::unique_ptr<CCloud> m_cloud;
|
||||
std::unique_ptr<CLightning> m_lightning;
|
||||
std::unique_ptr<CPlanet> m_planet;
|
||||
std::unique_ptr<CPauseManager> m_pause;
|
||||
std::unique_ptr<CPyroManager> m_pyroManager;
|
||||
|
||||
//! Last encountered error
|
||||
|
|
|
@ -347,48 +347,48 @@ bool CTerrain::RandomizeRelief()
|
|||
// http://amt2014.pl/archiwum/perlin.py
|
||||
|
||||
int size = (m_mosaicCount*m_brickCount)+1;
|
||||
const int ilosc_oktaw = 6;
|
||||
const int octaveCount = 6;
|
||||
|
||||
float* oktawy[ilosc_oktaw];
|
||||
for(int i=0; i<ilosc_oktaw; i++)
|
||||
std::unique_ptr<float[]> octaves[octaveCount];
|
||||
for(int i = 0; i < octaveCount; i++)
|
||||
{
|
||||
int pxCount = static_cast<int>(pow(2, (i+1)*2));
|
||||
oktawy[i] = new float[pxCount];
|
||||
for(int j=0; j<pxCount; j++)
|
||||
octaves[i] = MakeUniqueArray<float>(pxCount);
|
||||
for(int j = 0; j < pxCount; j++)
|
||||
{
|
||||
oktawy[i][j] = Math::Rand();
|
||||
octaves[i][j] = Math::Rand();
|
||||
}
|
||||
}
|
||||
|
||||
for(int y2=0; y2 < size; y2++)
|
||||
for(int y2 = 0; y2 < size; y2++)
|
||||
{
|
||||
float y = static_cast<float>(y2) / size;
|
||||
for(int x2=0; x2 < size; x2++)
|
||||
for(int x2 = 0; x2 < size; x2++)
|
||||
{
|
||||
float x = static_cast<float>(x2) / size;
|
||||
|
||||
float wart = 0;
|
||||
for(int i=0; i<ilosc_oktaw; i++)
|
||||
float value = 0;
|
||||
for(int i = 0; i < octaveCount; i++)
|
||||
{
|
||||
int rozmiar_oktawy = sqrt(static_cast<int>(pow(2, (i+1)*2)));
|
||||
int octaveSize = sqrt(static_cast<int>(pow(2, (i+1)*2)));
|
||||
double xi, yi, a, b;
|
||||
a = modf(x * (rozmiar_oktawy-1), &xi);
|
||||
b = modf(y * (rozmiar_oktawy-1), &yi);
|
||||
a = modf(x * (octaveSize-1), &xi);
|
||||
b = modf(y * (octaveSize-1), &yi);
|
||||
|
||||
float lg = oktawy[i][static_cast<int>(yi * rozmiar_oktawy + xi)];
|
||||
float pg = oktawy[i][static_cast<int>(yi * rozmiar_oktawy + xi + 1)];
|
||||
float ld = oktawy[i][static_cast<int>((yi+1) * rozmiar_oktawy + xi)];
|
||||
float pd = oktawy[i][static_cast<int>((yi+1) * rozmiar_oktawy + xi + 1)];
|
||||
float lg = octaves[i][static_cast<int>(yi * octaveSize + xi)];
|
||||
float pg = octaves[i][static_cast<int>(yi * octaveSize + xi + 1)];
|
||||
float ld = octaves[i][static_cast<int>((yi+1) * octaveSize + xi)];
|
||||
float pd = octaves[i][static_cast<int>((yi+1) * octaveSize + xi + 1)];
|
||||
|
||||
float g = pg * a + lg * (1-a);
|
||||
float d = pd * a + ld * (1-a);
|
||||
float res = d * b + g * (1-b);
|
||||
wart += res;
|
||||
value += res;
|
||||
}
|
||||
|
||||
wart /= ilosc_oktaw;
|
||||
value /= octaveCount;
|
||||
|
||||
m_relief[x2+y2*size] = wart * 255.0f;
|
||||
m_relief[x2+y2*size] = value * 255.0f;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -40,6 +40,19 @@
|
|||
namespace Gfx
|
||||
{
|
||||
|
||||
/**
|
||||
* \struct MultisizeFont
|
||||
* \brief Font with multiple possible sizes
|
||||
*/
|
||||
struct MultisizeFont
|
||||
{
|
||||
std::string fileName;
|
||||
std::map<int, std::unique_ptr<CachedFont>> fonts;
|
||||
|
||||
explicit MultisizeFont(const std::string &fn)
|
||||
: fileName(fn) {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \struct CachedFont
|
||||
|
@ -47,14 +60,28 @@ namespace Gfx
|
|||
*/
|
||||
struct CachedFont
|
||||
{
|
||||
TTF_Font* font;
|
||||
std::unique_ptr<CSDLFileWrapper> fontFile;
|
||||
TTF_Font* font = nullptr;
|
||||
std::map<UTF8Char, CharTexture> cache;
|
||||
|
||||
CachedFont() : font(nullptr) {}
|
||||
CachedFont(std::unique_ptr<CSDLFileWrapper> fontFile, int pointSize)
|
||||
: fontFile(std::move(fontFile))
|
||||
{
|
||||
font = TTF_OpenFontRW(this->fontFile->GetHandler(), 0, pointSize);
|
||||
}
|
||||
|
||||
~CachedFont()
|
||||
{
|
||||
if (font != nullptr)
|
||||
TTF_CloseFont(font);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
const Math::IntPoint REFERENCE_SIZE(800, 600);
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
CText::CText(CEngine* engine)
|
||||
|
@ -84,12 +111,12 @@ bool CText::Create()
|
|||
return false;
|
||||
}
|
||||
|
||||
m_fonts[FONT_COLOBOT] = new MultisizeFont("fonts/dvu_sans.ttf");
|
||||
m_fonts[FONT_COLOBOT_BOLD] = new MultisizeFont("fonts/dvu_sans_bold.ttf");
|
||||
m_fonts[FONT_COLOBOT_ITALIC] = new MultisizeFont("fonts/dvu_sans_italic.ttf");
|
||||
m_fonts[FONT_COLOBOT] = MakeUnique<MultisizeFont>("fonts/dvu_sans.ttf");
|
||||
m_fonts[FONT_COLOBOT_BOLD] = MakeUnique<MultisizeFont>("fonts/dvu_sans_bold.ttf");
|
||||
m_fonts[FONT_COLOBOT_ITALIC] = MakeUnique<MultisizeFont>("fonts/dvu_sans_italic.ttf");
|
||||
|
||||
m_fonts[FONT_COURIER] = new MultisizeFont("fonts/dvu_sans_mono.ttf");
|
||||
m_fonts[FONT_COURIER_BOLD] = new MultisizeFont("fonts/dvu_sans_mono_bold.ttf");
|
||||
m_fonts[FONT_COURIER] = MakeUnique<MultisizeFont>("fonts/dvu_sans_mono.ttf");
|
||||
m_fonts[FONT_COURIER_BOLD] = MakeUnique<MultisizeFont>("fonts/dvu_sans_mono_bold.ttf");
|
||||
|
||||
for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
|
||||
{
|
||||
|
@ -104,27 +131,11 @@ bool CText::Create()
|
|||
|
||||
void CText::Destroy()
|
||||
{
|
||||
for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
|
||||
{
|
||||
MultisizeFont* mf = (*it).second;
|
||||
|
||||
for (auto jt = mf->fonts.begin(); jt != mf->fonts.end(); ++jt)
|
||||
{
|
||||
CachedFont* cf = (*jt).second;
|
||||
|
||||
TTF_CloseFont(cf->font);
|
||||
|
||||
cf->font = nullptr;
|
||||
delete cf;
|
||||
}
|
||||
|
||||
mf->fonts.clear();
|
||||
delete mf;
|
||||
}
|
||||
|
||||
m_fonts.clear();
|
||||
|
||||
m_lastCachedFont = nullptr;
|
||||
m_lastFontType = FONT_COLOBOT;
|
||||
m_lastFontSize = 0;
|
||||
|
||||
TTF_Quit();
|
||||
}
|
||||
|
@ -141,25 +152,23 @@ std::string CText::GetError()
|
|||
|
||||
void CText::FlushCache()
|
||||
{
|
||||
for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
|
||||
for (auto& multisizeFont : m_fonts)
|
||||
{
|
||||
MultisizeFont *mf = (*it).second;
|
||||
for (auto jt = mf->fonts.begin(); jt != mf->fonts.end(); ++jt)
|
||||
for (auto& cachedFont : multisizeFont.second->fonts)
|
||||
{
|
||||
CachedFont *f = (*jt).second;
|
||||
for (auto ct = f->cache.begin(); ct != f->cache.end(); ++ct)
|
||||
for (auto& charTexture : cachedFont.second->cache)
|
||||
{
|
||||
Texture tex;
|
||||
tex.id = (*ct).second.id;
|
||||
tex.id = charTexture.second.id;
|
||||
m_device->DestroyTexture(tex);
|
||||
}
|
||||
f->cache.clear();
|
||||
cachedFont.second->cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
m_lastCachedFont = nullptr;
|
||||
m_lastFontType = FONT_COLOBOT;
|
||||
m_lastFontSize = 0;
|
||||
m_lastCachedFont = nullptr;
|
||||
}
|
||||
|
||||
int CText::GetTabSize()
|
||||
|
@ -695,7 +704,9 @@ void CText::StringToUTFCharList(const std::string &text, std::vector<UTF8Char> &
|
|||
}
|
||||
}
|
||||
|
||||
void CText::StringToUTFCharList(const std::string &text, std::vector<UTF8Char> &chars, std::vector<FontMetaChar>::iterator format, std::vector<FontMetaChar>::iterator end)
|
||||
void CText::StringToUTFCharList(const std::string &text, std::vector<UTF8Char> &chars,
|
||||
std::vector<FontMetaChar>::iterator format,
|
||||
std::vector<FontMetaChar>::iterator end)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
unsigned int totalLength = text.length();
|
||||
|
@ -704,7 +715,7 @@ void CText::StringToUTFCharList(const std::string &text, std::vector<UTF8Char> &
|
|||
UTF8Char ch;
|
||||
|
||||
FontType font = FONT_COLOBOT;
|
||||
if(format + index != end)
|
||||
if (format + index != end)
|
||||
font = static_cast<FontType>(*(format + index) & FONT_MASK_FONT);
|
||||
|
||||
int len;
|
||||
|
@ -935,10 +946,11 @@ CachedFont* CText::GetOrOpenFont(FontType font, float size)
|
|||
Math::IntPoint windowSize = m_engine->GetWindowSize();
|
||||
int pointSize = static_cast<int>(size * (windowSize.Length() / REFERENCE_SIZE.Length()));
|
||||
|
||||
if (m_lastCachedFont != nullptr)
|
||||
if (m_lastCachedFont != nullptr &&
|
||||
m_lastFontType == font &&
|
||||
m_lastFontSize == pointSize)
|
||||
{
|
||||
if (m_lastFontType == font && m_lastFontSize == pointSize)
|
||||
return m_lastCachedFont;
|
||||
return m_lastCachedFont;
|
||||
}
|
||||
|
||||
auto it = m_fonts.find(font);
|
||||
|
@ -948,12 +960,12 @@ CachedFont* CText::GetOrOpenFont(FontType font, float size)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
MultisizeFont* mf = (*it).second;
|
||||
MultisizeFont* mf = it->second.get();
|
||||
|
||||
auto jt = mf->fonts.find(pointSize);
|
||||
if (jt != mf->fonts.end())
|
||||
{
|
||||
m_lastCachedFont = (*jt).second;
|
||||
m_lastCachedFont = jt->second.get();
|
||||
m_lastFontType = font;
|
||||
m_lastFontSize = pointSize;
|
||||
return m_lastCachedFont;
|
||||
|
@ -966,20 +978,15 @@ CachedFont* CText::GetOrOpenFont(FontType font, float size)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
SDL_RWops* handler = file->ReleaseHandler();
|
||||
|
||||
m_lastCachedFont = new CachedFont();
|
||||
m_lastCachedFont->font = TTF_OpenFontRW(handler, 1, pointSize);
|
||||
if (m_lastCachedFont->font == nullptr)
|
||||
auto newFont = MakeUnique<CachedFont>(std::move(file), pointSize);
|
||||
if (newFont->font == nullptr)
|
||||
{
|
||||
SDL_RWclose(handler);
|
||||
m_error = std::string("TTF_OpenFont error ") + std::string(TTF_GetError());
|
||||
delete m_lastCachedFont;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mf->fonts[pointSize] = m_lastCachedFont;
|
||||
|
||||
m_lastCachedFont = newFont.get();
|
||||
mf->fonts[pointSize] = std::move(newFont);
|
||||
return m_lastCachedFont;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,9 @@
|
|||
|
||||
#include "math/point.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
||||
// Graphics module namespace
|
||||
|
@ -185,28 +186,14 @@ struct UTF8Char
|
|||
*/
|
||||
struct CharTexture
|
||||
{
|
||||
unsigned int id;
|
||||
unsigned int id = 0;
|
||||
Math::Point texSize;
|
||||
Math::Point charSize;
|
||||
|
||||
CharTexture() : id(0) {}
|
||||
};
|
||||
|
||||
// Definition is private - in text.cpp
|
||||
struct CachedFont;
|
||||
|
||||
/**
|
||||
* \struct MultisizeFont
|
||||
* \brief Font with multiple possible sizes
|
||||
*/
|
||||
struct MultisizeFont
|
||||
{
|
||||
std::string fileName;
|
||||
std::map<int, CachedFont*> fonts;
|
||||
|
||||
MultisizeFont(const std::string &fn)
|
||||
: fileName(fn) {}
|
||||
};
|
||||
struct MultisizeFont;
|
||||
|
||||
/**
|
||||
* \enum SpecialChar
|
||||
|
@ -339,7 +326,7 @@ protected:
|
|||
float m_defaultSize;
|
||||
int m_tabSize;
|
||||
|
||||
std::map<FontType, MultisizeFont*> m_fonts;
|
||||
std::map<FontType, std::unique_ptr<MultisizeFont>> m_fonts;
|
||||
|
||||
FontType m_lastFontType;
|
||||
int m_lastFontSize;
|
||||
|
|
|
@ -356,7 +356,7 @@ bool CGL21Device::Create()
|
|||
framebufferParams.height = m_config.size.y;
|
||||
framebufferParams.depth = m_config.depthSize;
|
||||
|
||||
m_framebuffers["default"] = new CDefaultFramebuffer(framebufferParams);
|
||||
m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams);
|
||||
|
||||
m_framebufferSupport = DetectFramebufferSupport();
|
||||
if (m_framebufferSupport != FBS_NONE)
|
||||
|
@ -375,11 +375,8 @@ void CGL21Device::Destroy()
|
|||
glDeleteProgram(m_program);
|
||||
|
||||
// delete framebuffers
|
||||
for (std::map<std::string, CFramebuffer*>::iterator i = m_framebuffers.begin(); i != m_framebuffers.end(); i++)
|
||||
{
|
||||
i->second->Destroy();
|
||||
delete i->second;
|
||||
}
|
||||
for (auto& framebuffer : m_framebuffers)
|
||||
framebuffer.second->Destroy();
|
||||
|
||||
m_framebuffers.clear();
|
||||
|
||||
|
@ -1706,26 +1703,18 @@ void CGL21Device::CopyFramebufferToTexture(Texture& texture, int xOffset, int yO
|
|||
glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
|
||||
}
|
||||
|
||||
void* CGL21Device::GetFrameBufferPixels()const
|
||||
std::unique_ptr<CFrameBufferPixels> CGL21Device::GetFrameBufferPixels() const
|
||||
{
|
||||
GLubyte* pixels = new GLubyte[4 * m_config.size.x * m_config.size.y];
|
||||
|
||||
glReadPixels(0, 0, m_config.size.x, m_config.size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
unsigned int* p = static_cast<unsigned int*> ( static_cast<void*>(pixels) );
|
||||
|
||||
for (int i = 0; i < m_config.size.x * m_config.size.y; ++i)
|
||||
p[i] |= 0xFF000000;
|
||||
|
||||
return static_cast<void*>(p);
|
||||
return GetGLFrameBufferPixels(m_config.size);
|
||||
}
|
||||
|
||||
CFramebuffer* CGL21Device::GetFramebuffer(std::string name)
|
||||
{
|
||||
if (m_framebuffers.find(name) != m_framebuffers.end())
|
||||
return m_framebuffers[name];
|
||||
else
|
||||
auto it = m_framebuffers.find(name);
|
||||
if (it == m_framebuffers.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
CFramebuffer* CGL21Device::CreateFramebuffer(std::string name, const FramebufferParams& params)
|
||||
|
@ -1735,22 +1724,21 @@ CFramebuffer* CGL21Device::CreateFramebuffer(std::string name, const Framebuffer
|
|||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<CFramebuffer> framebuffer;
|
||||
|
||||
if (m_framebufferSupport == FBS_ARB)
|
||||
framebuffer = MakeUnique<CGLFramebuffer>(params);
|
||||
else if (m_framebufferSupport == FBS_EXT)
|
||||
framebuffer = MakeUnique<CGLFramebufferEXT>(params);
|
||||
else
|
||||
{
|
||||
CFramebuffer *framebuffer;
|
||||
return nullptr;
|
||||
|
||||
if (m_framebufferSupport == FBS_ARB)
|
||||
framebuffer = new CGLFramebuffer(params);
|
||||
else if (m_framebufferSupport == FBS_EXT)
|
||||
framebuffer = new CGLFramebufferEXT(params);
|
||||
else
|
||||
return nullptr;
|
||||
framebuffer->Create();
|
||||
|
||||
framebuffer->Create();
|
||||
|
||||
m_framebuffers[name] = framebuffer;
|
||||
return framebuffer;
|
||||
}
|
||||
CFramebuffer* framebufferPtr = framebuffer.get();
|
||||
m_framebuffers[name] = std::move(framebuffer);
|
||||
return framebufferPtr;
|
||||
}
|
||||
|
||||
void CGL21Device::DeleteFramebuffer(std::string name)
|
||||
|
@ -1758,14 +1746,11 @@ void CGL21Device::DeleteFramebuffer(std::string name)
|
|||
// can't delete default framebuffer
|
||||
if (name == "default") return;
|
||||
|
||||
auto position = m_framebuffers.find(name);
|
||||
|
||||
if (position != m_framebuffers.end())
|
||||
auto it = m_framebuffers.find(name);
|
||||
if (it != m_framebuffers.end())
|
||||
{
|
||||
position->second->Destroy();
|
||||
delete position->second;
|
||||
|
||||
m_framebuffers.erase(position);
|
||||
it->second->Destroy();
|
||||
m_framebuffers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
|
||||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) override;
|
||||
|
||||
virtual void* GetFrameBufferPixels() const override;
|
||||
virtual std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const override;
|
||||
|
||||
virtual CFramebuffer* GetFramebuffer(std::string name) override;
|
||||
|
||||
|
@ -204,7 +204,7 @@ private:
|
|||
std::set<Texture> m_allTextures;
|
||||
|
||||
//! Map of framebuffers
|
||||
std::map<std::string, CFramebuffer*> m_framebuffers;
|
||||
std::map<std::string, std::unique_ptr<CFramebuffer>> m_framebuffers;
|
||||
|
||||
//! Type of vertex structure
|
||||
enum VertexType
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "common/config_file.h"
|
||||
#include "common/image.h"
|
||||
#include "common/logger.h"
|
||||
#include "common/make_unique.h"
|
||||
|
||||
#include "graphics/engine/engine.h"
|
||||
|
||||
|
@ -383,7 +384,7 @@ bool CGL33Device::Create()
|
|||
framebufferParams.height = m_config.size.y;
|
||||
framebufferParams.depth = m_config.depthSize;
|
||||
|
||||
m_framebuffers["default"] = new CDefaultFramebuffer(framebufferParams);
|
||||
m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams);
|
||||
|
||||
GetLogger()->Info("CDevice created successfully\n");
|
||||
|
||||
|
@ -397,11 +398,8 @@ void CGL33Device::Destroy()
|
|||
glDeleteProgram(m_shaderProgram);
|
||||
|
||||
// delete framebuffers
|
||||
for (std::map<std::string, CFramebuffer*>::iterator i = m_framebuffers.begin(); i != m_framebuffers.end(); i++)
|
||||
{
|
||||
i->second->Destroy();
|
||||
delete i->second;
|
||||
}
|
||||
for (auto& framebuffer : m_framebuffers)
|
||||
framebuffer.second->Destroy();
|
||||
|
||||
m_framebuffers.clear();
|
||||
|
||||
|
@ -1879,26 +1877,18 @@ void CGL33Device::CopyFramebufferToTexture(Texture& texture, int xOffset, int yO
|
|||
glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
|
||||
}
|
||||
|
||||
void* CGL33Device::GetFrameBufferPixels() const
|
||||
std::unique_ptr<CFrameBufferPixels> CGL33Device::GetFrameBufferPixels() const
|
||||
{
|
||||
GLubyte* pixels = new GLubyte[4 * m_config.size.x * m_config.size.y];
|
||||
|
||||
glReadPixels(0, 0, m_config.size.x, m_config.size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
unsigned int* p = static_cast<unsigned int*> ( static_cast<void*>(pixels) );
|
||||
|
||||
for (int i = 0; i < m_config.size.x * m_config.size.y; ++i)
|
||||
p[i] |= 0xFF000000;
|
||||
|
||||
return static_cast<void*>(p);
|
||||
return GetGLFrameBufferPixels(m_config.size);
|
||||
}
|
||||
|
||||
CFramebuffer* CGL33Device::GetFramebuffer(std::string name)
|
||||
{
|
||||
if (m_framebuffers.find(name) != m_framebuffers.end())
|
||||
return m_framebuffers[name];
|
||||
else
|
||||
auto it = m_framebuffers.find(name);
|
||||
if (it == m_framebuffers.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
CFramebuffer* CGL33Device::CreateFramebuffer(std::string name, const FramebufferParams& params)
|
||||
|
@ -1908,14 +1898,13 @@ CFramebuffer* CGL33Device::CreateFramebuffer(std::string name, const Framebuffer
|
|||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
CGLFramebuffer* framebuffer = new CGLFramebuffer(params);
|
||||
framebuffer->Create();
|
||||
|
||||
m_framebuffers[name] = framebuffer;
|
||||
return framebuffer;
|
||||
}
|
||||
auto framebuffer = MakeUnique<CGLFramebuffer>(params);
|
||||
framebuffer->Create();
|
||||
|
||||
CFramebuffer* framebufferPtr = framebuffer.get();
|
||||
m_framebuffers[name] = std::move(framebuffer);
|
||||
return framebufferPtr;
|
||||
}
|
||||
|
||||
void CGL33Device::DeleteFramebuffer(std::string name)
|
||||
|
@ -1923,14 +1912,11 @@ void CGL33Device::DeleteFramebuffer(std::string name)
|
|||
// can't delete default framebuffer
|
||||
if (name == "default") return;
|
||||
|
||||
auto position = m_framebuffers.find(name);
|
||||
|
||||
if (position != m_framebuffers.end())
|
||||
auto it = m_framebuffers.find(name);
|
||||
if (it != m_framebuffers.end())
|
||||
{
|
||||
position->second->Destroy();
|
||||
delete position->second;
|
||||
|
||||
m_framebuffers.erase(position);
|
||||
it->second->Destroy();
|
||||
m_framebuffers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,10 +29,11 @@
|
|||
#include "graphics/opengl/glframebuffer.h"
|
||||
#include "graphics/opengl/glutil.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
|
||||
// Graphics module namespace
|
||||
|
@ -140,7 +141,7 @@ public:
|
|||
|
||||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) override;
|
||||
|
||||
virtual void* GetFrameBufferPixels() const override;
|
||||
virtual std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const override;
|
||||
|
||||
virtual CFramebuffer* GetFramebuffer(std::string name) override;
|
||||
|
||||
|
@ -243,7 +244,7 @@ private:
|
|||
GLuint m_currentVAO = 0;
|
||||
|
||||
//! Map of framebuffers
|
||||
std::map<std::string, CFramebuffer*> m_framebuffers;
|
||||
std::map<std::string, std::unique_ptr<CFramebuffer>> m_framebuffers;
|
||||
|
||||
//! Shader program
|
||||
GLuint m_shaderProgram = 0;
|
||||
|
|
|
@ -300,7 +300,7 @@ bool CGLDevice::Create()
|
|||
framebufferParams.height = m_config.size.y;
|
||||
framebufferParams.depth = m_config.depthSize;
|
||||
|
||||
m_framebuffers["default"] = new CDefaultFramebuffer(framebufferParams);
|
||||
m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams);
|
||||
|
||||
m_framebufferSupport = DetectFramebufferSupport();
|
||||
if (m_framebufferSupport != FBS_NONE)
|
||||
|
@ -314,11 +314,8 @@ bool CGLDevice::Create()
|
|||
void CGLDevice::Destroy()
|
||||
{
|
||||
// delete framebuffers
|
||||
for (std::map<std::string, CFramebuffer*>::iterator i = m_framebuffers.begin(); i != m_framebuffers.end(); i++)
|
||||
{
|
||||
i->second->Destroy();
|
||||
delete i->second;
|
||||
}
|
||||
for (auto& framebuffer : m_framebuffers)
|
||||
framebuffer.second->Destroy();
|
||||
|
||||
m_framebuffers.clear();
|
||||
|
||||
|
@ -1834,26 +1831,18 @@ void CGLDevice::CopyFramebufferToTexture(Texture& texture, int xOffset, int yOff
|
|||
glBindTexture(GL_TEXTURE_2D, m_currentTextures[0].id);
|
||||
}
|
||||
|
||||
void* CGLDevice::GetFrameBufferPixels()const
|
||||
std::unique_ptr<CFrameBufferPixels> CGLDevice::GetFrameBufferPixels() const
|
||||
{
|
||||
GLubyte* pixels = new GLubyte[4 * m_config.size.x * m_config.size.y];
|
||||
|
||||
glReadPixels(0, 0, m_config.size.x, m_config.size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
unsigned int* p = static_cast<unsigned int*> ( static_cast<void*>(pixels) );
|
||||
|
||||
for (int i = 0; i < m_config.size.x * m_config.size.y; ++i)
|
||||
p[i] |= 0xFF000000;
|
||||
|
||||
return static_cast<void*>(p);
|
||||
return GetGLFrameBufferPixels(m_config.size);
|
||||
}
|
||||
|
||||
CFramebuffer* CGLDevice::GetFramebuffer(std::string name)
|
||||
{
|
||||
if (m_framebuffers.find(name) != m_framebuffers.end())
|
||||
return m_framebuffers[name];
|
||||
else
|
||||
auto it = m_framebuffers.find(name);
|
||||
if (it == m_framebuffers.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
CFramebuffer* CGLDevice::CreateFramebuffer(std::string name, const FramebufferParams& params)
|
||||
|
@ -1863,22 +1852,21 @@ CFramebuffer* CGLDevice::CreateFramebuffer(std::string name, const FramebufferPa
|
|||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<CFramebuffer> framebuffer;
|
||||
|
||||
if (m_framebufferSupport == FBS_ARB)
|
||||
framebuffer = MakeUnique<CGLFramebuffer>(params);
|
||||
else if (m_framebufferSupport == FBS_EXT)
|
||||
framebuffer = MakeUnique<CGLFramebufferEXT>(params);
|
||||
else
|
||||
{
|
||||
CFramebuffer *framebuffer;
|
||||
return nullptr;
|
||||
|
||||
if (m_framebufferSupport == FBS_ARB)
|
||||
framebuffer = new CGLFramebuffer(params);
|
||||
else if (m_framebufferSupport == FBS_EXT)
|
||||
framebuffer = new CGLFramebufferEXT(params);
|
||||
else
|
||||
return nullptr;
|
||||
framebuffer->Create();
|
||||
|
||||
framebuffer->Create();
|
||||
|
||||
m_framebuffers[name] = framebuffer;
|
||||
return framebuffer;
|
||||
}
|
||||
CFramebuffer* framebufferPtr = framebuffer.get();
|
||||
m_framebuffers[name] = std::move(framebuffer);
|
||||
return framebufferPtr;
|
||||
}
|
||||
|
||||
void CGLDevice::DeleteFramebuffer(std::string name)
|
||||
|
@ -1886,14 +1874,11 @@ void CGLDevice::DeleteFramebuffer(std::string name)
|
|||
// can't delete default framebuffer
|
||||
if (name == "default") return;
|
||||
|
||||
auto position = m_framebuffers.find(name);
|
||||
|
||||
if (position != m_framebuffers.end())
|
||||
auto it = m_framebuffers.find(name);
|
||||
if (it != m_framebuffers.end())
|
||||
{
|
||||
position->second->Destroy();
|
||||
delete position->second;
|
||||
|
||||
m_framebuffers.erase(position);
|
||||
it->second->Destroy();
|
||||
m_framebuffers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
|
||||
virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) override;
|
||||
|
||||
virtual void* GetFrameBufferPixels() const override;
|
||||
virtual std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const override;
|
||||
|
||||
virtual CFramebuffer* GetFramebuffer(std::string name) override;
|
||||
|
||||
|
@ -221,7 +221,7 @@ private:
|
|||
std::set<Texture> m_allTextures;
|
||||
|
||||
//! Map of framebuffers
|
||||
std::map<std::string, CFramebuffer*> m_framebuffers;
|
||||
std::map<std::string, std::unique_ptr<CFramebuffer>> m_framebuffers;
|
||||
|
||||
//! Type of vertex structure
|
||||
enum VertexType
|
||||
|
|
|
@ -216,12 +216,11 @@ GLint LoadShader(GLint type, const char* filename)
|
|||
GLint len;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||
|
||||
GLchar *message = new GLchar[len + 1];
|
||||
glGetShaderInfoLog(shader, len + 1, nullptr, message);
|
||||
auto message = MakeUniqueArray<GLchar>(len + 1);
|
||||
glGetShaderInfoLog(shader, len + 1, nullptr, message.get());
|
||||
|
||||
GetLogger()->Error("Shader compilation error occured!\n%s\n", message);
|
||||
GetLogger()->Error("Shader compilation error occured!\n%s\n", message.get());
|
||||
|
||||
delete[] message;
|
||||
glDeleteShader(shader);
|
||||
return 0;
|
||||
}
|
||||
|
@ -249,12 +248,11 @@ GLint LinkProgram(int count, GLint shaders[])
|
|||
GLint len;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
|
||||
|
||||
GLchar *message = new GLchar[len + 1];
|
||||
glGetProgramInfoLog(program, len + 1, nullptr, message);
|
||||
auto message = MakeUniqueArray<GLchar>(len + 1);
|
||||
glGetProgramInfoLog(program, len + 1, nullptr, message.get());
|
||||
|
||||
GetLogger()->Error("Shader program linking error occured!\n%s\n", message);
|
||||
GetLogger()->Error("Shader program linking error occured!\n%s\n", message.get());
|
||||
|
||||
delete[] message;
|
||||
glDeleteProgram(program);
|
||||
|
||||
return 0;
|
||||
|
@ -263,4 +261,19 @@ GLint LinkProgram(int count, GLint shaders[])
|
|||
return program;
|
||||
}
|
||||
|
||||
std::unique_ptr<CGLFrameBufferPixels> GetGLFrameBufferPixels(Math::IntPoint size)
|
||||
{
|
||||
auto pixels = MakeUnique<CGLFrameBufferPixels>(4 * size.x * size.y);
|
||||
|
||||
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels->GetPixelsData());
|
||||
|
||||
GLuint* p = static_cast<GLuint*> ( pixels->GetPixelsData() );
|
||||
|
||||
for (int i = 0; i < size.x * size.y; ++i)
|
||||
p[i] |= 0xFF000000;
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Gfx
|
||||
|
|
|
@ -22,8 +22,12 @@
|
|||
// config.h must be included first
|
||||
#include "common/config.h"
|
||||
|
||||
#include "common/make_unique.h"
|
||||
|
||||
#include "graphics/core/device.h"
|
||||
|
||||
#include "math/intpoint.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <memory>
|
||||
|
@ -70,4 +74,22 @@ GLint LoadShader(GLint type, const char* filename);
|
|||
|
||||
GLint LinkProgram(int count, GLint shaders[]);
|
||||
|
||||
class CGLFrameBufferPixels : public CFrameBufferPixels
|
||||
{
|
||||
public:
|
||||
CGLFrameBufferPixels(std::size_t size)
|
||||
: m_pixels(MakeUniqueArray<GLubyte>(size))
|
||||
{}
|
||||
|
||||
void* GetPixelsData() override
|
||||
{
|
||||
return static_cast<void*>(m_pixels.get());
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<GLubyte[]> m_pixels;
|
||||
};
|
||||
|
||||
std::unique_ptr<CGLFrameBufferPixels> GetGLFrameBufferPixels(Math::IntPoint size);
|
||||
|
||||
} // namespace Gfx
|
||||
|
|
Loading…
Reference in New Issue