Setup Multisampling for all rendering and frame buffers. Store in

settings.
This commit is contained in:
brunoherbelin
2020-05-31 10:27:10 +02:00
parent f105a114a9
commit 11d21bcaeb
9 changed files with 115 additions and 77 deletions

View File

@@ -57,9 +57,6 @@ void Frame::draw(glm::mat4 modelview, glm::mat4 projection)
if ( visible_ ) {
// enable antialiasing
glEnable(GL_MULTISAMPLE_ARB);
// shadow
if(shadow_)
shadow_->draw( modelview * transform_, projection);
@@ -83,8 +80,6 @@ void Frame::draw(glm::mat4 modelview, glm::mat4 projection)
border_->draw( ctm, projection );
}
}
// enable antialiasing
glDisable(GL_MULTISAMPLE_ARB);
}
}
@@ -129,8 +124,6 @@ void Handles::draw(glm::mat4 modelview, glm::mat4 projection)
}
if ( visible_ ) {
// enable antialiasing
glEnable(GL_MULTISAMPLE_ARB);
// set color
handle_->shader()->color = color;
@@ -185,8 +178,6 @@ void Handles::draw(glm::mat4 modelview, glm::mat4 projection)
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
}
glDisable(GL_MULTISAMPLE_ARB);
}
}
@@ -240,9 +231,6 @@ void Icon::draw(glm::mat4 modelview, glm::mat4 projection)
if ( visible_ ) {
// enable antialiasing
glEnable(GL_MULTISAMPLE_ARB);
if(icon_) {
// set color
icon_->shader()->color = color;
@@ -254,9 +242,6 @@ void Icon::draw(glm::mat4 modelview, glm::mat4 projection)
icon_->draw( ctm, projection);
}
// enable antialiasing
glDisable(GL_MULTISAMPLE_ARB);
}
}

View File

@@ -1,6 +1,7 @@
#include "FrameBuffer.h"
#include "ImageShader.h"
#include "Resource.h"
#include "Settings.h"
#include "Log.h"
@@ -20,58 +21,65 @@ glm::vec3 FrameBuffer::getResolutionFromParameters(int ar, int h)
return res;
}
FrameBuffer::FrameBuffer(glm::vec3 resolution, bool useAlpha, bool useDepthBuffer): textureid_(0), framebufferid_(0), usealpha_(useAlpha), usedepth_(useDepthBuffer)
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)
{
attrib_.viewport = glm::ivec2(resolution);
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, usealpha_ ? 0.f : 1.f);
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, use_alpha_ ? 0.f : 1.f);
}
FrameBuffer::FrameBuffer(uint width, uint height, bool useAlpha, bool useDepthBuffer): textureid_(0), framebufferid_(0), usealpha_(useAlpha), usedepth_(useDepthBuffer)
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)
{
attrib_.viewport = glm::ivec2(width, height);
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, usealpha_ ? 0.f : 1.f);
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, use_alpha_ ? 0.f : 1.f);
}
void FrameBuffer::init()
{
// create a renderbuffer object to store depth info
GLuint rboId;
if (usedepth_){
glGenRenderbuffers(1, &rboId);
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, attrib_.viewport.x, attrib_.viewport.y);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
// create a framebuffer object
glGenFramebuffers(1, &framebufferid_);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferid_);
// generate texture
glGenTextures(1, &textureid_);
glBindTexture(GL_TEXTURE_2D, textureid_);
if (usealpha_)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, attrib_.viewport.x, attrib_.viewport.y,
glTexImage2D(GL_TEXTURE_2D, 0, use_alpha_ ? GL_RGBA : GL_RGB, attrib_.viewport.x, attrib_.viewport.y,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, attrib_.viewport.x, attrib_.viewport.y,
0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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);
// attach the texture to FBO color attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, textureid_, 0);
// create a framebuffer object
glGenFramebuffers(1, &framebufferid_);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferid_);
// attach the renderbuffer to depth attachment point
if (usedepth_){
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, rboId);
// take settings into account: no multisampling for level 0
use_multi_sampling_ &= Settings::application.multisampling_level > 0;
if (use_multi_sampling_){
// create a multisample texture
glGenTextures(1, &intermediate_textureid_);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, intermediate_textureid_);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, Settings::application.multisampling_level,
use_alpha_ ? GL_RGBA : GL_RGB, attrib_.viewport.x, attrib_.viewport.y, GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
// attach the multisampled texture to FBO (currently binded)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, intermediate_textureid_, 0);
// create an intermediate FBO
glGenFramebuffers(1, &intermediate_framebufferid_);
glBindFramebuffer(GL_FRAMEBUFFER, intermediate_framebufferid_);
// attach the 2D texture to intermediate FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
}
else {
// direct attach the 2D texture to FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
}
checkFramebufferStatus();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
FrameBuffer::~FrameBuffer()
@@ -119,9 +127,18 @@ void FrameBuffer::begin()
void FrameBuffer::end()
{
Rendering::manager().popAttrib();
// if multisampling frame buffer
if (use_multi_sampling_) {
// blit the multisample FBO into unisample FBO to generate 2D texture
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediate_framebufferid_);
glBlitFramebuffer(0, 0, attrib_.viewport.x, attrib_.viewport.y,
0, 0, attrib_.viewport.x, attrib_.viewport.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
FrameBuffer::release();
Rendering::manager().popAttrib();
}
void FrameBuffer::release()
@@ -131,11 +148,11 @@ void FrameBuffer::release()
bool FrameBuffer::blit(FrameBuffer *other)
{
if (!framebufferid_ || !other || !other->id())
if (!framebufferid_ || !other || !other->framebufferid_)
return false;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other->framebufferid_);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other->framebufferid_);
// blit to the frame buffer object
glBlitFramebuffer(0, 0, attrib_.viewport.x, attrib_.viewport.y,
0, 0, other->width(), other->height(),

View File

@@ -14,8 +14,8 @@ public:
static float resolution_height[4];
static glm::vec3 getResolutionFromParameters(int ar, int h);
FrameBuffer(glm::vec3 resolution, bool useAlpha = false, bool useDepthBuffer = false);
FrameBuffer(uint width, uint height, bool useAlpha = false, bool useDepthBuffer = false);
FrameBuffer(glm::vec3 resolution, bool useAlpha = false, bool multiSampling = false);
FrameBuffer(uint width, uint height, bool useAlpha = false, bool multiSampling = false);
~FrameBuffer();
// bind the FrameBuffer as current to draw into
@@ -43,16 +43,16 @@ public:
// texture index for draw
uint texture() const;
inline uint id() const { return framebufferid_; }
// inline uint id() const { return framebufferid_; }
private:
void init();
void checkFramebufferStatus();
RenderingAttrib attrib_;
uint textureid_;
uint framebufferid_;
bool usealpha_, usedepth_;
uint textureid_, intermediate_textureid_;
uint framebufferid_, intermediate_framebufferid_;
bool use_alpha_, use_multi_sampling_;
};

View File

@@ -255,14 +255,9 @@ void LineStrip::draw(glm::mat4 modelview, glm::mat4 projection)
glLineWidth(linewidth_);
// enable antialiasing
glEnable(GL_MULTISAMPLE_ARB);
Primitive::draw(modelview, projection);
glLineWidth(1);
glDisable(GL_MULTISAMPLE_ARB);
}
void LineStrip::accept(Visitor& v)

View File

@@ -95,6 +95,32 @@ static void WindowMoveCallback( GLFWwindow *w, int x, int y)
}
}
static void WindowKeyCallback( GLFWwindow *w, int key, int scancode, int action, int mods)
{
if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE)
{
// Log::Info("Esc");
// escape fullscreen
}
}
static void WindowMouseCallback( GLFWwindow *w, int button, int action, int mods)
{
static double seconds = 0.f;
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
{
// detect double clic
if ( glfwGetTime() - seconds < 0.2f ) {
Log::Info("double clic");
// toggle fullscreen
}
// for next clic detection
seconds = glfwGetTime();
}
}
Rendering::Rendering()
{
@@ -121,7 +147,7 @@ bool Rendering::init()
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
#endif
// GL Multisampling #3
glfwWindowHint(GLFW_SAMPLES, 3);
glfwWindowHint(GLFW_SAMPLES, Settings::application.multisampling_level);
// Create window with graphics context
Settings::WindowConfig winset = Settings::application.windows[0];
@@ -160,11 +186,11 @@ bool Rendering::init()
return false;
}
// show window
glfwShowWindow(main_window_);
// restore fullscreen
if (winset.fullscreen)
toggleFullscreen();
// // show window
// glfwShowWindow(main_window_);
// // restore fullscreen
// if (winset.fullscreen)
// toggleFullscreen();
// Rendering area (here same as window)
glfwGetFramebufferSize(main_window_, &(main_window_attributes_.viewport.x), &(main_window_attributes_.viewport.y));
@@ -179,7 +205,10 @@ bool Rendering::init()
gst_init (NULL, NULL);
// Antialiasing
if (Settings::application.multisampling_level > 0) {
glEnable(GL_MULTISAMPLE_ARB);
glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
}
// This hint can improve the speed of texturing when perspective-correct texture coordinate interpolation isn't needed
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
// This hint can improve the speed of shading when dFdx dFdy aren't needed in GLSL
@@ -230,6 +259,12 @@ bool Rendering::init()
// output window
output.init(main_window_, 1);
// show window
glfwShowWindow(main_window_);
// restore fullscreen
if (winset.fullscreen)
toggleFullscreen();
return true;
}
@@ -530,9 +565,9 @@ bool RenderingWindow::init(GLFWwindow *share, int id)
glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_SAMPLES, 0);
glfwWindowHint(GLFW_DEPTH_BITS, 0);
glfwWindowHint(GLFW_ALPHA_BITS, 0);
// glfwWindowHint(GLFW_SAMPLES, 0);
// glfwWindowHint(GLFW_DEPTH_BITS, 0);
// glfwWindowHint(GLFW_ALPHA_BITS, 0);
window_ = glfwCreateWindow(winset.w, winset.h, winset.name.c_str(), NULL, master_);
if (window_ == NULL){
@@ -544,6 +579,8 @@ bool RenderingWindow::init(GLFWwindow *share, int id)
// callbacks
glfwSetFramebufferSizeCallback( window_, WindowResizeCallback );
glfwSetWindowPosCallback( window_, WindowMoveCallback );
glfwSetKeyCallback( window_, WindowKeyCallback);
glfwSetMouseButtonCallback( window_, WindowMouseCallback);
// take context ownership
glfwMakeContextCurrent(window_);
@@ -586,12 +623,10 @@ void RenderingWindow::draw(FrameBuffer *fb)
// take context ownership
glfwMakeContextCurrent(window_);
// render some stuff
// update viewport (could be done with callback)
glfwGetFramebufferSize(window_, &(window_attributes_.viewport.x), &(window_attributes_.viewport.y));
glViewport(0, 0, window_attributes_.viewport.x, window_attributes_.viewport.y);
glClearColor(window_attributes_.clear_color.r, window_attributes_.clear_color.g,
window_attributes_.clear_color.b, window_attributes_.clear_color.a);
Rendering::manager().pushAttrib(window_attributes_);
glClear(GL_COLOR_BUFFER_BIT);
static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
@@ -610,6 +645,10 @@ void RenderingWindow::draw(FrameBuffer *fb)
surface->draw(glm::scale(glm::identity<glm::mat4>(), scale), projection);
}
glBindTexture(GL_TEXTURE_2D, 0);
Rendering::manager().popAttrib();
// swap buffer
glfwSwapBuffers(window_);
}

View File

@@ -63,6 +63,7 @@ void Settings::Save()
applicationNode->SetAttribute("toolbox", application.toolbox);
applicationNode->SetAttribute("framebuffer_ar", application.framebuffer_ar);
applicationNode->SetAttribute("framebuffer_h", application.framebuffer_h);
applicationNode->SetAttribute("multisampling_level", application.multisampling_level);
pRoot->InsertEndChild(applicationNode);
// bloc views
@@ -166,6 +167,7 @@ void Settings::Load()
pElement->QueryIntAttribute("stats_corner", &application.stats_corner);
pElement->QueryIntAttribute("framebuffer_ar", &application.framebuffer_ar);
pElement->QueryIntAttribute("framebuffer_h", &application.framebuffer_h);
pElement->QueryIntAttribute("multisampling_level", &application.multisampling_level);
// bloc windows
{

View File

@@ -76,9 +76,9 @@ struct Application
std::map<int, ViewConfig> views;
int framebuffer_ar;
int framebuffer_h;
int multisampling_level;
// multiple windows handling
// TODO: manage other windows
std::vector<WindowConfig> windows;
// recent files histories
@@ -98,6 +98,7 @@ struct Application
current_view = 1;
framebuffer_ar = 3;
framebuffer_h = 1;
multisampling_level = 2; // todo GUI selection
std::vector<int> second (4,100);
windows = std::vector<WindowConfig>(3);
windows[0].name = APP_NAME APP_TITLE;

View File

@@ -205,7 +205,8 @@ void RenderView::setResolution(glm::vec3 resolution)
if (frame_buffer_)
delete frame_buffer_;
frame_buffer_ = new FrameBuffer(resolution);
// output frame is an RBG Multisamples FrameBuffer
frame_buffer_ = new FrameBuffer(resolution, false, true);
}
void RenderView::draw()

View File

@@ -34,14 +34,12 @@
#define IMGUI_TITLE_DELETE ICON_FA_BROOM " Delete?"
#define IMGUI_RIGHT_ALIGN -3.5f * ImGui::GetTextLineHeightWithSpacing()
#define IMGUI_NOTIFICATION_DURATION 1.5f
#ifdef APPLE
#define CTRL_MOD "Cmd+"
#else
#define CTRL_MOD "Ctrl+"
#endif
#define COLOR_BGROUND 0.2f, 0.2f, 0.2f
#define COLOR_NAVIGATOR 0.1f, 0.1f, 0.1f
#define COLOR_DEFAULT_SOURCE 1.f, 1.f, 1.f