mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-12 02:40:00 +01:00
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:
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
150
FrameBuffer.cpp
150
FrameBuffer.cpp
@@ -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
|
||||
|
||||
@@ -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] = {};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef FRAMEBUFFERFILTER_H
|
||||
#define FRAMEBUFFERFILTER_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class Visitor;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() )
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user