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