engine/src/FrameManager/FrameManager.cpp
2013-02-03 21:24:01 +00:00

357 lines
9.9 KiB
C++

#include "include/FrameManager/FrameManager.h"
#include "include/Utils/Utils.h"
#include "include/Engine.h"
namespace SE
{
const int CONST_SCREEN_FRAMEBUFFER = 0;
//===================================================
//================ FRAME MANAGER ====================
//===================================================
TFrameManager::~TFrameManager()
{
FreeFrameManager();
*Console<<"ResourceManager::FrameManager deleting";
}
void TFrameManager::FreeFrameManager()
{
AssertIfInMainThread();
BOOST_FOREACH(auto& i, FrameMap)
{
ResourceManager->TexList.DeleteTexture(i.second.TexName);
glDeleteRenderbuffers(1, &(i.second.DepthRenderBuffer));
glBindFramebuffer(GL_FRAMEBUFFER, CONST_SCREEN_FRAMEBUFFER);
glDeleteFramebuffers(1, &(i.second.FrameBuffer));
}
FrameMap.clear();
}
cardinal TFrameManager::AddFrameRenderBuffer(const std::string& frameName,cardinal width,cardinal height)
{
AssertIfInMainThread();
#ifdef TARGET_ANDROID
#define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE
#endif
#ifdef TARGET_IOS
#define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE
#endif
if (FrameMap.count(frameName) == 0)
{
std::string texName = frameName + "Texture";
cardinal texID = ResourceManager->TexList.AddEmptyTexture(texName,width,height);
cardinal frameBuffer;
cardinal depthRenderBuffer;
cardinal status;
glGenFramebuffers(1,&frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glGenRenderbuffers(1, &depthRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
#ifdef TARGET_WIN32
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
#endif
#ifdef TARGET_ANDROID
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
#endif
#ifdef TARGET_IOS
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
#endif
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texID, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
*Console<<"FrameManager:: frame buffer added: "+frameName;
FrameMap[frameName].FrameBuffer = frameBuffer;
FrameMap[frameName].DepthRenderBuffer = depthRenderBuffer;
FrameMap[frameName].TexID = texID;
FrameMap[frameName].Width = width;
FrameMap[frameName].Height = height;
FrameMap[frameName].TexName = texName;
glBindFramebuffer(GL_FRAMEBUFFER, CONST_SCREEN_FRAMEBUFFER);
return FrameMap[frameName].FrameBuffer;
break;
default:
*Console<<"FrameManager::ERROR - frame buffer can not be added correctly: "+frameName+", with error: "+tostr(status);
ResourceManager->TexList.DeleteTexture(texName);
glDeleteRenderbuffers(1, &depthRenderBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, CONST_SCREEN_FRAMEBUFFER);
glDeleteFramebuffers(1, &frameBuffer);
return 0;
}
}
else
return FrameMap[frameName].FrameBuffer;
#ifdef TARGET_ANDROID
#undef GL_FRAMEBUFFER_COMPLETE_EXT
#endif
#ifdef TARGET_IOS
#undef GL_FRAMEBUFFER_COMPLETE_EXT
#endif
}
cardinal TFrameManager::AddCubemapBuffer(const std::string& frameName,cardinal width,cardinal height)
{
AssertIfInMainThread();
#ifdef TARGET_ANDROID
#define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE
#endif
#ifdef TARGET_IOS
#define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE
#endif
if (FrameMap.count(frameName) == 0)
{
std::string texName = frameName + "Texture";
cardinal texID = ResourceManager->TexList.AddEmptyCubemapTexture(texName,width,height);
cardinal frameBuffer;
cardinal depthRenderBuffer;
cardinal status;
glGenFramebuffers(1,&frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glGenRenderbuffers(1, &depthRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
#ifdef TARGET_WIN32
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
#endif
#ifdef TARGET_ANDROID
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
#endif
#ifdef TARGET_IOS
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
#endif
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texID, 0);
//?? is it needed?
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+1, texID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+2, texID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+3, texID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+4, texID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+5, texID, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
*Console<<"FrameManager:: frame buffer added: "+frameName;
FrameMap[frameName].FrameBuffer = frameBuffer;
FrameMap[frameName].DepthRenderBuffer = depthRenderBuffer;
FrameMap[frameName].TexID = texID;
FrameMap[frameName].Width = width;
FrameMap[frameName].Height = height;
FrameMap[frameName].TexName = texName;
glBindFramebuffer(GL_FRAMEBUFFER, CONST_SCREEN_FRAMEBUFFER);
return FrameMap[frameName].FrameBuffer;
break;
default:
*Console<<"ERROR number : "+tostr(status)+endl;
*Console<<"FrameManager::ERROR - frame buffer can not be added correctly: "+frameName;
ResourceManager->TexList.DeleteTexture(texName);
glDeleteRenderbuffers(1, &depthRenderBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, CONST_SCREEN_FRAMEBUFFER);
glDeleteFramebuffers(1, &frameBuffer);
return 0;
}
}
else
return FrameMap[frameName].FrameBuffer;
#ifdef TARGET_ANDROID
#undef GL_FRAMEBUFFER_COMPLETE_EXT
#endif
#ifdef TARGET_IOS
#undef GL_FRAMEBUFFER_COMPLETE_EXT
#endif
}
void TFrameManager::DeleteFrameRenderBuffer(const std::string& frameName)
{
AssertIfInMainThread();
if (FrameMap.count(frameName) > 0)
{
ResourceManager->TexList.DeleteTexture(FrameMap[frameName].TexName);
glDeleteRenderbuffers(1, &(FrameMap[frameName].DepthRenderBuffer));
glBindFramebuffer(GL_FRAMEBUFFER, CONST_SCREEN_FRAMEBUFFER);
glDeleteFramebuffers(1, &(FrameMap[frameName].FrameBuffer));
FrameMap.erase(frameName);
}
}
cardinal TFrameManager::AddDepthBuffer(const std::string& frameName, cardinal width, cardinal height)
{
AssertIfInMainThread();
#ifdef TARGET_ANDROID
#define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE
#endif
if (FrameMap.count(frameName) == 0)
{
std::string texName = frameName + "Texture";
cardinal depthTexID = ResourceManager->TexList.AddDepthTexture(texName,width,height);
cardinal frameBuffer;
cardinal status;
glGenFramebuffers(1,&frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexID, 0);
#ifdef TARGET_WIN32
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
#endif
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE:
*Console<<"FrameManager:: frame buffer added: "+frameName;
FrameMap[frameName].FrameBuffer = frameBuffer;
FrameMap[frameName].DepthRenderBuffer = 0;
FrameMap[frameName].TexID = depthTexID;
FrameMap[frameName].Width = width;
FrameMap[frameName].Height = height;
FrameMap[frameName].TexName = texName;
glBindFramebuffer(GL_FRAMEBUFFER, CONST_SCREEN_FRAMEBUFFER);
return FrameMap[frameName].FrameBuffer;
break;
default:
*Console<<"FrameManager::ERROR - frame buffer can not be added correctly: "+frameName;
ResourceManager->TexList.DeleteTexture(texName);
glBindFramebuffer(GL_FRAMEBUFFER, CONST_SCREEN_FRAMEBUFFER);
glDeleteFramebuffers(1, &frameBuffer);
return 0;
}
}
else
return FrameMap[frameName].FrameBuffer;
#ifdef TARGET_ANDROID
#undef GL_FRAMEBUFFER_COMPLETE_EXT
#endif
}
cardinal TFrameManager::GetFrameTexture(const std::string& frameName)
{
if (FrameMap.count(frameName) > 0)
{
return FrameMap[frameName].TexID;
}
else
return 0;
}
ivec2 TFrameManager::GetFrameWidthHeight(const std::string& frameName)
{
if (FrameMap.count(frameName) == 0)
{
throw ErrorToLog("Frame "+frameName+" not found!");
}
return ivec2(FrameMap[frameName].Width, FrameMap[frameName].Height);
}
TTextureData TFrameManager::ReadFromBufferToTexData(const std::string& frameName)
{
TTextureData texData;
texData.Width = FrameMap[frameName].Width;
texData.Height = FrameMap[frameName].Height;
texData.DataSize = texData.Width * texData.Height * 3;
texData.Data = boost::shared_array<char>(new char[texData.DataSize]);
boost::shared_array<char> data(new char[texData.Width * texData.Height * 4]);
glReadPixels(0, 0, FrameMap[frameName].Width, FrameMap[frameName].Height, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
for (cardinal i=0; i < texData.Width; i++)
{
for (cardinal j=0; j < texData.Height; j++)
{
int x = (i * texData.Height + j) + (i * texData.Height + j) + (i * texData.Height + j);
int y = 4 * (i * texData.Height + j);
texData.Data[x + 2] = data[y + 2];
texData.Data[x + 1] = data[y + 1];
texData.Data[x + 0] = data[y + 0];
}
}
return texData;
}
} //namespace SE