diff --git a/qglengine/core/glframebuffer.cpp b/qglengine/core/glframebuffer.cpp index c473586..8d8cfbc 100644 --- a/qglengine/core/glframebuffer.cpp +++ b/qglengine/core/glframebuffer.cpp @@ -191,7 +191,7 @@ QVector Framebuffer::grabF(int index) const { } -void Framebuffer::blit(int index_from, GLuint fb_to, int index_to, QRect from, QRect to, GLbitfield mask, GLenum filter) { +void Framebuffer::blit(int index_from, GLuint fb_to, int index_to, QRect from, QRect to, GLbitfield mask, GLenum filter) const { if (index_from < 0 || index_from >= colors.size()) return; GLenum e = GL_COLOR_ATTACHMENT0 + index_to; f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_to); diff --git a/qglengine/core/glframebuffer.h b/qglengine/core/glframebuffer.h index a2e61e9..b544da7 100644 --- a/qglengine/core/glframebuffer.h +++ b/qglengine/core/glframebuffer.h @@ -24,6 +24,7 @@ class Framebuffer { + friend class FramebufferMipmap; public: Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum _target = GL_TEXTURE_2D); Framebuffer(QOpenGLExtraFunctions * f_, QVector colors_, bool withDepth = true, GLenum _target = GL_TEXTURE_2D); @@ -47,7 +48,7 @@ public: QVector getPoints() const; QImage getImage() const; int queriedPoints() const {return pbo_queried;} - void blit(int index_from, GLuint fb_to, int index_to, QRect from, QRect to, GLbitfield mask = GL_COLOR_BUFFER_BIT, GLenum filter = GL_NEAREST); + void blit(int index_from, GLuint fb_to, int index_to, QRect from, QRect to, GLbitfield mask = GL_COLOR_BUFFER_BIT, GLenum filter = GL_NEAREST) const; void resize(int width, int height, bool force = false); void bind(); diff --git a/qglengine/core/glframebuffer_mipmap.cpp b/qglengine/core/glframebuffer_mipmap.cpp new file mode 100644 index 0000000..59a3299 --- /dev/null +++ b/qglengine/core/glframebuffer_mipmap.cpp @@ -0,0 +1,50 @@ +/* + QGLView + Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include "glframebuffer_mipmap.h" +#include + + +FramebufferMipmap::FramebufferMipmap(const Framebuffer & fb, int index_from_, int levels): src_fb(fb) { + index_from = index_from_; + for (int i = 0; i < levels; ++i) + fbo << new Framebuffer(fb.f, 1, false, fb.color_formats[index_from]); +} + + +FramebufferMipmap::~FramebufferMipmap() { + +} + + +void FramebufferMipmap::resize() { + QSize sz = src_fb.size(); + for (int i = 0; i < fbo.size(); ++i) { + sz /= 2; + fbo[i]->resize(sz.width(), sz.height()); + } +} + + +void FramebufferMipmap::create() { + if (fbo.isEmpty()) return; + src_fb.blit(index_from, fbo[0]->id(), 0, src_fb.rect(), fbo[0]->rect(), GL_COLOR_BUFFER_BIT, GL_LINEAR); + for (int i = 0; i < fbo.size() - 1; ++i) + fbo[i]->blit(0, fbo[i + 1]->id(), 0, fbo[i]->rect(), fbo[i + 1]->rect(), GL_COLOR_BUFFER_BIT, GL_LINEAR); +} diff --git a/qglengine/core/glframebuffer_mipmap.h b/qglengine/core/glframebuffer_mipmap.h new file mode 100644 index 0000000..5320d21 --- /dev/null +++ b/qglengine/core/glframebuffer_mipmap.h @@ -0,0 +1,49 @@ +/* + QGLView + Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef GLFRAMEBUFFER_MIPMAP_H +#define GLFRAMEBUFFER_MIPMAP_H + +#include "glframebuffer.h" + + +class FramebufferMipmap +{ +public: + FramebufferMipmap(const Framebuffer & fb, int index_from_, int levels = 2); + virtual ~FramebufferMipmap(); + + int levelsCount() const {return fbo.size();} + int lastLevel() const {return fbo.size() - 1;} + Framebuffer & plane(int level) {return *fbo[level];} + int width (int level) const {return fbo[level]->wid;} + int height(int level) const {return fbo[level]->hei;} + QSize size(int level) const {return fbo[level]->size();} + QRect rect(int level) const {return fbo[level]->rect();} + + void resize(); + void create(); + +private: + int index_from; + const Framebuffer & src_fb; + QVector fbo; + +}; + +#endif // GLFRAMEBUFFER_MIPMAP_H diff --git a/qglengine/core/gltypes.h b/qglengine/core/gltypes.h index 2877e2d..5f08999 100644 --- a/qglengine/core/gltypes.h +++ b/qglengine/core/gltypes.h @@ -174,6 +174,8 @@ class Map; class Material; class TextureManager; class Texture2DArray; +class Framebuffer; +class FramebufferMipmap; class Mesh; class Scene; class RendererBase; diff --git a/qglengine/qglview.h b/qglengine/qglview.h index 15b24bb..fecde87 100644 --- a/qglengine/qglview.h +++ b/qglengine/qglview.h @@ -48,6 +48,7 @@ class QGLView: public OpenGLWindow Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth) Q_PROPERTY (float FOV READ FOV WRITE setFOV) Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart) + Q_PROPERTY (float exposure READ exposure WRITE setExposure) Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor) Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor) Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled) @@ -109,6 +110,7 @@ public: float FOV() const {return camera()->fov_;} float depthStart() const {return camera()->depth_start;} float currentFPS() const {return fps_;} + float exposure() const {return renderer_.exposure_;} int maxAnisotropicLevel() const {return max_anisotropic;} QColor ambientColor() const {return ambientColor_;} @@ -228,6 +230,7 @@ public slots: void setLineWidth(const float & arg) {lineWidth_ = arg;} void setFOV(const float & arg) {camera()->fov_ = arg;} void setDepthStart(const float & arg) {camera()->depth_start = arg;} + void setExposure(const float & arg) {renderer_.exposure_ = arg;} void setAmbientColor(const QColor & arg) {ambientColor_ = arg;} void setFogColor(const QColor & arg) {fogColor_ = arg;} void setFogDensity(const float & arg) {fogDensity_ = arg;} diff --git a/qglengine/qglview_test/qglview_window.cpp b/qglengine/qglview_test/qglview_window.cpp index e72c9a8..784e23e 100644 --- a/qglengine/qglview_test/qglview_window.cpp +++ b/qglengine/qglview_test/qglview_window.cpp @@ -30,7 +30,6 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView setupUi(this); session.setFile("session_qglview_test.conf"); session.addEntry(this); - spinViewLineWidth->setValue(lineThickness()*2); //view->view()->camera()->setPos(QVector3D(2, 2, 2)); //view->view()->camera()->setAim(QVector3D()); diff --git a/qglengine/qglview_test/qglview_window.h b/qglengine/qglview_test/qglview_window.h index d9b2737..39580e5 100644 --- a/qglengine/qglview_test/qglview_window.h +++ b/qglengine/qglview_test/qglview_window.h @@ -63,6 +63,7 @@ private: private slots: void on_spinFOV_valueChanged(double val) {view->view()->setFOV(val);} void on_spinDepthStart_valueChanged(double val) {view->view()->setDepthStart(val);} + void on_spinViewExposure_valueChanged(double val) {view->view()->setExposure(val);} void on_comboViewRenderMode_currentIndexChanged(int val) {static int modes[] = {GL_POINT, GL_LINE, GL_FILL}; view->view()->setRenderMode((ObjectBase::RenderMode)modes[val]);} void on_groupHoverHalo_clicked(bool val) {view->view()->setHoverHaloEnabled(val);} void on_groupSelectionHalo_clicked(bool val) {view->view()->setSelectionHaloEnabled(val);} diff --git a/qglengine/qglview_test/qglview_window.ui b/qglengine/qglview_test/qglview_window.ui index 0c6b934..d091dce 100644 --- a/qglengine/qglview_test/qglview_window.ui +++ b/qglengine/qglview_test/qglview_window.ui @@ -57,7 +57,7 @@ - 3 + 0 @@ -67,7 +67,7 @@ - 1 + 0 @@ -107,86 +107,14 @@ - - - - 0 - - - - - 3 - - - 999999999.000000000000000 - - - 1.000000000000000 - - - - - - - - 0 - 0 - - - - - - - - - - - - 3 - - - 999999999.000000000000000 - - - - - - - - Renderer - - - - - - - 0 - - - - Simple - - - - - Deferred shading - - - - - RT - - - - - Draw mode - + 2 @@ -208,14 +136,14 @@ - + Back color - + @@ -226,14 +154,14 @@ - + Ambient - + @@ -244,21 +172,40 @@ - - + + - MSAA + Exposure - + + + + 0.010000000000000 + + + 99.000000000000000 + + + 1.000000000000000 + + + 3 + + + true + + + + FXAA - + Hover halo @@ -313,7 +260,7 @@ - + Selection halo @@ -368,7 +315,7 @@ - + Camera @@ -397,29 +344,19 @@ - - - - 0.000000000000000 + + + + 3 - 99999.000000000000000 - - - 0.100000000000000 + 999999999.000000000000000 1.000000000000000 - - - - Line width - - - @@ -440,8 +377,8 @@ 0 0 - 968 - 636 + 960 + 737 @@ -1079,8 +1016,8 @@ 0 0 - 1009 - 877 + 999 + 853 @@ -1163,7 +1100,7 @@ 0 0 1125 - 21 + 24 diff --git a/qglengine/renderer.cpp b/qglengine/renderer.cpp index 372f6a0..8dd0359 100644 --- a/qglengine/renderer.cpp +++ b/qglengine/renderer.cpp @@ -30,9 +30,8 @@ using namespace QGLEngineShaders; Renderer::Renderer(QGLView * view_): RendererBase(view_), fbo_ds (view_, QVector() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F), fbo_out (view_, 6, false, GL_RGBA16F), - fbo_small_4 (view_, 1, false, GL_RGBA16F), - fbo_small_16 (view_, 1, false, GL_RGBA16F), fbo_1x1 (view_, 1, false, GL_RGB32F ), + fbomm(fbo_out, obrSum, 3), buffer_vbo(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW), rend_mat(this), rend_service(this), rend_selection(this) { shader_sum = 0; @@ -104,8 +103,7 @@ void Renderer::resize(int width, int height) { rend_selection.resize(width, height); fbo_ds .resize(width, height); fbo_out .resize(width, height); - fbo_small_4 .resize(width / 4 , height / 4 ); - fbo_small_16 .resize(width / 16, height / 16); + fbomm.resize(); resizeSum(); } @@ -228,12 +226,12 @@ void Renderer::prepareSum() { void Renderer::resizeSum() { QOpenGLExtraFunctions * f = view; - int pcnt = fbo_small_16.width() * fbo_small_16.height(); + int pcnt = fbomm.width(fbomm.lastLevel()) * fbomm.height(fbomm.lastLevel()); QVector _data; _data.resize(pcnt); pcnt = -1; - for (int x = 0; x < fbo_small_16.width(); ++x) - for (int y = 0; y < fbo_small_16.height(); ++y) + for (int x = 0; x < fbomm.width(fbomm.lastLevel()); ++x) + for (int y = 0; y < fbomm.height(fbomm.lastLevel()); ++y) _data[++pcnt] = Vector2i(x,y); buffer_vbo.bind(f); buffer_vbo.resize(f, _data.size() * sizeof(Vector2i)); @@ -348,11 +346,11 @@ void Renderer::renderScene() { fbo_out.setWriteBuffer(obrSum); renderQuad(prog, quad); } - fbo_out.blit(obrSum, fbo_small_4.id(), 0, fbo_out.rect(), fbo_small_4.rect(), GL_COLOR_BUFFER_BIT, GL_LINEAR); - fbo_small_4.blit(0, fbo_small_16.id(), 0, fbo_small_4.rect(), fbo_small_16.rect(), GL_COLOR_BUFFER_BIT, GL_LINEAR); - renderSum(fbo_small_16, 0); + fbomm.create(); + renderSum(fbomm.plane(fbomm.lastLevel()), 0); fbo_out.bind(); if (bindShader(srTonemapPass, &prog)) { + prog->setUniformValue("exposure", exposure_); fbo_1x1.bindColorTexture(0, 1); fbo_out.bindColorTexture(obrSum, 0); fbo_out.setWriteBuffer(obrTonemap); diff --git a/qglengine/renderer.h b/qglengine/renderer.h index 6e32930..d0f9b42 100644 --- a/qglengine/renderer.h +++ b/qglengine/renderer.h @@ -23,6 +23,7 @@ #include "renderer_material.h" #include "renderer_service.h" #include "renderer_selection.h" +#include "glframebuffer_mipmap.h" #include @@ -101,7 +102,8 @@ protected: private: float exposure_; bool edit_mode, need_init_shaders, is_camera_light; - Framebuffer fbo_ds, fbo_out, fbo_small_4, fbo_small_16, fbo_1x1; + Framebuffer fbo_ds, fbo_out, fbo_1x1; + FramebufferMipmap fbomm; /*QOpenGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1, * shader_hdr, * shader_small; QOpenGLShaderProgram * shader_bloom_0, * shader_bloom_1, * shader_motion_blur, * shader_fbo_add; QOpenGLShaderProgram * shader_shadow, * shader_ssr, * shader_ssr_blur, * shader_ssr_merge; diff --git a/qglengine/shaders/ds_final.glsl b/qglengine/shaders/ds_final.glsl index b48e9bf..0d3fcd2 100644 --- a/qglengine/shaders/ds_final.glsl +++ b/qglengine/shaders/ds_final.glsl @@ -9,11 +9,10 @@ void main(void) { uniform sampler2D tex_0, tex_1, tex_2, tex_3, tex_4; -const vec3 luma = vec3(0.299, 0.587, 0.114); - void main(void) { ivec2 tc = ivec2(gl_FragCoord.xy); vec4 v0 = texelFetch(tex_0, tc, 0); vec4 v1 = texelFetch(tex_1, tc, 0); - qgl_FragColor = v0 + v1; + vec3 res = v0.rgb + v1.rgb; + qgl_FragColor.rgb = res; } diff --git a/qglengine/shaders/ds_light.glsl b/qglengine/shaders/ds_light.glsl index eeba97b..95ad9c1 100644 --- a/qglengine/shaders/ds_light.glsl +++ b/qglengine/shaders/ds_light.glsl @@ -81,7 +81,7 @@ void calcLight(in int index, in vec3 n, in vec3 v) { float ndlc = (1. - NdotLs) / NdotLs; float der = NdotLs * (shm_diff + ndlc); diff = 2. / (1. + sqrt(1. + (1. - shm_diff) * ndlc)); - li += spot * diff * qgl_light_parameter[index].color.rgb;// * light_diffuse(0, ldir, n); + li += spot * diff * qgl_light_parameter[index].color.rgb; ndlc = (1. - NdotHs) / NdotHs; der = NdotHs * (shm_spec + ndlc); diff --git a/qglengine/shaders/ds_tonemap.glsl b/qglengine/shaders/ds_tonemap.glsl index bc11f4c..db08167 100644 --- a/qglengine/shaders/ds_tonemap.glsl +++ b/qglengine/shaders/ds_tonemap.glsl @@ -8,6 +8,7 @@ void main(void) { // frag // uniform sampler2D tex_0, tex_sum; +uniform float exposure; const vec3 luma = vec3(0.299, 0.587, 0.114); @@ -17,7 +18,7 @@ void main(void) { vec4 sum = texelFetch(tex_sum, ivec2(0,0), 0); vec3 res = src.rgb; float l = dot(res, luma); - float g = 2.2/dot(sum.rgb, luma); + float g = exposure / dot(sum.rgb, luma); res /= l; //res = log(res + vec3(2.)) - log(vec3(2.)); //res = pow(res,vec3(1/2.2));