git-svn-id: svn://db.shs.com.ru/libs@656 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2019-12-06 10:27:33 +00:00
parent edfe165f90
commit fa5c3e9b3d
13 changed files with 209 additions and 57 deletions

View File

@@ -49,6 +49,7 @@ void Buffer::destroy(QOpenGLExtraFunctions * f) {
void Buffer::bind(QOpenGLExtraFunctions * f) {
//qDebug() << "bind" << target_ << buffer_;
f->glBindBuffer(target_, buffer_);
}

View File

@@ -43,6 +43,8 @@ public:
GLuint ID() const {return buffer_;}
GLenum usage() const {return usage_;}
GLenum target() const {return target_;}
void setTarget(GLenum t) {target_ = t;}
bool isInit() const {return buffer_ != 0;}
private:

View File

@@ -68,8 +68,8 @@ void Framebuffer::resize(int width, int height, bool force) {
for (int i = 0; i < colors.size(); ++i) {
deleteGLTexture(f, colors[i]);
createGLTexture(f, colors[i], width, height, color_formats[i], target_);
f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
f->glTexParameteri(target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
f->glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, 4);
@@ -102,8 +102,6 @@ void Framebuffer::resize(int width, int height, bool force) {
QImage Framebuffer::grab() const {
//glReadPixels(0, 0, wid, hei, GL_RGBA, );
//QImage ret();
return QImage();
}
@@ -114,12 +112,10 @@ void Framebuffer::queryPoint(int index, QPoint p) {
if (!rect().contains(p) || !pbo.isInit()) return;
f->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
f->glReadBuffer(GL_COLOR_ATTACHMENT0 + index);
//QTime tm; tm.restart();
pbo.bind(f);
f->glReadPixels(p.x(), height() - p.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
pbo_queried = 1;
pbo.release(f);
//qDebug() << tm.elapsed();
}
@@ -130,12 +126,10 @@ void Framebuffer::queryPoints(int index, QRect rect_) {
if (rect_.isEmpty() || !pbo.isInit()) return;
f->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
f->glReadBuffer(GL_COLOR_ATTACHMENT0 + index);
//QTime tm; tm.restart();
pbo.bind(f);
f->glReadPixels(rect_.x(), height() - rect_.bottom(), rect_.width(), rect_.height(), GL_RGBA, GL_UNSIGNED_BYTE, 0);
pbo_queried = rect_.width() * rect_.height();
pbo.release(f);
//qDebug() << tm.elapsed();
}
@@ -146,17 +140,13 @@ void Framebuffer::queryImage(int index) {
uint Framebuffer::getPoint() const {
if (!pbo.isInit() || (pbo_queried == 0)) return 0;
//QTime tm; tm.restart();
uint ret = 0;
pbo.bind(f);
//glClearError();
void * map = pbo.map(f, GL_MAP_READ_BIT, sizeof(uint));
//qDebug() << map << QString::number(glGetError(), 16);
if (map)
memcpy(&ret, map, sizeof(uint));
pbo.unmap(f);
pbo.release(f);
//qDebug() << tm.elapsed();
return ret;
}
@@ -165,16 +155,12 @@ QVector<uint> Framebuffer::getPoints() const {
QVector<uint> ret;
if (!pbo.isInit() || (pbo_queried == 0)) return ret;
ret.resize(pbo_queried);
//QTime tm; tm.restart();
pbo.bind(f);
//glClearError();
void * map = pbo.map(f, GL_MAP_READ_BIT, pbo_queried * sizeof(uint));
//qDebug() << map << QString::number(glGetError(), 16);
if (map)
memcpy(ret.data(), map, pbo_queried * sizeof(uint));
pbo.unmap(f);
pbo.release(f);
//qDebug() << tm.elapsed();
return ret;
}
@@ -184,16 +170,12 @@ QImage Framebuffer::getImage() const {
if (!pbo.isInit() || (pbo_queried == 0)) return ret;
ret = QImage(size(), QImage::Format_RGBA8888);
int bytes = width() * height() * 4;
//QTime tm; tm.restart();
pbo.bind(f);
//glClearError();
void * map = pbo.map(f, GL_MAP_READ_BIT, bytes);
//qDebug() << map << QString::number(glGetError(), 16);
if (map)
memcpy(ret.bits(), map, bytes);
pbo.unmap(f);
pbo.release(f);
//qDebug() << tm.elapsed();
return ret;
}
@@ -279,6 +261,13 @@ void Framebuffer::enablePixelBuffer() {
}
void Framebuffer::setColorTextureFiltering(int index, GLenum filter) {
bindColorTexture(index);
f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, filter);
f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, filter);
}
void Framebuffer::bindColorTexture(int index, int channel) {
if (index < 0 || index >= colors.size()) return;
f->glActiveTexture(GL_TEXTURE0 + channel);

View File

@@ -59,6 +59,7 @@ public:
void unsetWriteBuffers();
//void setColorFormat(GLenum format) {color_format = format; is_changed = true;}
void enablePixelBuffer();
void setColorTextureFiltering(int index, GLenum filter);
void copyDepthFrom(GLuint tex) {;}
void bindColorTexture(int index, int channel = 0);

View File

@@ -24,12 +24,13 @@
using namespace QGLEngineShaders;
bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QString & content, const QString & file, const QString & defs) {
bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QString & content, const QString & file, bool add_qgl, const QString & defs) {
if (type == 0 || content.isEmpty()) {
content.clear();
return true;
}
//qDebug() << "[QGLView] Shader" << file << "found" << (QOpenGLShader::ShaderTypeBit)(int)type << "section ...";
if (add_qgl) {
switch (type) {
case QOpenGLShader::Fragment:
content.prepend(qgl_fragment_head);
@@ -43,6 +44,7 @@ bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QStr
content.prepend(qgl_geometry_head);
break;
}
}
content.prepend(defs);
content.prepend(qgl_common_head);
bool ret = prog->addShaderFromSourceCode(type, content.toLatin1());
@@ -61,7 +63,7 @@ QString prepareDefines(const QStringList & defines) {
}
bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, const QStringList & defines) {
bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, bool add_qgl, const QStringList & defines) {
if (!prog)
prog = new QOpenGLShaderProgram();
prog->removeAllShaders();
@@ -78,34 +80,34 @@ bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QStr
pl = line.trimmed().remove(' ').remove('\t').mid(2).toLower();
pl.chop(2);
if (pl == "vertex" || pl == "vert") {
if (!addShader(prog, type, cur_shader, file, defs)) return false;
if (!addShader(prog, type, cur_shader, file, add_qgl, defs)) return false;
type = QOpenGLShader::Vertex;
continue;
}
if (pl == "fragment" || pl == "frag") {
if (!addShader(prog, type, cur_shader, file, defs)) return false;
if (!addShader(prog, type, cur_shader, file, add_qgl, defs)) return false;
type = QOpenGLShader::Fragment;
continue;
}
if (pl == "geometry" || pl == "geom") {
if (!addShader(prog, type, cur_shader, file, defs)) return false;
if (!addShader(prog, type, cur_shader, file, add_qgl, defs)) return false;
type = QOpenGLShader::Geometry;
continue;
}
if (pl == "tessellation_control") {
if (!addShader(prog, type, cur_shader, file, defs)) return false;
if (!addShader(prog, type, cur_shader, file, add_qgl, defs)) return false;
type = QOpenGLShader::TessellationControl;
continue;
}
if (pl == "tessellation_evaluation") {
if (!addShader(prog, type, cur_shader, file, defs)) return false;
if (!addShader(prog, type, cur_shader, file, add_qgl, defs)) return false;
type = QOpenGLShader::TessellationEvaluation;
continue;
}
cur_shader.append("\n");
cur_shader.append(line);
}
if (!addShader(prog, type, cur_shader, file, defs)) return false;
if (!addShader(prog, type, cur_shader, file, add_qgl, defs)) return false;
if (!prog->link()) {
qDebug() << "[QGLView] Shader" << file << "Link error:\n" << prog->log();
return false;

View File

@@ -23,7 +23,7 @@
namespace QGLEngineShaders {
bool loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, const QStringList & defines = QStringList());
bool loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, bool add_qgl = true, const QStringList & defines = QStringList());
void setUniformMatrices(QOpenGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view, QMatrix4x4 prevproj = QMatrix4x4(), QMatrix4x4 prevview = QMatrix4x4());
void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light*> & lights, const QMatrix4x4 & mat, int shadow_start);

View File

@@ -26,7 +26,6 @@ const int max_lights = 64 ;
const char qgl_common_head[] =
"#version 400 core\n"
//"#extension GL_EXT_texture_aray: require\n"
"";
const char qgl_vertex_head[] =

View File

@@ -29,9 +29,13 @@ using namespace QGLEngineShaders;
Renderer::Renderer(QGLView * view_): RendererBase(view_),
fbo_ds (view_, QVector<GLenum>() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F),
fbo_out (view_, 3, false, GL_RGBA16F),
fbo_hsmall (view_, 1, false, GL_RGB16F ),
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 ),
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.);
cam_light = new Light();
cam_light->intensity = 0.75;
@@ -50,6 +54,7 @@ Renderer::Renderer(QGLView * view_): RendererBase(view_),
shader_files[srLightOmniPass] = "ds_light.glsl";
shader_files[srLightSpotPass] = "ds_light.glsl"; shader_defines[srLightSpotPass] << "SPOT";
shader_files[srFinalPass ] = "ds_final.glsl";
shader_files[srTonemapPass ] = "ds_tonemap.glsl";
/*shaders << ShaderPair("FXAA", &shader_fxaa)
<< ShaderPair("dsl_pass_0", &shader_ds_0)
@@ -76,10 +81,13 @@ Renderer::~Renderer() {
delete quad;
delete cam_light;
qDeleteAll(shaders.values());
if (shader_sum) delete shader_sum;
}
void Renderer::init(int width, int height) {
prepareSum();
fbo_1x1.resize(1, 1);
resize(width, height);
rend_mat.init(width, height);
rend_service.init(width, height);
@@ -96,16 +104,20 @@ void Renderer::resize(int width, int height) {
rend_selection.resize(width, height);
fbo_ds .resize(width, height);
fbo_out .resize(width, height);
fbo_hsmall .resize(width / 16, height / 16);
fbo_small_4 .resize(width / 4 , height / 4 );
fbo_small_16 .resize(width / 16, height / 16);
resizeSum();
}
void Renderer::reloadShaders() {
QMapIterator<ShaderRole, QString> it(shader_files);
QString dir = "shaders/";
while (it.hasNext()) {
it.next();
loadShadersMulti(shaders[it.key()], "shaders/" + it.value(), 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);
need_init_shaders = true;
view->scene()->setLightsChanged();
view->scene()->setTreeStructChanged();
@@ -144,6 +156,10 @@ void Renderer::initShaders() {
for (int i = 0; i < 5; ++i)
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
}
if (bindShader(srTonemapPass, &prog)) {
prog->setUniformValue("tex_0", 0);
prog->setUniformValue("tex_sum", 1);
}
}
@@ -197,6 +213,62 @@ 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 = fbo_small_16.width() * fbo_small_16.height();
QVector<Vector2i> _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)
_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() {
initShaders();
QOpenGLExtraFunctions * f = view;
@@ -255,7 +327,7 @@ void Renderer::renderScene() {
fbo_ds.bindColorTextures();
fbo_ds.bindDepthTexture(5);
fbo_out.bind();
int ri = 1, wi = 0;
//int ri = 1, wi = 0;
typedef QPair<Renderer::ShaderRole, Light::Type> PassPair;
QVector<PassPair> passes;
passes << PassPair(srLightOmniPass, Light::Omni) << PassPair(srLightSpotPass, Light::Cone);
@@ -265,26 +337,38 @@ void Renderer::renderScene() {
setUniformViewCorners(prog, cam);
prog->setUniformValue("lights_start", lights_start[pass.second]);
prog->setUniformValue("lights_count", ll[pass.second].size());
fbo_out.setWriteBuffer(1 + pass.second);
fbo_out.setWriteBuffer(obrSolidOmni + pass.second);
glClearFramebuffer(Qt::black, false);
renderQuad(prog, quad, cam);
}
}
if (bindShader(srFinalPass, &prog)) {
fbo_out.bindColorTexture(1, 0);
fbo_out.bindColorTexture(2, 1);
fbo_out.setWriteBuffer(0);
fbo_out.bindColorTexture(obrSolidOmni, 0);
fbo_out.bindColorTexture(obrSolidSpot, 1);
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);
fbo_out.bind();
if (bindShader(srTonemapPass, &prog)) {
fbo_1x1.bindColorTexture(0, 1);
fbo_out.bindColorTexture(obrSum, 0);
fbo_out.setWriteBuffer(obrTonemap);
renderQuad(prog, quad);
} else
fbo_out.blit(obrSum, fbo_out.id(), obrTonemap, fbo_out.rect(), fbo_out.rect());
fbo_out.release();
/// apply hovers and selection frame
if (edit_mode) {
rend_selection.drawSelection(fbo_out, 0);
rend_selection.drawSelection(fbo_out, obrTonemap);
rend_service.renderService();
} else {
fbo_out.blit(0, 0, 0, fbo_out.rect(), QRect(QPoint(), view->size()));
fbo_out.blit(obrTonemap, 0, 0, fbo_out.rect(), QRect(QPoint(), view->size()));
}
//fbo_small_16.blit(0, 0, 0, fbo_small_16.rect(), fbo_small_16.rect(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
}

View File

@@ -56,6 +56,7 @@ class Renderer: public RendererBase {
srLightOmniPass,
srLightSpotPass,
srFinalPass,
srTonemapPass,
};
enum DeferredBufferRole {
dbrDiffuseRough,
@@ -64,6 +65,12 @@ class Renderer: public RendererBase {
dbrEmissionBitangX,
dbrSpeedBitangXY,
};
enum OutBufferRole {
obrTonemap,
obrSum,
obrSolidOmni,
obrSolidSpot,
};
public:
Renderer(QGLView * view_);
@@ -83,6 +90,9 @@ protected:
void fillObjectsBuffer(const QList<ObjectBase*> & ol, RenderPass pass);
void reloadObjects();
void renderObjects(Scene & scene, RenderPass pass);
void prepareSum();
void resizeSum();
void renderSum(Framebuffer & fbo_src, int index);
bool bindShader(ShaderRole role, QOpenGLShaderProgram ** ret = 0);
void initShaders();
@@ -91,7 +101,7 @@ protected:
private:
float exposure_;
bool edit_mode, need_init_shaders, is_camera_light;
Framebuffer fbo_ds, fbo_out, fbo_hsmall;
Framebuffer fbo_ds, fbo_out, fbo_small_4, fbo_small_16, fbo_1x1;
/*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;
@@ -100,6 +110,10 @@ private:
QMap<ShaderRole, QStringList> shader_defines;
QMap<ShaderRole, QOpenGLShaderProgram*> shaders;
QOpenGLShaderProgram * shader_sum;
Buffer buffer_vbo;
GLenum vbo_vao;
RendererMaterial rend_mat;
RendererService rend_service;
RendererSelection rend_selection;

View File

@@ -46,9 +46,12 @@ void RendererSelection::init(int width, int height) {
void RendererSelection::resize(int width, int height) {
line_thick_ = lineThickness() + 1.;
scale_ = 0.5 / appScale();
fbo_selection.enablePixelBuffer();
fbo_selection.resize(width * scale_, height * scale_);
line_thick_ = lineThickness() + 1.;
//fbo_selection.setColorTextureFiltering(sbrSrcHover , GL_LINEAR);
//fbo_selection.setColorTextureFiltering(sbrSrcSelect, GL_LINEAR);
}

View File

@@ -0,0 +1,31 @@
// vert //
void main(void) {
gl_Position = qgl_ftransform();
}
// frag //
uniform sampler2D tex_0, tex_sum;
const vec3 luma = vec3(0.299, 0.587, 0.114);
void main(void) {
ivec2 tc = ivec2(gl_FragCoord.xy);
vec4 src = texelFetch(tex_0, tc, 0);
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);
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 /= 100;
//res = pow(res,vec3(2.2));
//l = pow(l,2.2);
qgl_FragColor.rgb = res * l;
//qgl_FragColor.rgb = sum.rgb*10;
}

View File

@@ -16,6 +16,7 @@ void main(void) {
vec4 src = texelFetch(fb_out , tc, 0);
vec4 hov = texture(fb_hover , stc);
vec4 sel = texture(fb_select, stc);
src.rgb = clamp(src.rgb, vec3(0), vec3(1));
src.rgb = mix(src.rgb, sel.rgb, sel.a);
src.rgb = mix(src.rgb, hov.rgb, hov.a * 0.667f);
//src.rgb = src.rgb + (sel.rgb*sel.a);

View File

@@ -0,0 +1,25 @@
// vert //
layout(location = 1) in ivec2 qgl_Vertex;
flat out vec4 color;
uniform sampler2D tex;
void main(void) {
color = texelFetch(tex, qgl_Vertex, 0);
gl_Position = vec4(0,0,0,1);
}
// frag //
out vec4 qgl_FragData[gl_MaxDrawBuffers];
flat in vec4 color;
uniform float pcnt;
void main(void) {
qgl_FragData[0] = color;// / pcnt;
}