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

This commit is contained in:
2015-11-26 11:53:29 +00:00
parent 2ace72ff47
commit 4cbcbb5174
26 changed files with 346 additions and 105 deletions

View File

@@ -53,6 +53,7 @@ void GLFramebuffer::resize(int width, int height) {
glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, 4);
glTexParameteri(target_, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, target_, colors[i], 0);
}
@@ -76,6 +77,13 @@ void GLFramebuffer::resize(int width, int height) {
}
QImage GLFramebuffer::grab() const {
//glReadPixels(0, 0, wid, hei, GL_RGBA, );
//QImage ret();
return QImage();
}
void GLFramebuffer::bind() {
if (is_changed) resize(wid, hei);
if (fbo == 0) return;

View File

@@ -35,6 +35,7 @@ public:
int width() const {return wid;}
int height() const {return hei;}
QSize size() const {return QSize(wid, hei);}
QImage grab() const;
void resize(int width, int height);
void bind();

View File

@@ -208,6 +208,32 @@ void GLObjectBase::render(int * id, QMap<int, GLObjectBase * > * ids, int sh_id_
}
Light::Light(): GLObjectBase(), shadow_map(true, 1, GL_R16F) {
type_ = GLObjectBase::Light;
light_type = Omni;
intensity = 1.;
angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.;
direction.setZ(1.);
}
Light::Light(const QVector3D & p, const QColor & c, GLdouble i): GLObjectBase(), shadow_map(true, 1, GL_R16F) {
type_ = GLObjectBase::Light;
light_type = Omni;
pos_ = p;
intensity = i;
/*color_ = c;*/
angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.;
direction.setZ(1.);
}
GLObjectBase * Light::clone(bool withChildren) {
Light * o = new Light(*this);
//GLObjectBase::clone(withChildren);
@@ -219,12 +245,14 @@ GLObjectBase * Light::clone(bool withChildren) {
for (int i = 0; i < children_.size(); ++i)
o->addChild(children_[i]->clone(withChildren));
}
o->light_type = light_type;
o->direction = direction;
o->angle_start = angle_start;
o->angle_end = angle_end;
o->intensity = intensity;
o->decay_const = decay_const;
o->decay_linear = decay_linear;
o->decay_quadratic = decay_quadratic;
o->light_type = light_type;
return o;
}

View File

@@ -214,15 +214,15 @@ class Light: public GLObjectBase {
public:
enum Type {Omni, Directional, Cone};
Light(): GLObjectBase(), shadow_map(true, 1, GL_R16F) {type_ = GLObjectBase::Light; light_type = Omni; intensity = 1.; decay_linear = decay_quadratic = angle_spread = angle_decay_exp = decay_start = 0.; decay_const = decay_end = 1.; direction.setZ(1.);}
Light(const QVector3D & p, const QColor & c = Qt::white, GLdouble i = 1.): GLObjectBase(), shadow_map(true, 1, GL_R16F) {type_ = GLObjectBase::Light; light_type = Omni; pos_ = p; intensity = i; /*color_ = c;*/ decay_linear = decay_quadratic = angle_spread = angle_decay_exp = decay_start = 0.; decay_const = decay_end = 1.; direction.setZ(1.);}
Light();
Light(const QVector3D & p, const QColor & c = Qt::white, GLdouble i = 1.);
virtual GLObjectBase * clone(bool withChildren = true);
virtual void init() {shadow_map.resize(512, 512); is_init = true;}
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
QVector3D direction;
GLdouble angle_spread;
GLdouble angle_decay_exp;
GLdouble angle_start;
GLdouble angle_end;
GLdouble intensity;
GLdouble decay_const;
GLdouble decay_linear;

View File

@@ -74,8 +74,8 @@ void GLObjectEditor::setObject(GLObjectBase * o) {
spinLightDecayConst->setValue(l->decay_const);
spinLightDecayLinear->setValue(l->decay_linear);
spinLightDecayQuadratic->setValue(l->decay_quadratic);
spinLightAngleSpread->setValue(l->angle_spread);
spinLightAngleDecayExp->setValue(l->angle_decay_exp);
spinLightAngleStart->setValue(l->angle_start);
spinLightAngleEnd->setValue(l->angle_end);
spinLightDirectionX->setValue(l->direction.x());
spinLightDirectionY->setValue(l->direction.y());
spinLightDirectionZ->setValue(l->direction.z());
@@ -111,9 +111,21 @@ void GLObjectEditor::objectChanged() {
l->decay_const = spinLightDecayConst->value();
l->decay_linear = spinLightDecayLinear->value();
l->decay_quadratic = spinLightDecayQuadratic->value();
l->angle_spread = spinLightAngleSpread->value();
l->angle_decay_exp = spinLightAngleDecayExp->value();
l->angle_start = spinLightAngleStart->value();
l->angle_end = spinLightAngleEnd->value();
l->direction = QVector3D(spinLightDirectionX->value(), spinLightDirectionY->value(), spinLightDirectionZ->value()).normalized();
}
emit changed();
}
void GLObjectEditor::on_spinLightAngleStart_valueChanged(double v) {
if (spinLightAngleEnd->value() < v)
spinLightAngleEnd->setValue(v);
}
void GLObjectEditor::on_spinLightAngleEnd_valueChanged(double v) {
if (spinLightAngleStart->value() > v)
spinLightAngleStart->setValue(v);
}

View File

@@ -39,6 +39,8 @@ protected:
private slots:
void objectChanged();
void on_spinLightAngleStart_valueChanged(double v);
void on_spinLightAngleEnd_valueChanged(double v);
signals:
void changed();

View File

@@ -364,6 +364,12 @@
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
@@ -390,6 +396,12 @@
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
@@ -416,6 +428,12 @@
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
@@ -442,6 +460,12 @@
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
<property name="squareScale">
<bool>true</bool>
</property>
@@ -450,52 +474,52 @@
<item row="6" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Angle Spread</string>
<string>Angle Start</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="SpinSlider" name="spinLightAngleSpread">
<widget class="SpinSlider" name="spinLightAngleStart">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
<property name="value">
<double>45.000000000000000</double>
<double>180.000000000000000</double>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="squareScale">
<bool>false</bool>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
<property name="pageStep">
<double>30.000000000000000</double>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Angle decay exp</string>
<string>Angle End</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="SpinSlider" name="spinLightAngleDecayExp">
<widget class="SpinSlider" name="spinLightAngleEnd">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>64.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
<double>180.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
<number>1</number>
</property>
<property name="squareScale">
<bool>true</bool>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
<property name="pageStep">
<double>30.000000000000000</double>
</property>
</widget>
</item>
@@ -520,6 +544,12 @@
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="9" column="0">
@@ -550,6 +580,12 @@
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="10" column="1">
@@ -566,6 +602,12 @@
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="pageStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
@@ -940,7 +982,7 @@
</hints>
</connection>
<connection>
<sender>spinLightAngleSpread</sender>
<sender>spinLightAngleStart</sender>
<signal>valueChanged(double)</signal>
<receiver>GLObjectEditor</receiver>
<slot>objectChanged()</slot>
@@ -956,7 +998,7 @@
</hints>
</connection>
<connection>
<sender>spinLightAngleDecayExp</sender>
<sender>spinLightAngleEnd</sender>
<signal>valueChanged(double)</signal>
<receiver>GLObjectEditor</receiver>
<slot>objectChanged()</slot>

View File

@@ -56,8 +56,8 @@ void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index)
glLightf(gl_index, GL_QUADRATIC_ATTENUATION, l.decay_quadratic);
if (l.light_type == Light::Cone) {
glLightfv(gl_index, GL_SPOT_DIRECTION, dir);
glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_spread);
glLightf(gl_index, GL_SPOT_EXPONENT, l.angle_decay_exp);
glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_end / 2.);
glLightf(gl_index, GL_SPOT_EXPONENT, (1. - piClamp<double>((l.angle_end - l.angle_start) / (l.angle_end + 0.001), 0., 1.)) * 128.);
} else {
glLightf(gl_index, GL_SPOT_CUTOFF, 180.);
}

View File

@@ -54,9 +54,14 @@ const char qgl_uniform[] =
const char qgl_structs[] =
"const int qgl_MaxLights = 16;\n"
"struct QGLLight {\n"
" vec4 position;\n"
" vec4 color;\n"
" vec4 position;\n"
" vec4 direction;\n"
" float intensity;\n"
" float startAngle;\n"
" float startAngleCos;\n"
" float endAngle;\n"
" float endAngleCos;\n"
" float constantAttenuation;\n"
" float linearAttenuation;\n"
" float quadraticAttenuation;\n"
@@ -192,19 +197,31 @@ void setUniformLights(QGLShaderProgram * prog, const QVector<Light*> & lights, c
}
/*
" vec3 position;\n"
" vec3 direction;\n"
" vec4 color;\n"
" float intensity;\n"
" float startAngle;\n"
" float endAngle;\n"
" float constantAttenuation;\n"
" float linearAttenuation;\n"
" float quadraticAttenuation;\n"
*/
void setUniformLight(QGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat, const QVector4D & dp) {
QMatrix4x4 m = mat * light->worldTransform();
QVector4D pos(0, 0, 0, 1.);
QVector4D pos(0, 0, 0, 1.), dir(light->direction);
pos = m * pos;
dir = (m * dir).normalized();
double ang_start = light->angle_start / 2., ang_end = light->angle_end / 2.;
if (light->light_type == Light::Omni)
ang_start = ang_end = 180.;
//qDebug() << "light" << light->name() << ulightn << pos;
prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos);
prog->setUniformValue((ulightn + ".direction").toLatin1().constData(), dir);
prog->setUniformValue((ulightn + ".intensity").toLatin1().constData(), GLfloat(light->intensity));
prog->setUniformValue((ulightn + ".startAngle").toLatin1().constData(), GLfloat(ang_start));
prog->setUniformValue((ulightn + ".startAngleCos").toLatin1().constData(), GLfloat(cos(ang_start * deg2rad)));
prog->setUniformValue((ulightn + ".endAngle").toLatin1().constData(), GLfloat(ang_end));
prog->setUniformValue((ulightn + ".endAngleCos").toLatin1().constData(), GLfloat(cos(ang_end * deg2rad)));
prog->setUniformValue((ulightn + ".color").toLatin1().constData(), light->color());
prog->setUniformValue((ulightn + ".constantAttenuation").toLatin1().constData(), GLfloat(light->decay_const));
prog->setUniformValue((ulightn + ".linearAttenuation").toLatin1().constData(), GLfloat(light->decay_linear));

View File

@@ -109,9 +109,14 @@ void createGLTexture(GLuint & tex, int width, int height, const GLenum & format,
glTexImage2D(target, 0, format, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
else {
int t = GL_UNSIGNED_BYTE;
if (format == GL_RGB32F || format == GL_RGB16F)
int f = GL_RGBA;
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGBA32F || format == GL_RGBA16F)
t = GL_FLOAT;
glTexImage2D(target, 0, format, width, height, 0, GL_RGBA, t, 0);
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGB8 || format == GL_RGB)
f = GL_RGB;
glTexImage2D(target, 0, format, width, height, 0, f, t, 0);
//glGenerateMipmap(target);
//qDebug() << "glTexImage2D" << width << height << QString::number(t, 16);
}
//qDebug() << QString::number(glGetError(), 16);
}

View File

@@ -142,6 +142,7 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
glBindBuffer(GL_ARRAY_BUFFER, buffer_);
if (prog) {
locs.clear();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -150,21 +151,25 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, 0);
loc = prog->attributeLocation("qgl_Normal");
locs << loc;
if (has_normals) {
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, offsets[0]);
locs << loc;
} else
glDisableVertexAttribArray(loc);
loc = prog->attributeLocation("qgl_Texture");
if (has_texcoords) {
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 2, GL_FLOAT, 0, 0, offsets[1]);
locs << loc;
} else
glDisableVertexAttribArray(loc);
loc = prog->attributeLocation("qgl_Color");
if (has_colors) {
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 4, GL_FLOAT, 0, 0, offsets[2]);
locs << loc;
} else
glDisableVertexAttribArray(loc);
loc = prog->attributeLocation("qgl_Tangent");
@@ -174,6 +179,7 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
glEnableVertexAttribArray(loc2);
glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, offsets[3]);
glVertexAttribPointer(loc2, 3, GL_FLOAT, 0, 0, offsets[4]);
locs << loc << loc2;
} else {
glDisableVertexAttribArray(loc);
glDisableVertexAttribArray(loc2);
@@ -200,6 +206,8 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
glDrawArrays(type, 0, vert_count);
//qDebug() << "draw" << vert_count << buffer_ << "done";
glBindBuffer(GL_ARRAY_BUFFER, 0);
foreach (int l, locs)
glDisableVertexAttribArray(l);
}

View File

@@ -53,6 +53,7 @@ private:
void calculateBinormals();
QVector<GLfloat> vertices_, normals_, texcoords_, colors_, tangents_, bitangents_;
QVector<int> locs;
GLenum usage;
GLuint buffer_, va_;
int vert_count;

View File

@@ -245,9 +245,8 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
globject_cast<Light * >(co)->direction = (pos.toQVector3D() - co->pos()).normalized();
stream.readRawData((char * )&fl1, sizeof(float));
stream.readRawData((char * )&fl, sizeof(float));
fl1 /= 2.f; fl /= 2.f;
globject_cast<Light * >(co)->angle_spread = fl;
globject_cast<Light * >(co)->angle_decay_exp = (fl - fl1) / fl * 16.;
globject_cast<Light * >(co)->angle_start = fl1;
globject_cast<Light * >(co)->angle_end = fl;
//qDebug() << "spotlight" << globject_cast<Light * >(co)->direction << globject_cast<Light * >(co)->angle_spread;
break;
case LOADER_3DS_CHUNK_LIGHT_OFF:

View File

@@ -371,6 +371,10 @@ GLObjectBase * loadFromDAEFile(const QString & filepath, double scale) {
sv = dl.firstChildElement("linear_attenuation").firstChild().nodeValue(); if (!sv.isEmpty()) lo->decay_linear = sv.toDouble();
sv = dl.firstChildElement("quadratic_attenuation").firstChild().nodeValue(); if (!sv.isEmpty()) lo->decay_quadratic = sv.toDouble();
///lo->setTransform(matrices.value(name));
if (lo->light_type == Light::Cone) {
ml = dn.elementsByTagName("decay_falloff"); if (!ml.isEmpty()) lo->angle_end = ml.at(0).firstChild().nodeValue().toDouble();
ml = dn.elementsByTagName("hotspot_beam"); if (!ml.isEmpty()) lo->angle_start = ml.at(0).firstChild().nodeValue().toDouble();
}
QVector<GLObjectBase*> ol;
ol << lo;
objects[gid] = ol;

View File

@@ -32,8 +32,8 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
sel_obj = 0;
//spinSliderShine->setDecimals(2);
view->setFrameShape(QFrame::NoFrame);
//view->setRenderer(new RendererDeferredShading(view));
view->setRenderer(new RendererSimple(view));
view->setRenderer(new RendererDeferredShading(view));
//view->setRenderer(new RendererSimple(view));
view->setMouseRotateEnabled(true);
view->setMouseSelectionEnabled(true);
view->setSelectionHaloEnabled(true);
@@ -76,8 +76,8 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
//obj = new GLPrimitiveEllipsoid(100, 100, 100, 100, 100);//GLPrimitiveCube();
for (int i = 0; i < obj->childCount(); ++i)
if (obj->child(i)->type() == GLObjectBase::Light) {
((Light*)obj->child(i))->intensity = 1.5;
((Light*)obj->child(i))->decay_linear = .5;
//((Light*)obj->child(i))->intensity = 1.5;
//((Light*)obj->child(i))->decay_linear = .5;
}
view->addObject(obj);
//obj->child("Box001")->addChild(&(view->camera()));
@@ -100,13 +100,13 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
view->camera().setPos(QVector3D(10, -20, 20));
view->camera().setAim(QVector3D());
view->camera().flyToDistance(100);
view->camera().flyToDistance(1000);
//view->camera().setMode(Camera::AimMatrix);
Light * l = new Light(view->camera().pos());
l->intensity = 0.5;
l->decay_linear = 0.2;
l->setName("camera");
view->addObject(l);
//view->addObject(l);
view->start(-1);
//view->light(0)->light_type = Light::Omni;
//obj = loadFrom3DSFile("34.3DS", 0.03);

View File

@@ -55,8 +55,8 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
//lmode = Simple;
shader_select = shader_halo = 0;
cur_luminance = 1.;
accom_time = 32.;
accom_max_speed = 0.1;
accom_time = 16.;
accom_max_speed = 0.2;
mouse_first = mouseSelect_ = accomodation_ = hoverHalo_ = selectionHalo_ = true;
fogEnabled_ = is_init = grabMouse_ = mouseRotate_ = mouseThis_ = shaders_bind = shadows_ = shadows_soft = dynamic_reflections = hdr_ = bloom_ = msaa_ = fxaa_ = changed_ = false;
rmode = GLObjectBase::Fill;
@@ -304,6 +304,10 @@ void QGLView::paintGL() {
qDebug() << QRect(downPos, lastPos).normalized();
}
glReleaseShaders();
glResetAllTransforms();
glReleaseFramebuffer();
emit glPainting();
/*releaseShaders();

View File

@@ -17,14 +17,40 @@
*/
#include "renderer_deferred_shading.h"
#include <QBoxLayout>
RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo_g(4, true, GL_RGBA16F), fbo_out(2, GL_RGBA16F) {
shader_fxaa = shader_ds_0 = shader_ds_1 = 0;
RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_),
fbo_g(4, true, GL_RGBA16F), fbo_out(2, false, GL_RGB16F), fbo_hsmall(1, false, GL_RGB16F) {
shader_fxaa = shader_ds_0 = shader_ds_1 = shader_hdr = shader_small = 0;
lights_per_pass = 2;
exposure_ = 1.;
df = new QWidget();
df->setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
label_exp = new QLabel();
label_exp_step = new QLabel();
df->layout()->addWidget(label_exp);
df->layout()->addWidget(label_exp_step);
QPalette pal(df->palette());
pal.setBrush(QPalette::Window, QColor(255, 255, 255, 192));
df->setPalette(pal);
if (view_)
view_->addObject(df);
}
RendererDeferredShading::~RendererDeferredShading() {
if (shader_fxaa != 0) delete shader_fxaa;
if (shader_ds_0 != 0) delete shader_ds_0;
if (shader_ds_1 != 0) delete shader_ds_1;
if (shader_hdr != 0) delete shader_hdr;
if (shader_small != 0) delete shader_small;
delete df;
}
void RendererDeferredShading::renderScene() {
//qDebug() << lights_per_pass;
QMatrix4x4 mproji = rp.proj_matrix_i;
QMatrix4x4 mview = rp.view_matrix;
corner_dirs[0] = (QVector4D(-1, -1, 1, 1) * rp.viewproj_matrix).normalized();
@@ -48,7 +74,7 @@ void RendererDeferredShading::renderScene() {
glActiveTextureChannel(0);
}
glClearFramebuffer(QColor(0, 0, 0, 0));
//glEnable(GL_TEXTURE_2D);
glDisable(GL_RESCALE_NORMAL);
glEnableDepth();
shader_ds_0->bind();
rp.setUniform(shader_ds_0);
@@ -61,7 +87,7 @@ void RendererDeferredShading::renderScene() {
shader_ds_0->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height()));
renderObjects(GLObjectBase::Solid, 0, shader_ds_0, true, false, false);
//glReleaseShaders();
//fbo.release();
fbo_g.release();
glResetAllTransforms();
rp.prepare();
@@ -89,28 +115,72 @@ void RendererDeferredShading::renderScene() {
glClearFramebuffer(Qt::black, false);
//QVector<QVector4D> lpos;
//qDebug() << view_matrix;
int passes = (view.lightsCount() - 1) / 16 + 1;
int passes = (view.lightsCount() - 1) / lights_per_pass + 1;
if (passes < 1) passes = 1;
shader_ds_1->setUniformValue("t_pp", 5);
//qDebug() << "render in" << passes << "passes";
//qDebug() << "render in" << passes << "passes (" << lights_per_pass << ")";
int wi, ri;
for (int l = 0; l < passes; ++l) {
int wi = 1 - l % 2, ri = l % 2;
wi = 1 - l % 2;
ri = l % 2;
//qDebug() << " pass" << l << "read from" << ri << "write to" << wi;
glActiveTextureChannel(5);
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
fbo_out.setWriteBuffer(wi);
setupDSLights(l, 16, mview);
setupDSLights(l, mview);
//shader_ds_1->setUniformValue("lightsCount", cplc);
glDrawQuad(shader_ds_1);
//renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled());
//renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled());
glFinish();
//glFinish();
//break;
}
fbo_out.release();
glReleaseShaders();
wi = 1 - passes % 2;
ri = passes % 2;
glActiveTextureChannel(0);
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(passes % 2));
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
fbo_hsmall.bind();
fbo_hsmall.setWriteBuffer(0);
shader_small->bind();
shader_small->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4());
shader_small->setUniformValue("t0", 0);
glDrawQuad(shader_small);
hcontent.resize(fbo_hsmall.width() * fbo_hsmall.height());
glReadPixels(0, 0, fbo_hsmall.width(), fbo_hsmall.height(), GL_RGB, GL_FLOAT, hcontent.data());
GLfloat max[3] = {0.,0.,0.};//min[3] = {10000.,10000.,10000.}, ;
for (int i = 0; i < hcontent.size(); ++i) {
//if (min[0] > hcontent[i].x) min[0] = hcontent[i].x;
if (max[0] < hcontent[i].x) max[0] = hcontent[i].x;
//if (min[1] > hcontent[i].y) min[1] = hcontent[i].y;
if (max[1] < hcontent[i].y) max[1] = hcontent[i].y;
//if (min[2] > hcontent[i].z) min[2] = hcontent[i].z;
if (max[2] < hcontent[i].z) max[2] = hcontent[i].z;
}
GLfloat mluma = (0.299 * max[0]) + (0.587 * max[1]) + (0.114 * max[2]);
double nexp = mluma / 16., dexp = nexp - exposure_, mestep = exposure_ * view.accomodationMaxSpeed();
dexp /= view.accomodationTime();
if (dexp > 0. && dexp > mestep/4) dexp = mestep/4;
if (dexp < 0. && dexp < -mestep) dexp = -mestep;
exposure_ += dexp;
label_exp->setText(QString("exposure: %1").arg(exposure_));
label_exp_step->setText(QString("d_exposure: %1").arg(dexp));
//qDebug() << min[0] << max[0] << min[1] << max[1] << min[2] << max[2];
fbo_hsmall.release();
//glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
fbo_out.bind();
fbo_out.setWriteBuffer(wi);
shader_hdr->bind();
shader_hdr->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4());
shader_hdr->setUniformValue("t0", 0);
shader_hdr->setUniformValue("exposure", GLfloat(1./exposure_));
glDrawQuad(shader_hdr);
fbo_out.release();
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(wi));
glReleaseShaders();
if (view.isFXAAEnabled()) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -127,14 +197,16 @@ void RendererDeferredShading::renderScene() {
void RendererDeferredShading::init(int width, int height) {
fbo_g.resize(width, height);
fbo_out.resize(width, height);
resize(width, height);
}
void RendererDeferredShading::resize(int width, int height) {
fbo_g.resize(width, height);
fbo_out.resize(width, height);
fbo_hsmall.resize(width / 16, height / 16);
view.setSceneRect(QRect(0, 0, width, height)); /// WARNING
//df->move(-width / 2, -height / 2);
}
@@ -142,10 +214,13 @@ void RendererDeferredShading::reloadShaders() {
if (shader_fxaa == 0) shader_fxaa = new QGLShaderProgram(view.context());
if (shader_ds_0 == 0) shader_ds_0 = new QGLShaderProgram(view.context());
if (shader_ds_1 == 0) shader_ds_1 = new QGLShaderProgram(view.context());
//if (shader_ds_0 == 0) shader_ds_0 = new QGLShaderProgram(view.context());
if (shader_hdr == 0) shader_hdr = new QGLShaderProgram(view.context());
if (shader_small == 0) shader_small = new QGLShaderProgram(view.context());
loadShaders(shader_fxaa, "FXAA", "shaders");
loadShaders(shader_ds_0, "dsl_pass_0", "shaders");
loadShaders(shader_ds_1, "dsl_pass_1", "shaders");
loadShaders(shader_hdr, "hdr", "shaders");
loadShaders(shader_small, "downscale", "shaders");
}
@@ -162,7 +237,7 @@ void RendererDeferredShading::setupShadersTextures(GLObjectBase & object, GLRend
}
void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix) {
void RendererDeferredShading::setupDSLights(int pass, const QMatrix4x4 & view_matrix) {
int light_start, light_end, lmax;
light_start = pass * lights_per_pass;
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights().size());

View File

@@ -20,12 +20,13 @@
#define RENDERER_DEFERRED_SHADING_H
#include "qglview.h"
#include <QLabel>
class RendererDeferredShading: public GLRendererBase
{
public:
RendererDeferredShading(QGLView * view);
virtual ~RendererDeferredShading() {if (shader_fxaa != 0) delete shader_fxaa;}
virtual ~RendererDeferredShading();
virtual void renderScene();
@@ -35,19 +36,24 @@ protected:
void reloadShaders();
void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp);
void setupShadersLights(int lights_count) {cplc = lights_count;}
void setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix);
void setupDSLights(int pass, const QMatrix4x4 & view_matrix);
void setupAmbientLight(const QColor & a, bool first_pass);
private:
int cplc;
GLFramebuffer fbo_g, fbo_out;
QGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1;
int cplc, BUG[8], lights_per_pass;
double exposure_;
GLFramebuffer fbo_g, fbo_out, fbo_hsmall;
QGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1, * shader_hdr, * shader_small;
QMatrix4x4 pm, mvm, mvpm, pim, mvim, mvpim;
QMatrix3x3 nm;
QVector4D corner_dirs[4];
QVector<Vector3d> hcontent;
Light amb_light;
QWidget * df;
QLabel * label_exp, * label_exp_step;
};
#endif // RENDERER_DEFERRED_SHADING_H

View File

@@ -58,6 +58,7 @@ void RendererSimple::renderScene() {
fbo.setWriteBuffer(0);
glClearFramebuffer();
}
glEnable(GL_RESCALE_NORMAL);
for (int l = 0; l < passes; ++l) {
if (passes > 1) fbo.setWriteBuffer(1);
if (l == 0) {

View File

@@ -0,0 +1,7 @@
#version 150
uniform sampler2D t0;
void main(void) {
qgl_FragData[0].rgb = textureLod(t0, qgl_FragTexture.xy, 3).rgb;
}

View File

@@ -0,0 +1,6 @@
#version 150
void main(void) {
qgl_FragTexture = qgl_Texture;
gl_Position = qgl_ftransform();
}

View File

@@ -15,11 +15,11 @@ void main(void) {
float z = pos.w;//((z_near / (z_near-z_far)) * z_far) / (pos.w - (z_far / (z_far-z_near)));
vec4 dc = qgl_FragColor;
vec2 tc = qgl_FragTexture.xy;
float hei = dot(texture2D(qgl_Material.map_relief.map, tc).rgb, luma) * qgl_Material.map_relief.amount + qgl_Material.map_relief.offset;
float hei = dot(texture(qgl_Material.map_relief.map, tc).rgb, luma) * qgl_Material.map_relief.amount + qgl_Material.map_relief.offset;
//if (acc_fog) dc.xyz = mix(dc.rgb, gl_Fog.color.rgb, fogCoord);
vec3 n, dn;
dn = (texture2D(qgl_Material.map_normal.map, tc).rgb - vec3(0.5, 0.5, 1.)) * qgl_Material.map_normal.amount + qgl_Material.map_normal.offset;
dn = (texture(qgl_Material.map_normal.map, tc).rgb - vec3(0.5, 0.5, 1.)) * qgl_Material.map_normal.amount + qgl_Material.map_normal.offset;
//float tx = dn.x;
dn.y = -dn.y;
//dn.y = tx;
@@ -34,12 +34,12 @@ void main(void) {
dpm = dpm * gl_ModelViewProjectionMatrixInverse;
dpm += */
//tc += 1+et.xy * hei/10;// / et.z;
dc *= texture2D(qgl_Material.map_diffuse.map, tc) * qgl_Material.map_diffuse.amount + qgl_Material.map_diffuse.offset;
dc *= texture(qgl_Material.map_diffuse.map, tc) * qgl_Material.map_diffuse.amount + qgl_Material.map_diffuse.offset;
vec4 spec = texture2D(qgl_Material.map_specular.map, tc) * qgl_Material.map_specular.amount + qgl_Material.map_specular.offset;
vec4 spec = texture(qgl_Material.map_specular.map, tc) * qgl_Material.map_specular.amount + qgl_Material.map_specular.offset;
spec *= qgl_Material.color_specular;
vec4 specularity = texture2D(qgl_Material.map_specularity.map, tc) * qgl_Material.map_specularity.amount + qgl_Material.map_specularity.offset;
vec4 self = texture2D(qgl_Material.map_self_illumination.map, tc) * qgl_Material.map_self_illumination.amount + qgl_Material.map_self_illumination.offset;
vec4 specularity = texture(qgl_Material.map_specularity.map, tc) * qgl_Material.map_specularity.amount + qgl_Material.map_specularity.offset;
vec4 self = texture(qgl_Material.map_self_illumination.map, tc) * qgl_Material.map_self_illumination.amount + qgl_Material.map_self_illumination.offset;
self *= qgl_Material.color_self_illumination;
qgl_FragData[0] = vec4(dc.rgb, z);

View File

@@ -25,5 +25,6 @@ void main(void) {
//tp /= tp.w;
src_normal = normalize(vec3(pos.xy * dt * 2., 0));
pos.w = tp.w;
//pos *= pos.w;
gl_Position = tp;//ftransform();
}

View File

@@ -30,11 +30,13 @@ void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) {
NdotH = max(dot(n, halfV), 0.);
spot = step(0., NdotL) * qgl_Light[index].intensity;
if (NdotL > 0.) {
/*if (gl_LightSource[index].spotCutoff < 180.) {
spot = max(dot(-ldir, gl_LightSource[index].spotDirection.xyz), 0.);
spot *= step(gl_LightSource[index].spotCosCutoff, spot);
spot = pow(spot, (gl_LightSource[index].spotExponent + 0.001));
}*/
if (qgl_Light[index].endAngle <= 90.) {
float scos = max(dot(-ldir, qgl_Light[index].direction.xyz), 0.);
spot *= scos * step(qgl_Light[index].endAngleCos, scos);
//spot = clamp(scos / (-qgl_Light[index].endAngleCos + qgl_Light[index].startAngleCos + 0.0001),0,1);
spot *= smoothstep(qgl_Light[index].endAngleCos, qgl_Light[index].startAngleCos, scos);
//spot = pow(spot, (qgl_Light[index].spotExponent + 0.001));
}
spot /= (qgl_Light[index].constantAttenuation + ldist * (qgl_Light[index].linearAttenuation + ldist * qgl_Light[index].quadraticAttenuation));
///li += spot * gl_LightSource[index].diffuse.rgb * light_diffuse(0, ldir, n);
//si += spot * qgl_Light[index].color.rgb * sh_mul * light_specular(0, ldir, n, halfV, v, sh_pow);
@@ -72,6 +74,7 @@ void main(void) {
pos.xy *= v3.w;
pos.z = posz;
pos.xyz += n * height;
//pos.xyz = v3.xyz;
//pos = v3;
//pos = vec4(sp, 0, 1.) * mat_proji;
//pos *= v0.w;
@@ -79,37 +82,15 @@ void main(void) {
//pos.xy *= 10.;
//pos.z = v0.w;
vec3 v = normalize(-pos.xyz);
sh_pow = 1. / max((1. - v1.w), 0.0001);
sh_mul = max(1. - v1.w, 0.0001);
//for (int i = 0; i < 16; ++i)
calcLight(7, n, v, v2);
/*if (lightsCount > 0) {
calcLight(0, n, v, v2);
if (lightsCount > 1) {
calcLight(1, n, v, v2);
if (lightsCount > 2) {
calcLight(2, n, v, v2);
if (lightsCount > 3) {
calcLight(3, n, v, v2);
if (lightsCount > 4) {
calcLight(4, n, v, v2);
if (lightsCount > 5) {
calcLight(5, n, v, v2);
if (lightsCount > 6) {
calcLight(6, n, v, v2);
if (lightsCount > 7) {
calcLight(7, n, v, v2);
}
}
}
}
}
}
}
}*/
qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb + texture2D(t_pp, tc).rgb;
for (int i = 0; i < 16; ++i)
calcLight(i, n, v, v2);
qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb + texture(t_pp, tc).rgb;
//qgl_FragData[0].rgb = vec3(abs(lpos.xyz - pos.xyz)/10);
//qgl_FragData[0].rgb = texture2D(t_pp, tc).rgb;
//qgl_FragData[0].rgb = vec3(pow(NdotH,100)*2);
//qgl_FragData[0].rgb = si.rgb;
//qgl_FragData[0].rgb = (v0.rgb)/2;
//qgl_FragData[0].a = 0.;
}

27
qglview/shaders/hdr.frag Normal file
View File

@@ -0,0 +1,27 @@
#version 150
uniform sampler2D t0;
uniform float exposure;
float tA = 0.15;
float tB = 0.50;
float tC = 0.10;
float tD = 0.20;
float tE = 0.02;
float tF = 0.30;
float tW = 11.2;
vec3 Uncharted2Tonemap(vec3 x) {
return ((x*(tA*x+tC*tB)+tD*tE)/(x*(tA*x+tB)+tD*tF))-tE/tF;
}
void main(void) {
vec3 inColor = texture(t0, qgl_FragTexture.xy).rgb;
inColor *= exposure;
float ExposureBias = 1;
vec3 curr = Uncharted2Tonemap(ExposureBias*inColor);
vec3 whiteScale = 1 / Uncharted2Tonemap(vec3(tW));
vec3 color = curr * whiteScale;
vec3 retColor = pow(color, vec3(1 / 2.2));
qgl_FragData[0].rgb = retColor;
}

6
qglview/shaders/hdr.vert Normal file
View File

@@ -0,0 +1,6 @@
#version 150
void main(void) {
qgl_FragTexture = qgl_Texture;
gl_Position = qgl_ftransform();
}