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

This commit is contained in:
2019-11-27 21:49:24 +00:00
parent 988c4e1150
commit 09298fadcd
22 changed files with 291 additions and 173 deletions

View File

@@ -81,22 +81,51 @@ Mesh * assimpMesh(const aiMesh * m) {
}
ObjectBase * assimpObject(const aiNode * n, const QVector<Mesh * > & meshes) {
Light * assimpLight(const aiLight * l) {
if (!l) return 0;
Light * ret = new Light();
ret->setName(l->mName.C_Str());
ret->setPos(fromAiVector3D(l->mPosition));
ret->direction = fromAiVector3D(l->mDirection);
ret->decay_const = l->mAttenuationConstant ;
ret->decay_linear = l->mAttenuationLinear ;
ret->decay_quadratic = l->mAttenuationQuadratic;
ret->angle_start = l->mAngleInnerCone * rad2deg;
ret->angle_end = l->mAngleOuterCone * rad2deg;
if (l->mType == aiLightSource_SPOT)
ret->light_type = Light::Cone;
QVector3D col(l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b);
ret->intensity = col.length();
col /= ret->intensity;
ret->setColor(QColor::fromRgbF(col[0], col[1], col[2]));
return ret;
}
ObjectBase * assimpObject(const aiNode * n, const QVector<Mesh * > & meshes, const QMap<QString, Light * > & light_by_name) {
if (!n) return 0;
ObjectBase * ret = new ObjectBase();
ret->setName(n->mName.C_Str());
ObjectBase * ret = 0;
QString name = n->mName.C_Str();
Light * light = light_by_name.value(name, 0);
if (light)
ret = light->clone();
else
ret = new ObjectBase();
ret->setName(name);
ret->setTransform(fromAiMatrix4D(n->mTransformation));
//qDebug() << "add object" << ret << ret->name();
for (uint i = 0; i < n->mNumMeshes; ++i) {
int mi = n->mMeshes[i];
if (meshes[mi]) {
ret->setMesh(meshes[mi]);
//qDebug() << "set mesh" << mi << ret->mesh();
break;
if (!light) {
for (uint i = 0; i < n->mNumMeshes; ++i) {
int mi = n->mMeshes[i];
if (meshes[mi]) {
ret->setMesh(meshes[mi]);
//qDebug() << "set mesh" << mi << ret->mesh();
break;
}
}
}
for (uint i = 0; i < n->mNumChildren; ++i) {
ObjectBase * co = assimpObject(n->mChildren[i], meshes);
ObjectBase * co = assimpObject(n->mChildren[i], meshes, light_by_name);
if (co) ret->addChild(co);
}
@@ -120,14 +149,23 @@ Scene * loadScene(const QString & filepath) {
QVector<Mesh * > meshes;
for (uint i = 0; i < ais->mNumMeshes; ++i)
meshes << assimpMesh(ais->mMeshes[i]);
QVector<Light * > lights;
for (uint i = 0; i < ais->mNumLights; ++i)
lights << assimpLight(ais->mLights[i]);
QMap<QString, Light * > light_by_name;
foreach (Light * l, lights)
light_by_name[l->name()] = l;
ObjectBase * root = assimpObject(ais->mRootNode, meshes);
ObjectBase * root = assimpObject(ais->mRootNode, meshes, light_by_name);
if (!root) return 0;
Scene * scene = new Scene();
scene->setName(root->name());
foreach (ObjectBase * o, root->children())
scene->addObject(o);
//foreach (ObjectBase * o, lights)
// scene->addObject(o);
qDeleteAll(lights);
return scene;
}

View File

@@ -500,6 +500,7 @@ ObjectBase * Light::clone(bool withChildren) {
for (int i = 0; i < children_.size(); ++i)
o->addChild(children_[i]->clone(withChildren));
}
o->color_ = color_;
o->light_type = light_type;
o->direction = direction;
o->angle_start = angle_start;

View File

@@ -274,4 +274,6 @@ inline T globject_cast(const ObjectBase * object) {return reinterpret_cast<T>(ob
QDataStream & operator <<(QDataStream & s, const ObjectBase * p);
QDataStream & operator >>(QDataStream & s, ObjectBase *& p);
inline QList<ObjectBase*> light2objectList(const QList<Light*> & v) {QList<ObjectBase*> ret; foreach (Light*i, v) ret << (ObjectBase*)i; return ret;}
#endif // GLOBJECT_H

View File

@@ -371,3 +371,37 @@ Mesh * Primitive::ellipsoidFrame(int segments_wl, int segments_h, float width, f
return ret;
}
Mesh * Primitive::coneFrame(int segments, float width, float length, float height) {
Mesh * ret = new Mesh(GL_LINES);
QVector<QVector3D> & v(ret->vertices ());
QVector<QVector3D> & n(ret->normals ());
QVector<QVector2D> & t(ret->texcoords());
QVector< Vector2i> & ind(ret->indicesLines());
int seg = qMax(segments + 1, 4);
double rx = width / 2., ry = length / 2.;
QVector3D cp;
for (int i = 0; i < seg; i++) {
double a = (double)i / (seg - 1) * M_2PI;
cp.setX(ry * cos(a));
cp.setY(rx * sin(a));
if (i > 0) {
v << QVector3D(0, 0, height);
t << QVector2D((double)(i - 1) / (seg - 1), 1.f);
double ta = ((double)i - 0.5) / (seg - 1) * M_2PI;
n << coneNormal(rx, ry, height, ta);
}
v << cp;
t << QVector2D((double)i / (seg - 1), 0.f);
n << coneNormal(rx, ry, height, a);
int si = v.size() - 1;
if (i > 0) {
ind << Vector2i(si - 1, si);
ind << Vector2i(si - 2, si);
}
}
return ret;
}

View File

@@ -46,6 +46,8 @@ Mesh * cubeFrame(float width = 1., float length = 1., float height = 1.);
Mesh * ellipsoidFrame(int segments_wl, int segments_h, float width = 1., float length = 1., float height = 1.);
Mesh * coneFrame(int segments, float width = 1., float length = 1., float height = 1.);
}
/*

View File

@@ -274,7 +274,6 @@ void Scene::removeMaterial(Material * m) {
if (o->material_ == m)
o->setMaterial(0);
materials.removeAll(m);
materials_used.remove(m);
changed_materials.removeAll(m);
mat_changed = true;
}
@@ -388,9 +387,10 @@ void Scene::prepareTree(ObjectBase * o) {
foreach (ObjectBase * co, o->children_) {
if (co->isHidden()) continue;
switch (co->type_) {
case ObjectBase::glLight:
lights_used << globject_cast<Light * >(co);
break;
case ObjectBase::glLight: {
Light * l = globject_cast<Light * >(co);
lights_used[l->light_type] << l;
} break;
case ObjectBase::glMesh:
if (co->mesh()) {
geometries_used[co->mesh()] << co;
@@ -427,15 +427,7 @@ bool Scene::prepare() {
lights_used.clear();
prepareTree(root_);
}
if (mat_changed) {
mat_changed = false;
materials_used.clear();
foreach (ObjectBase * o, aol) {
Material * m = o->material();
if (!m) continue;
materials_used << m;
}
}
mat_changed = false;
return true;
}

View File

@@ -102,7 +102,7 @@ protected:
void setTreeChanged();
void setTreeStructChanged();
void setMaterialsChanged() {mat_changed = true;}
void setLightsChanged() {lights_changed = true;}
void setLightsChanged() {lights_changed = tree_changed = true;}
void setObjectMeshChanged(ObjectBase * o);
@@ -116,8 +116,7 @@ protected:
QVector<Material*> materials;
QMap<Mesh*, QList<ObjectBase*> > geometries_used;
QSet<Material*> materials_used;
QList<Light*> lights_used;
QMap<int, QList<Light*>> lights_used; // by Light::Type
QVector<Material*> changed_materials;
SelectionMode sel_mode_;

View File

@@ -24,7 +24,7 @@
using namespace QGLEngineShaders;
bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QString & content, const QString & file) {
bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QString & content, const QString & file, const QString & defs) {
if (type == 0 || content.isEmpty()) {
content.clear();
return true;
@@ -43,6 +43,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());
if (!ret) qDebug() << "[QGLView] Shader" << file << "Compile error:\n" << prog->log();
@@ -51,59 +52,57 @@ bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QStr
}
bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file) {
QString prepareDefines(const QStringList & defines) {
if (defines.isEmpty()) return QString();
QString ret;
foreach (QString s, defines)
ret.append("#define " + s + "\n");
return ret;
}
bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, const QStringList & defines) {
if (!prog)
prog = new QOpenGLShaderProgram();
prog->removeAllShaders();
QFile f(file);
if (!f.open(QIODevice::ReadOnly)) return false;
QTextStream ts(&f);
QString cur_shader, line, pl;
QString cur_shader, line, pl, defs = prepareDefines(defines);
QOpenGLShader::ShaderType type = 0;
while (!ts.atEnd()) {
line = ts.readLine();
pl = line.trimmed().remove(' ').remove('\t').mid(2).toLower();
pl.chop(2);
if (pl == "vertex" || pl == "vert") {
if (!addShader(prog, type, cur_shader, file)) return false;
if (!addShader(prog, type, cur_shader, file, defs)) return false;
type = QOpenGLShader::Vertex;
continue;
}
if (pl == "fragment" || pl == "frag") {
if (!addShader(prog, type, cur_shader, file)) return false;
if (!addShader(prog, type, cur_shader, file, defs)) return false;
type = QOpenGLShader::Fragment;
continue;
}
if (pl == "geometry" || pl == "geom") {
if (!addShader(prog, type, cur_shader, file)) return false;
if (!addShader(prog, type, cur_shader, file, defs)) return false;
type = QOpenGLShader::Geometry;
continue;
}
if (pl == "tessellation_control") {
if (!addShader(prog, type, cur_shader, file)) return false;
if (!addShader(prog, type, cur_shader, file, defs)) return false;
type = QOpenGLShader::TessellationControl;
continue;
}
if (pl == "tessellation_evaluation") {
if (!addShader(prog, type, cur_shader, file)) return false;
if (!addShader(prog, type, cur_shader, file, defs)) return false;
type = QOpenGLShader::TessellationEvaluation;
continue;
}
cur_shader.append("\n");
cur_shader.append(line);
}
if (!addShader(prog, type, cur_shader, file)) return false;
/// WARNING
/*prog->bindAttributeLocation("qgl_Vertex" , 1 );
prog->bindAttributeLocation("qgl_Normal" , 2 );
prog->bindAttributeLocation("qgl_Tangent" , 3 );
prog->bindAttributeLocation("qgl_Bitangent" , 4 );
prog->bindAttributeLocation("qgl_Texture" , 5 );
prog->bindAttributeLocation("qgl_Material" , 6 );
prog->bindAttributeLocation("qgl_Color" , 7 );
prog->bindAttributeLocation("qgl_ModelViewMatrix" , 8 );
prog->bindAttributeLocation("qgl_ModelViewProjectionMatrix", 12);
prog->bindAttributeLocation("qgl_NormalMatrix" , 16);*/
if (!addShader(prog, type, cur_shader, file, 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);
bool loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, 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

@@ -31,7 +31,8 @@ public:
TextureManager(QOpenGLExtraFunctions * f_): f(f_) {}
virtual ~TextureManager() {}
void addSearchPath(const QString & path) {search_pathes << path;}
static void addSearchPath(const QString & path) {if (!search_pathes.contains(path)) search_pathes << path;}
static void clearSearchPathes() {search_pathes.clear();}
static QStringList searchPathes() {return search_pathes;}
QString findFile(const QString & path);
GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false);

View File

@@ -88,9 +88,12 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
//camera().aim_ = camera().pos_;
ktm_.restart();
//Mesh * m = Primitive::torus(30, 12, 1., 0.1, 90);
Mesh * m = Primitive::disc(10, 1, 1., true, 90);
QMatrix4x4 mat; mat.rotate(90, 1,0,0);
Mesh * m = Primitive::torus(30, 12, 1., 0.1, 90);
//Mesh * m = Primitive::coneFrame(10, 1, 1., 2.);
//QMatrix4x4 mat;
//mat.rotate(90, 0,1,0);
//mat.translate(0, 0, 2);
//mat.rotate(180, 1,0,0);
//m->transformPoints(mat);
ObjectBase * o = new ObjectBase(m);
o->setColor(Qt::cyan);

View File

@@ -19,6 +19,7 @@
#include "qglview_window.h"
#include "renderer.h"
#include "glwidget.h"
#include "gltexture_manager.h"
#include <QGraphicsRectItem>
#include <QImageReader>
#include <QMessageBox>
@@ -140,9 +141,11 @@ void QGLViewWindow::loadFile(const QString & path, bool import) {
s->setName(fi.baseName());
if (import) view->scene()->addScene(s);
else {
TextureManager::clearSearchPathes();
view->scene()->assignFrom(s);
view->view()->focusOn(view->scene()->boundingBox());
}
TextureManager::addSearchPath(fi.absoluteDir().path());
delete s;
}

View File

@@ -45,9 +45,10 @@ Renderer::Renderer(QGLView * view_): RendererBase(view_),
shader_files[srServiceFill ] = "service_fill.glsl";
shader_files[srServiceFrame] = "service_frame.glsl";
shader_files[srGeometryPass] = "ds_geom.glsl";
shader_files[srLightingPass] = "ds_light.glsl";
shader_files[srFinalPass ] = "ds_final.glsl";
shader_files[srGeometryPass ] = "ds_geom.glsl";
shader_files[srLightOmniPass] = "ds_light.glsl"; shader_defines[srLightOmniPass] << "FIRST_PASS";
shader_files[srLightSpotPass] = "ds_light.glsl"; shader_defines[srLightSpotPass] << "SPOT";
shader_files[srFinalPass ] = "ds_final.glsl";
/*shaders << ShaderPair("FXAA", &shader_fxaa)
<< ShaderPair("dsl_pass_0", &shader_ds_0)
@@ -102,9 +103,12 @@ void Renderer::reloadShaders() {
QMapIterator<ShaderRole, QString> it(shader_files);
while (it.hasNext()) {
it.next();
loadShadersMulti(shaders[it.key()], "shaders/" + it.value());
loadShadersMulti(shaders[it.key()], "shaders/" + it.value(), shader_defines.value(it.key()));
}
need_init_shaders = true;
view->scene()->setLightsChanged();
view->scene()->setTreeStructChanged();
view->scene()->setMaterialsChanged();
}
@@ -122,9 +126,12 @@ void Renderer::initShaders() {
if (!need_init_shaders) return;
need_init_shaders = false;
initUniformBuffer(shaders.value(srGeometryPass), &buffer_materials , bpMaterials , "QGLMaterialData" );
initUniformBuffer(shaders.value(srLightingPass), &buffer_materials , bpMaterials , "QGLMaterialData" );
initUniformBuffer(shaders.value(srLightingPass), &buffer_lights , bpLightParameters, "QGLLightParameterData");
initUniformBuffer(shaders.value(srLightingPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" );
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_materials , bpMaterials , "QGLMaterialData" );
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights , bpLightParameters, "QGLLightParameterData");
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" );
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_materials , bpMaterials , "QGLMaterialData" );
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights , bpLightParameters, "QGLLightParameterData");
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" );
}
@@ -167,7 +174,7 @@ void Renderer::renderObjects(Scene & scene, RenderPass pass) {
}
if (mesh->selected_changed && edit_mode) {
mesh->selected_changed = false;
rend_selection.fillSelectionsBuffer(it.value());
fillSelectionsBuffer(rend_selection.cur_selections_, it.value());
mesh->loadSelections(f, rend_selection.cur_selections_);
}
mesh->draw(f, it.value().size());
@@ -200,16 +207,16 @@ void Renderer::renderScene() {
}
/// lights
QList<Light*> ll = scene.lights_used;
QMap<int, QList<Light*>> ll = scene.lights_used;
if (is_camera_light) {
ll << cam_light;
ll[Light::Omni] << cam_light;
cam_light->setPos(cam->pos());
}
if (scene.lights_changed) {
scene.lights_changed = false;
reloadLightsParameters(ll);
}
reloadLightsPositions(ll, cam);
reloadLightsPositions(cam);
/// selection
if (edit_mode) {
@@ -233,31 +240,35 @@ void Renderer::renderScene() {
fbo_ds.bindColorTextures();
fbo_ds.bindDepthTexture(5);
fbo_out.bind();
if (bindShader(srLightingPass, &prog)) {
setUniformCamera(prog, cam);
setUniformViewCorners(prog, cam);
for (int i = 0; i < 5; ++i)
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
prog->setUniformValue("tex_d", 5);
prog->setUniformValue("lights_count", ll.size());
glClearFramebuffer(view->backColor(), false);
renderQuad(prog, quad, cam);
/*QVector<float> _fb = fbo_out.grabF(0);
if (!_fb.isEmpty()) {
double sum = 0.;
foreach (float f, _fb) sum += f;
sum /= _fb.size();
qDebug() << "sum =" << sum;
}*/
int ri = 1, wi = 0;
typedef QPair<Renderer::ShaderRole, Light::Type> PassPair;
QVector<PassPair> passes;
passes << PassPair(srLightOmniPass, Light::Omni) << PassPair(srLightSpotPass, Light::Cone);
foreach (PassPair pass, passes) {
if (bindShader(pass.first, &prog)) {
setUniformCamera(prog, cam);
setUniformViewCorners(prog, cam);
for (int i = 0; i < 5; ++i)
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
prog->setUniformValue("tex_d", 5);
prog->setUniformValue("lights_start", lights_start[pass.second]);
prog->setUniformValue("lights_count", ll[pass.second].size());
prog->setUniformValue("tex_sum", 7);
fbo_out.setWriteBuffer(wi);
fbo_out.bindColorTexture(ri, 7);
glClearFramebuffer(Qt::black, false);
renderQuad(prog, quad, cam);
piSwap(ri, wi);
}
}
fbo_out.release();
/// apply hovers and selection frame
if (edit_mode) {
rend_selection.drawSelection(fbo_out);
rend_selection.drawSelection(fbo_out, ri);
rend_service.renderService();
} else {
fbo_out.blit(0, 0, 0, fbo_out.rect(), QRect(QPoint(), view->size()));
fbo_out.blit(ri, 0, 0, fbo_out.rect(), QRect(QPoint(), view->size()));
}
}

View File

@@ -52,7 +52,8 @@ class Renderer: public RendererBase {
// Deferred shading
srGeometryPass,
srLightingPass,
srLightOmniPass,
srLightSpotPass,
srFinalPass,
};
enum DeferredBufferRole {
@@ -95,6 +96,7 @@ private:
QOpenGLShaderProgram * shader_shadow, * shader_ssr, * shader_ssr_blur, * shader_ssr_merge;
QOpenGLShaderProgram * shader_ssao_blur, * shader_ssao_merge, * shader_dof;*/
QMap<ShaderRole, QString> shader_files;
QMap<ShaderRole, QStringList> shader_defines;
QMap<ShaderRole, QOpenGLShaderProgram*> shaders;
RendererMaterial rend_mat;

View File

@@ -123,6 +123,21 @@ void RendererBase::setUniformViewCorners(QOpenGLShaderProgram * prog, Camera * c
}
void RendererBase::fillSelectionsBuffer(QVector<uchar> & buffer, const QList<ObjectBase *> & ol) {
buffer.resize(ol.size());
for (int i = 0; i < ol.size(); ++i) {
buffer[i] = (ol[i]->isSelected(true) ? 1 : 0);
}
}
void RendererBase::fillSelectionsBuffer(QVector<uchar> & buffer, bool yes, int size) {
buffer.resize(size);
for (int i = 0; i < size; ++i)
buffer[i] = (yes ? 1 : 0);
}
void RendererBase::reloadMaterials(Scene & scene) {
//qDebug() << "reloadMaterias";
QList<Map*> maps[2];
@@ -199,12 +214,21 @@ void RendererBase::reloadMaterials(Scene & scene) {
}
void RendererBase::reloadLightsParameters(const QList<Light*> & lights) {
cur_lights_params_.resize(qMin(lights.size(), max_lights));
void RendererBase::reloadLightsParameters(const QMap<int, QList<Light*>> & lights) {
lights_start.clear();
lights_start[Light::Omni] = 0;
QMapIterator<int, QList<Light*>> it(lights);
current_lights.clear();
while (it.hasNext()) {
it.next();
lights_start[it.key()] = current_lights.size();
current_lights.append(it.value());
}
cur_lights_params_.resize(qMin(current_lights.size(), max_lights));
//qDebug() << "reloadLightsParameters" << cur_lights_params_.size();
for (int i = 0; i < cur_lights_params_.size(); ++i) {
QGLLightParameter & so(cur_lights_params_[i]);
Light * l = lights[i];
Light * l = current_lights[i];
double ang_start = l->angle_start / 2.f, ang_end = l->angle_end / 2.f;
if (l->light_type == Light::Omni)
ang_start = ang_end = 180.;
@@ -227,12 +251,12 @@ void RendererBase::reloadLightsParameters(const QList<Light*> & lights) {
}
void RendererBase::reloadLightsPositions(const QList<Light *> & lights, Camera * cam) {
cur_lights_pos_.resize(qMin(lights.size(), max_lights));
void RendererBase::reloadLightsPositions(Camera * cam) {
cur_lights_pos_.resize(qMin(current_lights.size(), max_lights));
QMatrix4x4 mat = cam->viewMatrix() * cam->offsetMatrix();
for (int i = 0; i < cur_lights_pos_.size(); ++i) {
QGLLightPosition & so(cur_lights_pos_[i]);
Light * l = lights[i];
Light * l = current_lights[i];
QMatrix4x4 m = mat * l->worldTransform();
QVector4D pos(0, 0, 0, 1.), dir(l->direction, 1);//, dir0(light->dir0), dir1(light->dir1);
pos = m * pos;

View File

@@ -36,9 +36,11 @@ protected:
void setUniformMaps (QOpenGLShaderProgram * prog);
void setUniformCamera (QOpenGLShaderProgram * prog, Camera * cam, bool matrices = true, QSize viewport = QSize());
void setUniformViewCorners(QOpenGLShaderProgram * prog, Camera * cam, QSize viewport = QSize());
void fillSelectionsBuffer(QVector<uchar> & buffer, const QList<ObjectBase *> & ol);
void fillSelectionsBuffer(QVector<uchar> & buffer, bool yes, int size);
void reloadMaterials(Scene & scene);
void reloadLightsParameters(const QList<Light*> & lights);
void reloadLightsPositions (const QList<Light*> & lights, Camera * cam);
void reloadLightsParameters(const QMap<int, QList<Light*>> & lights);
void reloadLightsPositions (Camera * cam);
void markReloadTextures();
void setMapsSize(QSize sz);
void initQuad(Mesh * mesh, QMatrix4x4 mat = QMatrix4x4());
@@ -55,6 +57,8 @@ protected:
Texture2DArray textures_empty, textures_maps;
QSize maps_size;
uint maps_hash;
QMap<int, int> lights_start;
QList<Light*> current_lights;
};

View File

@@ -81,17 +81,18 @@ void RendererMaterial::renderMaterial(Material * m) {
fbo_mat_thumb.bindColorTextures();
fbo_mat_thumb.bindDepthTexture(5);
fbo_mat_thumb.setWriteBuffer(5);
if (r->bindShader(Renderer::srLightingPass, &prog)) {
if (r->bindShader(Renderer::srLightOmniPass, &prog)) {
r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size());
r->setUniformViewCorners(prog, mat_camera, fbo_mat_thumb.size());
for (int i = 0; i < 5; ++i)
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
prog->setUniformValue("tex_d", 5);
prog->setUniformValue("lights_start", 0);
prog->setUniformValue("lights_count", 1);
QList<Light*> mat_l;
mat_l << mat_light;
QMap<int, QList<Light*>> mat_l;
mat_l[Light::Omni] << mat_light;
r->reloadLightsParameters(mat_l);
r->reloadLightsPositions(mat_l, mat_camera);
r->reloadLightsPositions(mat_camera);
glClearFramebuffer(r->view->backColor(), false);
r->renderQuad(prog, r->quad, mat_camera);
r->view->scene()->setLightsChanged();

View File

@@ -62,29 +62,18 @@ void RendererSelection::generateObjectsID(Scene & scene) {
o->id_ = id;
}
}
foreach (ObjectBase * o, scene.lights_used) {
uint id = qHash(o);
ids[id] = o;
o->id_ = id;
QMapIterator<int, QList<Light*>> lit(scene.lights_used);
while (lit.hasNext()) {
lit.next();
foreach (ObjectBase * o, lit.value()) {
uint id = qHash(o);
ids[id] = o;
o->id_ = id;
}
}
}
void RendererSelection::fillSelectionsBuffer(const QList<ObjectBase *> & ol) {
cur_selections_.resize(ol.size());
for (int i = 0; i < ol.size(); ++i) {
cur_selections_[i] = (ol[i]->isSelected(true) ? 1 : 0);
}
}
void RendererSelection::fillSelectionsBuffer(bool yes, int size) {
cur_selections_.resize(size);
for (int i = 0; i < size; ++i)
cur_selections_[i] = (yes ? 1 : 0);
}
void RendererSelection::renderSelection(Scene & scene) {
QOpenGLShaderProgram * prog = 0;
QGLView * view = r->view;
@@ -120,12 +109,7 @@ void RendererSelection::renderSelection(Scene & scene) {
view->glClear(GL_DEPTH_BUFFER_BIT);
RendererService & rs(r->rend_service);
rs.fillOmniObjects();
rs.omni_mesh->loadObjects(view, rs.cur_objects);
fillSelectionsBuffer(light2objectList(scene.lights_used));
rs.omni_mesh->loadSelections(view, cur_selections_);
rs.omni_mesh->draw(view, rs.cur_objects.size());
rs.drawLights();
rs.drawCurrentHandleObjects();
//mouse_rect = fbo_selection.rect();

View File

@@ -27,6 +27,7 @@ class RendererSelection {
friend class QGLView;
friend class MouseController;
friend class Renderer;
friend class RendererService;
public:
RendererSelection(Renderer * r_);
@@ -44,12 +45,9 @@ protected:
};
void generateObjectsID(Scene & scene);
void fillSelectionsBuffer(const QList<ObjectBase *> & ol);
void fillSelectionsBuffer(bool yes, int size);
void renderSelection(Scene & scene);
void renderSelectionFrame();
void drawSelection(Framebuffer & fbo_out, int index_out = 0);
QList<ObjectBase*> light2objectList(const QList<Light*> & v) {QList<ObjectBase*> ret; foreach (Light*i, v) ret << (ObjectBase*)i; return ret;}
private:
Renderer * r;

View File

@@ -60,6 +60,15 @@ RendererService::RendererService(Renderer * r_): r(r_) {
omni_mesh_f = Primitive::ellipsoidFrame(2, 1);
omni_mesh ->scalePoints(1.5);
omni_mesh_f->scalePoints(1.5);
cone_mesh = Primitive::cone(8, 1., 1., 1.);
cone_mesh_f = Primitive::coneFrame(8, 1., 1., 1.);
QMatrix4x4 mat;
mat.rotate(90, 0,1,0);
mat.translate(0,0,2);
mat.rotate(180, 1,0,0);
cone_mesh ->transformPoints(mat);
cone_mesh_f->transformPoints(mat);
box_mesh ->scalePoints(1.3);
omni_mesh ->scalePoints(1.3);
@@ -98,6 +107,8 @@ RendererService::~RendererService() {
delete box_mesh_f;
delete omni_mesh;
delete omni_mesh_f;
delete cone_mesh;
delete cone_mesh_f;
delete axis_camera;
delete axis_mesh;
delete handle_move_mesh;
@@ -143,7 +154,7 @@ void RendererService::fillXYZObjects() {
void RendererService::fillOmniObjects() {
QList<Light*> ll = r->view->scene()->lights_used;
QList<Light*> ll = r->view->scene()->lights_used.value(Light::Omni);
Object o;
cur_objects.clear();
foreach (Light * l, ll) {
@@ -247,6 +258,15 @@ void RendererService::drawCurrentHandleObjects() {
}
void RendererService::drawLights() {
fillOmniObjects();
omni_mesh->loadObjects(r->view, cur_objects);
r->fillSelectionsBuffer(r->rend_selection.cur_selections_, light2objectList(r->view->scene_->lights_used.value(Light::Omni)));
omni_mesh->loadSelections(r->view, r->rend_selection.cur_selections_);
omni_mesh->draw(r->view, cur_objects.size());
}
void RendererService::setObjectsColor(QVector<Object> & ol, QColor col) {
QVector4D cv = QColor2QVector(col);
for (int i = 0; i < ol.size(); ++i)
@@ -279,7 +299,7 @@ void RendererService::renderService() {
setObjectsColor(cur_objects, Qt::black);
prog->setUniformValue("line_width", 1.f);
prog->setUniformValue("z_offset", -1.E-3f);
prog->setUniformValue("z_offset", -1.E-2f);
omni_mesh_f->loadObjects(f, cur_objects);
omni_mesh_f->draw(f, cur_objects.size());

View File

@@ -71,6 +71,7 @@ public:
void fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count = 3);
bool calculateCenter();
void drawCurrentHandleObjects();
void drawLights();
void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col);
void renderService();
void setCurrentAction(HandleAction ha) {current_action = ha;}
@@ -81,7 +82,7 @@ private:
Mesh * axis_mesh, * handle_move_mesh, * handle_rotate_mesh, * handle_scale_mesh;
Mesh * handle_ms_2_mesh, * handle_scale_3_mesh;
Mesh * box_mesh_f, * omni_mesh_f, * box_mesh, * omni_mesh;
Mesh * box_mesh_f, * omni_mesh_f, * cone_mesh_f, * box_mesh, * omni_mesh, * cone_mesh;
QMatrix4x4 v_mat, axis_mat;
QVector3D selection_center;
QVector<QMatrix4x4> mat_xyz, mat_ms2;

View File

@@ -17,8 +17,8 @@ in vec3 view_dir;
uniform vec2 dt;
uniform float z_near;
uniform sampler2D tex_0, tex_1, tex_2, tex_3, tex_4;
uniform sampler2D tex_d;
uniform int lights_count;
uniform sampler2D tex_d, tex_sum;
uniform int lights_start, lights_count;
const vec3 luma = vec3(0.299, 0.587, 0.114);
const float _pe = 2.4e-7;
@@ -36,45 +36,45 @@ void calcLight(in int index, in vec3 n, in vec3 v) {
halfV = normalize(ldir + v);
NdotL = max(dot(n, ldir), 1E-6);
NdotH = max(dot(n, halfV), 1E-6);
spot = step(1.01E-6, NdotL) * qgl_light_parameter[index].intensity;
/*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 *= smoothstep(qgl_Light[index].endAngleCos, qgl_Light[index].startAngleCos, scos);
//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/200.;//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.;
shadow += getShadow(index, pos.xyz, vds ) * 2.;
shadow += getShadow(index, pos.xyz, - vds ) * 2.;
shadow += getShadow(index, pos.xyz, - vds2 ) * 2.;
shadow += getShadow(index, pos.xyz, + vds2 ) * 2.;
//shadow += getShadow(index, pos.xyz, vds - vds2 ) * 1.5;
//shadow += getShadow(index, pos.xyz, vds + vds2 ) * 1.5;
//shadow += getShadow(index, pos.xyz, - vds - vds2 ) * 1.5;
//shadow += getShadow(index, pos.xyz, - vds + vds2 ) * 1.5;
//shadow += getShadow(index, pos.xyz, vds + vds );
//shadow += getShadow(index, pos.xyz, - vds - vds );
//shadow += getShadow(index, pos.xyz, - vds2 - vds2);
//shadow += getShadow(index, pos.xyz, + vds2 + vds2);
//shadow += getShadow(index, pos.xyz, vds + vds - vds2 );
//shadow += getShadow(index, pos.xyz, - vds - vds - vds2 );
//shadow += getShadow(index, pos.xyz, vds + vds + vds2 );
//shadow += getShadow(index, pos.xyz, - vds - vds + vds2 );
//shadow += getShadow(index, pos.xyz, vds - vds2 - vds2);
//shadow += getShadow(index, pos.xyz, vds + vds2 + vds2);
//shadow += getShadow(index, pos.xyz, - vds - vds2 - vds2);
//shadow += getShadow(index, pos.xyz, - vds + vds2 + vds2);
//shadow += shadow += getShadow(index, pos.xyz, vds+vds2)*10;
spot *= mix(1., shadow / 11., shadow_on);
}*/
//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 * shm_diff * light_specular(0, ldir, n, halfV, v, sh_pow);
spot = step(1.001E-6, NdotL) * qgl_light_parameter[index].intensity;
#ifdef SPOT
float scos = max(dot(-ldir, qgl_light_position[index].direction.xyz), 0.);
spot *= scos * step(qgl_light_parameter[index].endAngleCos, scos);
spot *= smoothstep(qgl_light_parameter[index].endAngleCos, qgl_light_parameter[index].startAngleCos, scos);
/*//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/200.;//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.;
shadow += getShadow(index, pos.xyz, vds ) * 2.;
shadow += getShadow(index, pos.xyz, - vds ) * 2.;
shadow += getShadow(index, pos.xyz, - vds2 ) * 2.;
shadow += getShadow(index, pos.xyz, + vds2 ) * 2.;
//shadow += getShadow(index, pos.xyz, vds - vds2 ) * 1.5;
//shadow += getShadow(index, pos.xyz, vds + vds2 ) * 1.5;
//shadow += getShadow(index, pos.xyz, - vds - vds2 ) * 1.5;
//shadow += getShadow(index, pos.xyz, - vds + vds2 ) * 1.5;
//shadow += getShadow(index, pos.xyz, vds + vds );
//shadow += getShadow(index, pos.xyz, - vds - vds );
//shadow += getShadow(index, pos.xyz, - vds2 - vds2);
//shadow += getShadow(index, pos.xyz, + vds2 + vds2);
//shadow += getShadow(index, pos.xyz, vds + vds - vds2 );
//shadow += getShadow(index, pos.xyz, - vds - vds - vds2 );
//shadow += getShadow(index, pos.xyz, vds + vds + vds2 );
//shadow += getShadow(index, pos.xyz, - vds - vds + vds2 );
//shadow += getShadow(index, pos.xyz, vds - vds2 - vds2);
//shadow += getShadow(index, pos.xyz, vds + vds2 + vds2);
//shadow += getShadow(index, pos.xyz, - vds - vds2 - vds2);
//shadow += getShadow(index, pos.xyz, - vds + vds2 + vds2);
//shadow += shadow += getShadow(index, pos.xyz, vds+vds2)*10;
spot *= mix(1., shadow / 11., shadow_on);*/
#endif
spot /= (qgl_light_parameter[index].constantAttenuation +
ldist * (qgl_light_parameter[index].linearAttenuation +
ldist * qgl_light_parameter[index].quadraticAttenuation));
float NdotLs = NdotL*NdotL;
float NdotHs = NdotH*NdotH;
@@ -106,7 +106,6 @@ void main(void) {
pos.w = 1;
pos.xyz = view_dir * z;
//pos.z = -pos.z;
vec3 v = normalize(-pos.xyz);
//vec2 sp = gl_FragCoord.xy * dt * 2 - vec2(1, 1);
@@ -127,14 +126,14 @@ void main(void) {
li = vec3(0.);//qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity;
si = vec3(0.);
for (int i = 0; i < lights_count; ++i)
calcLight(i, normal, v);
// calcLight(0, n, v, v2);
//calcLight(0, normal, v);
calcLight(lights_start + i, normal, v);
qgl_FragColor.rgb = max(vec3(0), li * diffuse + si * specular + emission);
vec4 result = vec4(max(vec3(0), li * diffuse + si * specular + emission), 1);
#ifndef FIRST_PASS
result += texelFetch(tex_sum, tc, 0);
#endif
qgl_FragColor = result;
//qgl_FragColor.rgb = vec3(1);
qgl_FragColor.a = 1;
//qgl_FragData[4] = vec4(speed.xy, bn.yz);