From 86c101eb799c88ff5da46bf75d599ffd3022ce1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Wed, 2 Dec 2015 13:53:02 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/libs@57 a8b55f48-bf90-11e4-a774-851b48703e85 --- qglview/glcamera.cpp | 6 ++- qglview/globject.cpp | 13 +++-- qglview/globject.h | 7 ++- qglview/glrendererbase.cpp | 3 +- qglview/glshaders.cpp | 2 +- qglview/mainwindow.cpp | 2 +- qglview/qglview.cpp | 3 ++ qglview/qglview.h | 1 + qglview/renderer_deferred_shading.cpp | 5 +- qglview/shaders/dsl_pass_0.vert | 2 +- qglview/shaders/dsl_pass_1.frag | 69 ++++++++++++++++++++------- 11 files changed, 83 insertions(+), 30 deletions(-) diff --git a/qglview/glcamera.cpp b/qglview/glcamera.cpp index cd298af..359334e 100644 --- a/qglview/glcamera.cpp +++ b/qglview/glcamera.cpp @@ -57,9 +57,11 @@ void Camera::apply(const GLdouble & aspect) { pm.rotate(angles_.y(), 1., 0., 0.); pm.rotate(angles_.x(), 0., 1., 0.); pm.rotate(angles_.z(), 0., 0., 1.); - pm.translate(-aim_); - if (parent_) + //pm.translate(-aim_); + if (parent_) { + pm.translate(-aim_); pm *= parent_->worldTransform().inverted(); + } setGLMatrix(pm); //qDebug() << angles_; } diff --git a/qglview/globject.cpp b/qglview/globject.cpp index abf622d..06ea04b 100644 --- a/qglview/globject.cpp +++ b/qglview/globject.cpp @@ -17,6 +17,7 @@ */ #include "globject.h" +#include "glcamera.h" GLObjectBase::GLObjectBase() { @@ -26,7 +27,7 @@ GLObjectBase::GLObjectBase() { geom_prim = Triangles; scale_ = QVector3D(1., 1., 1.); parent_ = 0; - is_init = is_tex_loaded = selected_ = false; + is_root = is_init = is_tex_loaded = selected_ = false; visible_ = accept_fog = accept_light = cast_shadow = rec_shadow = select_ = true; line_width = -1.; blend_src = GL_SRC_ALPHA; @@ -149,7 +150,7 @@ void GLObjectBase::buildTransform() { if (p != 0) itransform_ = p->itransform_; if (raw_matrix) { - itransform_.translate(pos_); + itransform_.translate(is_root ? dcam_pos_ : pos_); itransform_ *= mat_; //qDebug() << "raw_matrix" << itransform_; } else @@ -161,7 +162,7 @@ void GLObjectBase::buildTransform() { void GLObjectBase::localTransform(QMatrix4x4 & m) { - m.translate(pos_); + m.translate(is_root ? dcam_pos_ : pos_); m.rotate(angles_.z(), 0., 0., 1.); m.rotate(angles_.y(), 0., 1., 0.); m.rotate(angles_.x(), 1., 0., 0.); @@ -175,6 +176,12 @@ void GLObjectBase::checkPass() { } +void GLObjectBase::preparePos(const Camera & cam) { + dcam_pos_ = pos_ - cam.aim(); + buildTransform(); +} + + QMatrix4x4 GLObjectBase::worldMatrix(QMatrix4x4 parent) const { QMatrix4x4 mat; mat.translate(pos_); diff --git a/qglview/globject.h b/qglview/globject.h index 810bc0d..8ef8c3a 100644 --- a/qglview/globject.h +++ b/qglview/globject.h @@ -23,6 +23,8 @@ #include "glframebuffer.h" #include "glmaterial.h" +class Camera; + class GLObjectBase { friend class QGLView; @@ -166,6 +168,8 @@ public: const Box3D & boundingBox(bool withChildren = true) const {return bound;} GLVBO & VBO() {return vbo;} + void preparePos(const Camera & cam); + QVector3D pos_h; QVector points, puvws; QVector faces, uvws, norms; @@ -187,13 +191,14 @@ protected: int pass_; // Pass bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix; + bool is_root; double line_width; Type type_; GeomPrimitives geom_prim; RenderMode render_mode; Material material_; Box3D bound; - QVector3D pos_, angles_, scale_; + QVector3D pos_, angles_, scale_, dcam_pos_; QList children_; QList textures; QMatrix4x4 itransform_, mat_; diff --git a/qglview/glrendererbase.cpp b/qglview/glrendererbase.cpp index 3b0cee3..0ba0c71 100644 --- a/qglview/glrendererbase.cpp +++ b/qglview/glrendererbase.cpp @@ -238,6 +238,7 @@ void GLRendererBase::renderShadow(Light * l, QGLShaderProgram * prog, QMatrix4x4 cam.setDepthEnd(view.camera().depthEnd()); cam.setFOV(l->angle_end); cam.apply(1.); + view.objects_.preparePos(cam); RenderingParameters rpl; rpl.pass = GLObjectBase::Solid; rpl.shaders = prog; @@ -247,7 +248,7 @@ void GLRendererBase::renderShadow(Light * l, QGLShaderProgram * prog, QMatrix4x4 QMatrix4x4 mbias; mbias.scale(0.5, 0.5, 0.5); mbias.translate(1., 1., 1.); - l->shadow_matrix = mbias*rpl.proj_matrix*rpl.view_matrix*mat;//;// * mbias; + l->shadow_matrix = mbias*rpl.proj_matrix*rpl.view_matrix;//*mat; //qDebug() << mbias; //glPushMatrix(); renderSingleShadow(view.objects_, rpl); diff --git a/qglview/glshaders.cpp b/qglview/glshaders.cpp index d6d025c..0ca4c11 100644 --- a/qglview/glshaders.cpp +++ b/qglview/glshaders.cpp @@ -66,7 +66,7 @@ const char qgl_structs[] = " float linearAttenuation;\n" " float quadraticAttenuation;\n" " sampler2DShadow shadow;\n" - " sampler2D shadowColor;\n" + //" sampler2D shadowColor\n" " mat4 shadowMatrix;\n" "};\n" "struct QGLMap {\n" diff --git a/qglview/mainwindow.cpp b/qglview/mainwindow.cpp index 861e3af..95ddb0b 100644 --- a/qglview/mainwindow.cpp +++ b/qglview/mainwindow.cpp @@ -80,7 +80,7 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow() //((Light*)obj->child(i))->decay_linear = .5; } view->addObject(obj); - //obj->child("Box001")->addChild(&(view->camera())); + obj->child("Box001")->addChild(&(view->camera())); //view->camera().flyToDistance(30); double al = 7.; diff --git a/qglview/qglview.cpp b/qglview/qglview.cpp index 1408ba0..a4f104b 100644 --- a/qglview/qglview.cpp +++ b/qglview/qglview.cpp @@ -30,6 +30,7 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) { setFocusPolicy(Qt::WheelFocus); setScene(new QGraphicsScene()); setInteractive(true); + objects_.is_root = true; painter_ = 0; backColor_ = Qt::black; hoverHaloColor_ = QColor(195, 140, 255, 96); @@ -212,6 +213,7 @@ void QGLView::paintGL() { glEnable(GL_CULL_FACE); //glDisable(GL_CULL_FACE); camera().apply(aspect); + objects_.preparePos(camera()); start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX); start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX); //objects_.buildTransform(); @@ -274,6 +276,7 @@ void QGLView::paintGL() { } camera().apply(aspect); + objects_.preparePos(camera()); static GLRendererBase * prev_rend = 0; if (prev_rend != renderer_) { diff --git a/qglview/qglview.h b/qglview/qglview.h index b0a87f3..01f86d9 100644 --- a/qglview/qglview.h +++ b/qglview/qglview.h @@ -170,6 +170,7 @@ public: void addTexture(const QString & path) {textures_manager.addTexture(path);} void addAnimation(const QString & dir, const QString & name) {textures_manager.addAnimation(dir, name);} + const GLObjectBase & rootObject() {return objects_;} GLObjectBase * object(int index) {return objects_.child(index);} GLObjectBase * object(const QString & name) {return objects_.child(name);} Light * light(int index) {return lights_[index];} diff --git a/qglview/renderer_deferred_shading.cpp b/qglview/renderer_deferred_shading.cpp index 51afa0b..8ec43fc 100644 --- a/qglview/renderer_deferred_shading.cpp +++ b/qglview/renderer_deferred_shading.cpp @@ -154,6 +154,7 @@ void RendererDeferredShading::renderScene() { shader_ds_1->setUniformValue("td", 5); shader_ds_1->setUniformValue("back_color", view.backColor()); shader_ds_1->setUniformValue("mat_proji", mproji); + shader_ds_1->setUniformValue("mat_view", mview); shader_ds_1->setUniformValue("mat_viewi", mviewi); shader_ds_1->setUniformValue("mat_viewproji", mviewproji); shader_ds_1->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height())); @@ -364,10 +365,10 @@ void RendererDeferredShading::setupDSLights(int pass, const QMatrix4x4 & view_ma for (int i = light_start; i < light_end; ++i) { lv << view.lights()[i]; glActiveTextureChannel(shadow_start + i - light_start); - glBindTexture(GL_TEXTURE_2D, lv.back()->shadow_map.colorTexture()); + glBindTexture(GL_TEXTURE_2D, lv.back()->shadow_map.depthTexture()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); } amb_light.setName("null"); for (int i = light_end; i < lmax; ++i) diff --git a/qglview/shaders/dsl_pass_0.vert b/qglview/shaders/dsl_pass_0.vert index f3ad6d0..2a9baca 100644 --- a/qglview/shaders/dsl_pass_0.vert +++ b/qglview/shaders/dsl_pass_0.vert @@ -12,7 +12,7 @@ uniform mat4 prev_ModelViewProjectioMatrix; void main(void) { normal = qgl_Normal;//(qgl_NormalMatrix * qgl_Normal); - binormal = qgl_Tangent;//(qgl_NormalMatrix * qgl_Normal); + binormal = qgl_Bitangent;//(qgl_NormalMatrix * qgl_Normal); pos = qgl_ftransform(); TBN = mat3(qgl_Tangent, qgl_Bitangent, qgl_Normal); /*if (acc_fog) { diff --git a/qglview/shaders/dsl_pass_1.frag b/qglview/shaders/dsl_pass_1.frag index 29805ac..7f1730f 100644 --- a/qglview/shaders/dsl_pass_1.frag +++ b/qglview/shaders/dsl_pass_1.frag @@ -11,17 +11,24 @@ uniform float z_near, z_far; uniform bool firstPass; uniform vec2 dt; uniform vec4 back_color; -uniform mat4 mat_proji, mat_viewi, mat_viewproji; +uniform mat4 mat_proji, mat_view, mat_viewi, mat_viewproji; float light_diffuse(int model, vec3 l, vec3 n) {return max(0., dot(l, n));} float light_specular(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) {return max(0., pow(dot(n, h), shininess));} vec4 pos, lpos, shp; -vec3 li, si, ldir, halfV, bn, bn2; -vec2 vds, vds2; +vec3 li, si, ldir, halfV, bn, bn2, lwdir; +vec3 vds, vds2; float sh_pow, sh_mul, dist, NdotL, NdotH, spot, ldist, diff, sdist, shadow; - +float getShadow(int light, vec3 view_pos, vec3 dpos) { + shp = mat_viewi * vec4(view_pos, 1); + shp += vec4(dpos, 0); + shp = qgl_Light[light].shadowMatrix * shp; + //shp.xyz /= shp.w; + shp.z -= 0.1; + return textureProj(qgl_Light[light].shadow, shp); +} void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) { lpos = qgl_Light[index].position; @@ -39,19 +46,45 @@ void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) { //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)); - shp = qgl_Light[index].shadowMatrix*vec4(pos.xyz,1); + + lwdir = mat3(mat_viewi) * qgl_Light[index].direction.xyz; + bn = normalize(cross(lwdir, vec3(1, 0, 0))); + bn2 = normalize(cross(lwdir, bn)); + float ds = ldist/100;//max(abs(sdist) / 5000, 0.02); + //spot *= clamp(1. - sdist, 0, 1); + vds = ds * bn.xyz; + vds2 = ds * bn2.xyz; + float shadow = getShadow(index, pos.xyz, vec3(0)) * 3. + + getShadow(index, pos.xyz, vds ) * 2. + + getShadow(index, pos.xyz, - vds ) * 2. + + getShadow(index, pos.xyz, - vds2 ) * 2. + + getShadow(index, pos.xyz, + vds2 ) * 2. + + getShadow(index, pos.xyz, vds - vds2 ) * 1.5 + + getShadow(index, pos.xyz, vds + vds2 ) * 1.5 + + getShadow(index, pos.xyz, - vds - vds2 ) * 1.5 + + getShadow(index, pos.xyz, - vds + vds2 ) * 1.5 + + getShadow(index, pos.xyz, vds + vds ) + + getShadow(index, pos.xyz, - vds - vds ) + + getShadow(index, pos.xyz, - vds2 - vds2) + + getShadow(index, pos.xyz, + vds2 + vds2) + + getShadow(index, pos.xyz, vds + vds - vds2 ) + + getShadow(index, pos.xyz, - vds - vds - vds2 ) + + getShadow(index, pos.xyz, vds + vds + vds2 ) + + getShadow(index, pos.xyz, - vds - vds + vds2 ) + + getShadow(index, pos.xyz, vds - vds2 - vds2) + + getShadow(index, pos.xyz, vds + vds2 + vds2) + + getShadow(index, pos.xyz, - vds - vds2 - vds2) + + getShadow(index, pos.xyz, - vds + vds2 + vds2); + //spot *= shadow / 29.; + /*shp = qgl_Light[index].shadowMatrix*vec4(pos.xyz,1); //shp.z -= 0.1; shp.xyz /= shp.w; float shr = texture(qgl_Light[index].shadowColor, shp.xy).r; sdist = shp.w - shr - 1.; //if (sdist > 0.) { - float ds = 0.01;//max(abs(sdist) / 5000, 0.02); - //spot *= clamp(1. - sdist, 0, 1); - vds = vec2(ds,0);//bn.xy * ds; - vds2 = vec2(0,ds);//bn2.xy * ds; shadow = //shr + //texture(qgl_Light[index].shadowColor, shp.xy, shp.zw)) + clamp(shp.w - texture(qgl_Light[index].shadowColor, shp.xy + vds ).r - 1, 0, 1) - /*clamp(shp.w - texture(qgl_Light[index].shadowColor, shp.xy + vds - vds2 ).r - 1, 0, 1) + + clamp(shp.w - texture(qgl_Light[index].shadowColor, shp.xy + vds - vds2 ).r - 1, 0, 1) + clamp(shp.w - texture(qgl_Light[index].shadowColor, shp.xy + vds + vds2 ).r - 1, 0, 1) + clamp(shp.w - texture(qgl_Light[index].shadowColor, shp.xy - vds ).r - 1, 0, 1) + clamp(shp.w - texture(qgl_Light[index].shadowColor, shp.xy - vds - vds2 ).r - 1, 0, 1) + @@ -77,10 +110,10 @@ void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) { texture(qgl_Light[index].shadowColor, shp.xy + vds + vds + vds2 + vds2).r + texture(qgl_Light[index].shadowColor, shp.xy + vds + vds + vds2 + vds2).r + texture(qgl_Light[index].shadowColor, shp.xy + vds + vds + vds2 + vds2).r + - texture(qgl_Light[index].shadowColor, shp.xy + vds + vds + vds2 + vds2).r*/; + texture(qgl_Light[index].shadowColor, shp.xy + vds + vds + vds2 + vds2).r; shadow = shadow / 1;// - 0.5; spot *= ds*100;//clamp(1. - shadow, 0, 1); - //} + //}*/ ///spot *= textureProj(qgl_Light[index].shadow, shp); } spot /= (qgl_Light[index].constantAttenuation + ldist * (qgl_Light[index].linearAttenuation + ldist * qgl_Light[index].quadraticAttenuation)); @@ -112,8 +145,8 @@ void main(void) { v4 = texelFetch(t4, tc, 0); vec2 sp = gl_FragCoord.xy * dt * 2 - vec2(1, 1); vec3 dc = v0.rgb, n = v1.xyz * 2. - vec3(1.); - bn = vec3(v3.w, v4.zw); - bn2 = normalize(cross(n, bn)); + //bn = vec3(v3.w, v4.zw); + //bn2 = normalize(cross(n, bn)); float height = v2.w; li = qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity; si = vec3(0.); @@ -136,14 +169,14 @@ void main(void) { sh_mul = max(1. - v1.w, 0.0001); //for (int i = 0; i < 8; ++i) // calcLight(i, n, v, v2); - calcLight(4, n, v, v2); + calcLight(0, n, v, v2); qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb + texelFetch(t_pp, tc, 0).rgb; //qgl_FragData[0].rgb = vec3(abs(lpos.xyz - pos.xyz)/10); //qgl_FragData[0].rgb = li + vec3(texelFetch(t_pp, tc, 0).xyz); //shd = shd - shp.w; - //qgl_FragData[0].rgb = vec3(abs(shd)/10000); - //qgl_FragData[0].rgb = vec3((shp.z)/1000); - qgl_FragData[0].rgb = vec3((shp.w-1 - texture(qgl_Light[4].shadowColor, shp.xy-vec2(0.01,0)).r)); + //qgl_FragData[0].rgb = vec3(abs(shp.xy/shp.w)/1,0); + //qgl_FragData[0].rgb = vec3(abs(mat3(mat_viewi)* qgl_Light[0].direction.xyz)); + //qgl_FragData[0].rgb = vec3(texture(qgl_Light[0].shadow,shp.xyz/shp.w)/2); //qgl_FragData[0].a = 0.; }