133 lines
3.6 KiB
C++
133 lines
3.6 KiB
C++
#include "RenderTargetPool.h"
|
|
|
|
#include <cstddef>
|
|
|
|
namespace
|
|
{
|
|
void ConfigureRenderTargetTexture(
|
|
unsigned width,
|
|
unsigned height,
|
|
GLenum internalFormat,
|
|
GLenum pixelFormat,
|
|
GLenum pixelType)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, pixelFormat, pixelType, NULL);
|
|
}
|
|
}
|
|
|
|
bool RenderTargetPool::Create(
|
|
RenderTargetId id,
|
|
unsigned width,
|
|
unsigned height,
|
|
GLenum internalFormat,
|
|
GLenum pixelFormat,
|
|
GLenum pixelType,
|
|
const char* errorPrefix,
|
|
std::string& error)
|
|
{
|
|
RenderTarget& target = mTargets[TargetIndex(id)];
|
|
if (target.texture != 0 || target.framebuffer != 0)
|
|
{
|
|
error = std::string(errorPrefix) + " render target was already initialized.";
|
|
return false;
|
|
}
|
|
|
|
glGenTextures(1, &target.texture);
|
|
glBindTexture(GL_TEXTURE_2D, target.texture);
|
|
ConfigureRenderTargetTexture(width, height, internalFormat, pixelFormat, pixelType);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
glGenFramebuffers(1, &target.framebuffer);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, target.framebuffer);
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target.texture, 0);
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
{
|
|
error = std::string("Cannot initialize ") + errorPrefix + " framebuffer.";
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
return false;
|
|
}
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
target.width = width;
|
|
target.height = height;
|
|
target.internalFormat = internalFormat;
|
|
target.pixelFormat = pixelFormat;
|
|
target.pixelType = pixelType;
|
|
return true;
|
|
}
|
|
|
|
bool RenderTargetPool::ReserveTemporaryTargets(
|
|
std::size_t count,
|
|
unsigned width,
|
|
unsigned height,
|
|
GLenum internalFormat,
|
|
GLenum pixelFormat,
|
|
GLenum pixelType,
|
|
std::string& error)
|
|
{
|
|
if (!mTemporaryTargets.empty())
|
|
{
|
|
error = "Temporary render targets were already initialized.";
|
|
return false;
|
|
}
|
|
|
|
mTemporaryTargets.resize(count);
|
|
for (std::size_t index = 0; index < mTemporaryTargets.size(); ++index)
|
|
{
|
|
RenderTarget& target = mTemporaryTargets[index];
|
|
glGenTextures(1, &target.texture);
|
|
glBindTexture(GL_TEXTURE_2D, target.texture);
|
|
ConfigureRenderTargetTexture(width, height, internalFormat, pixelFormat, pixelType);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
glGenFramebuffers(1, &target.framebuffer);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, target.framebuffer);
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target.texture, 0);
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
{
|
|
error = "Cannot initialize temporary render target.";
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
return false;
|
|
}
|
|
|
|
target.width = width;
|
|
target.height = height;
|
|
target.internalFormat = internalFormat;
|
|
target.pixelFormat = pixelFormat;
|
|
target.pixelType = pixelType;
|
|
}
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
return true;
|
|
}
|
|
|
|
void RenderTargetPool::Destroy()
|
|
{
|
|
for (RenderTarget& target : mTargets)
|
|
{
|
|
if (target.framebuffer != 0)
|
|
glDeleteFramebuffers(1, &target.framebuffer);
|
|
if (target.texture != 0)
|
|
glDeleteTextures(1, &target.texture);
|
|
target = RenderTarget();
|
|
}
|
|
|
|
for (RenderTarget& target : mTemporaryTargets)
|
|
{
|
|
if (target.framebuffer != 0)
|
|
glDeleteFramebuffers(1, &target.framebuffer);
|
|
if (target.texture != 0)
|
|
glDeleteTextures(1, &target.texture);
|
|
}
|
|
mTemporaryTargets.clear();
|
|
}
|
|
|
|
const RenderTarget& RenderTargetPool::Target(RenderTargetId id) const
|
|
{
|
|
return mTargets[TargetIndex(id)];
|
|
}
|