git-svn-id: svn://db.shs.com.ru/libs@661 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
@@ -93,9 +93,7 @@ void Framebuffer::resize(int width, int height, bool force) {
|
|||||||
}
|
}
|
||||||
f->glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
f->glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
if (pbo.isInit()) {
|
if (pbo.isInit()) {
|
||||||
pbo.bind(f);
|
enablePixelBuffer();
|
||||||
pbo.resize(f, width*height*4);
|
|
||||||
pbo.release(f);
|
|
||||||
}
|
}
|
||||||
is_changed = false;
|
is_changed = false;
|
||||||
}
|
}
|
||||||
@@ -119,7 +117,7 @@ void Framebuffer::queryPoint(int index, QPoint p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Framebuffer::queryPoints(int index, QRect rect_) {
|
void Framebuffer::queryPoints(int index, QRect rect_, GLenum pixel_format) {
|
||||||
pbo_queried = 0;
|
pbo_queried = 0;
|
||||||
if (index < 0 || index >= colors.size()) return;
|
if (index < 0 || index >= colors.size()) return;
|
||||||
rect_ &= rect();
|
rect_ &= rect();
|
||||||
@@ -127,7 +125,7 @@ void Framebuffer::queryPoints(int index, QRect rect_) {
|
|||||||
f->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
f->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||||
f->glReadBuffer(GL_COLOR_ATTACHMENT0 + index);
|
f->glReadBuffer(GL_COLOR_ATTACHMENT0 + index);
|
||||||
pbo.bind(f);
|
pbo.bind(f);
|
||||||
f->glReadPixels(rect_.x(), height() - rect_.bottom(), rect_.width(), rect_.height(), GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
f->glReadPixels(rect_.x(), height() - rect_.bottom(), rect_.width(), rect_.height(), GL_RGBA, pixel_format, 0);
|
||||||
pbo_queried = rect_.width() * rect_.height();
|
pbo_queried = rect_.width() * rect_.height();
|
||||||
pbo.release(f);
|
pbo.release(f);
|
||||||
}
|
}
|
||||||
@@ -151,7 +149,7 @@ uint Framebuffer::getPoint() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QVector<uint> Framebuffer::getPoints() const {
|
QVector<uint> Framebuffer::getPointsByte() const {
|
||||||
QVector<uint> ret;
|
QVector<uint> ret;
|
||||||
if (!pbo.isInit() || (pbo_queried == 0)) return ret;
|
if (!pbo.isInit() || (pbo_queried == 0)) return ret;
|
||||||
ret.resize(pbo_queried);
|
ret.resize(pbo_queried);
|
||||||
@@ -165,6 +163,20 @@ QVector<uint> Framebuffer::getPoints() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QVector<QVector4D> Framebuffer::getPointsFloat() const {
|
||||||
|
QVector<QVector4D> ret;
|
||||||
|
if (!pbo.isInit() || (pbo_queried == 0)) return ret;
|
||||||
|
ret.resize(pbo_queried);
|
||||||
|
pbo.bind(f);
|
||||||
|
void * map = pbo.map(f, GL_MAP_READ_BIT, pbo_queried * sizeof(QVector4D));
|
||||||
|
if (map)
|
||||||
|
memcpy(ret.data(), map, pbo_queried * sizeof(QVector4D));
|
||||||
|
pbo.unmap(f);
|
||||||
|
pbo.release(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QImage Framebuffer::getImage() const {
|
QImage Framebuffer::getImage() const {
|
||||||
QImage ret;
|
QImage ret;
|
||||||
if (!pbo.isInit() || (pbo_queried == 0)) return ret;
|
if (!pbo.isInit() || (pbo_queried == 0)) return ret;
|
||||||
@@ -258,6 +270,9 @@ void Framebuffer::unsetWriteBuffers() {
|
|||||||
|
|
||||||
void Framebuffer::enablePixelBuffer() {
|
void Framebuffer::enablePixelBuffer() {
|
||||||
pbo.init(f);
|
pbo.init(f);
|
||||||
|
pbo.bind(f);
|
||||||
|
pbo.resize(f, width()*height()*4*4);
|
||||||
|
pbo.release(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ public:
|
|||||||
//GLenum colorFormat() const {return color_format;}
|
//GLenum colorFormat() const {return color_format;}
|
||||||
GLuint depthTexture() const {return tex_d;}
|
GLuint depthTexture() const {return tex_d;}
|
||||||
GLenum target() const {return target_;}
|
GLenum target() const {return target_;}
|
||||||
|
bool isInit() const {return fbo != 0;}
|
||||||
int width() const {return wid;}
|
int width() const {return wid;}
|
||||||
int height() const {return hei;}
|
int height() const {return hei;}
|
||||||
QSize size() const {return QSize(wid, hei);}
|
QSize size() const {return QSize(wid, hei);}
|
||||||
@@ -42,10 +43,11 @@ public:
|
|||||||
QImage grab() const;
|
QImage grab() const;
|
||||||
QVector<float> grabF(int index) const;
|
QVector<float> grabF(int index) const;
|
||||||
void queryPoint(int index, QPoint p);
|
void queryPoint(int index, QPoint p);
|
||||||
void queryPoints(int index, QRect rect);
|
void queryPoints(int index, QRect rect, GLenum pixel_format = GL_UNSIGNED_BYTE);
|
||||||
void queryImage(int index);
|
void queryImage(int index);
|
||||||
uint getPoint() const;
|
uint getPoint() const;
|
||||||
QVector<uint> getPoints() const;
|
QVector<uint> getPointsByte() const;
|
||||||
|
QVector<QVector4D> getPointsFloat() const;
|
||||||
QImage getImage() const;
|
QImage getImage() const;
|
||||||
int queriedPoints() const {return pbo_queried;}
|
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) const;
|
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;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public:
|
|||||||
int levelsCount() const {return fbo.size();}
|
int levelsCount() const {return fbo.size();}
|
||||||
int lastLevel() const {return fbo.size() - 1;}
|
int lastLevel() const {return fbo.size() - 1;}
|
||||||
Framebuffer & plane(int level) {return *fbo[level];}
|
Framebuffer & plane(int level) {return *fbo[level];}
|
||||||
|
Framebuffer & lastPlane() {return *fbo[lastLevel()];}
|
||||||
int width (int level) const {return fbo[level]->wid;}
|
int width (int level) const {return fbo[level]->wid;}
|
||||||
int height(int level) const {return fbo[level]->hei;}
|
int height(int level) const {return fbo[level]->hei;}
|
||||||
QSize size(int level) const {return fbo[level]->size();}
|
QSize size(int level) const {return fbo[level]->size();}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ class QGLView: public OpenGLWindow
|
|||||||
friend class RendererMaterial;
|
friend class RendererMaterial;
|
||||||
friend class RendererService;
|
friend class RendererService;
|
||||||
friend class RendererSelection;
|
friend class RendererSelection;
|
||||||
|
friend class TonemappingProc;
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor)
|
Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor)
|
||||||
Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth)
|
Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth)
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ private slots:
|
|||||||
void on_colorAmbient_colorChanged(QColor color) {view->view()->setAmbientColor(color);}
|
void on_colorAmbient_colorChanged(QColor color) {view->view()->setAmbientColor(color);}
|
||||||
void on_checkCameraOrbit_clicked(bool val) {view->view()->setCameraOrbit(val);}
|
void on_checkCameraOrbit_clicked(bool val) {view->view()->setCameraOrbit(val);}
|
||||||
void on_checkCameraLight_clicked(bool val) {view->view()->setCameraLightOn(val);}
|
void on_checkCameraLight_clicked(bool val) {view->view()->setCameraLightOn(val);}
|
||||||
void on_spinViewLineWidth_valueChanged(double val) {view->view()->setLineWidth(val);}
|
|
||||||
|
|
||||||
void on_groupShadows_clicked(bool val) {view->view()->setFeature(QGLView::qglShadowsEnabled, val);}
|
void on_groupShadows_clicked(bool val) {view->view()->setFeature(QGLView::qglShadowsEnabled, val);}
|
||||||
void on_groupEyeAccomodation_clicked(bool val) {view->view()->setFeature(QGLView::qglEyeAccomodationEnabled, val);}
|
void on_groupEyeAccomodation_clicked(bool val) {view->view()->setFeature(QGLView::qglEyeAccomodationEnabled, val);}
|
||||||
|
|||||||
@@ -30,11 +30,7 @@ using namespace QGLEngineShaders;
|
|||||||
Renderer::Renderer(QGLView * view_): RendererBase(view_),
|
Renderer::Renderer(QGLView * view_): RendererBase(view_),
|
||||||
fbo_ds (view_, QVector<GLenum>() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F),
|
fbo_ds (view_, QVector<GLenum>() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F),
|
||||||
fbo_out (view_, 6, false, GL_RGBA16F),
|
fbo_out (view_, 6, false, GL_RGBA16F),
|
||||||
fbo_1x1 (view_, 1, false, GL_RGB32F ),
|
rend_mat(this), rend_service(this), rend_selection(this), tone_proc(this) {
|
||||||
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;
|
|
||||||
quad = Primitive::plane(2., 2.);
|
quad = Primitive::plane(2., 2.);
|
||||||
cam_light = new Light();
|
cam_light = new Light();
|
||||||
cam_light->intensity = 0.75;
|
cam_light->intensity = 0.75;
|
||||||
@@ -80,17 +76,15 @@ Renderer::~Renderer() {
|
|||||||
delete quad;
|
delete quad;
|
||||||
delete cam_light;
|
delete cam_light;
|
||||||
qDeleteAll(shaders.values());
|
qDeleteAll(shaders.values());
|
||||||
if (shader_sum) delete shader_sum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Renderer::init(int width, int height) {
|
void Renderer::init(int width, int height) {
|
||||||
prepareSum();
|
|
||||||
fbo_1x1.resize(1, 1);
|
|
||||||
resize(width, height);
|
resize(width, height);
|
||||||
rend_mat.init(width, height);
|
rend_mat.init(width, height);
|
||||||
rend_service.init(width, height);
|
rend_service.init(width, height);
|
||||||
rend_selection.init(width, height);
|
rend_selection.init(width, height);
|
||||||
|
tone_proc.init();
|
||||||
initQuad(quad);
|
initQuad(quad);
|
||||||
initTextureArrays();
|
initTextureArrays();
|
||||||
need_init_shaders = true;
|
need_init_shaders = true;
|
||||||
@@ -103,8 +97,7 @@ void Renderer::resize(int width, int height) {
|
|||||||
rend_selection.resize(width, height);
|
rend_selection.resize(width, height);
|
||||||
fbo_ds .resize(width, height);
|
fbo_ds .resize(width, height);
|
||||||
fbo_out .resize(width, height);
|
fbo_out .resize(width, height);
|
||||||
fbomm.resize();
|
tone_proc.resize();
|
||||||
resizeSum();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,7 +108,7 @@ void Renderer::reloadShaders() {
|
|||||||
it.next();
|
it.next();
|
||||||
loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key()));
|
loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key()));
|
||||||
}
|
}
|
||||||
loadShadersMulti(shader_sum, dir + "sum.glsl", false);
|
loadShadersMulti(tone_proc.shader_sum, dir + "sum.glsl", false);
|
||||||
need_init_shaders = true;
|
need_init_shaders = true;
|
||||||
view->scene()->setLightsChanged();
|
view->scene()->setLightsChanged();
|
||||||
view->scene()->setTreeStructChanged();
|
view->scene()->setTreeStructChanged();
|
||||||
@@ -211,62 +204,6 @@ void Renderer::renderObjects(Scene & scene, RenderPass pass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Renderer::prepareSum() {
|
|
||||||
QOpenGLExtraFunctions * f = view;
|
|
||||||
buffer_vbo.init(f);
|
|
||||||
f->glGenVertexArrays(1, &vbo_vao);
|
|
||||||
f->glBindVertexArray(vbo_vao);
|
|
||||||
buffer_vbo.bind(f);
|
|
||||||
f->glEnableVertexAttribArray(1);
|
|
||||||
f->glVertexAttribIPointer(1, 2, GL_UNSIGNED_INT, 0, 0);
|
|
||||||
buffer_vbo.release(f);
|
|
||||||
f->glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::resizeSum() {
|
|
||||||
QOpenGLExtraFunctions * f = view;
|
|
||||||
int pcnt = fbomm.width(fbomm.lastLevel()) * fbomm.height(fbomm.lastLevel());
|
|
||||||
QVector<Vector2i> _data;
|
|
||||||
_data.resize(pcnt);
|
|
||||||
pcnt = -1;
|
|
||||||
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));
|
|
||||||
buffer_vbo.load(f, _data.constData(), _data.size() * sizeof(Vector2i));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::renderSum(Framebuffer & fbo_src, int index) {
|
|
||||||
QOpenGLExtraFunctions * f = view;
|
|
||||||
int pcnt = fbo_src.width() * fbo_src.height();
|
|
||||||
fbo_src.bindColorTexture(index);
|
|
||||||
fbo_1x1.bind();
|
|
||||||
//glClearFramebuffer(Qt::white, false);
|
|
||||||
glClearFramebuffer();
|
|
||||||
if (shader_sum) {
|
|
||||||
if (shader_sum->isLinked()) {
|
|
||||||
if (shader_sum->bind()) {
|
|
||||||
shader_sum->setUniformValue("tex", 0);
|
|
||||||
shader_sum->setUniformValue("pcnt", float(pcnt));
|
|
||||||
f->glBindVertexArray(vbo_vao);
|
|
||||||
f->glEnable(GL_BLEND);
|
|
||||||
f->glBlendFunc(GL_ONE, GL_ONE);
|
|
||||||
f->glBlendEquation(GL_MAX);
|
|
||||||
f->glDrawArrays(GL_POINTS, 0, pcnt);
|
|
||||||
f->glBlendEquation(GL_FUNC_ADD);
|
|
||||||
f->glDisable(GL_BLEND);
|
|
||||||
f->glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fbo_1x1.release();
|
|
||||||
//fbo_src.bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::renderScene() {
|
void Renderer::renderScene() {
|
||||||
initShaders();
|
initShaders();
|
||||||
QOpenGLExtraFunctions * f = view;
|
QOpenGLExtraFunctions * f = view;
|
||||||
@@ -346,12 +283,12 @@ void Renderer::renderScene() {
|
|||||||
fbo_out.setWriteBuffer(obrSum);
|
fbo_out.setWriteBuffer(obrSum);
|
||||||
renderQuad(prog, quad);
|
renderQuad(prog, quad);
|
||||||
}
|
}
|
||||||
fbomm.create();
|
if (tone_proc.process())
|
||||||
renderSum(fbomm.plane(fbomm.lastLevel()), 0);
|
|
||||||
fbo_out.bind();
|
fbo_out.bind();
|
||||||
if (bindShader(srTonemapPass, &prog)) {
|
if (bindShader(srTonemapPass, &prog)) {
|
||||||
prog->setUniformValue("exposure", exposure_);
|
prog->setUniformValue("exposure", exposure_);
|
||||||
fbo_1x1.bindColorTexture(0, 1);
|
prog->setUniformValue("frame_max", tone_proc.frameMax());
|
||||||
|
//fbo_1x1.bindColorTexture(0, 1);
|
||||||
fbo_out.bindColorTexture(obrSum, 0);
|
fbo_out.bindColorTexture(obrSum, 0);
|
||||||
fbo_out.setWriteBuffer(obrTonemap);
|
fbo_out.setWriteBuffer(obrTonemap);
|
||||||
renderQuad(prog, quad);
|
renderQuad(prog, quad);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "renderer_material.h"
|
#include "renderer_material.h"
|
||||||
#include "renderer_service.h"
|
#include "renderer_service.h"
|
||||||
#include "renderer_selection.h"
|
#include "renderer_selection.h"
|
||||||
#include "glframebuffer_mipmap.h"
|
#include "tonemapping_proc.h"
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ class Renderer: public RendererBase {
|
|||||||
friend class RendererMaterial;
|
friend class RendererMaterial;
|
||||||
friend class RendererService;
|
friend class RendererService;
|
||||||
friend class RendererSelection;
|
friend class RendererSelection;
|
||||||
|
friend class TonemappingProc;
|
||||||
enum RenderPass {
|
enum RenderPass {
|
||||||
rpSolid,
|
rpSolid,
|
||||||
rpTransparent,
|
rpTransparent,
|
||||||
@@ -91,9 +92,6 @@ protected:
|
|||||||
void fillObjectsBuffer(const QList<ObjectBase*> & ol, RenderPass pass);
|
void fillObjectsBuffer(const QList<ObjectBase*> & ol, RenderPass pass);
|
||||||
void reloadObjects();
|
void reloadObjects();
|
||||||
void renderObjects(Scene & scene, RenderPass pass);
|
void renderObjects(Scene & scene, RenderPass pass);
|
||||||
void prepareSum();
|
|
||||||
void resizeSum();
|
|
||||||
void renderSum(Framebuffer & fbo_src, int index);
|
|
||||||
|
|
||||||
bool bindShader(ShaderRole role, QOpenGLShaderProgram ** ret = 0);
|
bool bindShader(ShaderRole role, QOpenGLShaderProgram ** ret = 0);
|
||||||
void initShaders();
|
void initShaders();
|
||||||
@@ -101,9 +99,8 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
float exposure_;
|
float exposure_;
|
||||||
bool edit_mode, need_init_shaders, is_camera_light;
|
bool edit_mode, need_init_shaders, is_camera_light, need_render_sum;
|
||||||
Framebuffer fbo_ds, fbo_out, fbo_1x1;
|
Framebuffer fbo_ds, fbo_out;
|
||||||
FramebufferMipmap fbomm;
|
|
||||||
/*QOpenGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1, * shader_hdr, * shader_small;
|
/*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_bloom_0, * shader_bloom_1, * shader_motion_blur, * shader_fbo_add;
|
||||||
QOpenGLShaderProgram * shader_shadow, * shader_ssr, * shader_ssr_blur, * shader_ssr_merge;
|
QOpenGLShaderProgram * shader_shadow, * shader_ssr, * shader_ssr_blur, * shader_ssr_merge;
|
||||||
@@ -112,13 +109,10 @@ private:
|
|||||||
QMap<ShaderRole, QStringList> shader_defines;
|
QMap<ShaderRole, QStringList> shader_defines;
|
||||||
QMap<ShaderRole, QOpenGLShaderProgram*> shaders;
|
QMap<ShaderRole, QOpenGLShaderProgram*> shaders;
|
||||||
|
|
||||||
QOpenGLShaderProgram * shader_sum;
|
|
||||||
Buffer buffer_vbo;
|
|
||||||
GLenum vbo_vao;
|
|
||||||
|
|
||||||
RendererMaterial rend_mat;
|
RendererMaterial rend_mat;
|
||||||
RendererService rend_service;
|
RendererService rend_service;
|
||||||
RendererSelection rend_selection;
|
RendererSelection rend_selection;
|
||||||
|
TonemappingProc tone_proc;
|
||||||
|
|
||||||
Mesh * quad;
|
Mesh * quad;
|
||||||
Light * cam_light;
|
Light * cam_light;
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ void RendererSelection::renderSelection(Scene & scene) {
|
|||||||
}
|
}
|
||||||
//qDebug() << id_hover;
|
//qDebug() << id_hover;
|
||||||
} else {
|
} else {
|
||||||
QVector<uint> points = fbo_selection.getPoints();
|
QVector<uint> points = fbo_selection.getPointsByte();
|
||||||
QSet<uint> ids_hover;
|
QSet<uint> ids_hover;
|
||||||
foreach (uint i, points)
|
foreach (uint i, points)
|
||||||
ids_hover << i;
|
ids_hover << i;
|
||||||
|
|||||||
@@ -7,26 +7,18 @@ void main(void) {
|
|||||||
|
|
||||||
// frag //
|
// frag //
|
||||||
|
|
||||||
uniform sampler2D tex_0, tex_sum;
|
uniform sampler2D tex_0;
|
||||||
uniform float exposure;
|
uniform float exposure, frame_max;
|
||||||
|
|
||||||
const vec3 luma = vec3(0.299, 0.587, 0.114);
|
const vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
ivec2 tc = ivec2(gl_FragCoord.xy);
|
ivec2 tc = ivec2(gl_FragCoord.xy);
|
||||||
vec4 src = texelFetch(tex_0, tc, 0);
|
vec4 src = texelFetch(tex_0, tc, 0);
|
||||||
vec4 sum = texelFetch(tex_sum, ivec2(0,0), 0);
|
|
||||||
vec3 res = src.rgb;
|
vec3 res = src.rgb;
|
||||||
float l = dot(res, luma);
|
float l = dot(res, luma) * 0.75;
|
||||||
float g = exposure / dot(sum.rgb, luma);
|
float g = exposure / frame_max;
|
||||||
res /= l;
|
res /= l;
|
||||||
//res = log(res + vec3(2.)) - log(vec3(2.));
|
|
||||||
//res = pow(res,vec3(1/2.2));
|
|
||||||
//l = pow(l,1/2.2);
|
|
||||||
l = 1 - exp(-l*g);
|
l = 1 - exp(-l*g);
|
||||||
//l /= 100;
|
|
||||||
//res = pow(res,vec3(2.2));
|
|
||||||
//l = pow(l,2.2);
|
|
||||||
qgl_FragColor.rgb = res * l;
|
qgl_FragColor.rgb = res * l;
|
||||||
//qgl_FragColor.rgb = sum.rgb*10;
|
|
||||||
}
|
}
|
||||||
|
|||||||
185
qglengine/tonemapping_proc.cpp
Normal file
185
qglengine/tonemapping_proc.cpp
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
#include <QOpenGLExtraFunctions>
|
||||||
|
#include "tonemapping_proc.h"
|
||||||
|
#include "qglview.h"
|
||||||
|
#include <qad_types.h>
|
||||||
|
|
||||||
|
using namespace QGLEngineShaders;
|
||||||
|
|
||||||
|
|
||||||
|
TonemappingProc::TonemappingProc(Renderer * rend): QThread(), r(rend),
|
||||||
|
fbo_1x1(r->view, 1, false, GL_RGB32F),
|
||||||
|
fbomm(r->fbo_out, Renderer::obrSum, 3),
|
||||||
|
buffer_vbo(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW) {
|
||||||
|
shader_sum = 0;
|
||||||
|
timer_delim = 0;
|
||||||
|
frame_max = cur_max = 1.;
|
||||||
|
need_render_sum = exit_ = false;
|
||||||
|
timer_tone = startTimer(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TonemappingProc::~TonemappingProc() {
|
||||||
|
exit_ = true;
|
||||||
|
if (!wait(1000))
|
||||||
|
terminate();
|
||||||
|
killTimer(timer_tone);
|
||||||
|
if (shader_sum) delete shader_sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TonemappingProc::init() {
|
||||||
|
QOpenGLExtraFunctions * f = r->view;
|
||||||
|
buffer_vbo.init(f);
|
||||||
|
f->glGenVertexArrays(1, &vbo_vao);
|
||||||
|
f->glBindVertexArray(vbo_vao);
|
||||||
|
buffer_vbo.bind(f);
|
||||||
|
f->glEnableVertexAttribArray(1);
|
||||||
|
f->glVertexAttribIPointer(1, 2, GL_UNSIGNED_INT, 0, 0);
|
||||||
|
buffer_vbo.release(f);
|
||||||
|
f->glBindVertexArray(0);
|
||||||
|
fbomm.lastPlane().enablePixelBuffer();
|
||||||
|
fbo_1x1.resize(1, 1);
|
||||||
|
resize();
|
||||||
|
if (!isRunning()) start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TonemappingProc::resize() {
|
||||||
|
QOpenGLExtraFunctions * f = r->view;
|
||||||
|
fbomm.resize();
|
||||||
|
int pcnt = fbomm.width(fbomm.lastLevel()) * fbomm.height(fbomm.lastLevel());
|
||||||
|
QVector<Vector2i> _data;
|
||||||
|
_data.resize(pcnt);
|
||||||
|
pcnt = -1;
|
||||||
|
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));
|
||||||
|
buffer_vbo.load(f, _data.constData(), _data.size() * sizeof(Vector2i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TonemappingProc::timerEvent(QTimerEvent * e) {
|
||||||
|
if (!fbo_1x1.isInit()) return;
|
||||||
|
if (timer_delim == 0)
|
||||||
|
need_render_sum = true;
|
||||||
|
timer_delim = (++timer_delim) % 10;
|
||||||
|
mutex.lock();
|
||||||
|
float fmax = frame_max;
|
||||||
|
mutex.unlock();
|
||||||
|
float dt = 0.01f, a = dt * 5.f, b = 1.f - a;
|
||||||
|
cur_max = fmax * a + cur_max * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TonemappingProc::renderSum(Framebuffer & fbo_src, int index) {
|
||||||
|
QOpenGLExtraFunctions * f = r->view;
|
||||||
|
int pcnt = fbo_src.width() * fbo_src.height();
|
||||||
|
fbo_src.bindColorTexture(index);
|
||||||
|
fbo_1x1.bind();
|
||||||
|
//glClearFramebuffer(Qt::white, false);
|
||||||
|
glClearFramebuffer();
|
||||||
|
if (shader_sum) {
|
||||||
|
if (shader_sum->isLinked()) {
|
||||||
|
if (shader_sum->bind()) {
|
||||||
|
shader_sum->setUniformValue("tex", 0);
|
||||||
|
shader_sum->setUniformValue("pcnt", float(pcnt));
|
||||||
|
f->glBindVertexArray(vbo_vao);
|
||||||
|
f->glEnable(GL_BLEND);
|
||||||
|
f->glBlendFunc(GL_ONE, GL_ONE);
|
||||||
|
f->glBlendEquation(GL_MAX);
|
||||||
|
f->glDrawArrays(GL_POINTS, 0, pcnt);
|
||||||
|
f->glBlendEquation(GL_FUNC_ADD);
|
||||||
|
f->glDisable(GL_BLEND);
|
||||||
|
f->glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fbo_1x1.release();
|
||||||
|
//fbo_src.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TonemappingProc::run() {
|
||||||
|
while (!exit_) {
|
||||||
|
mutex.lock();
|
||||||
|
if (last_data.isEmpty()) {
|
||||||
|
mutex.unlock();
|
||||||
|
msleep(10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QVector<QVector4D> data = last_data;
|
||||||
|
last_data.clear();
|
||||||
|
mutex.unlock();
|
||||||
|
float max = calcHistogram(data);
|
||||||
|
last_max << max;
|
||||||
|
if (last_max.size() > 5)
|
||||||
|
last_max.removeAt(0);
|
||||||
|
float cm = last_max[0];
|
||||||
|
for (int i = 1; i < last_max.size(); ++i)
|
||||||
|
cm += last_max[i];
|
||||||
|
cm /= last_max.size();
|
||||||
|
mutex.lock();
|
||||||
|
frame_max = cm;
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float TonemappingProc::calcHistogram(const QVector<QVector4D> & data) {
|
||||||
|
if (data.isEmpty()) return 1.f;
|
||||||
|
float max = 0.;
|
||||||
|
QVector3D luma(0.299, 0.587, 0.114);
|
||||||
|
foreach (const QVector4D & p, data) {
|
||||||
|
float l = QVector3D::dotProduct(p.toVector3D(), luma);
|
||||||
|
max = qMax(max, l);
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TonemappingProc::process() {
|
||||||
|
if (!need_render_sum) return false;
|
||||||
|
need_render_sum = false;
|
||||||
|
Framebuffer & fbo(fbomm.lastPlane());
|
||||||
|
if (fbo.queriedPoints() > 0) {
|
||||||
|
QVector<QVector4D> data = fbo.getPointsFloat();
|
||||||
|
mutex.lock();
|
||||||
|
last_data = data;
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
fbomm.create();
|
||||||
|
fbo.queryPoints(0, fbo.rect(), GL_FLOAT);
|
||||||
|
//renderSum(fbomm.plane(fbomm.lastLevel()), 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float TonemappingProc::frameMax() {
|
||||||
|
return cur_max;
|
||||||
|
/*mutex.lock();
|
||||||
|
float ret = frame_max;
|
||||||
|
mutex.unlock();
|
||||||
|
return ret;*/
|
||||||
|
|
||||||
|
}
|
||||||
65
qglengine/tonemapping_proc.h
Normal file
65
qglengine/tonemapping_proc.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TONEMAPPING_PROC_H
|
||||||
|
#define TONEMAPPING_PROC_H
|
||||||
|
|
||||||
|
#include "glframebuffer_mipmap.h"
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
|
||||||
|
class TonemappingProc: public QThread
|
||||||
|
{
|
||||||
|
friend class Renderer;
|
||||||
|
public:
|
||||||
|
TonemappingProc(Renderer * rend);
|
||||||
|
virtual ~TonemappingProc();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void resize();
|
||||||
|
void prepareSum();
|
||||||
|
void renderSum(Framebuffer & fbo_src, int index);
|
||||||
|
|
||||||
|
bool process();
|
||||||
|
float frameMax();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void timerEvent(QTimerEvent * e);
|
||||||
|
void run() override;
|
||||||
|
float calcHistogram(const QVector<QVector4D> & data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Renderer * r;
|
||||||
|
QMutex mutex;
|
||||||
|
QVector<QVector4D> last_data;
|
||||||
|
QVector<float> last_max;
|
||||||
|
|
||||||
|
float frame_max, cur_max;
|
||||||
|
bool need_render_sum;
|
||||||
|
volatile bool exit_;
|
||||||
|
int timer_tone, timer_delim;
|
||||||
|
Framebuffer fbo_1x1;
|
||||||
|
FramebufferMipmap fbomm;
|
||||||
|
|
||||||
|
QOpenGLShaderProgram * shader_sum;
|
||||||
|
Buffer buffer_vbo;
|
||||||
|
GLenum vbo_vao;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RENDERER_H
|
||||||
Reference in New Issue
Block a user