FrameBuffer creation flags replace booleans

Instead of many creation options (with alpha, with multisampling, etc) use a single flag with boolean operators. Creation of the new mipmap flag for FrameBuffer, rendering the current FBO into multiple sub-resolutions.
This commit is contained in:
Bruno Herbelin
2022-05-22 15:14:10 +02:00
parent 7867aac55f
commit d695aa9f57
15 changed files with 151 additions and 77 deletions

View File

@@ -66,7 +66,7 @@ void CloneSource::init()
if (origin_ && origin_->ready_ && origin_->mode_ > Source::UNINITIALIZED && origin_->renderbuffer_) {
// create render Frame buffer matching size of images
FrameBuffer *renderbuffer = new FrameBuffer( origin_->frame()->resolution(), origin_->frame()->use_alpha() );
FrameBuffer *renderbuffer = new FrameBuffer( origin_->frame()->resolution(), origin_->frame()->flags() );
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);

View File

@@ -54,8 +54,8 @@ void DelayFilter::update (float dt)
if ( frames_.empty() || now_ - elapsed_.front() < delay_ + ( double(dt) * 0.002) )
{
// create a FBO if none can be reused (from above) and test for RAM in GPU
if (temp_frame_ == nullptr && ( frames_.empty() || Rendering::shouldHaveEnoughMemory(input_->resolution(), input_->use_alpha()) ) ){
temp_frame_ = new FrameBuffer( input_->resolution(), input_->use_alpha() );
if (temp_frame_ == nullptr && ( frames_.empty() || Rendering::shouldHaveEnoughMemory(input_->resolution(), input_->flags()) ) ){
temp_frame_ = new FrameBuffer( input_->resolution(), input_->flags() );
}
// image available
if (temp_frame_ != nullptr) {

View File

@@ -75,22 +75,24 @@ glm::ivec2 FrameBuffer::getParametersFromResolution(glm::vec3 res)
return p;
}
FrameBuffer::FrameBuffer(glm::vec3 resolution, bool useAlpha, bool multiSampling):
textureid_(0), intermediate_textureid_(0), framebufferid_(0), intermediate_framebufferid_(0),
use_alpha_(useAlpha), use_multi_sampling_(multiSampling)
FrameBuffer::FrameBuffer(glm::vec3 resolution, FrameBufferFlags flags): flags_(flags),
textureid_(0), multisampling_textureid_(0), framebufferid_(0), multisampling_framebufferid_(0)
{
attrib_.viewport = glm::ivec2(resolution);
setProjectionArea(glm::vec2(1.f, 1.f));
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, 0.f);
for(int i=0; i<MIPMAP_LEVEL; ++i)
mipmap_framebufferid_[MIPMAP_LEVEL] = 0;
}
FrameBuffer::FrameBuffer(uint width, uint height, bool useAlpha, bool multiSampling):
textureid_(0), intermediate_textureid_(0), framebufferid_(0), intermediate_framebufferid_(0),
use_alpha_(useAlpha), use_multi_sampling_(multiSampling)
FrameBuffer::FrameBuffer(uint width, uint height, FrameBufferFlags flags): flags_(flags),
textureid_(0), multisampling_textureid_(0), framebufferid_(0), multisampling_framebufferid_(0)
{
attrib_.viewport = glm::ivec2(width, height);
setProjectionArea(glm::vec2(1.f, 1.f));
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, 0.f);
for(int i=0; i<MIPMAP_LEVEL; ++i)
mipmap_framebufferid_[MIPMAP_LEVEL] = 0;
}
void FrameBuffer::init()
@@ -98,27 +100,40 @@ void FrameBuffer::init()
// generate texture
glGenTextures(1, &textureid_);
glBindTexture(GL_TEXTURE_2D, textureid_);
glTexStorage2D(GL_TEXTURE_2D, 1, use_alpha_ ? GL_RGBA8 : GL_RGB8, attrib_.viewport.x, attrib_.viewport.y);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (flags_ & FrameBuffer_mipmap) {
glTexStorage2D(GL_TEXTURE_2D, MIPMAP_LEVEL + 1, (flags_ & FrameBuffer_alpha) ? GL_RGBA8 : GL_RGB8, attrib_.viewport.x, attrib_.viewport.y);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else {
glTexStorage2D(GL_TEXTURE_2D, 1, (flags_ & FrameBuffer_alpha) ? GL_RGBA8 : GL_RGB8, attrib_.viewport.x, attrib_.viewport.y);
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);
glBindTexture(GL_TEXTURE_2D, 0);
// create a framebuffer object
glGenFramebuffers(1, &framebufferid_);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferid_);
// take settings into account: no multisampling for level 0
use_multi_sampling_ &= Settings::application.render.multisampling > 0;
#ifdef FRAMEBUFFER_DEBUG
g_printerr("New FBO %d (%d x %d)\n", framebufferid_, attrib_.viewport.x, attrib_.viewport.y);
#endif
if (use_multi_sampling_){
// take settings into account: no multisampling if application multisampling is level 0
if ( Settings::application.render.multisampling < 1 )
flags_ &= ~FrameBuffer_multisampling;
if (flags_ & FrameBuffer_multisampling){
// create a multisample texture
glGenTextures(1, &intermediate_textureid_);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, intermediate_textureid_);
glGenTextures(1, &multisampling_textureid_);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, multisampling_textureid_);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, Settings::application.render.multisampling,
use_alpha_ ? GL_RGBA8 : GL_RGB8, attrib_.viewport.x, attrib_.viewport.y, GL_TRUE);
(flags_ & FrameBuffer_alpha) ? GL_RGBA8 : GL_RGB8, attrib_.viewport.x, attrib_.viewport.y, GL_TRUE);
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);
@@ -126,28 +141,34 @@ void FrameBuffer::init()
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
// attach the multisampled texture to FBO (framebufferid_ currently binded)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, intermediate_textureid_, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, multisampling_textureid_, 0);
// create an intermediate FBO : this is the FBO to use for reading
glGenFramebuffers(1, &intermediate_framebufferid_);
glBindFramebuffer(GL_FRAMEBUFFER, intermediate_framebufferid_);
// attach the 2D texture to intermediate FBO (intermediate_framebufferid_)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
glGenFramebuffers(1, &multisampling_framebufferid_);
glBindFramebuffer(GL_FRAMEBUFFER, multisampling_framebufferid_);
#ifdef FRAMEBUFFER_DEBUG
g_printerr("New FBO %d Multi Sampling\n", framebufferid_);
g_printerr(" - with Multi Sampling (%d) \n", Settings::application.render.multisampling);
#endif
}
else {
// direct attach the 2D texture to FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
// attach the 2D texture to latest binded FBO
// (i.e. the multisampling_framebufferid_ FBO if enabled, default framebufferid_ otherwise)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
if (flags_ & FrameBuffer_mipmap) {
glGenFramebuffers(MIPMAP_LEVEL, mipmap_framebufferid_);
for(int i=0; i < MIPMAP_LEVEL; ++i) {
glBindFramebuffer(GL_FRAMEBUFFER, mipmap_framebufferid_[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, i + 1);
}
#ifdef FRAMEBUFFER_DEBUG
g_printerr("New FBO %d Single Sampling\n", framebufferid_);
g_printerr(" - with Mipmap (%d)\n", MIPMAP_LEVEL);
#endif
}
checkFramebufferStatus();
@@ -159,15 +180,17 @@ FrameBuffer::~FrameBuffer()
{
if (framebufferid_)
glDeleteFramebuffers(1, &framebufferid_);
if (intermediate_framebufferid_)
glDeleteFramebuffers(1, &intermediate_framebufferid_);
if (multisampling_framebufferid_)
glDeleteFramebuffers(1, &multisampling_framebufferid_);
if (mipmap_framebufferid_[0])
glDeleteFramebuffers(MIPMAP_LEVEL, mipmap_framebufferid_);
if (textureid_)
glDeleteTextures(1, &textureid_);
if (intermediate_textureid_)
glDeleteTextures(1, &intermediate_textureid_);
if (multisampling_textureid_)
glDeleteTextures(1, &multisampling_textureid_);
#ifdef FRAMEBUFFER_DEBUG
GLint framebufferMemoryInKB = ( width() * height() * (use_alpha_?4:3) ) / 1024;
GLint framebufferMemoryInKB = ( width() * height() * (flags_ & FrameBuffer_alpha?4:3) ) / 1024;
g_printerr("Framebuffer deleted %d x %d, ~%d kB freed\n", width(), height(), framebufferMemoryInKB);
#endif
}
@@ -213,15 +236,22 @@ void FrameBuffer::resize(int width, int height)
glDeleteFramebuffers(1, &framebufferid_);
framebufferid_ = 0;
if (intermediate_framebufferid_)
glDeleteFramebuffers(1, &intermediate_framebufferid_);
intermediate_framebufferid_ = 0;
if (multisampling_framebufferid_)
glDeleteFramebuffers(1, &multisampling_framebufferid_);
multisampling_framebufferid_ = 0;
if (mipmap_framebufferid_[0])
glDeleteFramebuffers(MIPMAP_LEVEL, mipmap_framebufferid_);
for(int i=0; i<MIPMAP_LEVEL; ++i)
mipmap_framebufferid_[MIPMAP_LEVEL] = 0;
if (textureid_)
glDeleteTextures(1, &textureid_);
textureid_ = 0;
if (intermediate_textureid_)
glDeleteTextures(1, &intermediate_textureid_);
intermediate_textureid_ = 0;
if (multisampling_textureid_)
glDeleteTextures(1, &multisampling_textureid_);
multisampling_textureid_ = 0;
// change resolution
attrib_.viewport = glm::ivec2(width, height);
@@ -245,15 +275,35 @@ void FrameBuffer::begin(bool clear)
void FrameBuffer::end()
{
// if multisampling frame buffer
if (use_multi_sampling_) {
if (flags_ & FrameBuffer_multisampling) {
// blit the multisample FBO into unisample FBO to generate 2D texture
// Doing this blit will automatically resolve the multisampled FBO.
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediate_framebufferid_);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, multisampling_framebufferid_);
glBlitFramebuffer(0, 0, attrib_.viewport.x, attrib_.viewport.y,
0, 0, attrib_.viewport.x, attrib_.viewport.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
// if mipmapped texture, fill FBOs
if (flags_ & FrameBuffer_mipmap) {
// First read full-size framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
int width = attrib_.viewport.x;
int height = attrib_.viewport.y;
// iterate over all levels of mipmaps
for(int i=0; i < MIPMAP_LEVEL; ++i) {
// draw on Mipmap level i
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mipmap_framebufferid_[i]);
// blit into half-sized mipmap i (with linear nearest color)
glBlitFramebuffer(0, 0, width, height,
0, 0, width / 2, height / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// next iteration (i+1), read half-size mipmap level i
glBindFramebuffer(GL_READ_FRAMEBUFFER, mipmap_framebufferid_[i]);
width = MAX(1, (width / 2));
height = MAX(1, (height / 2));
}
}
FrameBuffer::release();
Rendering::manager().popAttrib();
@@ -273,23 +323,23 @@ void FrameBuffer::readPixels(uint8_t *target_data)
return;
}
if (use_multi_sampling_)
glBindFramebuffer(GL_READ_FRAMEBUFFER, intermediate_framebufferid_);
if (flags_ & FrameBuffer_multisampling)
glBindFramebuffer(GL_READ_FRAMEBUFFER, multisampling_framebufferid_);
else
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
if (use_alpha())
if (flags_ & FrameBuffer_alpha)
glPixelStorei(GL_PACK_ALIGNMENT, 4);
else
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, attrib_.viewport.x, attrib_.viewport.y, (use_alpha_? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, target_data);
glReadPixels(0, 0, attrib_.viewport.x, attrib_.viewport.y, ((flags_ & FrameBuffer_alpha)? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, target_data);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
bool FrameBuffer::blit(FrameBuffer *destination)
{
if (!framebufferid_ || !destination || (use_alpha_ != destination->use_alpha_) ){
if (!framebufferid_ || !destination || (flags_ & FrameBuffer_alpha) != (destination->flags_ & FrameBuffer_alpha) ){
#ifdef FRAMEBUFFER_DEBUG
g_printerr("FrameBuffer blit failed\n");
#endif
@@ -299,8 +349,8 @@ bool FrameBuffer::blit(FrameBuffer *destination)
if (!destination->framebufferid_)
destination->init();
if (use_multi_sampling_)
glBindFramebuffer(GL_READ_FRAMEBUFFER, intermediate_framebufferid_);
if (flags_ & FrameBuffer_multisampling)
glBindFramebuffer(GL_READ_FRAMEBUFFER, multisampling_framebufferid_);
else
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
@@ -310,6 +360,8 @@ bool FrameBuffer::blit(FrameBuffer *destination)
0, 0, destination->width(), destination->height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// TODO : verify blit onto FBO with mipmapping ?
return true;
}
@@ -353,7 +405,7 @@ void FrameBuffer::checkFramebufferStatus()
{
// approximation of RAM needed for this FBO
GLint framebufferMemoryInKB = ( width() * height() * (use_alpha_?4:3) * (use_multi_sampling_?2:1) ) / 1024;
GLint framebufferMemoryInKB = ( width() * height() * (flags_ & FrameBuffer_alpha?4:3) * (flags_ & FrameBuffer_multisampling?2:1) ) / 1024;
// test available memory if created buffer is big (more than 8MB)
if ( framebufferMemoryInKB > 8000 ) {
@@ -463,7 +515,7 @@ FrameBufferImage *FrameBuffer::image(){
return img;
// only compatible for RGB FrameBuffers
if (use_alpha_ || use_multi_sampling_)
if (flags_ & FrameBuffer_alpha || flags_ & FrameBuffer_multisampling)
return img;
// allocate image
@@ -482,7 +534,7 @@ bool FrameBuffer::fill(FrameBufferImage *image)
init();
// only compatible for RGB FrameBuffers
if (use_alpha_ || use_multi_sampling_)
if (flags_ & FrameBuffer_alpha || flags_ & FrameBuffer_multisampling)
return false;
// invalid image

View File

@@ -4,6 +4,7 @@
#include "RenderingManager.h"
#define FBI_JPEG_QUALITY 90
#define MIPMAP_LEVEL 6
/**
* @brief The FrameBufferImage class stores an RGB image in RAM
@@ -45,8 +46,17 @@ public:
static glm::vec3 getResolutionFromParameters(int ar, int h);
static glm::ivec2 getParametersFromResolution(glm::vec3 res);
FrameBuffer(glm::vec3 resolution, bool useAlpha = false, bool multiSampling = false);
FrameBuffer(uint width, uint height, bool useAlpha = false, bool multiSampling = false);
enum FrameBufferCreationFlags_
{
FrameBuffer_rgb = 0,
FrameBuffer_alpha = 1 << 1,
FrameBuffer_multisampling = 1 << 2,
FrameBuffer_mipmap = 1 << 3
};
typedef int FrameBufferFlags;
FrameBuffer(glm::vec3 resolution, FrameBufferFlags flags = FrameBuffer_rgb);
FrameBuffer(uint width, uint height, FrameBufferFlags flags = FrameBuffer_rgb);
FrameBuffer(FrameBuffer const&) = delete;
~FrameBuffer();
@@ -81,8 +91,7 @@ public:
// internal pixel format
inline uint opengl_id() const { return framebufferid_; }
inline bool use_alpha() const { return use_alpha_; }
inline bool use_multisampling() const { return use_multi_sampling_; }
inline FrameBufferFlags flags() const { return flags_; }
// index for texturing
uint texture() const;
@@ -95,12 +104,12 @@ private:
void init();
void checkFramebufferStatus();
FrameBufferFlags flags_;
RenderingAttrib attrib_;
glm::mat4 projection_;
glm::vec2 projection_area_;
uint textureid_, intermediate_textureid_;
uint framebufferid_, intermediate_framebufferid_;
bool use_alpha_, use_multi_sampling_;
uint textureid_, multisampling_textureid_;
uint framebufferid_, multisampling_framebufferid_, mipmap_framebufferid_[MIPMAP_LEVEL] = {};
};

View File

@@ -6,7 +6,7 @@
#include "FrameBufferFilter.h"
const char* FrameBufferFilter::type_label[FrameBufferFilter::FILTER_INVALID] = {
"None", "Delay", "Custom"
"None", "Delay", "Shader code"
};
FrameBufferFilter::FrameBufferFilter() : enabled_(true), input_(nullptr)

View File

@@ -1,6 +1,7 @@
#ifndef FRAMEBUFFERFILTER_H
#define FRAMEBUFFERFILTER_H
#include <sys/types.h>
#include <glm/glm.hpp>
class Visitor;

View File

@@ -138,12 +138,12 @@ void FrameGrabbing::grabFrame(FrameBuffer *frame_buffer)
// if different frame buffer from previous frame
if ( frame_buffer->width() != width_ ||
frame_buffer->height() != height_ ||
frame_buffer->use_alpha() != use_alpha_) {
(frame_buffer->flags() & FrameBuffer::FrameBuffer_alpha) != use_alpha_) {
// define stream properties
width_ = frame_buffer->width();
height_ = frame_buffer->height();
use_alpha_ = frame_buffer->use_alpha();
use_alpha_ = (frame_buffer->flags() & FrameBuffer::FrameBuffer_alpha);
size_ = width_ * height_ * (use_alpha_ ? 4 : 3);
// first time initialization

View File

@@ -374,7 +374,9 @@ void ImageFilter::draw (FrameBuffer *input)
// (re)create framebuffer for result of first-pass
if (buffers_.first != nullptr)
delete buffers_.first;
buffers_.first = new FrameBuffer( input_->resolution(), input_->use_alpha() );
// FBO with mipmapping
FrameBuffer::FrameBufferFlags f = input_->flags() | FrameBuffer::FrameBuffer_mipmap;
buffers_.first = new FrameBuffer( input_->resolution(), f );
// enforce framebuffer if first-pass is created now, filled with input framebuffer
input_->blit( buffers_.first );
// create second-pass surface and shader, taking as texture the first-pass framebuffer
@@ -383,7 +385,7 @@ void ImageFilter::draw (FrameBuffer *input)
// (re)create framebuffer for result of second-pass
if (buffers_.second != nullptr)
delete buffers_.second;
buffers_.second = new FrameBuffer( buffers_.first->resolution(), buffers_.first->use_alpha() );
buffers_.second = new FrameBuffer( buffers_.first->resolution(), buffers_.first->flags() );
}
if ( enabled() )

View File

@@ -206,13 +206,13 @@ void InfoVisitor::visit (RenderSource& s)
if (s.frame()){
if (brief_) {
oss << (s.frame()->use_alpha() ? "RGBA, " : "RGB, ");
oss << (s.frame()->flags() & FrameBuffer::FrameBuffer_alpha ? "RGBA, " : "RGB, ");
oss << s.frame()->width() << " x " << s.frame()->height();
}
else {
oss << "Rendering Output (";
oss << RenderSource::rendering_provenance_label[s.renderingProvenance()] << ") " << std::endl;
oss << (s.frame()->use_alpha() ? "RGBA" : "RGB") << std::endl;
oss << (s.frame()->flags() & FrameBuffer::FrameBuffer_alpha ? "RGBA" : "RGB") << std::endl;
oss << s.frame()->width() << " x " << s.frame()->height();
}
}
@@ -230,13 +230,13 @@ void InfoVisitor::visit (CloneSource& s)
if (s.frame()){
if (brief_) {
oss << (s.frame()->use_alpha() ? "RGBA, " : "RGB, ");
oss << (s.frame()->flags() & FrameBuffer::FrameBuffer_alpha ? "RGBA, " : "RGB, ");
oss << s.frame()->width() << " x " << s.frame()->height();
}
else {
if (s.origin())
oss << "Clone of '" << s.origin()->name() << "' " << std::endl;
oss << (s.frame()->use_alpha() ? "RGBA, " : "RGB, ");
oss << (s.frame()->flags() & FrameBuffer::FrameBuffer_alpha ? "RGBA, " : "RGB, ");
oss << FrameBufferFilter::type_label[s.filter()->type()] << " filter" << std::endl;
oss << s.frame()->width() << " x " << s.frame()->height();
}

View File

@@ -106,7 +106,7 @@ void MediaSource::init()
// create Frame buffer matching size of media player
float height = float(mediaplayer_->width()) / mediaplayer_->aspectRatio();
FrameBuffer *renderbuffer = new FrameBuffer(mediaplayer_->width(), (uint)height, true);
FrameBuffer *renderbuffer = new FrameBuffer(mediaplayer_->width(), (uint)height, FrameBuffer::FrameBuffer_alpha);
// icon in mixing view
if (mediaplayer_->isImage())

View File

@@ -78,9 +78,14 @@ void RenderSource::init()
// rendered_surface_ = new Surface;
// rendered_surface_->setTextureIndex( fb->texture() );
// use same flags than session frame, without multisampling
FrameBuffer::FrameBufferFlags flag = fb->flags();
flag &= ~FrameBuffer::FrameBuffer_multisampling;
// create the frame buffer displayed by the source (all modes)
rendered_output_ = new FrameBuffer( fb->resolution(), fb->use_alpha() );
// needs a first initialization
rendered_output_ = new FrameBuffer( fb->resolution(), flag );
// needs a first initialization (to get texture)
fb->blit(rendered_output_);
// set the texture index from internal framebuffer, apply it to the source texture surface

View File

@@ -77,9 +77,13 @@ void RenderView::setResolution(glm::vec3 resolution, bool useAlpha)
frame_buffer_ = nullptr;
}
if (!frame_buffer_)
if (!frame_buffer_) {
// output frame is an RBG Multisamples FrameBuffer
frame_buffer_ = new FrameBuffer(resolution, useAlpha, true);
FrameBuffer::FrameBufferFlags flag = FrameBuffer::FrameBuffer_multisampling;
if (useAlpha)
flag |= FrameBuffer::FrameBuffer_alpha;
frame_buffer_ = new FrameBuffer(resolution, flag);
}
// reset fading
setFading();

View File

@@ -522,12 +522,13 @@ glm::ivec2 Rendering::getGPUMemoryInformation()
}
bool Rendering::shouldHaveEnoughMemory(glm::vec3 resolution, bool useAlpha, bool multiSampling)
bool Rendering::shouldHaveEnoughMemory(glm::vec3 resolution, int flags)
{
glm::ivec2 RAM = getGPUMemoryInformation();
// approximation of RAM needed for such FBO
GLint framebufferMemoryInKB = ( resolution.x * resolution.x * (useAlpha?4:3) * (multiSampling?2:1) ) / 1024;
GLint framebufferMemoryInKB = ( resolution.x * resolution.x *
((flags & FrameBuffer::FrameBuffer_alpha)?4:3) * ((flags & FrameBuffer::FrameBuffer_multisampling)?2:1) ) / 1024;
return ( RAM.x > framebufferMemoryInKB * 3 );
}

View File

@@ -149,7 +149,7 @@ public:
// memory management
static glm::ivec2 getGPUMemoryInformation();
static bool shouldHaveEnoughMemory(glm::vec3 resolution, bool useAlpha = false, bool multiSampling = false);
static bool shouldHaveEnoughMemory(glm::vec3 resolution, int flags);
#ifdef USE_GST_OPENGL_SYNC_HANDLER
// for opengl pipeline in gstreamer

View File

@@ -124,7 +124,7 @@ void StreamSource::init()
// create Frame buffer matching size of media player
float height = float(stream_->width()) / stream_->aspectRatio();
FrameBuffer *renderbuffer = new FrameBuffer(stream_->width(), (uint)height, true);
FrameBuffer *renderbuffer = new FrameBuffer(stream_->width(), (uint)height, FrameBuffer::FrameBuffer_alpha);
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);