Files
video-shader-toys/apps/LoopThroughWithOpenGLCompositing/gl/renderer/RenderTargetPool.cpp
Aiden 7d8f9a39d1
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m15s
CI / Windows Release Package (push) Successful in 2m31s
render target pool
2026-05-08 16:59:43 +10:00

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