diff --git a/CMakeLists.txt b/CMakeLists.txt index 32a26b9..3d83eef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ HunterGate( LOCAL ) -project(ogles_gpgpu VERSION 0.3.3) +project(ogles_gpgpu VERSION 0.3.4) hunter_add_package(check_ci_tag) find_package(check_ci_tag CONFIG REQUIRED) diff --git a/ogles_gpgpu/common/proc/disp.cpp b/ogles_gpgpu/common/proc/disp.cpp index b4e11fe..8176fa2 100644 --- a/ogles_gpgpu/common/proc/disp.cpp +++ b/ogles_gpgpu/common/proc/disp.cpp @@ -28,9 +28,30 @@ void main() ); // clang-format on +Disp::Disp() = default; + +Disp::Disp(const Callback &renderbufferStorage) + : renderbufferStorage(renderbufferStorage) +{ + +} + +Disp::~Disp() +{ + if (renderbufferStorage) + { + glDeleteRenderbuffers(1, &renderbuffer); + } +} + int Disp::init(int inW, int inH, unsigned int order, bool prepareForExternalInput) { OG_LOGINF(getProcName(), "initialize"); + if(renderbufferStorage) + { + createFBO(); + } + // ProcBase init - set defaults baseInit(inW, inH, order, prepareForExternalInput, procParamOutW, procParamOutH, procParamOutScale); @@ -50,12 +71,48 @@ int Disp::render(int position) { filterRenderSetCoords(); Tools::checkGLErr(getProcName(), "render set coords"); - //glBindBuffer(GL_FRAMEBUFFER, 0); filterRenderDraw(); Tools::checkGLErr(getProcName(), "render draw"); + + if(renderbufferStorage) + { + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + Tools::checkGLErr(getProcName(), "glBindRenderbuffer"); + } filterRenderCleanup(); Tools::checkGLErr(getProcName(), "render cleanup"); return 0; } + +void Disp::createFBO() +{ + FilterProcBase::createFBO(); + + if (renderbufferStorage) { + + fbo->bind(); + Tools::checkGLErr(getProcName(), "glBindFramebuffer"); + + // Create a Renderbuffer + glGenRenderbuffers(1, &renderbuffer); + Tools::checkGLErr(getProcName(), "glGenRenderbuffers"); + + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + Tools::checkGLErr(getProcName(), "glBindRenderbuffer"); + + renderbufferStorage(); + Tools::checkGLErr(getProcName(), "renderbufferStorage"); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer); + Tools::checkGLErr(getProcName(), "glFramebufferRenderbuffer"); + + auto fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (fboStatus != GL_FRAMEBUFFER_COMPLETE) { + std::stringstream ss; + ss << "Framebuffer incomplete :" << int(fboStatus); + throw std::runtime_error(ss.str()); + } + } +} diff --git a/ogles_gpgpu/common/proc/disp.h b/ogles_gpgpu/common/proc/disp.h index 3593be0..4a49be8 100644 --- a/ogles_gpgpu/common/proc/disp.h +++ b/ogles_gpgpu/common/proc/disp.h @@ -17,6 +17,8 @@ #include "base/filterprocbase.h" +#include + namespace ogles_gpgpu { /** @@ -25,6 +27,24 @@ namespace ogles_gpgpu { */ class Disp : public FilterProcBase { public: + + using Callback = std::function; + + /** + * Default constructor + */ + Disp(); + + /** + * Constructor for renderbuffer based display + */ + Disp(const Callback &renderbufferStorage); + + /** + * Destructor + */ + virtual ~Disp(); + /** * Output resolution of display. * @@ -87,6 +107,13 @@ class Disp : public FilterProcBase { return NULL; } + /** + * Create an FBO for this processor. This will contain the result after rendering in its attached texture. + * + * (optional) create renderbuffer if renderbufferStorage callback was specified in constructor. + */ + virtual void createFBO(); + private: float tx = 0.f; float ty = 0.f; @@ -94,6 +121,9 @@ class Disp : public FilterProcBase { float resolutionY = 1.f; static const char* fshaderDispSrc; // fragment shader source + + GLuint renderbuffer; // (optional) renderbuffer based display + Callback renderbufferStorage; }; }