Remove manual memory management from graphics classes

master
Piotr Dziwinski 2015-08-12 21:07:16 +02:00
parent 5d52214737
commit 93a06c0c23
18 changed files with 259 additions and 308 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);
} }
} }

View File

@ -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

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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);
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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