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

View File

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

View File

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

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

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* GetFrameBufferPixels() const;
virtual std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const;
virtual CFramebuffer* GetFramebuffer(std::string name);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

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

View File

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

View File

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