175 lines
4.4 KiB
C++
175 lines
4.4 KiB
C++
#include "pch.h"
|
|
#include "log.h"
|
|
#include "rtt.h"
|
|
|
|
RTT::RTT()
|
|
{
|
|
fboID = 0;
|
|
rboID = 0;
|
|
w = 0;
|
|
h = 0;
|
|
}
|
|
|
|
RTT::~RTT()
|
|
{
|
|
//destroy();
|
|
}
|
|
|
|
void RTT::destroy()
|
|
{
|
|
if (rboID)
|
|
{
|
|
glDeleteRenderbuffers(1, &rboID);
|
|
}
|
|
if (texID)
|
|
{
|
|
unbindTexture();
|
|
glDeleteTextures(1, &texID);
|
|
//LOG("TEX rtt destroy %d", texID)
|
|
}
|
|
if (fboID)
|
|
{
|
|
unbindFramebuffer();
|
|
glDeleteFramebuffers(1, &fboID);
|
|
//LOG("RTT DESTROY %d", fboID);
|
|
}
|
|
texID = 0;
|
|
fboID = 0;
|
|
rboID = 0;
|
|
// w = 0;
|
|
// h = 0;
|
|
}
|
|
|
|
bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format)
|
|
{
|
|
// Destroy any previously created object
|
|
destroy();
|
|
|
|
w = width;
|
|
h = height;
|
|
|
|
if (tex == -1)
|
|
{
|
|
glGenTextures(1, &texID);
|
|
//LOG("TEX rtt create %d", texID);
|
|
}
|
|
else
|
|
{
|
|
texID = tex;
|
|
}
|
|
|
|
glBindTexture(GL_TEXTURE_2D, texID);
|
|
if (tex == -1)
|
|
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, GL_RGBA,
|
|
internal_format == GL_RGBA32F ? GL_FLOAT : GL_UNSIGNED_BYTE, 0);
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
// Create a renderbuffer object to store depth info
|
|
// glGenRenderbuffers(1, &rboID);
|
|
// glBindRenderbuffer(GL_RENDERBUFFER, rboID);
|
|
// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
|
|
// glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
|
|
GLint oldFboID;
|
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldFboID);
|
|
|
|
// Create a framebuffer object
|
|
glGenFramebuffers(1, &fboID);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
|
|
//LOG("RTT CREATE %d - tex %d", fboID, texID);
|
|
|
|
// Attach the texture to FBO color attachment point
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texID, 0);
|
|
|
|
// Attach the renderbuffer to depth attachment point
|
|
//glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboID);
|
|
|
|
auto err2str = [](GLenum err) {
|
|
switch (err)
|
|
{
|
|
case GL_FRAMEBUFFER_UNDEFINED: return "GL_FRAMEBUFFER_UNDEFINED";
|
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
|
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
|
|
case GL_FRAMEBUFFER_UNSUPPORTED: return "GL_FRAMEBUFFER_UNSUPPORTED";
|
|
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
|
|
default: return "UNKNOWN";
|
|
}
|
|
};
|
|
|
|
// Check FBO status
|
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
if (status != GL_FRAMEBUFFER_COMPLETE)
|
|
LOG("RTT::create failed because: %s", err2str(status));
|
|
|
|
// Switch back to window-system-provided framebuffer
|
|
glBindFramebuffer(GL_FRAMEBUFFER, oldFboID);
|
|
oldRFboID = 0;
|
|
oldDFboID = 0;
|
|
|
|
return status == GL_FRAMEBUFFER_COMPLETE;
|
|
}
|
|
|
|
void RTT::bindFramebuffer()
|
|
{
|
|
#ifdef DEBUG
|
|
if (bound)
|
|
{
|
|
LOG("framebuffer bound twice!");
|
|
#ifdef _WIN32
|
|
__debugbreak();
|
|
#endif
|
|
}
|
|
#endif // _DEBUG
|
|
bound = true;
|
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldDFboID);
|
|
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldRFboID);
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboID);
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID);
|
|
}
|
|
|
|
void RTT::unbindFramebuffer()
|
|
{
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldDFboID);
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, oldRFboID);
|
|
oldRFboID = 0;
|
|
oldDFboID = 0;
|
|
bound = false;
|
|
}
|
|
|
|
void RTT::clear(glm::vec4 color)
|
|
{
|
|
glClearColor(color.r, color.g, color.b, color.a);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
}
|
|
|
|
void RTT::readTextureData(uint8_t* buffer)
|
|
{
|
|
glReadBuffer(GL_BACK);
|
|
bindFramebuffer();
|
|
//glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
|
|
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
|
unbindFramebuffer();
|
|
//glReadBuffer(GL_NONE);
|
|
}
|
|
|
|
uint8_t* RTT::createBuffer()
|
|
{
|
|
return new uint8_t[w * h * 4];
|
|
}
|
|
|
|
void RTT::bindTexture()
|
|
{
|
|
glBindTexture(GL_TEXTURE_2D, texID);
|
|
}
|
|
|
|
void RTT::unbindTexture()
|
|
{
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
}
|
|
|
|
|