mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-13 19:29:58 +01:00
Implementation of FrameBuffer blit in output window.
This commit is contained in:
@@ -73,15 +73,21 @@ void FrameBuffer::init()
|
|||||||
|
|
||||||
// attach the 2D texture to intermediate FBO
|
// attach the 2D texture to intermediate FBO
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
|
||||||
|
|
||||||
|
Log::Info("New FBO %d Multi Sampling ", framebufferid_);
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// direct attach the 2D texture to FBO
|
// direct attach the 2D texture to FBO
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
|
||||||
|
|
||||||
|
Log::Info("New FBO %d Single Sampling ", framebufferid_);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkFramebufferStatus();
|
checkFramebufferStatus();
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer::~FrameBuffer()
|
FrameBuffer::~FrameBuffer()
|
||||||
@@ -158,8 +164,7 @@ bool FrameBuffer::blit(FrameBuffer *other)
|
|||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other->framebufferid_);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other->framebufferid_);
|
||||||
// blit to the frame buffer object
|
// blit to the frame buffer object
|
||||||
glBlitFramebuffer(0, 0, attrib_.viewport.x, attrib_.viewport.y,
|
glBlitFramebuffer(0, 0, attrib_.viewport.x, attrib_.viewport.y,
|
||||||
0, 0, other->width(), other->height(),
|
0, 0, other->width(), other->height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -622,7 +622,7 @@ void RenderingWindow::makeCurrent()
|
|||||||
glfwGetFramebufferSize(window_, &(window_attributes_.viewport.x), &(window_attributes_.viewport.y));
|
glfwGetFramebufferSize(window_, &(window_attributes_.viewport.x), &(window_attributes_.viewport.y));
|
||||||
|
|
||||||
// ensure main context is current
|
// ensure main context is current
|
||||||
glfwMakeContextCurrent(window_);
|
// glfwMakeContextCurrent(window_);
|
||||||
|
|
||||||
// set and clear
|
// set and clear
|
||||||
glViewport(0, 0, window_attributes_.viewport.x, window_attributes_.viewport.y);
|
glViewport(0, 0, window_attributes_.viewport.x, window_attributes_.viewport.y);
|
||||||
@@ -631,6 +631,8 @@ void RenderingWindow::makeCurrent()
|
|||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO update parameters for draw on resize event (not every frame)
|
||||||
|
|
||||||
void RenderingWindow::draw(FrameBuffer *fb)
|
void RenderingWindow::draw(FrameBuffer *fb)
|
||||||
{
|
{
|
||||||
if (!window_)
|
if (!window_)
|
||||||
@@ -648,33 +650,82 @@ void RenderingWindow::draw(FrameBuffer *fb)
|
|||||||
// setup attribs
|
// setup attribs
|
||||||
Rendering::manager().pushAttrib(window_attributes_);
|
Rendering::manager().pushAttrib(window_attributes_);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
|
|
||||||
|
|
||||||
// VAO is not shared between multiple contexts of different windows
|
|
||||||
// so we have to create a new VAO for rendering the surface in this window
|
|
||||||
static WindowSurface *surface = new WindowSurface;
|
|
||||||
|
|
||||||
// draw frame buffer provided
|
// draw frame buffer provided
|
||||||
if (fb) {
|
if (fb) {
|
||||||
|
|
||||||
// calculate scaling factor of frame buffer inside window
|
if (false) {
|
||||||
float windowAspectRatio = aspectRatio();
|
// VAO is not shared between multiple contexts of different windows
|
||||||
float renderingAspectRatio = fb->aspectRatio();
|
// so we have to create a new VAO for rendering the surface in this window
|
||||||
glm::vec3 scale;
|
static WindowSurface *surface = new WindowSurface;
|
||||||
if (windowAspectRatio < renderingAspectRatio)
|
static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
|
||||||
scale = glm::vec3(1.f, windowAspectRatio / renderingAspectRatio, 1.f);
|
|
||||||
else
|
|
||||||
scale = glm::vec3(renderingAspectRatio / windowAspectRatio, 1.f, 1.f);
|
|
||||||
|
|
||||||
// draw
|
// calculate scaling factor of frame buffer inside window
|
||||||
ShadingProgram::enduse();
|
float windowAspectRatio = aspectRatio();
|
||||||
glBindTexture(GL_TEXTURE_2D, fb->texture());
|
float renderingAspectRatio = fb->aspectRatio();
|
||||||
// surface->shader()->color.a = 0.4f; // TODO alpha blending ?
|
glm::vec3 scale;
|
||||||
surface->draw(glm::scale(glm::identity<glm::mat4>(), scale), projection);
|
if (windowAspectRatio < renderingAspectRatio)
|
||||||
|
scale = glm::vec3(1.f, windowAspectRatio / renderingAspectRatio, 1.f);
|
||||||
|
else
|
||||||
|
scale = glm::vec3(renderingAspectRatio / windowAspectRatio, 1.f, 1.f);
|
||||||
|
|
||||||
|
// draw
|
||||||
|
ShadingProgram::enduse();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, fb->texture());
|
||||||
|
// surface->shader()->color.a = 0.4f; // TODO alpha blending ?
|
||||||
|
surface->draw(glm::scale(glm::identity<glm::mat4>(), scale), projection);
|
||||||
|
|
||||||
|
// done drawing
|
||||||
|
ShadingProgram::enduse();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
static int attached_textureid_fbo_ = 0;
|
||||||
|
static uint local_fbo_ = 0;
|
||||||
|
if ( attached_textureid_fbo_ != fb->texture()) {
|
||||||
|
|
||||||
|
// create a new fbo in this opengl context
|
||||||
|
if (local_fbo_ != 0)
|
||||||
|
glDeleteFramebuffers(1, &local_fbo_);
|
||||||
|
glGenFramebuffers(1, &local_fbo_);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, local_fbo_);
|
||||||
|
|
||||||
|
// attach the 2D texture to local FBO
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->texture(), 0);
|
||||||
|
attached_textureid_fbo_ = fb->texture();
|
||||||
|
|
||||||
|
Log::Info("Blit to output window enabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate scaling factor of frame buffer inside window
|
||||||
|
int rx, ry, rw, rh;
|
||||||
|
float renderingAspectRatio = fb->aspectRatio();
|
||||||
|
if (aspectRatio() < renderingAspectRatio) {
|
||||||
|
int nh = (int)( float(window_attributes_.viewport.x) / renderingAspectRatio);
|
||||||
|
rx = 0;
|
||||||
|
ry = (window_attributes_.viewport.y - nh) / 2;
|
||||||
|
rw = window_attributes_.viewport.x;
|
||||||
|
rh = (window_attributes_.viewport.y + nh) / 2;
|
||||||
|
} else {
|
||||||
|
int nw = (int)( float(window_attributes_.viewport.y) * renderingAspectRatio );
|
||||||
|
rx = (window_attributes_.viewport.x - nw) / 2;
|
||||||
|
ry = 0;
|
||||||
|
rw = (window_attributes_.viewport.x + nw) / 2;
|
||||||
|
rh = window_attributes_.viewport.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// select fbo texture read target
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, local_fbo_);
|
||||||
|
|
||||||
|
// select screen target
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
// glBlitFramebuffer(0, 0, fb->width(), fb->height(), 0, 0, window_attributes_.viewport.x, window_attributes_.viewport.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
glBlitFramebuffer(0, fb->height(), fb->width(), 0, rx, ry, rw, rh, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// done drawing
|
|
||||||
ShadingProgram::enduse();
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log::Info("No Framebuffer Provided to draw Rendering Window");
|
Log::Info("No Framebuffer Provided to draw Rendering Window");
|
||||||
|
|||||||
Reference in New Issue
Block a user