357 lines
9.9 KiB
C++
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
|