code format

This commit is contained in:
2022-12-14 14:14:44 +03:00
parent 1dfca0aeab
commit cb944b62e4
85 changed files with 4451 additions and 3744 deletions

View File

@@ -1,36 +1,36 @@
/* /*
QGL Buffer QGL Buffer
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "glbuffer.h" #include "glbuffer.h"
#include <QOpenGLExtraFunctions>
Buffer::Buffer(GLenum target, GLenum _usage) { Buffer::Buffer(GLenum target, GLenum _usage) {
target_ = target; target_ = target;
usage_ = _usage; usage_ = _usage;
buffer_ = 0; buffer_ = 0;
prev_size = 0; prev_size = 0;
} }
Buffer::~Buffer() { Buffer::~Buffer() {}
}
void Buffer::init(QOpenGLExtraFunctions * f) { void Buffer::init(QOpenGLExtraFunctions * f) {
@@ -49,13 +49,13 @@ void Buffer::destroy(QOpenGLExtraFunctions * f) {
void Buffer::reinit() { void Buffer::reinit() {
buffer_ = 0; buffer_ = 0;
prev_size = 0; prev_size = 0;
} }
void Buffer::bind(QOpenGLExtraFunctions * f) { void Buffer::bind(QOpenGLExtraFunctions * f) {
//qDebug() << "bind" << target_ << buffer_; // qDebug() << "bind" << target_ << buffer_;
f->glBindBuffer(target_, buffer_); f->glBindBuffer(target_, buffer_);
} }
@@ -78,10 +78,10 @@ void Buffer::unmap(QOpenGLExtraFunctions * f) {
bool Buffer::resize(QOpenGLExtraFunctions * f, int new_size) { bool Buffer::resize(QOpenGLExtraFunctions * f, int new_size) {
if (new_size <= 0) return false; if (new_size <= 0) return false;
//qDebug() << "check resize buffer" << buffer_ << "bytes" << new_size << ", old =" << prev_size; // qDebug() << "check resize buffer" << buffer_ << "bytes" << new_size << ", old =" << prev_size;
if (new_size <= prev_size) return false; if (new_size <= prev_size) return false;
prev_size = new_size; prev_size = new_size;
//qDebug() << "resize buffer " << buffer_ << target_ << "for" << new_size << "bytes"; // qDebug() << "resize buffer " << buffer_ << target_ << "for" << new_size << "bytes";
f->glBufferData(target_, new_size, 0, usage_); f->glBufferData(target_, new_size, 0, usage_);
return true; return true;
} }
@@ -89,6 +89,6 @@ bool Buffer::resize(QOpenGLExtraFunctions * f, int new_size) {
void Buffer::load(QOpenGLExtraFunctions * f, const void * data, int size, int offset) { void Buffer::load(QOpenGLExtraFunctions * f, const void * data, int size, int offset) {
if (!data || size <= 0) return; if (!data || size <= 0) return;
//qDebug() << "load buffer" << buffer_ << "bytes" << size; // qDebug() << "load buffer" << buffer_ << "bytes" << size;
f->glBufferSubData(target_, offset, size, data); f->glBufferSubData(target_, offset, size, data);
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGL Buffer QGL Buffer
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLBUFFER_H #ifndef GLBUFFER_H
@@ -22,37 +22,36 @@
#include "gltypes.h" #include "gltypes.h"
class Buffer class Buffer {
{
friend class ObjectBase; friend class ObjectBase;
public: public:
Buffer(GLenum target, GLenum usage = GL_DYNAMIC_DRAW); Buffer(GLenum target, GLenum usage = GL_DYNAMIC_DRAW);
~Buffer(); ~Buffer();
void init (QOpenGLExtraFunctions * f); void init(QOpenGLExtraFunctions * f);
void destroy (QOpenGLExtraFunctions * f); void destroy(QOpenGLExtraFunctions * f);
void reinit(); void reinit();
void bind (QOpenGLExtraFunctions * f); void bind(QOpenGLExtraFunctions * f);
void release (QOpenGLExtraFunctions * f); void release(QOpenGLExtraFunctions * f);
void * map (QOpenGLExtraFunctions * f, GLbitfield mode, int size = -1); void * map(QOpenGLExtraFunctions * f, GLbitfield mode, int size = -1);
void unmap (QOpenGLExtraFunctions * f); void unmap(QOpenGLExtraFunctions * f);
// returns true if size changed // returns true if size changed
bool resize (QOpenGLExtraFunctions * f, int new_size); bool resize(QOpenGLExtraFunctions * f, int new_size);
void load (QOpenGLExtraFunctions * f, const void * data, int size, int offset = 0); void load(QOpenGLExtraFunctions * f, const void * data, int size, int offset = 0);
GLuint ID() const {return buffer_;} GLuint ID() const { return buffer_; }
GLenum usage() const {return usage_;} GLenum usage() const { return usage_; }
GLenum target() const {return target_;} GLenum target() const { return target_; }
void setTarget(GLenum t) {target_ = t;} void setTarget(GLenum t) { target_ = t; }
bool isInit() const {return buffer_ != 0;} bool isInit() const { return buffer_ != 0; }
private: private:
GLenum target_, usage_; GLenum target_, usage_;
GLuint buffer_; GLuint buffer_;
int prev_size; int prev_size;
}; };

View File

@@ -1,23 +1,24 @@
/* /*
QGL CubeTexture QGL CubeTexture
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "gltypes.h"
#include "glcubemap.h" #include "glcubemap.h"
#include "gltypes.h"
#include "hdr_p.h" #include "hdr_p.h"
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
@@ -51,9 +52,9 @@ QVector<QVector3D> loadFileHDR(const QString & path, QSize * size) {
qDebug() << "[QGLEngine] File" << path << "has unknown size!"; qDebug() << "[QGLEngine] File" << path << "has unknown size!";
return ret; return ret;
} }
sz.setWidth (sl[3].toInt()); sz.setWidth(sl[3].toInt());
sz.setHeight(sl[1].toInt()); sz.setHeight(sl[1].toInt());
//qDebug() << "found size" << sz; // qDebug() << "found size" << sz;
break; break;
} }
} }
@@ -61,26 +62,23 @@ QVector<QVector3D> loadFileHDR(const QString & path, QSize * size) {
f.seek(ts.pos()); f.seek(ts.pos());
QDataStream ds(&f); QDataStream ds(&f);
int count = sz.width() * sz.height(); int count = sz.width() * sz.height();
QVector<float> data(count*3); QVector<float> data(count * 3);
if (!RGBE_ReadPixels_RLE(&ds, data.data(), sz.width(), sz.height())) if (!RGBE_ReadPixels_RLE(&ds, data.data(), sz.width(), sz.height())) return ret;
return ret;
if (size) *size = sz; if (size) *size = sz;
ret.resize(count); ret.resize(count);
//QColor col; // QColor col;
//QImage im(sz, QImage::Format_ARGB32); // QImage im(sz, QImage::Format_ARGB32);
//QRgb * imdata = (QRgb*)im.bits(); // QRgb * imdata = (QRgb*)im.bits();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
QVector3D p(pow(data[i*3 + 2], 1. / 2.2), QVector3D p(pow(data[i * 3 + 2], 1. / 2.2), pow(data[i * 3 + 1], 1. / 2.2), pow(data[i * 3 + 0], 1. / 2.2));
pow(data[i*3 + 1], 1. / 2.2),
pow(data[i*3 + 0], 1. / 2.2));
ret[i] = p; ret[i] = p;
//col = QColor::fromRgbF(piClamp(p[0], 0.f, 1.f), // col = QColor::fromRgbF(piClamp(p[0], 0.f, 1.f),
// piClamp(p[1], 0.f, 1.f), // piClamp(p[1], 0.f, 1.f),
// piClamp(p[2], 0.f, 1.f)); // piClamp(p[2], 0.f, 1.f));
//imdata[i] = col.rgb(); // imdata[i] = col.rgb();
} }
//im.save("_hdr.png"); // im.save("_hdr.png");
return ret; return ret;
} }
@@ -90,72 +88,71 @@ QVector<QVector3D> faceHDR(const QVector<QVector3D> & data, QSize sz, QSize & fs
QVector<QVector3D> ret; QVector<QVector3D> ret;
if (data.isEmpty() || sz.isNull()) return ret; if (data.isEmpty() || sz.isNull()) return ret;
QRect fr; QRect fr;
int fw = sz.width () / 4; int fw = sz.width() / 4;
int fh = sz.height() / 3; int fh = sz.height() / 3;
fsz = QSize(fw, fh); fsz = QSize(fw, fh);
ret.reserve(fw * fh); ret.reserve(fw * fh);
switch (face) { switch (face) {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
fr.setRect(fw, fh, fw, fh); fr.setRect(fw, fh, fw, fh);
for (int x = fr.left(); x <= fr.right(); ++x) { for (int x = fr.left(); x <= fr.right(); ++x) {
for (int y = fr.top(); y <= fr.bottom(); ++y) { for (int y = fr.top(); y <= fr.bottom(); ++y) {
ret << data[y*sz.width() + x]; ret << data[y * sz.width() + x];
} }
} }
break; break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
fr.setRect(fw*3, fh, fw, fh); fr.setRect(fw * 3, fh, fw, fh);
for (int x = fr.right(); x >= fr.left(); --x) { for (int x = fr.right(); x >= fr.left(); --x) {
for (int y = fr.bottom(); y >= fr.top(); --y) { for (int y = fr.bottom(); y >= fr.top(); --y) {
ret << data[y*sz.width() + x]; ret << data[y * sz.width() + x];
} }
} }
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
fr.setRect( 0, fh, fw, fh); fr.setRect(0, fh, fw, fh);
for (int y = fr.bottom(); y >= fr.top(); --y) { for (int y = fr.bottom(); y >= fr.top(); --y) {
for (int x = fr.left(); x <= fr.right(); ++x) { for (int x = fr.left(); x <= fr.right(); ++x) {
ret << data[y*sz.width() + x]; ret << data[y * sz.width() + x];
} }
} }
break; break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
fr.setRect(fw*2, fh, fw, fh); fr.setRect(fw * 2, fh, fw, fh);
for (int y = fr.top(); y <= fr.bottom(); ++y) { for (int y = fr.top(); y <= fr.bottom(); ++y) {
for (int x = fr.right(); x >= fr.left(); --x) { for (int x = fr.right(); x >= fr.left(); --x) {
ret << data[y*sz.width() + x]; ret << data[y * sz.width() + x];
} }
} }
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
fr.setRect(fw, 0, fw, fh); fr.setRect(fw, 0, fw, fh);
for (int x = fr.left(); x <= fr.right(); ++x) { for (int x = fr.left(); x <= fr.right(); ++x) {
for (int y = fr.top(); y <= fr.bottom(); ++y) { for (int y = fr.top(); y <= fr.bottom(); ++y) {
ret << data[y*sz.width() + x]; ret << data[y * sz.width() + x];
} }
} }
break; break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
fr.setRect(fw, fh*2, fw, fh); fr.setRect(fw, fh * 2, fw, fh);
for (int x = fr.left(); x <= fr.right(); ++x) { for (int x = fr.left(); x <= fr.right(); ++x) {
for (int y = fr.top(); y <= fr.bottom(); ++y) { for (int y = fr.top(); y <= fr.bottom(); ++y) {
ret << data[y*sz.width() + x]; ret << data[y * sz.width() + x];
} }
} }
break; break;
default: break; default: break;
} }
if (fr.isEmpty()) return ret; if (fr.isEmpty()) return ret;
//qDebug() << ret.size() << fr; // qDebug() << ret.size() << fr;
return ret; return ret;
} }
CubeTexture::CubeTexture(QOpenGLExtraFunctions * f_, int _size, const GLenum & _format): f(f_) { CubeTexture::CubeTexture(QOpenGLExtraFunctions * f_, int _size, const GLenum & _format): f(f_) {
size = _size; size = _size;
format_ = _format; format_ = _format;
id_ = 0; id_ = 0;
changed_ = false; changed_ = false;
} }
@@ -199,9 +196,17 @@ void CubeTexture::loadHDR(const QVector<QVector3D> & data, QSize sz) {
QVector<QVector3D> fd; QVector<QVector3D> fd;
for (int i = 0; i < 6; ++i) { for (int i = 0; i < 6; ++i) {
fd = faceHDR(data, sz, fsz, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); fd = faceHDR(data, sz, fsz, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
//qDebug() << "load cube" << fd[0]; // qDebug() << "load cube" << fd[0];
f->glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format_, fsz.width(), fsz.height(), 0, GL_RGB, GL_FLOAT, fd.isEmpty() ? 0 : fd.constData()); f->glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
//qDebug() << QString::number(GetLastError(), 16); 0,
format_,
fsz.width(),
fsz.height(),
0,
GL_RGB,
GL_FLOAT,
fd.isEmpty() ? 0 : fd.constData());
// qDebug() << QString::number(GetLastError(), 16);
} }
f->glGenerateMipmap(GL_TEXTURE_CUBE_MAP); f->glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
} }
@@ -230,4 +235,3 @@ void CubeTexture::load() {
} }
changed_ = false; changed_ = false;
} }

View File

@@ -1,26 +1,26 @@
/* /*
QGL CubeTexture QGL CubeTexture
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLCUBEMAP_H #ifndef GLCUBEMAP_H
#define GLCUBEMAP_H #define GLCUBEMAP_H
#include "glshaders_types.h"
#include "chunkstream.h" #include "chunkstream.h"
#include "glshaders_types.h"
QVector<QVector3D> loadFileHDR(const QString & path, QSize * size = 0); QVector<QVector3D> loadFileHDR(const QString & path, QSize * size = 0);
@@ -31,17 +31,23 @@ public:
void destroy(); void destroy();
void bind(int channel = 0); void bind(int channel = 0);
void release(); void release();
void resize(int _size) {size = _size; changed_ = true;} void resize(int _size) {
size = _size;
changed_ = true;
}
void loadHDR(const QVector<QVector3D> & data, QSize sz); void loadHDR(const QVector<QVector3D> & data, QSize sz);
void setFileHDR(const QString & path); void setFileHDR(const QString & path);
QString fileHDR() const {return hdr_path;} QString fileHDR() const { return hdr_path; }
GLenum format() const {return format_;} GLenum format() const { return format_; }
void setFormat(GLenum f) {format_ = f; changed_ = true;} void setFormat(GLenum f) {
GLuint id() const {return id_;} format_ = f;
bool isInit() const {return id_ != 0;} changed_ = true;
}
GLuint id() const { return id_; }
bool isInit() const { return id_ != 0; }
void load(); void load();
private:
private:
QOpenGLExtraFunctions * f; QOpenGLExtraFunctions * f;
bool changed_; bool changed_;
int size; int size;

View File

@@ -1,51 +1,54 @@
/* /*
QGL Framebuffer QGL Framebuffer
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QOpenGLExtraFunctions>
#include "glframebuffer.h" #include "glframebuffer.h"
#include <QOpenGLExtraFunctions>
#include <QTime> #include <QTime>
Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum _target) Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum _target)
: f(f_), pbo(GL_PIXEL_PACK_BUFFER, GL_STREAM_DRAW) { : f(f_)
, pbo(GL_PIXEL_PACK_BUFFER, GL_STREAM_DRAW) {
is_depth = withDepth; is_depth = withDepth;
target_ = _target; target_ = _target;
color_formats.fill(colorFormat_, colorAttachments_); color_formats.fill(colorFormat_, colorAttachments_);
colors.fill(0, colorAttachments_); colors.fill(0, colorAttachments_);
fbo = drbo = 0; fbo = drbo = 0;
tex_d = 0; tex_d = 0;
wid = hei = 0; wid = hei = 0;
pbo_queried = 0; pbo_queried = 0;
is_changed = false; is_changed = false;
} }
Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, QVector<GLenum> colors_, bool withDepth, GLenum _target) Framebuffer::Framebuffer(QOpenGLExtraFunctions * f_, QVector<GLenum> colors_, bool withDepth, GLenum _target)
: f(f_), pbo(GL_PIXEL_PACK_BUFFER, GL_STREAM_DRAW) { : f(f_)
is_depth = withDepth; , pbo(GL_PIXEL_PACK_BUFFER, GL_STREAM_DRAW) {
target_ = _target; is_depth = withDepth;
target_ = _target;
color_formats = colors_; color_formats = colors_;
colors.fill(0, colors_.size()); colors.fill(0, colors_.size());
fbo = drbo = 0; fbo = drbo = 0;
tex_d = 0; tex_d = 0;
wid = hei = 0; wid = hei = 0;
pbo_queried = 0; pbo_queried = 0;
is_changed = false; is_changed = false;
} }
@@ -67,7 +70,7 @@ void Framebuffer::resize(int width, int height, bool force) {
if (fbo > 0) deleteGLFramebuffer(fbo); if (fbo > 0) deleteGLFramebuffer(fbo);
f->glGenFramebuffers(1, &fbo); f->glGenFramebuffers(1, &fbo);
f->glBindFramebuffer(GL_FRAMEBUFFER, fbo); f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
//qDebug() << "resize" << f << wid << hei << fbo; // qDebug() << "resize" << f << wid << hei << fbo;
for (int i = 0; i < colors.size(); ++i) { for (int i = 0; i < colors.size(); ++i) {
deleteGLTexture(f, colors[i]); deleteGLTexture(f, colors[i]);
createGLTexture(f, colors[i], width, height, color_formats[i], target_); createGLTexture(f, colors[i], width, height, color_formats[i], target_);
@@ -103,10 +106,10 @@ void Framebuffer::resize(int width, int height, bool force) {
void Framebuffer::reinit() { void Framebuffer::reinit() {
pbo.reinit(); pbo.reinit();
colors.fill(0); colors.fill(0);
fbo = drbo = 0; fbo = drbo = 0;
tex_d = 0; tex_d = 0;
pbo_queried = 0; pbo_queried = 0;
is_changed = true; is_changed = true;
} }
@@ -152,8 +155,7 @@ uint Framebuffer::getPoint() const {
uint ret = 0; uint ret = 0;
pbo.bind(f); pbo.bind(f);
void * map = pbo.map(f, GL_MAP_READ_BIT, sizeof(uint)); void * map = pbo.map(f, GL_MAP_READ_BIT, sizeof(uint));
if (map) if (map) memcpy(&ret, map, sizeof(uint));
memcpy(&ret, map, sizeof(uint));
pbo.unmap(f); pbo.unmap(f);
pbo.release(f); pbo.release(f);
return ret; return ret;
@@ -166,8 +168,7 @@ QVector<uint> Framebuffer::getPointsByte() const {
ret.resize(pbo_queried); ret.resize(pbo_queried);
pbo.bind(f); pbo.bind(f);
void * map = pbo.map(f, GL_MAP_READ_BIT, pbo_queried * sizeof(uint)); void * map = pbo.map(f, GL_MAP_READ_BIT, pbo_queried * sizeof(uint));
if (map) if (map) memcpy(ret.data(), map, pbo_queried * sizeof(uint));
memcpy(ret.data(), map, pbo_queried * sizeof(uint));
pbo.unmap(f); pbo.unmap(f);
pbo.release(f); pbo.release(f);
return ret; return ret;
@@ -180,8 +181,7 @@ QVector<QVector4D> Framebuffer::getPointsFloat() const {
ret.resize(pbo_queried); ret.resize(pbo_queried);
pbo.bind(f); pbo.bind(f);
void * map = pbo.map(f, GL_MAP_READ_BIT, pbo_queried * sizeof(QVector4D)); void * map = pbo.map(f, GL_MAP_READ_BIT, pbo_queried * sizeof(QVector4D));
if (map) if (map) memcpy(ret.data(), map, pbo_queried * sizeof(QVector4D));
memcpy(ret.data(), map, pbo_queried * sizeof(QVector4D));
pbo.unmap(f); pbo.unmap(f);
pbo.release(f); pbo.release(f);
return ret; return ret;
@@ -191,12 +191,11 @@ QVector<QVector4D> Framebuffer::getPointsFloat() const {
QImage Framebuffer::getImage() const { QImage Framebuffer::getImage() const {
QImage ret; QImage ret;
if (!pbo.isInit() || (pbo_queried == 0)) return ret; if (!pbo.isInit() || (pbo_queried == 0)) return ret;
ret = QImage(size(), QImage::Format_RGBA8888); ret = QImage(size(), QImage::Format_RGBA8888);
int bytes = width() * height() * 4; int bytes = width() * height() * 4;
pbo.bind(f); pbo.bind(f);
void * map = pbo.map(f, GL_MAP_READ_BIT, bytes); void * map = pbo.map(f, GL_MAP_READ_BIT, bytes);
if (map) if (map) memcpy(ret.bits(), map, bytes);
memcpy(ret.bits(), map, bytes);
pbo.unmap(f); pbo.unmap(f);
pbo.release(f); pbo.release(f);
return ret; return ret;
@@ -277,7 +276,7 @@ void Framebuffer::unsetWriteBuffers() {
void Framebuffer::enablePixelBuffer() { void Framebuffer::enablePixelBuffer() {
pbo.init(f); pbo.init(f);
pbo.bind(f); pbo.bind(f);
pbo.resize(f, width()*height()*4*4); pbo.resize(f, width() * height() * 4 * 4);
pbo.release(f); pbo.release(f);
} }
@@ -311,14 +310,12 @@ void Framebuffer::bindDepthTexture(int channel) {
void Framebuffer::deleteGLRenderbuffer(GLuint & drbo) { void Framebuffer::deleteGLRenderbuffer(GLuint & drbo) {
if (drbo != 0) if (drbo != 0) f->glDeleteRenderbuffers(1, &drbo);
f->glDeleteRenderbuffers(1, &drbo);
drbo = 0; drbo = 0;
} }
void Framebuffer::deleteGLFramebuffer(GLuint & fbo) { void Framebuffer::deleteGLFramebuffer(GLuint & fbo) {
if (fbo != 0) if (fbo != 0) f->glDeleteFramebuffers(1, &fbo);
f->glDeleteFramebuffers(1, &fbo);
fbo = 0; fbo = 0;
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGL Framebuffer QGL Framebuffer
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLFRAMEBUFFER_H #ifndef GLFRAMEBUFFER_H
@@ -22,23 +22,27 @@
#include "glbuffer.h" #include "glbuffer.h"
class Framebuffer class Framebuffer {
{
friend class FramebufferMipmap; friend class FramebufferMipmap;
public: public:
Framebuffer(QOpenGLExtraFunctions * f_, int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum _target = GL_TEXTURE_2D); Framebuffer(QOpenGLExtraFunctions * f_,
int colorAttachments = 1,
bool withDepth = true,
GLenum colorFormat = GL_RGBA8,
GLenum _target = GL_TEXTURE_2D);
Framebuffer(QOpenGLExtraFunctions * f_, QVector<GLenum> colors_, bool withDepth = true, GLenum _target = GL_TEXTURE_2D); Framebuffer(QOpenGLExtraFunctions * f_, QVector<GLenum> colors_, bool withDepth = true, GLenum _target = GL_TEXTURE_2D);
virtual ~Framebuffer(); virtual ~Framebuffer();
GLuint id() const {return fbo;} GLuint id() const { return fbo; }
GLuint colorTexture(int index = 0) const {return colors[index];} GLuint colorTexture(int index = 0) const { return colors[index]; }
GLuint depthTexture() const {return tex_d;} GLuint depthTexture() const { return tex_d; }
GLenum target() const {return target_;} GLenum target() const { return target_; }
bool isInit() const {return fbo != 0;} bool isInit() const { return fbo != 0; }
int width() const {return wid;} int width() const { return wid; }
int height() const {return hei;} int height() const { return hei; }
QSize size() const {return QSize(wid, hei);} QSize size() const { return QSize(wid, hei); }
QRect rect() const {return QRect(0, 0, wid, hei);} QRect rect() const { return QRect(0, 0, wid, hei); }
QImage grab() const; QImage grab() const;
QVector<float> grabF(int index) const; QVector<float> grabF(int index) const;
void queryPoint(int index, QPoint p); void queryPoint(int index, QPoint p);
@@ -48,23 +52,29 @@ public:
QVector<uint> getPointsByte() const; QVector<uint> getPointsByte() const;
QVector<QVector4D> getPointsFloat() const; QVector<QVector4D> getPointsFloat() const;
QImage getImage() const; QImage getImage() const;
int queriedPoints() const {return pbo_queried;} int queriedPoints() const { return pbo_queried; }
void blit(int index_from, GLuint fb_to, int index_to, QRect from, QRect to, GLbitfield mask = GL_COLOR_BUFFER_BIT, GLenum filter = GL_NEAREST) const; void blit(int index_from,
GLuint fb_to,
int index_to,
QRect from,
QRect to,
GLbitfield mask = GL_COLOR_BUFFER_BIT,
GLenum filter = GL_NEAREST) const;
void resize(int width, int height, bool force = false); void resize(int width, int height, bool force = false);
void reinit(); void reinit();
void bind(); void bind();
void release(); void release();
void setReadBuffer(int index) {glReadBuffer(GL_COLOR_ATTACHMENT0 + index);} void setReadBuffer(int index) { glReadBuffer(GL_COLOR_ATTACHMENT0 + index); }
void setWriteBuffer(int index); void setWriteBuffer(int index);
void setWriteBuffers(const int * indeces, int count); void setWriteBuffers(const int * indeces, int count);
void setWriteBuffers(const QVector<int> & indeces) {setWriteBuffers(indeces.constData(), indeces.size());} void setWriteBuffers(const QVector<int> & indeces) { setWriteBuffers(indeces.constData(), indeces.size()); }
void setWriteBuffers(); void setWriteBuffers();
void unsetWriteBuffers(); void unsetWriteBuffers();
void enablePixelBuffer(); void enablePixelBuffer();
void setColorTextureFiltering(int index, GLenum filter); void setColorTextureFiltering(int index, GLenum filter);
void copyDepthFrom(GLuint tex) {;} void copyDepthFrom(GLuint tex) { ; }
void bindColorTexture(int index, int channel = 0); void bindColorTexture(int index, int channel = 0);
void bindColorTextures(); void bindColorTextures();
void bindDepthTexture(int channel); void bindDepthTexture(int channel);

View File

@@ -1,23 +1,24 @@
/* /*
QGL FramebufferMipmap QGL FramebufferMipmap
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QOpenGLExtraFunctions>
#include "glframebuffer_mipmap.h" #include "glframebuffer_mipmap.h"
#include <QOpenGLExtraFunctions>
#include <QTime> #include <QTime>
@@ -28,9 +29,7 @@ FramebufferMipmap::FramebufferMipmap(const Framebuffer & fb, int index_from_, in
} }
FramebufferMipmap::~FramebufferMipmap() { FramebufferMipmap::~FramebufferMipmap() {}
}
void FramebufferMipmap::resize() { void FramebufferMipmap::resize() {

View File

@@ -1,19 +1,19 @@
/* /*
QGL FramebufferMipmap QGL FramebufferMipmap
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLFRAMEBUFFER_MIPMAP_H #ifndef GLFRAMEBUFFER_MIPMAP_H
@@ -22,20 +22,19 @@
#include "glframebuffer.h" #include "glframebuffer.h"
class FramebufferMipmap class FramebufferMipmap {
{
public: public:
FramebufferMipmap(const Framebuffer & fb, int index_from_, int levels = 2); FramebufferMipmap(const Framebuffer & fb, int index_from_, int levels = 2);
virtual ~FramebufferMipmap(); virtual ~FramebufferMipmap();
int levelsCount() const {return fbo.size();} int levelsCount() const { return fbo.size(); }
int lastLevel() const {return fbo.size() - 1;} int lastLevel() const { return fbo.size() - 1; }
Framebuffer & plane(int level) {return *fbo[level];} Framebuffer & plane(int level) { return *fbo[level]; }
Framebuffer & lastPlane() {return *fbo[lastLevel()];} Framebuffer & lastPlane() { return *fbo[lastLevel()]; }
int width (int level) const {return fbo[level]->wid;} int width(int level) const { return fbo[level]->wid; }
int height(int level) const {return fbo[level]->hei;} int height(int level) const { return fbo[level]->hei; }
QSize size(int level) const {return fbo[level]->size();} QSize size(int level) const { return fbo[level]->size(); }
QRect rect(int level) const {return fbo[level]->rect();} QRect rect(int level) const { return fbo[level]->rect(); }
void resize(); void resize();
void create(); void create();
@@ -44,8 +43,7 @@ public:
private: private:
int index_from; int index_from;
const Framebuffer & src_fb; const Framebuffer & src_fb;
QVector<Framebuffer*> fbo; QVector<Framebuffer *> fbo;
}; };
#endif // GLFRAMEBUFFER_MIPMAP_H #endif // GLFRAMEBUFFER_MIPMAP_H

View File

@@ -1,48 +1,47 @@
/* /*
QGL Material QGL Material
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "gltypes.h"
#include "gltexture_manager.h" #include "gltexture_manager.h"
#include "gltypes.h"
#include "qglview.h" #include "qglview.h"
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
Map::Map() { Map::Map() {
bitmap_id = 0; bitmap_id = 0;
color_amount = 1.f; color_amount = 1.f;
color_offset = 0.f; color_offset = 0.f;
bitmap_scale = QPointF(1., 1.); bitmap_scale = QPointF(1., 1.);
use_bitmap = false; use_bitmap = false;
_changed = true; _changed = true;
_layer = 0; _layer = 0;
} }
void Map::setBitmapPath(const QString & p) { void Map::setBitmapPath(const QString & p) {
bitmap_path = p; bitmap_path = p;
_changed = true; _changed = true;
} }
void Map::load(TextureManager * tm) { void Map::load(TextureManager * tm) {
if (bitmap_id == 0) if (bitmap_id == 0) bitmap_id = tm->loadTexture(bitmap_path, true, _type == mtNormal);
bitmap_id = tm->loadTexture(bitmap_path, true, _type == mtNormal);
} }
@@ -60,21 +59,19 @@ void Map::copyToQGLMap(QGLMap & m) const {
} }
Material::Material(const QString _name) { Material::Material(const QString _name) {
setTypes(); setTypes();
name = _name; name = _name;
color_diffuse = Qt::white; color_diffuse = Qt::white;
color_emission = Qt::black; color_emission = Qt::black;
glass = false; glass = false;
transparency = reflectivity = 0.f; transparency = reflectivity = 0.f;
map_roughness.color_amount = 0.75f; map_roughness.color_amount = 0.75f;
map_metalness.color_amount = 0.25f; map_metalness.color_amount = 0.25f;
iof = 1.f; iof = 1.f;
dispersion = 0.05f; dispersion = 0.05f;
_changed = true; _changed = true;
_index = 0; _index = 0;
} }
@@ -89,63 +86,59 @@ bool Material::hasTransparency() const {
bool Material::isMapsChanged() const { bool Material::isMapsChanged() const {
return map_diffuse ._changed || return map_diffuse._changed || map_normal._changed || map_metalness._changed || map_roughness._changed || map_emission._changed ||
map_normal ._changed || map_relief._changed;
map_metalness._changed ||
map_roughness._changed ||
map_emission ._changed ||
map_relief ._changed;
} }
bool Material::isMapChanged(int type) const { bool Material::isMapChanged(int type) const {
switch (type) { switch (type) {
case mtDiffuse : return map_diffuse ._changed; case mtDiffuse: return map_diffuse._changed;
case mtNormal : return map_normal ._changed; case mtNormal: return map_normal._changed;
case mtMetalness: return map_metalness._changed; case mtMetalness: return map_metalness._changed;
case mtRoughness: return map_roughness._changed; case mtRoughness: return map_roughness._changed;
case mtEmission : return map_emission ._changed; case mtEmission: return map_emission._changed;
case mtRelief : return map_relief ._changed; case mtRelief: return map_relief._changed;
} }
return false; return false;
} }
void Material::load(TextureManager * tm) { void Material::load(TextureManager * tm) {
map_diffuse .load(tm); map_diffuse.load(tm);
map_normal .load(tm); map_normal.load(tm);
map_metalness.load(tm); map_metalness.load(tm);
map_roughness.load(tm); map_roughness.load(tm);
map_emission .load(tm); map_emission.load(tm);
map_relief .load(tm); map_relief.load(tm);
} }
void Material::setMapsChanged() { void Material::setMapsChanged() {
map_diffuse ._changed = true; map_diffuse._changed = true;
map_normal ._changed = true; map_normal._changed = true;
map_metalness._changed = true; map_metalness._changed = true;
map_roughness._changed = true; map_roughness._changed = true;
map_emission ._changed = true; map_emission._changed = true;
map_relief ._changed = true; map_relief._changed = true;
} }
void Material::setTypes() { void Material::setTypes() {
map_diffuse ._type = mtDiffuse ; map_diffuse._type = mtDiffuse;
map_normal ._type = mtNormal ; map_normal._type = mtNormal;
map_metalness._type = mtMetalness; map_metalness._type = mtMetalness;
map_roughness._type = mtRoughness; map_roughness._type = mtRoughness;
map_emission ._type = mtEmission ; map_emission._type = mtEmission;
map_relief ._type = mtRelief ; map_relief._type = mtRelief;
} }
void Material::detectMaps() { void Material::detectMaps() {
map_diffuse .use_bitmap = !map_diffuse .bitmap_path.isEmpty(); map_diffuse.use_bitmap = !map_diffuse.bitmap_path.isEmpty();
map_normal .use_bitmap = !map_normal .bitmap_path.isEmpty(); map_normal.use_bitmap = !map_normal.bitmap_path.isEmpty();
map_metalness.use_bitmap = !map_metalness.bitmap_path.isEmpty(); map_metalness.use_bitmap = !map_metalness.bitmap_path.isEmpty();
map_roughness.use_bitmap = !map_roughness.bitmap_path.isEmpty(); map_roughness.use_bitmap = !map_roughness.bitmap_path.isEmpty();
map_emission .use_bitmap = !map_emission .bitmap_path.isEmpty(); map_emission.use_bitmap = !map_emission.bitmap_path.isEmpty();
map_relief .use_bitmap = !map_relief .bitmap_path.isEmpty(); map_relief.use_bitmap = !map_relief.bitmap_path.isEmpty();
} }

View File

@@ -1,38 +1,38 @@
/* /*
QGL Material QGL Material
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLMATERIAL_H #ifndef GLMATERIAL_H
#define GLMATERIAL_H #define GLMATERIAL_H
#include "glshaders_types.h"
#include "chunkstream.h" #include "chunkstream.h"
#include "glshaders_types.h"
class Map { class Map {
public: public:
Map(); Map();
void setBitmapPath(const QString & p); void setBitmapPath(const QString & p);
void clearBitmap() {setBitmapPath(QString());} void clearBitmap() { setBitmapPath(QString()); }
bool hasBitmap() const {return !bitmap_path.isEmpty();} bool hasBitmap() const { return !bitmap_path.isEmpty(); }
void load(TextureManager * tm); void load(TextureManager * tm);
void copyToQGLMap(QGLEngineShaders::QGLMap & m) const; void copyToQGLMap(QGLEngineShaders::QGLMap & m) const;
QString bitmap_path; QString bitmap_path;
GLuint bitmap_id; GLuint bitmap_id;
QPointF bitmap_offset; QPointF bitmap_offset;
QPointF bitmap_scale; QPointF bitmap_scale;
float color_amount; float color_amount;
@@ -62,51 +62,60 @@ public:
float reflectivity; float reflectivity;
float iof; float iof;
float dispersion; float dispersion;
Map map_diffuse ; Map map_diffuse;
Map map_normal ; Map map_normal;
Map map_metalness; Map map_metalness;
Map map_roughness; Map map_roughness;
Map map_emission ; Map map_emission;
Map map_relief ; Map map_relief;
bool _changed; bool _changed;
int _index; int _index;
}; };
inline QDataStream & operator <<(QDataStream & s, const Map & m) { inline QDataStream & operator<<(QDataStream & s, const Map & m) {
ChunkStream cs; ChunkStream cs;
cs.add(1, m.bitmap_path).add(2, m.color_amount).add(3, m.color_offset).add(6, m.bitmap_scale) cs.add(1, m.bitmap_path).add(2, m.color_amount).add(3, m.color_offset).add(6, m.bitmap_scale).add(7, m.use_bitmap);
.add(7, m.use_bitmap); s << cs.data();
s << cs.data(); return s; return s;
} }
inline QDataStream & operator >>(QDataStream & s, Map & m) { inline QDataStream & operator>>(QDataStream & s, Map & m) {
ChunkStream cs(s); ChunkStream cs(s);
cs.readAll(); cs.readAll();
cs.get(1, m.bitmap_path).get(2, m.color_amount).get(3, m.color_offset).get(6, m.bitmap_scale) cs.get(1, m.bitmap_path).get(2, m.color_amount).get(3, m.color_offset).get(6, m.bitmap_scale).get(7, m.use_bitmap);
.get(7, m.use_bitmap);
return s; return s;
} }
inline QDataStream & operator <<(QDataStream & s, const Material * m) { inline QDataStream & operator<<(QDataStream & s, const Material * m) {
ChunkStream cs; ChunkStream cs;
cs.add(1, m->name).add(2, m->color_diffuse).add(4, m->color_emission) cs.add(1, m->name)
.add(5, m->transparency).add(6, m->reflectivity).add(7, m->glass).add(8, m->map_diffuse).add(9, m->map_normal) .add(2, m->color_diffuse)
.add(10, m->map_relief).add(11, m->map_metalness).add(12, m->map_roughness).add(13, m->map_emission); .add(4, m->color_emission)
s << (cs.data()); return s; .add(5, m->transparency)
.add(6, m->reflectivity)
.add(7, m->glass)
.add(8, m->map_diffuse)
.add(9, m->map_normal)
.add(10, m->map_relief)
.add(11, m->map_metalness)
.add(12, m->map_roughness)
.add(13, m->map_emission);
s << (cs.data());
return s;
} }
inline QDataStream & operator >>(QDataStream & s, Material *& m) { inline QDataStream & operator>>(QDataStream & s, Material *& m) {
m = new Material(); m = new Material();
ChunkStream cs(s); ChunkStream cs(s);
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
case 1: cs.get(m->name); break; case 1: cs.get(m->name); break;
case 2: cs.get(m->color_diffuse); break; case 2: cs.get(m->color_diffuse); break;
case 4: cs.get(m->color_emission); break; case 4: cs.get(m->color_emission); break;
case 5: cs.get(m->transparency); break; case 5: cs.get(m->transparency); break;
case 6: cs.get(m->reflectivity); break; case 6: cs.get(m->reflectivity); break;
case 7: cs.get(m->glass); break; case 7: cs.get(m->glass); break;
case 8: cs.get(m->map_diffuse); break; case 8: cs.get(m->map_diffuse); break;
case 9: cs.get(m->map_normal); break; case 9: cs.get(m->map_normal); break;
case 10: cs.get(m->map_relief); break; case 10: cs.get(m->map_relief); break;
case 11: cs.get(m->map_metalness); break; case 11: cs.get(m->map_metalness); break;
case 12: cs.get(m->map_roughness); break; case 12: cs.get(m->map_roughness); break;

View File

@@ -1,56 +1,59 @@
/* /*
QGL Mesh QGL Mesh
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "glmesh.h" #include "glmesh.h"
#include "globject.h" #include "globject.h"
#include <QOpenGLExtraFunctions>
#include <QTime> #include <QTime>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
//static int _count = 0; // static int _count = 0;
Mesh::Mesh(GLenum geom_type_): geom_type(geom_type_), Mesh::Mesh(GLenum geom_type_)
buffer_geom(GL_ARRAY_BUFFER, GL_STATIC_DRAW), : geom_type(geom_type_)
buffer_ind (GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW) { , buffer_geom(GL_ARRAY_BUFFER, GL_STATIC_DRAW)
hash_ = 0; , buffer_ind(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW) {
hash_ = 0;
changed = hash_changed = true; changed = hash_changed = true;
//qDebug() << "Mesh, now" << ++_count; // qDebug() << "Mesh, now" << ++_count;
} }
Mesh::~Mesh() { Mesh::~Mesh() {
//qDebug() << "~Mesh, now" << --_count; // qDebug() << "~Mesh, now" << --_count;
} }
Mesh * Mesh::clone() { Mesh * Mesh::clone() {
Mesh * c = new Mesh(); Mesh * c = new Mesh();
c->vertices_ = vertices_ ; c->vertices_ = vertices_;
c->normals_ = normals_ ; c->normals_ = normals_;
c->texcoords_ = texcoords_; c->texcoords_ = texcoords_;
c->triangles_ = triangles_; c->triangles_ = triangles_;
c->lines_ = lines_; c->lines_ = lines_;
c->geom_type = geom_type; c->geom_type = geom_type;
c->hash_ = hash_; c->hash_ = hash_;
c->hash_changed = hash_changed; c->hash_changed = hash_changed;
//qDebug() << "clone VBO"; // qDebug() << "clone VBO";
return c; return c;
} }
@@ -58,7 +61,7 @@ Mesh * Mesh::clone() {
void Mesh::init(QOpenGLExtraFunctions * f) { void Mesh::init(QOpenGLExtraFunctions * f) {
if (!isInit()) { if (!isInit()) {
buffer_geom.init(f); buffer_geom.init(f);
buffer_ind .init(f); buffer_ind.init(f);
changed = true; changed = true;
} }
} }
@@ -66,8 +69,8 @@ void Mesh::init(QOpenGLExtraFunctions * f) {
void Mesh::reinit() { void Mesh::reinit() {
buffer_geom.reinit(); buffer_geom.reinit();
buffer_ind .reinit(); buffer_ind.reinit();
QMapIterator<int, VertexObject * > it(vao_map); QMapIterator<int, VertexObject *> it(vao_map);
while (it.hasNext()) while (it.hasNext())
it.next().value()->reinit(); it.next().value()->reinit();
changed = true; changed = true;
@@ -76,9 +79,9 @@ void Mesh::reinit() {
void Mesh::destroy(QOpenGLExtraFunctions * f) { void Mesh::destroy(QOpenGLExtraFunctions * f) {
buffer_geom.destroy(f); buffer_geom.destroy(f);
buffer_ind .destroy(f); buffer_ind.destroy(f);
QList<VertexObject*> vaol = vao_map.values(); QList<VertexObject *> vaol = vao_map.values();
foreach (VertexObject* vao, vaol) foreach(VertexObject * vao, vaol)
vao->destroy(f); vao->destroy(f);
qDeleteAll(vao_map); qDeleteAll(vao_map);
vao_map.clear(); vao_map.clear();
@@ -88,12 +91,12 @@ void Mesh::destroy(QOpenGLExtraFunctions * f) {
void Mesh::calculateNormals() { void Mesh::calculateNormals() {
normals_.resize(vertices_.size()); normals_.resize(vertices_.size());
QVector3D dv1, dv2, n; QVector3D dv1, dv2, n;
foreach (const Vector3i & t, triangles_) { foreach(const Vector3i & t, triangles_) {
QVector3D & v0(vertices_[t.p0]); QVector3D & v0(vertices_[t.p0]);
QVector3D & v1(vertices_[t.p1]); QVector3D & v1(vertices_[t.p1]);
QVector3D & v2(vertices_[t.p2]); QVector3D & v2(vertices_[t.p2]);
dv1 = v1 - v0, dv2 = v2 - v0; dv1 = v1 - v0, dv2 = v2 - v0;
n = QVector3D::crossProduct(dv1, dv2).normalized(); n = QVector3D::crossProduct(dv1, dv2).normalized();
normals_[t.p0] = n; normals_[t.p0] = n;
normals_[t.p1] = n; normals_[t.p1] = n;
normals_[t.p2] = n; normals_[t.p2] = n;
@@ -104,32 +107,32 @@ void Mesh::calculateNormals() {
void Mesh::calculateTangents() { void Mesh::calculateTangents() {
if (vertices_.isEmpty() || texcoords_.isEmpty()) return; if (vertices_.isEmpty() || texcoords_.isEmpty()) return;
if (texcoords_.size() != vertices_.size()) return; if (texcoords_.size() != vertices_.size()) return;
tangents_ .resize(vertices_.size()); tangents_.resize(vertices_.size());
bitangents_.resize(vertices_.size()); bitangents_.resize(vertices_.size());
//qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "..."; // qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "...";
QVector3D dv1, dv2; QVector3D dv1, dv2;
QVector2D dt1, dt2; QVector2D dt1, dt2;
QVector3D tan, bitan; QVector3D tan, bitan;
foreach (const Vector3i & t, triangles_) { foreach(const Vector3i & t, triangles_) {
QVector3D & v0(vertices_ [t.p0]); QVector3D & v0(vertices_[t.p0]);
QVector3D & v1(vertices_ [t.p1]); QVector3D & v1(vertices_[t.p1]);
QVector3D & v2(vertices_ [t.p2]); QVector3D & v2(vertices_[t.p2]);
QVector2D & t0(texcoords_[t.p0]); QVector2D & t0(texcoords_[t.p0]);
QVector2D & t1(texcoords_[t.p1]); QVector2D & t1(texcoords_[t.p1]);
QVector2D & t2(texcoords_[t.p2]); QVector2D & t2(texcoords_[t.p2]);
dv1 = v1 - v0, dv2 = v2 - v0; dv1 = v1 - v0, dv2 = v2 - v0;
dt1 = t1 - t0, dt2 = t2 - t0; dt1 = t1 - t0, dt2 = t2 - t0;
tan = (dv1 * dt2.y() - dv2 * dt1.y()).normalized(); tan = (dv1 * dt2.y() - dv2 * dt1.y()).normalized();
bitan = (dv2 * dt1.x() - dv1 * dt2.x()).normalized(); bitan = (dv2 * dt1.x() - dv1 * dt2.x()).normalized();
tangents_ [t.p0] = tan; tangents_[t.p0] = tan;
tangents_ [t.p1] = tan; tangents_[t.p1] = tan;
tangents_ [t.p2] = tan; tangents_[t.p2] = tan;
bitangents_[t.p0] = bitan; bitangents_[t.p0] = bitan;
bitangents_[t.p1] = bitan; bitangents_[t.p1] = bitan;
bitangents_[t.p2] = bitan; bitangents_[t.p2] = bitan;
//qDebug() << " t" << t << vi << ti << dv1.toQVector3D() << "..."; // qDebug() << " t" << t << vi << ti << dv1.toQVector3D() << "...";
} }
//qDebug() << "calculateBinormals" << vcnt << tcnt << tangents_.size(); // qDebug() << "calculateBinormals" << vcnt << tcnt << tangents_.size();
} }
@@ -145,8 +148,7 @@ VertexObject * Mesh::vaoByType(int type) {
bool Mesh::rebuffer(QOpenGLExtraFunctions * f) { bool Mesh::rebuffer(QOpenGLExtraFunctions * f) {
changed = false; changed = false;
if (vertices_.isEmpty()) return true; if (vertices_.isEmpty()) return true;
if (normals_.isEmpty()) if (normals_.isEmpty()) calculateNormals();
calculateNormals();
calculateTangents(); calculateTangents();
vert_count = qMin(vertices_.size(), normals_.size()); vert_count = qMin(vertices_.size(), normals_.size());
vert_count = qMin(vert_count, tangents_.size()); vert_count = qMin(vert_count, tangents_.size());
@@ -155,11 +157,11 @@ bool Mesh::rebuffer(QOpenGLExtraFunctions * f) {
data_.resize(vert_count); data_.resize(vert_count);
for (int i = 0; i < vert_count; ++i) { for (int i = 0; i < vert_count; ++i) {
Vertex & v(data_[i]); Vertex & v(data_[i]);
v.pos = vertices_ [i]; v.pos = vertices_[i];
v.normal = normals_ [i]; v.normal = normals_[i];
v.tangent = tangents_ [i]; v.tangent = tangents_[i];
v.bitangent = bitangents_[i]; v.bitangent = bitangents_[i];
v.tex = texcoords_ [i]; v.tex = texcoords_[i];
} }
int gsize = data_.size() * sizeof(Vertex); int gsize = data_.size() * sizeof(Vertex);
int tsize = triangles_.size() * sizeof(Vector3i); int tsize = triangles_.size() * sizeof(Vector3i);
@@ -186,7 +188,7 @@ void Mesh::draw(QOpenGLExtraFunctions * f, int count, int type) {
if (isEmpty()) return; if (isEmpty()) return;
if (!isInit()) init(f); if (!isInit()) init(f);
if (changed) rebuffer(f); if (changed) rebuffer(f);
//qDebug() << "draw" << geom_type << vert_count << count; // qDebug() << "draw" << geom_type << vert_count << count;
VertexObject * vao = vaoByType(type); VertexObject * vao = vaoByType(type);
vao->bindBuffers(f, buffer_geom, buffer_ind); vao->bindBuffers(f, buffer_geom, buffer_ind);
@@ -198,14 +200,14 @@ void Mesh::draw(QOpenGLExtraFunctions * f, int count, int type) {
void Mesh::clear() { void Mesh::clear() {
vertices_ .clear(); vertices_.clear();
normals_ .clear(); normals_.clear();
tangents_ .clear(); tangents_.clear();
bitangents_.clear(); bitangents_.clear();
texcoords_ .clear(); texcoords_.clear();
triangles_ .clear(); triangles_.clear();
lines_ .clear(); lines_.clear();
data_ .clear(); data_.clear();
changed = hash_changed = true; changed = hash_changed = true;
} }
@@ -231,23 +233,23 @@ void Mesh::loadSelections(QOpenGLExtraFunctions * f, const QVector<uchar> & sels
uint Mesh::hash() const { uint Mesh::hash() const {
if (hash_changed) { if (hash_changed) {
hash_changed = false; hash_changed = false;
hash_ = qHashBits(vertices_ .constData(), vertices_ .size() * sizeof(QVector3D)); hash_ = qHashBits(vertices_.constData(), vertices_.size() * sizeof(QVector3D));
hash_ ^= qHashBits(normals_ .constData(), normals_ .size() * sizeof(QVector3D)); hash_ ^= qHashBits(normals_.constData(), normals_.size() * sizeof(QVector3D));
hash_ ^= qHashBits(texcoords_.constData(), texcoords_.size() * sizeof(QVector2D)); hash_ ^= qHashBits(texcoords_.constData(), texcoords_.size() * sizeof(QVector2D));
hash_ ^= qHashBits(triangles_.constData(), triangles_.size() * sizeof( Vector3i)); hash_ ^= qHashBits(triangles_.constData(), triangles_.size() * sizeof(Vector3i));
hash_ ^= qHashBits(lines_ .constData(), lines_ .size() * sizeof( Vector2i)); hash_ ^= qHashBits(lines_.constData(), lines_.size() * sizeof(Vector2i));
} }
return hash_; return hash_;
} }
bool Mesh::isObjectsChanged(int type) const { bool Mesh::isObjectsChanged(int type) const {
return (const_cast<Mesh*>(this))->vaoByType(type)->isObjectsChanged(); return (const_cast<Mesh *>(this))->vaoByType(type)->isObjectsChanged();
} }
bool Mesh::isSelectionChanged(int type) const { bool Mesh::isSelectionChanged(int type) const {
return (const_cast<Mesh*>(this))->vaoByType(type)->isSelectionChanged(); return (const_cast<Mesh *>(this))->vaoByType(type)->isSelectionChanged();
} }
@@ -262,14 +264,14 @@ void Mesh::setSelectionChanged(int type, bool yes) {
void Mesh::setAllObjectsChanged(bool yes) { void Mesh::setAllObjectsChanged(bool yes) {
QMapIterator<int, VertexObject * > it(vao_map); QMapIterator<int, VertexObject *> it(vao_map);
while (it.hasNext()) while (it.hasNext())
it.next().value()->setObjectsChanged(yes); it.next().value()->setObjectsChanged(yes);
} }
void Mesh::setAllSelectionChanged(bool yes) { void Mesh::setAllSelectionChanged(bool yes) {
QMapIterator<int, VertexObject * > it(vao_map); QMapIterator<int, VertexObject *> it(vao_map);
while (it.hasNext()) while (it.hasNext())
it.next().value()->setSelectionChanged(yes); it.next().value()->setSelectionChanged(yes);
} }
@@ -301,8 +303,7 @@ void Mesh::transformPoints(const QMatrix4x4 & mat) {
int vcnt = vertices_.size(), ncnt = normals_.size(); int vcnt = vertices_.size(), ncnt = normals_.size();
for (int i = 0; i < vcnt; ++i) { for (int i = 0; i < vcnt; ++i) {
vertices_[i] = (mat * QVector4D(vertices_[i], 1)).toVector3D(); vertices_[i] = (mat * QVector4D(vertices_[i], 1)).toVector3D();
if (i < ncnt) if (i < ncnt) normals_[i] = (mat * QVector4D(normals_[i], 0)).toVector3D();
normals_[i] = (mat * QVector4D(normals_[i], 0)).toVector3D();
} }
changed = hash_changed = true; changed = hash_changed = true;
} }
@@ -326,8 +327,8 @@ void Mesh::append(const Mesh * m) {
if (m->isEmpty()) return; if (m->isEmpty()) return;
if (normals_.isEmpty()) calculateNormals(); if (normals_.isEmpty()) calculateNormals();
int vcnt = vertices_.size(); int vcnt = vertices_.size();
vertices_ .append(m->vertices_ ); vertices_.append(m->vertices_);
normals_ .append(m->normals_ ); normals_.append(m->normals_);
texcoords_.append(m->texcoords_); texcoords_.append(m->texcoords_);
QVector<Vector3i> tri = m->triangles_; QVector<Vector3i> tri = m->triangles_;
for (int i = 0; i < tri.size(); ++i) for (int i = 0; i < tri.size(); ++i)
@@ -378,7 +379,7 @@ bool Mesh::loadFromFile(const QString & filename) {
Box3D Mesh::boundingBox() const { Box3D Mesh::boundingBox() const {
if (vertices_.isEmpty()) return Box3D(); if (vertices_.isEmpty()) return Box3D();
int vcnt = vertices_.size(); int vcnt = vertices_.size();
//qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "..."; // qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "...";
GLfloat mix, miy, miz, max, may, maz; GLfloat mix, miy, miz, max, may, maz;
QVector3D v0(vertices_[0]); QVector3D v0(vertices_[0]);
mix = max = v0.x(); mix = max = v0.x();
@@ -394,9 +395,9 @@ Box3D Mesh::boundingBox() const {
if (miz > v.z()) miz = v.z(); if (miz > v.z()) miz = v.z();
if (maz < v.z()) maz = v.z(); if (maz < v.z()) maz = v.z();
} }
bound.x = mix; bound.x = mix;
bound.y = miy; bound.y = miy;
bound.z = miz; bound.z = miz;
bound.length = max - mix; bound.length = max - mix;
bound.width = may - miy; bound.width = may - miy;
bound.height = maz - miz; bound.height = maz - miz;
@@ -404,26 +405,26 @@ Box3D Mesh::boundingBox() const {
} }
QDataStream & operator <<(QDataStream & s, const Mesh * m) { QDataStream & operator<<(QDataStream & s, const Mesh * m) {
ChunkStream cs; ChunkStream cs;
//qDebug() << "place VBO" << m.vertices_.size() << m.normals_.size() << m.texcoords_.size() << m.colors_.size() << "..."; // qDebug() << "place VBO" << m.vertices_.size() << m.normals_.size() << m.texcoords_.size() << m.colors_.size() << "...";
cs.add(1, m->vertices_).add(2, m->normals_).add(3, m->texcoords_) cs.add(1, m->vertices_).add(2, m->normals_).add(3, m->texcoords_).add(6, m->triangles_).add(7, m->lines_).add(10, int(m->geom_type));
.add(6, m->triangles_).add(7, m->lines_).add(10, int(m->geom_type)); // qDebug() << "place VBO done" << cs.data().size() << "...";
//qDebug() << "place VBO done" << cs.data().size() << "..."; s << cs.data();
s << cs.data(); return s; return s;
} }
QDataStream & operator >>(QDataStream & s, Mesh *& m) { QDataStream & operator>>(QDataStream & s, Mesh *& m) {
m = new Mesh(); m = new Mesh();
ChunkStream cs(s); ChunkStream cs(s);
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
case 1 : cs.get(m->vertices_ ); break; case 1: cs.get(m->vertices_); break;
case 2 : cs.get(m->normals_ ); break; case 2: cs.get(m->normals_); break;
case 3 : cs.get(m->texcoords_); break; case 3: cs.get(m->texcoords_); break;
case 6 : cs.get(m->triangles_); break; case 6: cs.get(m->triangles_); break;
case 7 : cs.get(m->lines_ ); break; case 7: cs.get(m->lines_); break;
case 10: m->geom_type = cs.getData<int>(); break; case 10: m->geom_type = cs.getData<int>(); break;
} }
} }

View File

@@ -1,74 +1,92 @@
/* /*
QGL Mesh QGL Mesh
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLMESH_H #ifndef GLMESH_H
#define GLMESH_H #define GLMESH_H
#include <chunkstream.h>
#include "glvertexobject.h" #include "glvertexobject.h"
#include <chunkstream.h>
class Mesh {
friend QDataStream & operator<<(QDataStream & s, const Mesh * m);
friend QDataStream & operator>>(QDataStream & s, Mesh *& m);
class Mesh
{
friend QDataStream & operator <<(QDataStream & s, const Mesh * m);
friend QDataStream & operator >>(QDataStream & s, Mesh *& m);
public: public:
Mesh(GLenum geom_type_ = GL_TRIANGLES); Mesh(GLenum geom_type_ = GL_TRIANGLES);
~Mesh(); ~Mesh();
Mesh * clone(); Mesh * clone();
void init (QOpenGLExtraFunctions * f); void init(QOpenGLExtraFunctions * f);
void destroy (QOpenGLExtraFunctions * f); void destroy(QOpenGLExtraFunctions * f);
bool rebuffer(QOpenGLExtraFunctions * f); bool rebuffer(QOpenGLExtraFunctions * f);
void draw (QOpenGLExtraFunctions * f, int count, int type = 0); void draw(QOpenGLExtraFunctions * f, int count, int type = 0);
void reinit(); void reinit();
void clear(); void clear();
void loadObject (QOpenGLExtraFunctions * f, const QGLEngineShaders::Object & object, int type = 0); void loadObject(QOpenGLExtraFunctions * f, const QGLEngineShaders::Object & object, int type = 0);
void loadObjects (QOpenGLExtraFunctions * f, const QVector<QGLEngineShaders::Object> & objects, int type = 0); void loadObjects(QOpenGLExtraFunctions * f, const QVector<QGLEngineShaders::Object> & objects, int type = 0);
void loadSelections(QOpenGLExtraFunctions * f, const QVector<uchar> & sels, int type = 0); void loadSelections(QOpenGLExtraFunctions * f, const QVector<uchar> & sels, int type = 0);
int verticesCount() const {return vertices_.size();} int verticesCount() const { return vertices_.size(); }
int trianglesCount() const {return triangles_.size();} int trianglesCount() const { return triangles_.size(); }
int linesCount() const {return lines_.size();} int linesCount() const { return lines_.size(); }
bool isInit() const {return buffer_geom.isInit();} bool isInit() const { return buffer_geom.isInit(); }
bool isEmpty() const {return vertices_.isEmpty();} bool isEmpty() const { return vertices_.isEmpty(); }
uint hash() const; uint hash() const;
bool isObjectsChanged (int type = 0) const; bool isObjectsChanged(int type = 0) const;
bool isSelectionChanged (int type = 0) const; bool isSelectionChanged(int type = 0) const;
void setObjectsChanged (int type = 0, bool yes = true); void setObjectsChanged(int type = 0, bool yes = true);
void setSelectionChanged(int type = 0, bool yes = true); void setSelectionChanged(int type = 0, bool yes = true);
void setAllObjectsChanged (bool yes = true); void setAllObjectsChanged(bool yes = true);
void setAllSelectionChanged(bool yes = true); void setAllSelectionChanged(bool yes = true);
QVector<QVector3D> & vertices () {changed = hash_changed = true; return vertices_;} QVector<QVector3D> & vertices() {
QVector<QVector3D> & normals () {changed = hash_changed = true; return normals_;} changed = hash_changed = true;
QVector<QVector2D> & texcoords() {changed = hash_changed = true; return texcoords_;} return vertices_;
QVector< Vector3i> & indicesTriangles() {changed = hash_changed = true; return triangles_;} }
QVector< Vector2i> & indicesLines () {changed = hash_changed = true; return lines_;} QVector<QVector3D> & normals() {
changed = hash_changed = true;
return normals_;
}
QVector<QVector2D> & texcoords() {
changed = hash_changed = true;
return texcoords_;
}
QVector<Vector3i> & indicesTriangles() {
changed = hash_changed = true;
return triangles_;
}
QVector<Vector2i> & indicesLines() {
changed = hash_changed = true;
return lines_;
}
void translatePoints(const QVector3D & dp); void translatePoints(const QVector3D & dp);
void translatePoints(const double & x, const double & y, const double & z) {translatePoints(QVector3D(x, y, z));} void translatePoints(const double & x, const double & y, const double & z) { translatePoints(QVector3D(x, y, z)); }
void scalePoints (const QVector3D & dp); void scalePoints(const QVector3D & dp);
void scalePoints (const double & s) {scalePoints(QVector3D(s, s, s));} void scalePoints(const double & s) { scalePoints(QVector3D(s, s, s)); }
void rotatePoints (const double & angle, const QVector3D & a); void rotatePoints(const double & angle, const QVector3D & a);
void rotatePoints (const double & angle, const double & x, const double & y, const double & z) {rotatePoints(angle, QVector3D(x, y, z));} void rotatePoints(const double & angle, const double & x, const double & y, const double & z) {
rotatePoints(angle, QVector3D(x, y, z));
}
void transformPoints(const QMatrix4x4 & mat); void transformPoints(const QMatrix4x4 & mat);
void flipNormals(); void flipNormals();
void append(const Mesh * m); void append(const Mesh * m);
@@ -85,13 +103,13 @@ private:
QVector<QVector3D> vertices_, normals_, tangents_, bitangents_; QVector<QVector3D> vertices_, normals_, tangents_, bitangents_;
QVector<QVector2D> texcoords_; QVector<QVector2D> texcoords_;
QVector< Vector3i> triangles_; QVector<Vector3i> triangles_;
QVector< Vector2i> lines_; QVector<Vector2i> lines_;
QVector<QGLEngineShaders::Vertex> data_; QVector<QGLEngineShaders::Vertex> data_;
GLenum geom_type; GLenum geom_type;
Buffer buffer_geom, buffer_ind; Buffer buffer_geom, buffer_ind;
QMap<int, VertexObject * > vao_map; QMap<int, VertexObject *> vao_map;
mutable uint hash_; mutable uint hash_;
mutable bool hash_changed; mutable bool hash_changed;
int vert_count; int vert_count;
@@ -99,7 +117,7 @@ private:
}; };
QDataStream & operator <<(QDataStream & s, const Mesh * m); QDataStream & operator<<(QDataStream & s, const Mesh * m);
QDataStream & operator >>(QDataStream & s, Mesh *& m); QDataStream & operator>>(QDataStream & s, Mesh *& m);
#endif // GLMESH_H #endif // GLMESH_H

View File

@@ -1,34 +1,36 @@
/* /*
QGL Primitives QGL Primitives
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "glprimitives.h" #include "glprimitives.h"
#include "glmesh.h" #include "glmesh.h"
Mesh * Primitive::plane(float width, float length) { Mesh * Primitive::plane(float width, float length) {
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector3i> & i(ret->indicesTriangles ()); QVector<Vector3i> & i(ret->indicesTriangles());
float hw = width / 2.f, hl = length / 2.f; float hw = width / 2.f, hl = length / 2.f;
for (int j = 0; j < 4; ++j) n << QVector3D(0., 0., 1.); for (int j = 0; j < 4; ++j)
t << QVector2D(0., 0.) << QVector2D(0., 1.) << QVector2D(1., 1.) << QVector2D(1., 0.); n << QVector3D(0., 0., 1.);
t << QVector2D(0., 0.) << QVector2D(0., 1.) << QVector2D(1., 1.) << QVector2D(1., 0.);
v << QVector3D(-hw, -hl, 0.) << QVector3D(-hw, hl, 0.) << QVector3D(hw, hl, 0.) << QVector3D(hw, -hl, 0.); v << QVector3D(-hw, -hl, 0.) << QVector3D(-hw, hl, 0.) << QVector3D(hw, hl, 0.) << QVector3D(hw, -hl, 0.);
i << Vector3i(0, 2, 1) << Vector3i(0, 3, 2); i << Vector3i(0, 2, 1) << Vector3i(0, 3, 2);
return ret; return ret;
@@ -38,17 +40,18 @@ Mesh * Primitive::plane(float width, float length) {
Mesh * Primitive::cube(float width, float length, float height) { Mesh * Primitive::cube(float width, float length, float height) {
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
QVector3D scale(width, length, height); QVector3D scale(width, length, height);
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector3i> & i(ret->indicesTriangles ()); QVector<Vector3i> & i(ret->indicesTriangles());
float hs = 0.5f; float hs = 0.5f;
int si = 0; int si = 0;
QMatrix4x4 mat; QMatrix4x4 mat;
si = v.size(); si = v.size();
for (int j = 0; j < 4; ++j) n << QVector3D(0., -1., 0.); for (int j = 0; j < 4; ++j)
t << QVector2D(0., 0.) << QVector2D(1., 0.) << QVector2D(1., 1.) << QVector2D(0., 1.); n << QVector3D(0., -1., 0.);
t << QVector2D(0., 0.) << QVector2D(1., 0.) << QVector2D(1., 1.) << QVector2D(0., 1.);
v << QVector3D(-hs, -hs, -hs) << QVector3D(hs, -hs, -hs) << QVector3D(hs, -hs, hs) << QVector3D(-hs, -hs, hs); v << QVector3D(-hs, -hs, -hs) << QVector3D(hs, -hs, -hs) << QVector3D(hs, -hs, hs) << QVector3D(-hs, -hs, hs);
i << Vector3i(si + 0, si + 1, si + 2) << Vector3i(si + 0, si + 2, si + 3); i << Vector3i(si + 0, si + 1, si + 2) << Vector3i(si + 0, si + 2, si + 3);
@@ -60,21 +63,21 @@ Mesh * Primitive::cube(float width, float length, float height) {
n << cn; n << cn;
v << mat.map(QVector4D(v[j])).toVector3D(); v << mat.map(QVector4D(v[j])).toVector3D();
} }
t << QVector2D(0., 0.) << QVector2D(1., 0.) << QVector2D(1., 1.) << QVector2D(0., 1.); t << QVector2D(0., 0.) << QVector2D(1., 0.) << QVector2D(1., 1.) << QVector2D(0., 1.);
i << Vector3i(si + 0, si + 1, si + 2) << Vector3i(si + 0, si + 2, si + 3); i << Vector3i(si + 0, si + 1, si + 2) << Vector3i(si + 0, si + 2, si + 3);
} }
mat.setToIdentity(); mat.setToIdentity();
mat.rotate(90., 1., 0.,0.); mat.rotate(90., 1., 0., 0.);
for (int r = 0; r < 2; ++r) { for (int r = 0; r < 2; ++r) {
si = v.size(); si = v.size();
mat.rotate(180., 1., 0.,0.); mat.rotate(180., 1., 0., 0.);
QVector3D cn = mat.map(n[0]); QVector3D cn = mat.map(n[0]);
for (int j = 0; j < 4; ++j) { for (int j = 0; j < 4; ++j) {
n << cn; n << cn;
v << mat.map(QVector4D(v[j])).toVector3D(); v << mat.map(QVector4D(v[j])).toVector3D();
} }
t << QVector2D(0., 0.) << QVector2D(1., 0.) << QVector2D(1., 1.) << QVector2D(0., 1.); t << QVector2D(0., 0.) << QVector2D(1., 0.) << QVector2D(1., 1.) << QVector2D(0., 1.);
i << Vector3i(si + 0, si + 1, si + 2) << Vector3i(si + 0, si + 2, si + 3); i << Vector3i(si + 0, si + 1, si + 2) << Vector3i(si + 0, si + 2, si + 3);
} }
@@ -87,10 +90,10 @@ Mesh * Primitive::cube(float width, float length, float height) {
Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float radius, float end_angle) { Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float radius, float end_angle) {
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector3i> & ind(ret->indicesTriangles()); QVector<Vector3i> & ind(ret->indicesTriangles());
int hseg = segments_h + 1, wlseg = segments_wl + 1; int hseg = segments_h + 1, wlseg = segments_wl + 1;
double crw, crl, a, ch, twl; double crw, crl, a, ch, twl;
double eang = deg2rad * end_angle; double eang = deg2rad * end_angle;
@@ -99,16 +102,16 @@ Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float radius, float
for (int i = 0; i <= hseg; i++) { for (int i = 0; i <= hseg; i++) {
ch = -cos((double)i / hseg * M_PI); ch = -cos((double)i / hseg * M_PI);
cp.setZ(ch * radius); cp.setZ(ch * radius);
twl = sqrt(1. - ch * ch); twl = sqrt(1. - ch * ch);
crw = twl * radius; crw = twl * radius;
crl = twl * radius; crl = twl * radius;
int cvcnt = wlseg * 2; int cvcnt = wlseg * 2;
for (int j = 0; j < cvcnt; j++) { for (int j = 0; j < cvcnt; j++) {
a = (double)j / (cvcnt - 1) * eang; a = (double)j / (cvcnt - 1) * eang;
cp.setX(crl * cos(a)); cp.setX(crl * cos(a));
cp.setY(crw * sin(a)); cp.setY(crw * sin(a));
v << cp; v << cp;
t << QVector2D((double)j / (cvcnt - 1), ch/2.f + 0.5f); t << QVector2D((double)j / (cvcnt - 1), ch / 2.f + 0.5f);
n << cp.normalized(); n << cp.normalized();
int si = v.size() - 1; int si = v.size() - 1;
if (j > 0 && i > 0) { if (j > 0 && i > 0) {
@@ -118,7 +121,7 @@ Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float radius, float
} }
} }
if (end_angle < 360.) { if (end_angle < 360.) {
Mesh * cap = Primitive::disc(segments_h+1, radius, 180); Mesh * cap = Primitive::disc(segments_h + 1, radius, 180);
cap->rotatePoints(90, 0, 1, 0); cap->rotatePoints(90, 0, 1, 0);
cap->rotatePoints(-90, 0, 0, 1); cap->rotatePoints(-90, 0, 0, 1);
ret->append(cap); ret->append(cap);
@@ -133,10 +136,10 @@ Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float radius, float
Mesh * Primitive::disc(int segments, float radius, float end_angle) { Mesh * Primitive::disc(int segments, float radius, float end_angle) {
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector3i> & ind(ret->indicesTriangles()); QVector<Vector3i> & ind(ret->indicesTriangles());
segments = qMax(segments + 1, 4); segments = qMax(segments + 1, 4);
QVector3D cp; QVector3D cp;
@@ -173,10 +176,10 @@ QVector3D coneNormal(double r, double height, double ang) {
Mesh * Primitive::cone(int segments, float radius, float height) { Mesh * Primitive::cone(int segments, float radius, float height) {
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector3i> & ind(ret->indicesTriangles()); QVector<Vector3i> & ind(ret->indicesTriangles());
int seg = qMax(segments + 1, 4); int seg = qMax(segments + 1, 4);
QVector3D cp; QVector3D cp;
@@ -194,8 +197,7 @@ Mesh * Primitive::cone(int segments, float radius, float height) {
t << QVector2D((double)i / (seg - 1), 0.f); t << QVector2D((double)i / (seg - 1), 0.f);
n << coneNormal(radius, height, a); n << coneNormal(radius, height, a);
int si = v.size() - 1; int si = v.size() - 1;
if (i > 0) if (i > 0) ind << Vector3i(si - 1, si - 2, si);
ind << Vector3i(si - 1, si - 2, si);
} }
Mesh * cap = Primitive::disc(segments, radius); Mesh * cap = Primitive::disc(segments, radius);
@@ -209,10 +211,10 @@ Mesh * Primitive::cone(int segments, float radius, float height) {
Mesh * Primitive::cylinder(int segments, float radius, float height, float end_angle) { Mesh * Primitive::cylinder(int segments, float radius, float height, float end_angle) {
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector3i> & ind(ret->indicesTriangles()); QVector<Vector3i> & ind(ret->indicesTriangles());
int seg = qMax(segments + 1, 4); int seg = qMax(segments + 1, 4);
QVector3D cp, norm; QVector3D cp, norm;
@@ -229,7 +231,8 @@ Mesh * Primitive::cylinder(int segments, float radius, float height, float end_a
v << cp; v << cp;
t << QVector2D((double)i / (seg - 1), 0.f); t << QVector2D((double)i / (seg - 1), 0.f);
t << QVector2D((double)i / (seg - 1), 1.f); t << QVector2D((double)i / (seg - 1), 1.f);
n << norm; n << norm; n << norm;
n << norm;
int si = v.size() - 1; int si = v.size() - 1;
if (i > 0) { if (i > 0) {
ind << Vector3i(si - 2, si - 1, si); ind << Vector3i(si - 2, si - 1, si);
@@ -248,7 +251,7 @@ Mesh * Primitive::cylinder(int segments, float radius, float height, float end_a
if (end_angle < 360.) { if (end_angle < 360.) {
Mesh * cap = Primitive::plane(radius, height); Mesh * cap = Primitive::plane(radius, height);
cap->rotatePoints(90, 1, 0, 0); cap->rotatePoints(90, 1, 0, 0);
cap->translatePoints(radius/2, 0, height/2); cap->translatePoints(radius / 2, 0, height / 2);
ret->append(cap); ret->append(cap);
cap->flipNormals(); cap->flipNormals();
cap->rotatePoints(end_angle, 0, 0, 1); cap->rotatePoints(end_angle, 0, 0, 1);
@@ -263,8 +266,8 @@ Mesh * Primitive::cylinder(int segments, float radius, float height, float end_a
Mesh * Primitive::arrow(int segments, float thick, float angle) { Mesh * Primitive::arrow(int segments, float thick, float angle) {
double cone_r = 1.5 * thick; double cone_r = 1.5 * thick;
double cone_h = 2. * cone_r / tan(angle * deg2rad); double cone_h = 2. * cone_r / tan(angle * deg2rad);
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
Mesh * m = Primitive::cylinder(segments, thick / 2., 1. - cone_h); Mesh * m = Primitive::cylinder(segments, thick / 2., 1. - cone_h);
ret->append(m); ret->append(m);
delete m; delete m;
m = Primitive::cone(segments, cone_r, cone_h); m = Primitive::cone(segments, cone_r, cone_h);
@@ -277,10 +280,10 @@ Mesh * Primitive::arrow(int segments, float thick, float angle) {
Mesh * Primitive::torus(int segments_main, int segments_second, float radius_main, float radius_second, float end_angle) { Mesh * Primitive::torus(int segments_main, int segments_second, float radius_main, float radius_second, float end_angle) {
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector3i> & ind(ret->indicesTriangles()); QVector<Vector3i> & ind(ret->indicesTriangles());
QVector<QVector3D> cv, cn; QVector<QVector3D> cv, cn;
QVector<QVector2D> ct; QVector<QVector2D> ct;
@@ -315,7 +318,7 @@ Mesh * Primitive::torus(int segments_main, int segments_second, float radius_mai
pcnt = v.size(); pcnt = v.size();
} }
if (end_angle < 360.) { if (end_angle < 360.) {
Mesh * cap = Primitive::disc(segments_second-1, radius_second); Mesh * cap = Primitive::disc(segments_second - 1, radius_second);
cap->rotatePoints(90, 1, 0, 0); cap->rotatePoints(90, 1, 0, 0);
cap->translatePoints(radius_main, 0, 0); cap->translatePoints(radius_main, 0, 0);
ret->append(cap); ret->append(cap);
@@ -328,22 +331,20 @@ Mesh * Primitive::torus(int segments_main, int segments_second, float radius_mai
} }
Mesh * Primitive::cubeFrame(float width, float length, float height) { Mesh * Primitive::cubeFrame(float width, float length, float height) {
Mesh * ret = new Mesh(GL_LINES); Mesh * ret = new Mesh(GL_LINES);
QVector3D scale(width, length, height); QVector3D scale(width, length, height);
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector2i> & i(ret->indicesLines()); QVector<Vector2i> & i(ret->indicesLines());
float hs = 0.5f; float hs = 0.5f;
v << QVector3D(-hs, -hs, -hs) << QVector3D(-hs, hs, -hs) << QVector3D( hs, hs, -hs) << QVector3D( hs, -hs, -hs); v << QVector3D(-hs, -hs, -hs) << QVector3D(-hs, hs, -hs) << QVector3D(hs, hs, -hs) << QVector3D(hs, -hs, -hs);
v << QVector3D(-hs, -hs, hs) << QVector3D(-hs, hs, hs) << QVector3D( hs, hs, hs) << QVector3D( hs, -hs, hs); v << QVector3D(-hs, -hs, hs) << QVector3D(-hs, hs, hs) << QVector3D(hs, hs, hs) << QVector3D(hs, -hs, hs);
for (int j = 0; j < 8; ++j) { for (int j = 0; j < 8; ++j) {
v[j] *= scale; v[j] *= scale;
t << QVector2D(0, 0); t << QVector2D(0, 0);
n << QVector3D(0,0,1); n << QVector3D(0, 0, 1);
} }
for (int j = 0; j < 4; ++j) { for (int j = 0; j < 4; ++j) {
i << Vector2i(j, (j + 1) % 4); i << Vector2i(j, (j + 1) % 4);
@@ -356,10 +357,10 @@ Mesh * Primitive::cubeFrame(float width, float length, float height) {
Mesh * Primitive::ellipsoidFrame(int segments_wl, int segments_h, float radius) { Mesh * Primitive::ellipsoidFrame(int segments_wl, int segments_h, float radius) {
Mesh * ret = new Mesh(GL_LINES); Mesh * ret = new Mesh(GL_LINES);
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector2i> & ind(ret->indicesLines()); QVector<Vector2i> & ind(ret->indicesLines());
int hseg = segments_h + 1, wlseg = segments_wl + 1; int hseg = segments_h + 1, wlseg = segments_wl + 1;
double crw, crl, a, ch, twl; double crw, crl, a, ch, twl;
@@ -367,16 +368,16 @@ Mesh * Primitive::ellipsoidFrame(int segments_wl, int segments_h, float radius)
for (int i = 0; i <= hseg; i++) { for (int i = 0; i <= hseg; i++) {
ch = -cos((double)i / hseg * M_PI); ch = -cos((double)i / hseg * M_PI);
cp.setZ(ch * radius); cp.setZ(ch * radius);
twl = sqrt(1. - ch * ch); twl = sqrt(1. - ch * ch);
crw = twl * radius; crw = twl * radius;
crl = twl * radius; crl = twl * radius;
int cvcnt = wlseg * 2; int cvcnt = wlseg * 2;
for (int j = 0; j < cvcnt; j++) { for (int j = 0; j < cvcnt; j++) {
a = (double)j / (cvcnt - 1) * M_2PI; a = (double)j / (cvcnt - 1) * M_2PI;
cp.setX(crl * cos(a)); cp.setX(crl * cos(a));
cp.setY(crw * sin(a)); cp.setY(crw * sin(a));
v << cp; v << cp;
t << QVector2D((double)j / (cvcnt - 1), ch/2.f + 0.5f); t << QVector2D((double)j / (cvcnt - 1), ch / 2.f + 0.5f);
n << cp.normalized(); n << cp.normalized();
int si = v.size() - 1; int si = v.size() - 1;
if (j > 0 && i > 0) { if (j > 0 && i > 0) {
@@ -391,10 +392,10 @@ Mesh * Primitive::ellipsoidFrame(int segments_wl, int segments_h, float radius)
Mesh * Primitive::coneFrame(int segments, float radius, float height) { Mesh * Primitive::coneFrame(int segments, float radius, float height) {
Mesh * ret = new Mesh(GL_LINES); Mesh * ret = new Mesh(GL_LINES);
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector2i> & ind(ret->indicesLines()); QVector<Vector2i> & ind(ret->indicesLines());
int seg = qMax(segments + 1, 4); int seg = qMax(segments + 1, 4);
QVector3D cp; QVector3D cp;
@@ -424,13 +425,13 @@ Mesh * Primitive::coneFrame(int segments, float radius, float height) {
Mesh * Primitive::lineFrame(QVector3D p0, QVector3D p1) { Mesh * Primitive::lineFrame(QVector3D p0, QVector3D p1) {
Mesh * ret = new Mesh(GL_LINES); Mesh * ret = new Mesh(GL_LINES);
QVector<QVector3D> & v(ret->vertices ()); QVector<QVector3D> & v(ret->vertices());
QVector<QVector3D> & n(ret->normals ()); QVector<QVector3D> & n(ret->normals());
QVector<QVector2D> & t(ret->texcoords()); QVector<QVector2D> & t(ret->texcoords());
QVector< Vector2i> & ind(ret->indicesLines()); QVector<Vector2i> & ind(ret->indicesLines());
v << p0 << p1; v << p0 << p1;
n << QVector3D(0,0,1) << QVector3D(0,0,1); n << QVector3D(0, 0, 1) << QVector3D(0, 0, 1);
t << QVector2D(0,0) << QVector2D(1,0); t << QVector2D(0, 0) << QVector2D(1, 0);
ind << Vector2i(0, 1); ind << Vector2i(0, 1);
return ret; return ret;
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGL Primitives QGL Primitives
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLPRIMITIVE_CUBE_H #ifndef GLPRIMITIVE_CUBE_H
@@ -50,6 +50,6 @@ Mesh * ellipsoidFrame(int segments_wl, int segments_h, float radius = 1.);
Mesh * coneFrame(int segments, float radius = 1., float height = 1.); Mesh * coneFrame(int segments, float radius = 1., float height = 1.);
} } // namespace Primitive
#endif // GLPRIMITIVE_CUBE_H #endif // GLPRIMITIVE_CUBE_H

View File

@@ -1,35 +1,41 @@
/* /*
QGLEngineShaders QGLEngineShaders
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "glshaders.h"
#include "glshaders_headers.h"
#include "gltypes.h" #include "gltypes.h"
#include "qglview.h" #include "qglview.h"
#include "glshaders.h"
#include "glshaders_headers.h"
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QString & content, const QString & file, bool add_qgl, 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()) { if (type == 0 || content.isEmpty()) {
content.clear(); content.clear();
return true; return true;
} }
//qDebug() << "[QGLEngine] Shader" << file << "found" << (QOpenGLShader::ShaderTypeBit)(int)type << "section ..."; // qDebug() << "[QGLEngine] Shader" << file << "found" << (QOpenGLShader::ShaderTypeBit)(int)type << "section ...";
if (add_qgl) { if (add_qgl) {
switch (type) { switch (type) {
case QOpenGLShader::Fragment: case QOpenGLShader::Fragment:
@@ -37,12 +43,8 @@ bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QStr
content.prepend(qgl_uniform); content.prepend(qgl_uniform);
content.prepend(qgl_structs); content.prepend(qgl_structs);
break; break;
case QOpenGLShader::Vertex : case QOpenGLShader::Vertex: content.prepend(qgl_vertex_head); break;
content.prepend(qgl_vertex_head ); case QOpenGLShader::Geometry: content.prepend(qgl_geometry_head); break;
break;
case QOpenGLShader::Geometry:
content.prepend(qgl_geometry_head);
break;
} }
} }
content.prepend(defs); content.prepend(defs);
@@ -57,15 +59,14 @@ bool addShader(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, QStr
QString prepareDefines(const QStringList & defines) { QString prepareDefines(const QStringList & defines) {
if (defines.isEmpty()) return QString(); if (defines.isEmpty()) return QString();
QString ret; QString ret;
foreach (QString s, defines) foreach(QString s, defines)
ret.append("#define " + s + "\n"); ret.append("#define " + s + "\n");
return ret; return ret;
} }
bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, bool add_qgl, const QStringList & defines) { bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, bool add_qgl, const QStringList & defines) {
if (!prog) if (!prog) prog = new QOpenGLShaderProgram();
prog = new QOpenGLShaderProgram();
QFile f(file); QFile f(file);
if (!f.open(QIODevice::ReadOnly)) { if (!f.open(QIODevice::ReadOnly)) {
qDebug() << "[QGLEngine] Shader" << file << "Error: can`t open file!"; qDebug() << "[QGLEngine] Shader" << file << "Error: can`t open file!";
@@ -76,7 +77,7 @@ bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QStr
QOpenGLShader::ShaderType type = QOpenGLShader::ShaderType(); QOpenGLShader::ShaderType type = QOpenGLShader::ShaderType();
while (!ts.atEnd()) { while (!ts.atEnd()) {
line = ts.readLine(); line = ts.readLine();
pl = line.trimmed().remove(' ').remove('\t').mid(2).toLower(); pl = line.trimmed().remove(' ').remove('\t').mid(2).toLower();
pl.chop(2); pl.chop(2);
if (pl == "vertex" || pl == "vert") { if (pl == "vertex" || pl == "vert") {
if (!addShader(prog, type, cur_shader, file, add_qgl, defs)) return false; if (!addShader(prog, type, cur_shader, file, add_qgl, defs)) return false;
@@ -117,14 +118,13 @@ bool QGLEngineShaders::loadShadersMulti(QOpenGLShaderProgram *& prog, const QStr
bool QGLEngineShaders::loadShaders(QOpenGLShaderProgram *& prog, const QStringList & files, bool add_qgl, const QStringList & defines) { bool QGLEngineShaders::loadShaders(QOpenGLShaderProgram *& prog, const QStringList & files, bool add_qgl, const QStringList & defines) {
if (!prog) if (!prog) prog = new QOpenGLShaderProgram();
prog = new QOpenGLShaderProgram();
prog->removeAllShaders(); prog->removeAllShaders();
QString cur_shader, defs = prepareDefines(defines); QString cur_shader, defs = prepareDefines(defines);
foreach (QString f, files) { foreach(QString f, files) {
QFileInfo fi(f); QFileInfo fi(f);
QOpenGLShader::ShaderType type = QOpenGLShader::ShaderType(); QOpenGLShader::ShaderType type = QOpenGLShader::ShaderType();
if (fi.suffix().toLower() == "vert") type = QOpenGLShader::Vertex ; if (fi.suffix().toLower() == "vert") type = QOpenGLShader::Vertex;
if (fi.suffix().toLower() == "frag") type = QOpenGLShader::Fragment; if (fi.suffix().toLower() == "frag") type = QOpenGLShader::Fragment;
if (fi.suffix().toLower() == "geom") type = QOpenGLShader::Geometry; if (fi.suffix().toLower() == "geom") type = QOpenGLShader::Geometry;
if (type == 0) continue; if (type == 0) continue;

View File

@@ -1,19 +1,19 @@
/* /*
QGLEngineShaders QGLEngineShaders
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLSHADERS_H #ifndef GLSHADERS_H
@@ -26,6 +26,6 @@ namespace QGLEngineShaders {
bool loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, bool add_qgl = true, const QStringList & defines = QStringList()); bool loadShadersMulti(QOpenGLShaderProgram *& prog, const QString & file, bool add_qgl = true, const QStringList & defines = QStringList());
bool loadShaders(QOpenGLShaderProgram *& prog, const QStringList & files, bool add_qgl = true, const QStringList & defines = QStringList()); bool loadShaders(QOpenGLShaderProgram *& prog, const QStringList & files, bool add_qgl = true, const QStringList & defines = QStringList());
} } // namespace QGLEngineShaders
#endif // GLSHADERS_H #endif // GLSHADERS_H

View File

@@ -1,19 +1,19 @@
/* /*
QGLEngineShaders QGLEngineShaders
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLSHADERS_HEADERS_H #ifndef GLSHADERS_HEADERS_H
@@ -21,32 +21,30 @@
namespace QGLEngineShaders { namespace QGLEngineShaders {
const int max_materials = 128; const int max_materials = 128;
const int max_lights = 256 ; const int max_lights = 256;
const char qgl_common_head[] = const char qgl_common_head[] = "#version 400 core\n"
"#version 400 core\n" "";
"";
const char qgl_vertex_head[] = const char qgl_vertex_head[] = "layout(location = 1 ) in vec3 qgl_Vertex ;\n"
"layout(location = 1 ) in vec3 qgl_Vertex ;\n" "layout(location = 2 ) in vec3 qgl_Normal ;\n"
"layout(location = 2 ) in vec3 qgl_Normal ;\n" "layout(location = 3 ) in vec3 qgl_Tangent ;\n"
"layout(location = 3 ) in vec3 qgl_Tangent ;\n" "layout(location = 4 ) in vec3 qgl_Bitangent ;\n"
"layout(location = 4 ) in vec3 qgl_Bitangent ;\n" "layout(location = 5 ) in vec2 qgl_Texture ;\n"
"layout(location = 5 ) in vec2 qgl_Texture ;\n" "layout(location = 6 ) in uint qgl_Material ;\n"
"layout(location = 6 ) in uint qgl_Material ;\n" "layout(location = 7 ) in uint qgl_ObjectSelected;\n"
"layout(location = 7 ) in uint qgl_ObjectSelected;\n" "layout(location = 8 ) in uint qgl_ObjectID ;\n"
"layout(location = 8 ) in uint qgl_ObjectID ;\n" "layout(location = 9 ) in vec4 qgl_ObjectColor ;\n"
"layout(location = 9 ) in vec4 qgl_ObjectColor ;\n" "layout(location = 10) in mat4 qgl_ModelMatrix ;\n"
"layout(location = 10) in mat4 qgl_ModelMatrix ;\n" "out vec2 qgl_FragTexture;\n"
"out vec2 qgl_FragTexture;\n" "flat out uint qgl_MaterialIndex;\n"
"flat out uint qgl_MaterialIndex;\n" "uniform mat4 qgl_ViewMatrix;\n"
"uniform mat4 qgl_ViewMatrix;\n" "uniform mat4 qgl_ViewProjMatrix;\n"
"uniform mat4 qgl_ViewProjMatrix;\n" "mat3 qgl_getNormalMatrix() {return inverse(mat3(qgl_ViewMatrix * qgl_ModelMatrix));}\n"
"mat3 qgl_getNormalMatrix() {return inverse(mat3(qgl_ViewMatrix * qgl_ModelMatrix));}\n" "mat3 qgl_getTangentMatrix() {return mat3(qgl_ViewMatrix * qgl_ModelMatrix);}\n"
"mat3 qgl_getTangentMatrix() {return mat3(qgl_ViewMatrix * qgl_ModelMatrix);}\n" "vec4 qgl_ftransform() {return qgl_ViewProjMatrix * (qgl_ModelMatrix * vec4(qgl_Vertex, 1));}\n"
"vec4 qgl_ftransform() {return qgl_ViewProjMatrix * (qgl_ModelMatrix * vec4(qgl_Vertex, 1));}\n" "";
"";
const char qgl_fragment_head[] = const char qgl_fragment_head[] =
"in vec2 qgl_FragTexture;\n" "in vec2 qgl_FragTexture;\n"
@@ -63,59 +61,56 @@ const char qgl_fragment_head[] =
"#define qgl_FragColor qgl_FragData[0]\n" "#define qgl_FragColor qgl_FragData[0]\n"
""; "";
const char qgl_geometry_head[] = const char qgl_geometry_head[] = "";
"";
const char qgl_structs[] = const char qgl_structs[] = "#define QGL_MAPS_COUNT 6\n"
"#define QGL_MAPS_COUNT 6\n" "#define QGL_MAP_DIFFUSE 0\n"
"#define QGL_MAP_DIFFUSE 0\n" "#define QGL_MAP_NORMAL 1\n"
"#define QGL_MAP_NORMAL 1\n" "#define QGL_MAP_METALNESS 2\n"
"#define QGL_MAP_METALNESS 2\n" "#define QGL_MAP_ROUGHNESS 3\n"
"#define QGL_MAP_ROUGHNESS 3\n" "#define QGL_MAP_EMISSION 4\n"
"#define QGL_MAP_EMISSION 4\n" "#define QGL_MAP_RELIEF 5\n"
"#define QGL_MAP_RELIEF 5\n" "#define QGL_TEXTURE_ARRAY_EMPTY 0\n"
"#define QGL_TEXTURE_ARRAY_EMPTY 0\n" "#define QGL_TEXTURE_ARRAY_MAPS 1\n"
"#define QGL_TEXTURE_ARRAY_MAPS 1\n" "struct QGLMap {\n"
"struct QGLMap {\n" " float offset;\n"
" float offset;\n" " float amount;\n"
" float amount;\n" " vec2 scale;\n"
" vec2 scale;\n" " uint array_index;\n"
" uint array_index;\n" " uint map_index;\n"
" uint map_index;\n" "};\n"
"};\n" "struct QGLMaterial {\n"
"struct QGLMaterial {\n" " vec4 color_diffuse;\n"
" vec4 color_diffuse;\n" " vec4 color_emission;\n"
" vec4 color_emission;\n" " float transparency;\n"
" float transparency;\n" " float reflectivity;\n"
" float reflectivity;\n" " float iof;\n"
" float iof;\n" " float dispersion;\n"
" float dispersion;\n" " QGLMap map[QGL_MAPS_COUNT];\n"
" QGLMap map[QGL_MAPS_COUNT];\n" "};\n"
"};\n" "struct QGLLightParameter {\n"
"struct QGLLightParameter {\n" " vec4 color;\n"
" vec4 color;\n" " vec4 decay_intensity;\n"
" vec4 decay_intensity;\n" " vec4 angles;\n"
" vec4 angles;\n" "};\n"
"};\n" "struct QGLLightPosition {\n"
"struct QGLLightPosition {\n" " vec4 position;\n"
" vec4 position;\n" " vec4 direction;\n"
" vec4 direction;\n" "};\n"
"};\n" "";
"";
const char qgl_uniform[] = const char qgl_uniform[] = "layout (std140) uniform QGLMaterialData {\n"
"layout (std140) uniform QGLMaterialData {\n" " QGLMaterial qgl_material[128];\n"
" QGLMaterial qgl_material[128];\n" "};\n"
"};\n" "layout (std140) uniform QGLLightParameterData {\n"
"layout (std140) uniform QGLLightParameterData {\n" " QGLLightParameter qgl_light_parameter[256];\n"
" QGLLightParameter qgl_light_parameter[256];\n" "};\n"
"};\n" "layout (std140) uniform QGLLightPositionData {\n"
"layout (std140) uniform QGLLightPositionData {\n" " QGLLightPosition qgl_light_position[256];\n"
" QGLLightPosition qgl_light_position[256];\n" "};\n"
"};\n" "uniform sampler2DArray qgl_texture_array[2];\n"
"uniform sampler2DArray qgl_texture_array[2];\n" "";
"";
} } // namespace QGLEngineShaders
#endif // GLSHADERS_HEADERS_H #endif // GLSHADERS_HEADERS_H

View File

@@ -1,39 +1,39 @@
/* /*
QGLEngineShaders QGLEngineShaders
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "glshaders_types.h" #include "glshaders_types.h"
QGLEngineShaders::QGLMap::QGLMap() { QGLEngineShaders::QGLMap::QGLMap() {
offset = 0.; offset = 0.;
amount = 1.; amount = 1.;
scale = QVector2D(1., 1.); scale = QVector2D(1., 1.);
array_index = map_index = 0; array_index = map_index = 0;
} }
QGLEngineShaders::QGLMaterial::QGLMaterial() { QGLEngineShaders::QGLMaterial::QGLMaterial() {
color_diffuse = QVector4D(1., 1., 1., 0.); color_diffuse = QVector4D(1., 1., 1., 0.);
color_emission = QVector4D(0., 0., 0., 0.); color_emission = QVector4D(0., 0., 0., 0.);
transparency = 0.; transparency = 0.;
reflectivity = 0.; reflectivity = 0.;
iof = 0.; iof = 0.;
dispersion = 0.; dispersion = 0.;
map[mtNormal].map_index = emrBlue; map[mtNormal].map_index = emrBlue;
map[mtRoughness].amount = 0.75; map[mtRoughness].amount = 0.75;
map[mtMetalness].amount = 0.25; map[mtMetalness].amount = 0.25;
@@ -41,57 +41,60 @@ QGLEngineShaders::QGLMaterial::QGLMaterial() {
void QGLEngineShaders::prepareDrawGeom(QOpenGLExtraFunctions * f) { void QGLEngineShaders::prepareDrawGeom(QOpenGLExtraFunctions * f) {
//qDebug() << "prepareDrawGeom"; // qDebug() << "prepareDrawGeom";
f->glEnableVertexAttribArray(pos_loc ); f->glEnableVertexAttribArray(pos_loc);
f->glEnableVertexAttribArray(normal_loc ); f->glEnableVertexAttribArray(normal_loc);
f->glEnableVertexAttribArray(tangent_loc ); f->glEnableVertexAttribArray(tangent_loc);
f->glEnableVertexAttribArray(bitangent_loc); f->glEnableVertexAttribArray(bitangent_loc);
f->glEnableVertexAttribArray(tex_loc ); f->glEnableVertexAttribArray(tex_loc);
int size = sizeof(Vertex); int size = sizeof(Vertex);
f->glVertexAttribPointer(pos_loc , 3, GL_FLOAT, GL_FALSE, size, (const void *)pos_offset ); f->glVertexAttribPointer(pos_loc, 3, GL_FLOAT, GL_FALSE, size, (const void *)pos_offset);
f->glVertexAttribPointer(normal_loc , 3, GL_FLOAT, GL_FALSE, size, (const void *)normal_offset ); f->glVertexAttribPointer(normal_loc, 3, GL_FLOAT, GL_FALSE, size, (const void *)normal_offset);
f->glVertexAttribPointer(tangent_loc , 3, GL_FLOAT, GL_FALSE, size, (const void *)tangent_offset ); f->glVertexAttribPointer(tangent_loc, 3, GL_FLOAT, GL_FALSE, size, (const void *)tangent_offset);
f->glVertexAttribPointer(bitangent_loc, 3, GL_FLOAT, GL_FALSE, size, (const void *)bitangent_offset); f->glVertexAttribPointer(bitangent_loc, 3, GL_FLOAT, GL_FALSE, size, (const void *)bitangent_offset);
f->glVertexAttribPointer(tex_loc , 2, GL_FLOAT, GL_FALSE, size, (const void *)tex_offset ); f->glVertexAttribPointer(tex_loc, 2, GL_FLOAT, GL_FALSE, size, (const void *)tex_offset);
} }
void QGLEngineShaders::prepareDrawObj(QOpenGLExtraFunctions * f) { void QGLEngineShaders::prepareDrawObj(QOpenGLExtraFunctions * f) {
//qDebug() << "prepareDrawObj"; // qDebug() << "prepareDrawObj";
f->glEnableVertexAttribArray(material_loc ); f->glEnableVertexAttribArray(material_loc);
f->glEnableVertexAttribArray(object_id_loc); f->glEnableVertexAttribArray(object_id_loc);
f->glEnableVertexAttribArray(color_loc ); f->glEnableVertexAttribArray(color_loc);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
f->glEnableVertexAttribArray(modelmatrix_loc + i); f->glEnableVertexAttribArray(modelmatrix_loc + i);
} }
GLsizei size = sizeof(Object); GLsizei size = sizeof(Object);
f->glVertexAttribIPointer(material_loc , 1, GL_UNSIGNED_INT , size, (const void *)material_offset ); f->glVertexAttribIPointer(material_loc, 1, GL_UNSIGNED_INT, size, (const void *)material_offset);
f->glVertexAttribIPointer(object_id_loc, 1, GL_UNSIGNED_INT , size, (const void *)object_id_offset); f->glVertexAttribIPointer(object_id_loc, 1, GL_UNSIGNED_INT, size, (const void *)object_id_offset);
f->glVertexAttribPointer (color_loc , 4, GL_FLOAT, GL_FALSE, size, (const void *)color_offset ); f->glVertexAttribPointer(color_loc, 4, GL_FLOAT, GL_FALSE, size, (const void *)color_offset);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
f->glVertexAttribPointer(modelmatrix_loc + i, 4, GL_FLOAT, GL_FALSE, size, (const void *)(modelmatrix_offset + sizeof(QVector4D)*i)); f->glVertexAttribPointer(modelmatrix_loc + i,
4,
GL_FLOAT,
GL_FALSE,
size,
(const void *)(modelmatrix_offset + sizeof(QVector4D) * i));
} }
f->glVertexAttribDivisor(material_loc , 1); f->glVertexAttribDivisor(material_loc, 1);
f->glVertexAttribDivisor(object_id_loc, 1); f->glVertexAttribDivisor(object_id_loc, 1);
f->glVertexAttribDivisor(color_loc , 1); f->glVertexAttribDivisor(color_loc, 1);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
f->glVertexAttribDivisor(modelmatrix_loc + i, 1); f->glVertexAttribDivisor(modelmatrix_loc + i, 1);
} }
} }
void QGLEngineShaders::prepareDrawSel(QOpenGLExtraFunctions * f) { void QGLEngineShaders::prepareDrawSel(QOpenGLExtraFunctions * f) {
//qDebug() << "prepareDrawObj"; // qDebug() << "prepareDrawObj";
f->glEnableVertexAttribArray(is_selected_loc); f->glEnableVertexAttribArray(is_selected_loc);
GLsizei size = 1; GLsizei size = 1;
f->glVertexAttribIPointer(is_selected_loc, 1, GL_UNSIGNED_BYTE, size, (const void *)is_selected_offset); f->glVertexAttribIPointer(is_selected_loc, 1, GL_UNSIGNED_BYTE, size, (const void *)is_selected_offset);
f->glVertexAttribDivisor(is_selected_loc, 1); f->glVertexAttribDivisor(is_selected_loc, 1);
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGLEngineShaders QGLEngineShaders
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLSHADERS_TYPES_H #ifndef GLSHADERS_TYPES_H
@@ -27,32 +27,32 @@ namespace QGLEngineShaders {
/// VBO /// VBO
// geometry // geometry
const GLsizei pos_offset = 0; const GLsizei pos_offset = 0;
const GLsizei normal_offset = sizeof(QVector3D) + pos_offset ; const GLsizei normal_offset = sizeof(QVector3D) + pos_offset;
const GLsizei tangent_offset = sizeof(QVector3D) + normal_offset ; const GLsizei tangent_offset = sizeof(QVector3D) + normal_offset;
const GLsizei bitangent_offset = sizeof(QVector3D) + tangent_offset ; const GLsizei bitangent_offset = sizeof(QVector3D) + tangent_offset;
const GLsizei tex_offset = sizeof(QVector3D) + bitangent_offset; const GLsizei tex_offset = sizeof(QVector3D) + bitangent_offset;
// object // object
const GLsizei material_offset = 0; const GLsizei material_offset = 0;
const GLsizei object_id_offset = sizeof(GLuint ) + material_offset ; const GLsizei object_id_offset = sizeof(GLuint) + material_offset;
const GLsizei color_offset = sizeof(GLuint ) + object_id_offset ; const GLsizei color_offset = sizeof(GLuint) + object_id_offset;
const GLsizei modelmatrix_offset = sizeof(QVector4D) + color_offset; const GLsizei modelmatrix_offset = sizeof(QVector4D) + color_offset;
const GLsizei is_selected_offset = 0; const GLsizei is_selected_offset = 0;
const GLuint pos_loc = 1 ; // qgl_Vertex const GLuint pos_loc = 1; // qgl_Vertex
const GLuint normal_loc = 2 ; // qgl_Normal const GLuint normal_loc = 2; // qgl_Normal
const GLuint tangent_loc = 3 ; // qgl_Tangent const GLuint tangent_loc = 3; // qgl_Tangent
const GLuint bitangent_loc = 4 ; // qgl_Bitangent const GLuint bitangent_loc = 4; // qgl_Bitangent
const GLuint tex_loc = 5 ; // qgl_Texture const GLuint tex_loc = 5; // qgl_Texture
const GLuint material_loc = 6 ; // qgl_Material const GLuint material_loc = 6; // qgl_Material
const GLuint object_id_loc = 8 ; // qgl_ObjectID const GLuint object_id_loc = 8; // qgl_ObjectID
const GLuint color_loc = 9 ; // qgl_ObjectColor const GLuint color_loc = 9; // qgl_ObjectColor
const GLuint modelmatrix_loc = 10; // qgl_ModelViewProjectionMatrix const GLuint modelmatrix_loc = 10; // qgl_ModelViewProjectionMatrix
const GLuint is_selected_loc = 7 ; // qgl_ObjectSelected const GLuint is_selected_loc = 7; // qgl_ObjectSelected
#pragma pack(push, 1) #pragma pack(push, 1)
struct Vertex { struct Vertex {
@@ -65,13 +65,13 @@ struct Vertex {
struct Object { struct Object {
Object() { Object() {
material = object_id = 0; material = object_id = 0;
color = QVector4D(1,1,1,1); color = QVector4D(1, 1, 1, 1);
QMatrix4x4().copyDataTo(modelmatrix); QMatrix4x4().copyDataTo(modelmatrix);
} }
GLuint material; GLuint material;
GLuint object_id; GLuint object_id;
QVector4D color; QVector4D color;
GLfloat modelmatrix[16]; GLfloat modelmatrix[16];
}; };
#pragma pack(pop) #pragma pack(pop)
@@ -87,7 +87,7 @@ enum BindingPoints {
enum MapType { enum MapType {
mtDiffuse = 0, mtDiffuse = 0,
mtNormal = 1, mtNormal = 1,
mtMetalness = 2, mtMetalness = 2,
mtRoughness = 3, mtRoughness = 3,
mtEmission = 4, mtEmission = 4,
mtRelief = 5, mtRelief = 5,
@@ -124,7 +124,7 @@ struct QGLMaterial {
struct QGLLightParameter { struct QGLLightParameter {
QVector4D color; QVector4D color;
QVector4D decay_intensity; // [^0, ^1, ^2, intensity] QVector4D decay_intensity; // [^0, ^1, ^2, intensity]
QVector4D angles; // [start, cos(start), end, cos(end)] QVector4D angles; // [start, cos(start), end, cos(end)]
}; };
struct QGLLightPosition { struct QGLLightPosition {
QVector4D position; QVector4D position;
@@ -133,10 +133,10 @@ struct QGLLightPosition {
#pragma pack(pop) #pragma pack(pop)
void prepareDrawGeom(QOpenGLExtraFunctions * f); void prepareDrawGeom(QOpenGLExtraFunctions * f);
void prepareDrawObj (QOpenGLExtraFunctions * f); void prepareDrawObj(QOpenGLExtraFunctions * f);
void prepareDrawSel (QOpenGLExtraFunctions * f); void prepareDrawSel(QOpenGLExtraFunctions * f);
} } // namespace QGLEngineShaders
#endif // GLSHADERS_TYPES_H #endif // GLSHADERS_TYPES_H

View File

@@ -1,36 +1,36 @@
/* /*
QGL Texture2DArray QGL Texture2DArray
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "gltexturearray.h" #include "gltexturearray.h"
#include <QOpenGLExtraFunctions>
Texture2DArray::Texture2DArray(bool filter) { Texture2DArray::Texture2DArray(bool filter) {
target_ = GL_TEXTURE_2D_ARRAY; target_ = GL_TEXTURE_2D_ARRAY;
texture_ = 0; texture_ = 0;
layers_ = 0; layers_ = 0;
filtering_ = filter; filtering_ = filter;
} }
Texture2DArray::~Texture2DArray() { Texture2DArray::~Texture2DArray() {}
}
void Texture2DArray::init(QOpenGLExtraFunctions * f) { void Texture2DArray::init(QOpenGLExtraFunctions * f) {
@@ -50,7 +50,7 @@ void Texture2DArray::destroy(QOpenGLExtraFunctions * f) {
void Texture2DArray::reinit() { void Texture2DArray::reinit() {
texture_ = 0; texture_ = 0;
layers_ = 0; layers_ = 0;
} }
@@ -68,7 +68,7 @@ void Texture2DArray::release(QOpenGLExtraFunctions * f) {
bool Texture2DArray::resize(QOpenGLExtraFunctions * f, QSize new_size, int layers_count) { bool Texture2DArray::resize(QOpenGLExtraFunctions * f, QSize new_size, int layers_count) {
if (new_size.isNull() || layers_count <= 0) return false; if (new_size.isNull() || layers_count <= 0) return false;
if ((size_ == new_size) && (layers_ >= layers_count)) return false; if ((size_ == new_size) && (layers_ >= layers_count)) return false;
size_ = new_size; size_ = new_size;
layers_ = layers_count; layers_ = layers_count;
f->glBindTexture(target_, texture_); f->glBindTexture(target_, texture_);
f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_REPEAT); f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -88,10 +88,9 @@ bool Texture2DArray::resize(QOpenGLExtraFunctions * f, QSize new_size, int layer
void Texture2DArray::load(QOpenGLExtraFunctions * f, const QImage & image, int layer) { void Texture2DArray::load(QOpenGLExtraFunctions * f, const QImage & image, int layer) {
if (image.isNull() || size_.isNull() || layer < 0 || layer >= layers_) return; if (image.isNull() || size_.isNull() || layer < 0 || layer >= layers_) return;
QImage im = image.mirrored(false, true) QImage im =
.scaled(size_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation) image.mirrored(false, true).scaled(size_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).convertToFormat(QImage::Format_RGBA8888);
.convertToFormat(QImage::Format_RGBA8888); // qDebug() << "Texture2DArray::load image" << image.size() << "to layer" << layer;
//qDebug() << "Texture2DArray::load image" << image.size() << "to layer" << layer;
f->glTexSubImage3D(target_, 0, 0, 0, layer, size_.width(), size_.height(), 1, GL_RGBA, GL_UNSIGNED_BYTE, im.constBits()); f->glTexSubImage3D(target_, 0, 0, 0, layer, size_.width(), size_.height(), 1, GL_RGBA, GL_UNSIGNED_BYTE, im.constBits());
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGL Texture2DArray QGL Texture2DArray
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLTEXTUREARRAY_H #ifndef GLTEXTUREARRAY_H
@@ -22,26 +22,25 @@
#include "gltypes.h" #include "gltypes.h"
class Texture2DArray class Texture2DArray {
{
public: public:
Texture2DArray(bool filter); Texture2DArray(bool filter);
~Texture2DArray(); ~Texture2DArray();
void init (QOpenGLExtraFunctions * f); void init(QOpenGLExtraFunctions * f);
void destroy (QOpenGLExtraFunctions * f); void destroy(QOpenGLExtraFunctions * f);
void reinit(); void reinit();
void bind (QOpenGLExtraFunctions * f, int channel = 0); void bind(QOpenGLExtraFunctions * f, int channel = 0);
void release (QOpenGLExtraFunctions * f); void release(QOpenGLExtraFunctions * f);
// returns true if size changed // returns true if size changed
bool resize (QOpenGLExtraFunctions * f, QSize new_size, int layers_count); bool resize(QOpenGLExtraFunctions * f, QSize new_size, int layers_count);
void load (QOpenGLExtraFunctions * f, const QImage & image, int layer); void load(QOpenGLExtraFunctions * f, const QImage & image, int layer);
void mipmaps (QOpenGLExtraFunctions * f); void mipmaps(QOpenGLExtraFunctions * f);
GLuint ID() const {return texture_;} GLuint ID() const { return texture_; }
bool isInit() const {return texture_ != 0;} bool isInit() const { return texture_ != 0; }
private: private:
GLenum target_; GLenum target_;

View File

@@ -1,36 +1,50 @@
/* /*
QGL Transform QGL Transform
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "gltransform.h" #include "gltransform.h"
#include "gltypes.h" #include "gltypes.h"
#include <cmath> #include <cmath>
inline void composeQMatrix4x4(const QVector3D & position, const QVector3D & orientation, const QVector3D & scale, QMatrix4x4 &m) { inline void composeQMatrix4x4(const QVector3D & position, const QVector3D & orientation, const QVector3D & scale, QMatrix4x4 & m) {
const QMatrix3x3 rot3x3(Transform::toRotationMatrix(orientation)); const QMatrix3x3 rot3x3(Transform::toRotationMatrix(orientation));
// set up final matrix with scale, rotation and translation // set up final matrix with scale, rotation and translation
m(0, 0) = scale.x() * rot3x3(0, 0); m(0, 1) = scale.y() * rot3x3(0, 1); m(0, 2) = scale.z() * rot3x3(0, 2); m(0, 3) = position.x(); m(0, 0) = scale.x() * rot3x3(0, 0);
m(1, 0) = scale.x() * rot3x3(1, 0); m(1, 1) = scale.y() * rot3x3(1, 1); m(1, 2) = scale.z() * rot3x3(1, 2); m(1, 3) = position.y(); m(0, 1) = scale.y() * rot3x3(0, 1);
m(2, 0) = scale.x() * rot3x3(2, 0); m(2, 1) = scale.y() * rot3x3(2, 1); m(2, 2) = scale.z() * rot3x3(2, 2); m(2, 3) = position.z(); m(0, 2) = scale.z() * rot3x3(0, 2);
m(0, 3) = position.x();
m(1, 0) = scale.x() * rot3x3(1, 0);
m(1, 1) = scale.y() * rot3x3(1, 1);
m(1, 2) = scale.z() * rot3x3(1, 2);
m(1, 3) = position.y();
m(2, 0) = scale.x() * rot3x3(2, 0);
m(2, 1) = scale.y() * rot3x3(2, 1);
m(2, 2) = scale.z() * rot3x3(2, 2);
m(2, 3) = position.z();
// no projection term // no projection term
m(3, 0) = 0.0f; m(3, 1) = 0.0f; m(3, 2) = 0.0f; m(3, 3) = 1.0f; m(3, 0) = 0.0f;
m(3, 1) = 0.0f;
m(3, 2) = 0.0f;
m(3, 3) = 1.0f;
} }
inline void decomposeQMatrix3x3(const QMatrix3x3 & m, QMatrix3x3 & Q, QVector3D & D, QVector3D & U) { inline void decomposeQMatrix3x3(const QMatrix3x3 & m, QMatrix3x3 & Q, QVector3D & D, QVector3D & U) {
@@ -62,24 +76,24 @@ inline void decomposeQMatrix3x3(const QMatrix3x3 & m, QMatrix3x3 & Q, QVector3D
// build orthogonal matrix Q // build orthogonal matrix Q
float invLen = 1.0f / std::sqrt(m(0, 0) * m(0, 0) + m(1, 0) * m(1, 0) + m(2, 0) * m(2, 0)); float invLen = 1.0f / std::sqrt(m(0, 0) * m(0, 0) + m(1, 0) * m(1, 0) + m(2, 0) * m(2, 0));
Q(0, 0) = m(0, 0) * invLen; Q(0, 0) = m(0, 0) * invLen;
Q(1, 0) = m(1, 0) * invLen; Q(1, 0) = m(1, 0) * invLen;
Q(2, 0) = m(2, 0) * invLen; Q(2, 0) = m(2, 0) * invLen;
float dot = Q(0, 0) * m(0, 1) + Q(1, 0) * m(1, 1) + Q(2, 0) * m(2, 1); float dot = Q(0, 0) * m(0, 1) + Q(1, 0) * m(1, 1) + Q(2, 0) * m(2, 1);
Q(0, 1) = m(0, 1) - dot * Q(0, 0); Q(0, 1) = m(0, 1) - dot * Q(0, 0);
Q(1, 1) = m(1, 1) - dot * Q(1, 0); Q(1, 1) = m(1, 1) - dot * Q(1, 0);
Q(2, 1) = m(2, 1) - dot * Q(2, 0); Q(2, 1) = m(2, 1) - dot * Q(2, 0);
invLen = 1.0f / std::sqrt(Q(0, 1) * Q(0, 1) + Q(1, 1) * Q(1, 1) + Q(2, 1) * Q(2, 1)); invLen = 1.0f / std::sqrt(Q(0, 1) * Q(0, 1) + Q(1, 1) * Q(1, 1) + Q(2, 1) * Q(2, 1));
Q(0, 1) *= invLen; Q(0, 1) *= invLen;
Q(1, 1) *= invLen; Q(1, 1) *= invLen;
Q(2, 1) *= invLen; Q(2, 1) *= invLen;
dot = Q(0, 0) * m(0, 2) + Q(1, 0) * m(1, 2) + Q(2, 0) * m(2, 2); dot = Q(0, 0) * m(0, 2) + Q(1, 0) * m(1, 2) + Q(2, 0) * m(2, 2);
Q(0, 2) = m(0, 2) - dot * Q(0, 0); Q(0, 2) = m(0, 2) - dot * Q(0, 0);
Q(1, 2) = m(1, 2) - dot * Q(1, 0); Q(1, 2) = m(1, 2) - dot * Q(1, 0);
Q(2, 2) = m(2, 2) - dot * Q(2, 0); Q(2, 2) = m(2, 2) - dot * Q(2, 0);
dot = Q(0, 1) * m(0, 2) + Q(1, 1) * m(1, 2) + Q(2, 1) * m(2, 2); dot = Q(0, 1) * m(0, 2) + Q(1, 1) * m(1, 2) + Q(2, 1) * m(2, 2);
Q(0, 2) -= dot * Q(0, 1); Q(0, 2) -= dot * Q(0, 1);
Q(1, 2) -= dot * Q(1, 1); Q(1, 2) -= dot * Q(1, 1);
Q(2, 2) -= dot * Q(2, 1); Q(2, 2) -= dot * Q(2, 1);
@@ -89,11 +103,9 @@ inline void decomposeQMatrix3x3(const QMatrix3x3 & m, QMatrix3x3 & Q, QVector3D
Q(2, 2) *= invLen; Q(2, 2) *= invLen;
// guarantee that orthogonal matrix has determinant 1 (no reflections) // guarantee that orthogonal matrix has determinant 1 (no reflections)
const float det = Q(0, 0) * Q(1, 1) * Q(2, 2) + Q(0, 1) * Q(1, 2) * Q(2, 0) + const float det = Q(0, 0) * Q(1, 1) * Q(2, 2) + Q(0, 1) * Q(1, 2) * Q(2, 0) + Q(0, 2) * Q(1, 0) * Q(2, 1) -
Q(0, 2) * Q(1, 0) * Q(2, 1) - Q(0, 2) * Q(1, 1) * Q(2, 0) - Q(0, 2) * Q(1, 1) * Q(2, 0) - Q(0, 1) * Q(1, 0) * Q(2, 2) - Q(0, 0) * Q(1, 2) * Q(2, 1);
Q(0, 1) * Q(1, 0) * Q(2, 2) - Q(0, 0) * Q(1, 2) * Q(2, 1); if (det < 0.0f) Q *= -1.0f;
if (det < 0.0f)
Q *= -1.0f;
// build "right" matrix R // build "right" matrix R
QMatrix3x3 R(Qt::Uninitialized); QMatrix3x3 R(Qt::Uninitialized);
@@ -105,30 +117,26 @@ inline void decomposeQMatrix3x3(const QMatrix3x3 & m, QMatrix3x3 & Q, QVector3D
R(2, 2) = Q(0, 2) * m(0, 2) + Q(1, 2) * m(1, 2) + Q(2, 2) * m(2, 2); R(2, 2) = Q(0, 2) * m(0, 2) + Q(1, 2) * m(1, 2) + Q(2, 2) * m(2, 2);
// the scaling component // the scaling component
D[0] = R(0, 0); D[0] = R(0, 0);
D[1] = R(1, 1); D[1] = R(1, 1);
D[2] = R(2, 2); D[2] = R(2, 2);
// the shear component // the shear component
U[0] = R(0, 1) / D[0]; U[0] = R(0, 1) / D[0];
U[1] = R(0, 2) / D[0]; U[1] = R(0, 2) / D[0];
U[2] = R(1, 2) / D[1]; U[2] = R(1, 2) / D[1];
} }
inline bool hasScale(const QMatrix4x4 &m) { inline bool hasScale(const QMatrix4x4 & m) {
// If the columns are orthonormal and form a right-handed system, then there is no scale // If the columns are orthonormal and form a right-handed system, then there is no scale
float t(m.determinant()); float t(m.determinant());
if (!qFuzzyIsNull(t - 1.0f)) if (!qFuzzyIsNull(t - 1.0f)) return true;
return true;
t = m(0, 0) * m(0, 0) + m(1, 0) * m(1, 0) + m(2, 0) * m(2, 0); t = m(0, 0) * m(0, 0) + m(1, 0) * m(1, 0) + m(2, 0) * m(2, 0);
if (!qFuzzyIsNull(t - 1.0f)) if (!qFuzzyIsNull(t - 1.0f)) return true;
return true;
t = m(0, 1) * m(0, 1) + m(1, 1) * m(1, 1) + m(2, 1) * m(2, 1); t = m(0, 1) * m(0, 1) + m(1, 1) * m(1, 1) + m(2, 1) * m(2, 1);
if (!qFuzzyIsNull(t - 1.0f)) if (!qFuzzyIsNull(t - 1.0f)) return true;
return true;
t = m(0, 2) * m(0, 2) + m(1, 2) * m(1, 2) + m(2, 2) * m(2, 2); t = m(0, 2) * m(0, 2) + m(1, 2) * m(1, 2) + m(2, 2) * m(2, 2);
if (!qFuzzyIsNull(t - 1.0f)) if (!qFuzzyIsNull(t - 1.0f)) return true;
return true;
return false; return false;
} }
@@ -142,64 +150,57 @@ inline void decomposeQMatrix4x4(const QMatrix4x4 & m, QVector3D & position, QVec
decomposeQMatrix3x3(m3x3, rot3x3, scale, position); decomposeQMatrix3x3(m3x3, rot3x3, scale, position);
} else { } else {
// we know there is no scaling part; no need for QDU decomposition // we know there is no scaling part; no need for QDU decomposition
scale = QVector3D(1.0f, 1.0f, 1.0f); scale = QVector3D(1.0f, 1.0f, 1.0f);
rot3x3 = m3x3; rot3x3 = m3x3;
} }
orientation = Transform::fromRotationMatrix(rot3x3); orientation = Transform::fromRotationMatrix(rot3x3);
position = QVector3D(m(0, 3), m(1, 3), m(2, 3)); position = QVector3D(m(0, 3), m(1, 3), m(2, 3));
} }
Transform::Transform(): m_scale(1.0f, 1.0f, 1.0f), m_translation(), m_eulerRotationAngles(), m_matrixDirty(false) {}
Transform::Transform(): m_scale(1.0f, 1.0f, 1.0f), Transform & Transform::operator=(const Transform & t) {
m_translation(), m_eulerRotationAngles(), m_matrixDirty(false) { m_scale = t.m_scale;
} m_translation = t.m_translation;
Transform & Transform::operator =(const Transform & t) {
m_scale = t.m_scale;
m_translation = t.m_translation;
m_eulerRotationAngles = t.m_eulerRotationAngles; m_eulerRotationAngles = t.m_eulerRotationAngles;
m_matrixDirty = true; m_matrixDirty = true;
return *this; return *this;
} }
void Transform::setMatrix(const QMatrix4x4 & m) { void Transform::setMatrix(const QMatrix4x4 & m) {
if (m != matrix()) { if (m != matrix()) {
m_matrix = m; m_matrix = m;
m_matrixDirty = false; m_matrixDirty = false;
QVector3D s; QVector3D s;
QVector3D t; QVector3D t;
QVector3D r; QVector3D r;
decomposeQMatrix4x4(m, t, r, s); decomposeQMatrix4x4(m, t, r, s);
m_scale = s; m_scale = s;
m_translation = t; m_translation = t;
m_eulerRotationAngles = r; m_eulerRotationAngles = r;
} }
} }
void Transform::setRotationX(float r) { void Transform::setRotationX(float r) {
if (m_eulerRotationAngles.x() == r) if (m_eulerRotationAngles.x() == r) return;
return;
m_eulerRotationAngles.setX(r); m_eulerRotationAngles.setX(r);
m_matrixDirty = true; m_matrixDirty = true;
} }
void Transform::setRotationY(float r) { void Transform::setRotationY(float r) {
if (m_eulerRotationAngles.y() == r) if (m_eulerRotationAngles.y() == r) return;
return;
m_eulerRotationAngles.setY(r); m_eulerRotationAngles.setY(r);
m_matrixDirty = true; m_matrixDirty = true;
} }
void Transform::setRotationZ(float r) { void Transform::setRotationZ(float r) {
if (m_eulerRotationAngles.z() == r) if (m_eulerRotationAngles.z() == r) return;
return;
m_eulerRotationAngles.setZ(r); m_eulerRotationAngles.setZ(r);
m_matrixDirty = true; m_matrixDirty = true;
} }
@@ -230,7 +231,7 @@ QMatrix4x4 Transform::matrixRotateScale() const {
QVector3D Transform::direction() const { QVector3D Transform::direction() const {
return matrixRotate().mapVector(QVector3D(0,0,-1)).normalized(); return matrixRotate().mapVector(QVector3D(0, 0, -1)).normalized();
} }
@@ -238,7 +239,7 @@ void Transform::buildMatrix() const {
if (m_matrixDirty) { if (m_matrixDirty) {
composeQMatrix4x4(m_translation, m_eulerRotationAngles, m_scale, m_matrix); composeQMatrix4x4(m_translation, m_eulerRotationAngles, m_scale, m_matrix);
composeQMatrix4x4(QVector3D(), m_eulerRotationAngles, m_scale, m_matrixWT); composeQMatrix4x4(QVector3D(), m_eulerRotationAngles, m_scale, m_matrixWT);
composeQMatrix4x4(QVector3D(), m_eulerRotationAngles, QVector3D(1,1,1), m_matrixR); composeQMatrix4x4(QVector3D(), m_eulerRotationAngles, QVector3D(1, 1, 1), m_matrixR);
composeQMatrix4x4(QVector3D(), QVector3D(), m_scale, m_matrixS); composeQMatrix4x4(QVector3D(), QVector3D(), m_scale, m_matrixS);
m_matrixDirty = false; m_matrixDirty = false;
} }
@@ -262,7 +263,7 @@ float Transform::rotationZ() const {
void Transform::setScale(const QVector3D & s) { void Transform::setScale(const QVector3D & s) {
if (s != m_scale) { if (s != m_scale) {
m_scale = s; m_scale = s;
m_matrixDirty = true; m_matrixDirty = true;
} }
} }
@@ -305,7 +306,7 @@ float Transform::scale() const {
void Transform::setRotation(const QVector3D & r) { void Transform::setRotation(const QVector3D & r) {
if (r != m_eulerRotationAngles) { if (r != m_eulerRotationAngles) {
m_eulerRotationAngles = r; m_eulerRotationAngles = r;
m_matrixDirty = true; m_matrixDirty = true;
} }
} }
@@ -362,17 +363,19 @@ QQuaternion Transform::fromAxisAndAngle(float x, float y, float z, float angle)
} }
QQuaternion Transform::fromAxesAndAngles(const QVector3D & axis1, float angle1, QQuaternion Transform::fromAxesAndAngles(const QVector3D & axis1, float angle1, const QVector3D & axis2, float angle2) {
const QVector3D & axis2, float angle2) {
const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis1, angle1); const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis1, angle1);
const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis2, angle2); const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis2, angle2);
return q2 * q1; return q2 * q1;
} }
QQuaternion Transform::fromAxesAndAngles(const QVector3D & axis1, float angle1, QQuaternion Transform::fromAxesAndAngles(const QVector3D & axis1,
const QVector3D & axis2, float angle2, float angle1,
const QVector3D & axis3, float angle3) { const QVector3D & axis2,
float angle2,
const QVector3D & axis3,
float angle3) {
const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis1, angle1); const QQuaternion q1 = QQuaternion::fromAxisAndAngle(axis1, angle1);
const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis2, angle2); const QQuaternion q2 = QQuaternion::fromAxisAndAngle(axis2, angle2);
const QQuaternion q3 = QQuaternion::fromAxisAndAngle(axis3, angle3); const QQuaternion q3 = QQuaternion::fromAxisAndAngle(axis3, angle3);
@@ -398,16 +401,16 @@ QVector3D Transform::fromDirection(QVector3D d, float pitch) {
QVector3D Transform::fromRotationMatrix(const QMatrix3x3 & m) { QVector3D Transform::fromRotationMatrix(const QMatrix3x3 & m) {
float sy = sqrt(m(0,0) * m(0,0) + m(1,0) * m(1,0)); float sy = sqrt(m(0, 0) * m(0, 0) + m(1, 0) * m(1, 0));
bool singular = sy < 1.E-6; // If bool singular = sy < 1.E-6; // If
float x, y, z; float x, y, z;
if (!singular) { if (!singular) {
x = atan2( m(2,1), m(2,2)); x = atan2(m(2, 1), m(2, 2));
y = atan2(-m(2,0), sy); y = atan2(-m(2, 0), sy);
z = atan2( m(1,0), m(0,0)); z = atan2(m(1, 0), m(0, 0));
} else { } else {
x = atan2(-m(1,2), m(1,1)); x = atan2(-m(1, 2), m(1, 1));
y = atan2(-m(2,0), sy); y = atan2(-m(2, 0), sy);
z = 0.; z = 0.;
} }
return QVector3D(x, y, z) * rad2deg; return QVector3D(x, y, z) * rad2deg;
@@ -419,7 +422,7 @@ QMatrix3x3 Transform::toRotationMatrix(const QVector3D & r) {
if (r.z() != 0.f) m.rotate(r.z(), 0., 0., 1.); if (r.z() != 0.f) m.rotate(r.z(), 0., 0., 1.);
if (r.y() != 0.f) m.rotate(r.y(), 0., 1., 0.); if (r.y() != 0.f) m.rotate(r.y(), 0., 1., 0.);
if (r.x() != 0.f) m.rotate(r.x(), 1., 0., 0.); if (r.x() != 0.f) m.rotate(r.x(), 1., 0., 0.);
return m.toGenericMatrix<3,3>(); return m.toGenericMatrix<3, 3>();
} }
@@ -433,8 +436,20 @@ QMatrix4x4 Transform::rotateAround(const QVector3D & point, float angle, const Q
QMatrix4x4 Transform::rotateFromAxes(const QVector3D & xAxis, const QVector3D & yAxis, const QVector3D & zAxis) { QMatrix4x4 Transform::rotateFromAxes(const QVector3D & xAxis, const QVector3D & yAxis, const QVector3D & zAxis) {
return QMatrix4x4(xAxis.x(), yAxis.x(), zAxis.x(), 0.0f, return QMatrix4x4(xAxis.x(),
xAxis.y(), yAxis.y(), zAxis.y(), 0.0f, yAxis.x(),
xAxis.z(), yAxis.z(), zAxis.z(), 0.0f, zAxis.x(),
0.0f, 0.0f, 0.0f, 1.0f); 0.0f,
xAxis.y(),
yAxis.y(),
zAxis.y(),
0.0f,
xAxis.z(),
yAxis.z(),
zAxis.z(),
0.0f,
0.0f,
0.0f,
0.0f,
1.0f);
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGL Transform QGL Transform
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLTRANSFORM_H #ifndef GLTRANSFORM_H
@@ -26,10 +26,11 @@
class Transform { class Transform {
friend QDataStream & operator >>(QDataStream & s, Transform & v); friend QDataStream & operator>>(QDataStream & s, Transform & v);
public: public:
Transform(); Transform();
Transform & operator =(const Transform & t); Transform & operator=(const Transform & t);
float scale() const; float scale() const;
QVector3D scale3D() const; QVector3D scale3D() const;
@@ -45,7 +46,7 @@ public:
float rotationY() const; float rotationY() const;
float rotationZ() const; float rotationZ() const;
void setScale(float s) {setScale(QVector3D(s, s, s));} void setScale(float s) { setScale(QVector3D(s, s, s)); }
void setScale(const QVector3D & s); void setScale(const QVector3D & s);
void setScaleX(float s); void setScaleX(float s);
void setScaleY(float s); void setScaleY(float s);
@@ -62,17 +63,15 @@ public:
void setTranslationZ(float t); void setTranslationZ(float t);
void setMatrix(const QMatrix4x4 & matrix); void setMatrix(const QMatrix4x4 & matrix);
void setDirty(bool yes = true) {m_matrixDirty = yes;} void setDirty(bool yes = true) { m_matrixDirty = yes; }
static QQuaternion fromAxisAndAngle(const QVector3D & axis, float angle); static QQuaternion fromAxisAndAngle(const QVector3D & axis, float angle);
static QQuaternion fromAxisAndAngle(float x, float y, float z, float angle); static QQuaternion fromAxisAndAngle(float x, float y, float z, float angle);
static QQuaternion fromAxesAndAngles(const QVector3D & axis1, float angle1, static QQuaternion fromAxesAndAngles(const QVector3D & axis1, float angle1, const QVector3D & axis2, float angle2);
const QVector3D & axis2, float angle2); static QQuaternion
static QQuaternion fromAxesAndAngles(const QVector3D & axis1, float angle1, fromAxesAndAngles(const QVector3D & axis1, float angle1, const QVector3D & axis2, float angle2, const QVector3D & axis3, float angle3);
const QVector3D & axis2, float angle2,
const QVector3D & axis3, float angle3);
static QQuaternion fromAxes(const QVector3D & xAxis, const QVector3D & yAxis, const QVector3D & zAxis); static QQuaternion fromAxes(const QVector3D & xAxis, const QVector3D & yAxis, const QVector3D & zAxis);
static QVector3D fromDirection(QVector3D d, float pitch = 0.f); static QVector3D fromDirection(QVector3D d, float pitch = 0.f);
@@ -91,14 +90,14 @@ protected:
mutable QMatrix4x4 m_matrix, m_matrixWT, m_matrixR, m_matrixS; mutable QMatrix4x4 m_matrix, m_matrixWT, m_matrixR, m_matrixS;
mutable bool m_matrixDirty; mutable bool m_matrixDirty;
}; };
inline QDataStream & operator <<(QDataStream & s, const Transform & v) { inline QDataStream & operator<<(QDataStream & s, const Transform & v) {
s << v.matrix(); return s; s << v.matrix();
return s;
} }
inline QDataStream & operator >>(QDataStream & s, Transform & v) { inline QDataStream & operator>>(QDataStream & s, Transform & v) {
QMatrix4x4 m; QMatrix4x4 m;
s >> m; s >> m;
v.setMatrix(m); v.setMatrix(m);

View File

@@ -1,24 +1,24 @@
/* /*
QGLView Types QGLView Types
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "glcamera.h" #include "glcamera.h"
#include "qglview.h"
#include "gltexture_manager.h" #include "gltexture_manager.h"
#include "qglview.h"
#include <QPainter> #include <QPainter>
@@ -37,15 +37,14 @@ QString readCharsUntilNull(QDataStream & s) {
QString findFile(const QString & file, const QStringList & pathes) { QString findFile(const QString & file, const QStringList & pathes) {
QFileInfo fi(QString(file).replace("\\", "/")); QFileInfo fi(QString(file).replace("\\", "/"));
//qDebug() << "search" << file << "in" << pathes; // qDebug() << "search" << file << "in" << pathes;
if (fi.exists()) return fi.absoluteFilePath(); if (fi.exists()) return fi.absoluteFilePath();
QString fn = fi.fileName(); QString fn = fi.fileName();
if (fn.contains("/")) fn = fn.mid(fn.lastIndexOf("/")); if (fn.contains("/")) fn = fn.mid(fn.lastIndexOf("/"));
foreach (QString p, pathes) { foreach(QString p, pathes) {
QFileInfoList fil = QDir(p).entryInfoList(QStringList(fn), QDir::Files | QDir::NoDotAndDotDot); QFileInfoList fil = QDir(p).entryInfoList(QStringList(fn), QDir::Files | QDir::NoDotAndDotDot);
//qDebug() << "findFile" << fn << "in" << p << "->" << fil.size(); // qDebug() << "findFile" << fn << "in" << p << "->" << fil.size();
if (!fil.isEmpty()) if (!fil.isEmpty()) return fil[0].absoluteFilePath();
return fil[0].absoluteFilePath();
} }
return QString(); return QString();
} }
@@ -55,21 +54,27 @@ void glDrawQuad(QOpenGLShaderProgram * prog, QVector4D * corner_dirs, GLfloat x,
glSetPolygonMode(GL_FILL); glSetPolygonMode(GL_FILL);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
int loc = prog ? prog->attributeLocation("qgl_Color") : -1, int loc = prog ? prog->attributeLocation("qgl_Color") : -1, locv = prog ? prog->attributeLocation("qgl_Vertex") : -1,
locv = prog ? prog->attributeLocation("qgl_Vertex") : -1, loct = prog ? prog->attributeLocation("qgl_Texture") : -1, locc = prog ? prog->attributeLocation("view_corner") : -1;
loct = prog ? prog->attributeLocation("qgl_Texture") : -1,
locc = prog ? prog->attributeLocation("view_corner") : -1;
QOpenGLFunctions * glFuncs = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions * glFuncs = QOpenGLContext::currentContext()->functions();
if (prog) { if (prog) {
static const GLfloat cols [] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; static const GLfloat cols[] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
static const GLfloat verts[] = {x, y, x+w, y, x, y+h, x+w, y+h}; static const GLfloat verts[] = {x, y, x + w, y, x, y + h, x + w, y + h};
static const GLfloat texs [] = {0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f}; static const GLfloat texs[] = {0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f};
GLfloat vcs[] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; GLfloat vcs[] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
if (corner_dirs) { if (corner_dirs) {
vcs[0] = corner_dirs[0].x(); vcs[1] = corner_dirs[0].y(); vcs[2] = corner_dirs[0].z(); vcs[0] = corner_dirs[0].x();
vcs[3] = corner_dirs[1].x(); vcs[4] = corner_dirs[1].y(); vcs[5] = corner_dirs[1].z(); vcs[1] = corner_dirs[0].y();
vcs[6] = corner_dirs[2].x(); vcs[7] = corner_dirs[2].y(); vcs[8] = corner_dirs[2].z(); vcs[2] = corner_dirs[0].z();
vcs[9] = corner_dirs[3].x(); vcs[10] = corner_dirs[3].y(); vcs[11] = corner_dirs[3].z(); vcs[3] = corner_dirs[1].x();
vcs[4] = corner_dirs[1].y();
vcs[5] = corner_dirs[1].z();
vcs[6] = corner_dirs[2].x();
vcs[7] = corner_dirs[2].y();
vcs[8] = corner_dirs[2].z();
vcs[9] = corner_dirs[3].x();
vcs[10] = corner_dirs[3].y();
vcs[11] = corner_dirs[3].z();
} }
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
@@ -92,10 +97,14 @@ void glDrawQuad(QOpenGLShaderProgram * prog, QVector4D * corner_dirs, GLfloat x,
} else { } else {
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
glTexCoord2f(0.f, 0.f); glVertex2f(x, y); glTexCoord2f(0.f, 0.f);
glTexCoord2f(1.f, 0.f); glVertex2f(x+w, y); glVertex2f(x, y);
glTexCoord2f(0.f, 1.f); glVertex2f(x, y+h); glTexCoord2f(1.f, 0.f);
glTexCoord2f(1.f, 1.f); glVertex2f(x+w, y+h); glVertex2f(x + w, y);
glTexCoord2f(0.f, 1.f);
glVertex2f(x, y + h);
glTexCoord2f(1.f, 1.f);
glVertex2f(x + w, y + h);
glEnd(); glEnd();
} }
} }
@@ -140,15 +149,13 @@ void createGLTexture(QOpenGLExtraFunctions * f, GLuint & tex, int width, int hei
f->glTexImage2D(target, 0, format, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, nullptr); f->glTexImage2D(target, 0, format, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, nullptr);
else { else {
int type = GL_UNSIGNED_BYTE; int type = GL_UNSIGNED_BYTE;
int fmt = GL_RGBA; int fmt = GL_RGBA;
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGBA32F || format == GL_RGBA16F) if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGBA32F || format == GL_RGBA16F) type = GL_FLOAT;
type = GL_FLOAT; if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGB8 || format == GL_RGB) fmt = GL_RGB;
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGB8 || format == GL_RGB)
fmt = GL_RGB;
f->glTexImage2D(target, 0, format, width, height, 0, fmt, type, nullptr); f->glTexImage2D(target, 0, format, width, height, 0, fmt, type, nullptr);
//qDebug() << "glTexImage2D" << width << height << QString::number(t, 16); // qDebug() << "glTexImage2D" << width << height << QString::number(t, 16);
} }
//qDebug() << QString::number(glGetError(), 16); // qDebug() << QString::number(glGetError(), 16);
} }
@@ -174,7 +181,7 @@ void createGLTexture(QOpenGLExtraFunctions * f, GLuint & tex, const QImage & ima
if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D || target == GL_TEXTURE_3D) { if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D || target == GL_TEXTURE_3D) {
f->glGenerateMipmap(target); f->glGenerateMipmap(target);
} }
//qDebug() << target << format << tex << im.width() << im.height() << im.bits() << QString::number(glGetError(), 16); // qDebug() << target << format << tex << im.width() << im.height() << im.bits() << QString::number(glGetError(), 16);
} }
@@ -216,14 +223,15 @@ QImage rotateQImageRight(const QImage & im) {
} }
QColor colorFromString(const QString & str) { QColor colorFromString(const QString & str) {
QString s = str.trimmed(); QString s = str.trimmed();
int i = s.indexOf("\t"); int i = s.indexOf("\t");
float r, g, b; float r, g, b;
r = s.left(i).toFloat(); s = s.right(s.length() - i - 1); i = s.indexOf("\t"); r = s.left(i).toFloat();
g = s.left(i).toFloat(); s = s.right(s.length() - i - 1); s = s.right(s.length() - i - 1);
i = s.indexOf("\t");
g = s.left(i).toFloat();
s = s.right(s.length() - i - 1);
b = s.toFloat(); b = s.toFloat();
return QColor(r * 255.f, g * 255.f, b * 255.f); return QColor(r * 255.f, g * 255.f, b * 255.f);
} }
@@ -232,9 +240,12 @@ QColor colorFromString(const QString & str) {
QVector3D orthToVector(const QVector3D & v, const float & scale) { QVector3D orthToVector(const QVector3D & v, const float & scale) {
if (v.isNull()) return QVector3D(); if (v.isNull()) return QVector3D();
QVector3D rv, fn, sn; QVector3D rv, fn, sn;
if (v.x() != 0.f) rv.setZ(1.); if (v.x() != 0.f)
else if (v.y() != 0.f) rv.setX(1.); rv.setZ(1.);
else rv.setY(1.); else if (v.y() != 0.f)
rv.setX(1.);
else
rv.setY(1.);
fn = QVector3D::crossProduct(v, rv).normalized(); fn = QVector3D::crossProduct(v, rv).normalized();
sn = QVector3D::crossProduct(v, fn).normalized(); sn = QVector3D::crossProduct(v, fn).normalized();
return fn * urand(scale) + sn * urand(scale); return fn * urand(scale) + sn * urand(scale);
@@ -268,18 +279,22 @@ void lengthenVector(QVector3D & v, const float & l) {
Vector2i::Vector2i(const QString & str) { Vector2i::Vector2i(const QString & str) {
QString s = str.trimmed(); QString s = str.trimmed();
int i = s.indexOf("\t"); int i = s.indexOf("\t");
p0 = s.left(i).toInt(); s = s.right(s.length() - i - 1); p0 = s.left(i).toInt();
p1 = s.toInt(); s = s.right(s.length() - i - 1);
p1 = s.toInt();
} }
Vector3i::Vector3i(const QString & str) { Vector3i::Vector3i(const QString & str) {
QString s = str.trimmed(); QString s = str.trimmed();
int i = s.indexOf("\t"); int i = s.indexOf("\t");
p0 = s.left(i).toInt(); s = s.right(s.length() - i - 1); i = s.indexOf("\t"); p0 = s.left(i).toInt();
p1 = s.left(i).toInt(); s = s.right(s.length() - i - 1); s = s.right(s.length() - i - 1);
p2 = s.toInt(); i = s.indexOf("\t");
p1 = s.left(i).toInt();
s = s.right(s.length() - i - 1);
p2 = s.toInt();
} }
@@ -305,8 +320,6 @@ void glClearFramebuffer(const QColor & color, bool depth) {
} }
Box3D::Box3D(const QVector<QVector3D> & points) { Box3D::Box3D(const QVector<QVector3D> & points) {
x = y = z = width = length = height = angle_z = angle_xy = angle_roll = 0.f; x = y = z = width = length = height = angle_z = angle_xy = angle_roll = 0.f;
if (points.isEmpty()) return; if (points.isEmpty()) return;
@@ -315,13 +328,16 @@ Box3D::Box3D(const QVector<QVector3D> & points) {
iy = ay = points[0].y(); iy = ay = points[0].y();
iz = az = points[0].z(); iz = az = points[0].z();
for (int i = 1; i < points.size(); ++i) { for (int i = 1; i < points.size(); ++i) {
ix = qMin<float>(ix, points[i].x()); ax = qMax<float>(ax, points[i].x()); ix = qMin<float>(ix, points[i].x());
iy = qMin<float>(iy, points[i].y()); ay = qMax<float>(ay, points[i].y()); ax = qMax<float>(ax, points[i].x());
iz = qMin<float>(iz, points[i].z()); az = qMax<float>(az, points[i].z()); iy = qMin<float>(iy, points[i].y());
ay = qMax<float>(ay, points[i].y());
iz = qMin<float>(iz, points[i].z());
az = qMax<float>(az, points[i].z());
} }
x = ix; x = ix;
y = iy; y = iy;
z = iz; z = iz;
length = ax - ix; length = ax - ix;
width = ay - iy; width = ay - iy;
height = az - iz; height = az - iz;
@@ -331,32 +347,42 @@ Box3D::Box3D(const QVector<QVector3D> & points) {
QVector<QVector3D> Box3D::corners() const { QVector<QVector3D> Box3D::corners() const {
QVector<QVector3D> ret; QVector<QVector3D> ret;
ret << QVector3D(x, y, z) << QVector3D(x, y + width, z) << QVector3D(x, y, z + height) << QVector3D(x, y + width, z + height) ret << QVector3D(x, y, z) << QVector3D(x, y + width, z) << QVector3D(x, y, z + height) << QVector3D(x, y + width, z + height)
<< QVector3D(x + length, y, z) << QVector3D(x + length, y + width, z) << QVector3D(x + length, y, z) << QVector3D(x + length, y + width, z) << QVector3D(x + length, y, z + height)
<< QVector3D(x + length, y, z + height) << QVector3D(x + length, y + width, z + height); << QVector3D(x + length, y + width, z + height);
return ret; return ret;
} }
Box3D & Box3D::operator |=(const Box3D & o) { Box3D & Box3D::operator|=(const Box3D & o) {
if (o.isEmpty()) return *this; if (o.isEmpty()) return *this;
if (isEmpty()) *this = o; if (isEmpty())
*this = o;
else { else {
GLfloat mx = x + length, my = y + width, mz = z + height; GLfloat mx = x + length, my = y + width, mz = z + height;
GLfloat omx = o.x + o.length, omy = o.y + o.width, omz = o.z + o.height; GLfloat omx = o.x + o.length, omy = o.y + o.width, omz = o.z + o.height;
x = qMin(x, o.x); y = qMin(y, o.y); z = qMin(z, o.z); x = qMin(x, o.x);
mx = qMax(mx, omx); my = qMax(my, omy); mz = qMax(mz, omz); y = qMin(y, o.y);
length = mx - x; width = my - y; height = mz - z; z = qMin(z, o.z);
mx = qMax(mx, omx);
my = qMax(my, omy);
mz = qMax(mz, omz);
length = mx - x;
width = my - y;
height = mz - z;
} }
return *this; return *this;
} }
QVector3D vectorFromString(const QString & str) { QVector3D vectorFromString(const QString & str) {
QTextStream s(const_cast<QString*>(&str), QIODevice::ReadOnly); QTextStream s(const_cast<QString *>(&str), QIODevice::ReadOnly);
QVector3D ret; QVector3D ret;
float f(0.f); float f(0.f);
s >> f; ret.setX(f); s >> f;
s >> f; ret.setY(f); ret.setX(f);
s >> f; ret.setZ(f); s >> f;
ret.setY(f);
s >> f;
ret.setZ(f);
return ret; return ret;
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGLView Types QGLView Types
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLTYPES_H #ifndef GLTYPES_H
@@ -30,9 +30,9 @@
#endif #endif
#ifndef WINDOWS #ifndef WINDOWS
# ifndef QNX # ifndef QNX
# ifndef MAC # ifndef MAC
# define LINUX # define LINUX
# endif # endif
# endif # endif
#endif #endif
#if __GNUC__ #if __GNUC__
@@ -43,49 +43,50 @@
#include <QObject> #include <QObject>
//#ifndef WINDOWS // #ifndef WINDOWS
//# ifdef MAC // # ifdef MAC
//# include <OpenGL/gl.h> // # include <OpenGL/gl.h>
//# include <OpenGL/glu.h> // # include <OpenGL/glu.h>
//# include <GLUT/glut.h> // # include <GLUT/glut.h>
//# else // # else
//# include <GL/gl.h> // # include <GL/gl.h>
//# include <GL/glext.h> // # include <GL/glext.h>
//# include <GL/glu.h> // # include <GL/glu.h>
//# endif // # endif
//#endif // #endif
#include <QColor>
#include <QDataStream>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QImage>
#include <QMatrix4x4>
#include <QMutex>
#include <QOpenGLExtraFunctions> #include <QOpenGLExtraFunctions>
#include <QOpenGLShader> #include <QOpenGLShader>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <qopenglext.h>
#include <cmath>
#include <float.h>
#include <QMatrix4x4>
#include <QDebug>
#include <QDataStream>
#include <QColor>
#include <QVector2D> #include <QVector2D>
#include <QVector3D> #include <QVector3D>
#include <QImage> #include <cmath>
#include <QMutex> #include <float.h>
#include <QFile> #include <qopenglext.h>
#include <QDir>
#ifndef QNX #ifndef QNX
# include <cmath> # include <cmath>
# include <complex> # include <complex>
#else #else
# include <math.h> # include <complex.h>
# include <complex.h> # include <math.h>
#endif #endif
#include <iostream>
#include "qglengine_version.h"
#include "qglengine_core_export.h" #include "qglengine_core_export.h"
#include "qglengine_version.h"
#include <iostream>
//#ifdef WINDOWS // #ifdef WINDOWS
//# define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF // # define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
//# define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE // # define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
//#endif // #endif
#ifndef M_PI #ifndef M_PI
# define M_PI 3.14159265358979323846 # define M_PI 3.14159265358979323846
@@ -116,53 +117,131 @@ const float deg2rad = atanf(1.f) / 45.f;
const float rad2deg = 45.f / atanf(1.f); const float rad2deg = 45.f / atanf(1.f);
# ifdef WINDOWS # ifdef WINDOWS
inline int random() {return rand();} inline int random() {
return rand();
}
# endif # endif
#else #else
#define random randomi # define random randomi
#endif #endif
#ifdef CC_VC #ifdef CC_VC
inline float round(const float & v) {return floor(v + 0.5);} inline float round(const float & v) {
return floor(v + 0.5);
}
#endif #endif
inline float randomu() {return float(random()) / RAND_MAX;} inline float randomu() {
return float(random()) / RAND_MAX;
}
inline const QSizeF operator *(const QSizeF & f, const QSizeF & s) {return QSizeF(f.width() * s.width(), f.height() * s.height());} inline const QSizeF operator*(const QSizeF & f, const QSizeF & s) {
return QSizeF(f.width() * s.width(), f.height() * s.height());
}
#ifndef PIP_VERSION #ifndef PIP_VERSION
template<typename T> inline void piSwap(T & f, T & s) {T t(f); f = s; s = t;} template<typename T>
template<typename Type> inline Type piMin(const Type & f, const Type & s) {return (f > s) ? s : f;} inline void piSwap(T & f, T & s) {
template<typename Type> inline Type piMin(const Type & f, const Type & s, const Type & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);} T t(f);
template<typename Type> inline Type piMax(const Type & f, const Type & s) {return (f < s) ? s : f;} f = s;
template<typename Type> inline Type piMax(const Type & f, const Type & s, const Type & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);} s = t;
template<typename Type> inline Type piClamp(const Type & v, const Type & min, const Type & max) {return (v > max ? max : (v < min ? min : v));} }
inline ushort letobe_s(ushort v) {return (v << 8) | (v >> 8);} template<typename Type>
inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);} inline Type piMin(const Type & f, const Type & s) {
return (f > s) ? s : f;
}
template<typename Type>
inline Type piMin(const Type & f, const Type & s, const Type & t) {
return (f < s && f < t) ? f : ((s < t) ? s : t);
}
template<typename Type>
inline Type piMax(const Type & f, const Type & s) {
return (f < s) ? s : f;
}
template<typename Type>
inline Type piMax(const Type & f, const Type & s, const Type & t) {
return (f > s && f > t) ? f : ((s > t) ? s : t);
}
template<typename Type>
inline Type piClamp(const Type & v, const Type & min, const Type & max) {
return (v > max ? max : (v < min ? min : v));
}
inline ushort letobe_s(ushort v) {
return (v << 8) | (v >> 8);
}
inline uint letobe_i(const uint & v) {
return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);
}
#endif #endif
// return [-1, 1] // return [-1, 1]
inline float urand(const float & scale = 1.) {return ((float)rand() / RAND_MAX - .5f) * (scale + scale);} inline float urand(const float & scale = 1.) {
return ((float)rand() / RAND_MAX - .5f) * (scale + scale);
}
// return [0, 1] // return [0, 1]
inline float uprand(const float & scale = 1.) {return ((float)rand() / RAND_MAX) * scale;} inline float uprand(const float & scale = 1.) {
return ((float)rand() / RAND_MAX) * scale;
}
QString readCharsUntilNull(QDataStream & s); QString readCharsUntilNull(QDataStream & s);
QString findFile(const QString & file, const QStringList & pathes); QString findFile(const QString & file, const QStringList & pathes);
inline QColor operator *(const QColor & c, float v) {return QColor(piClamp<int>(c.red() * v, 0, 255), piClamp<int>(c.green() * v, 0, 255), piClamp<int>(c.blue() * v, 0, 255), piClamp<int>(c.alpha() * v, 0, 255));} inline QColor operator*(const QColor & c, float v) {
inline QColor operator /(const QColor & c, float v) {return QColor(piClamp<int>(c.red() / v, 0, 255), piClamp<int>(c.green() / v, 0, 255), piClamp<int>(c.blue() / v, 0, 255), piClamp<int>(c.alpha() / v, 0, 255));} return QColor(piClamp<int>(c.red() * v, 0, 255),
piClamp<int>(c.green() * v, 0, 255),
piClamp<int>(c.blue() * v, 0, 255),
piClamp<int>(c.alpha() * v, 0, 255));
}
inline QColor operator/(const QColor & c, float v) {
return QColor(piClamp<int>(c.red() / v, 0, 255),
piClamp<int>(c.green() / v, 0, 255),
piClamp<int>(c.blue() / v, 0, 255),
piClamp<int>(c.alpha() / v, 0, 255));
}
inline void qglColor(const QColor & c) {glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());} inline void qglColor(const QColor & c) {
inline void glClearError() {int c = 100; while (glGetError() != GL_NO_ERROR && --c > 0) glGetError();} glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
inline void glSetCapEnabled(GLenum cap, bool on = true) {if (on) glEnable(cap); else glDisable(cap);} }
inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);} inline void glClearError() {
inline void deleteGLTexture(QOpenGLExtraFunctions * f, GLuint & tex) {if (tex != 0) f->glDeleteTextures(1, &tex); tex = 0;} int c = 100;
while (glGetError() != GL_NO_ERROR && --c > 0)
glGetError();
}
inline void glSetCapEnabled(GLenum cap, bool on = true) {
if (on)
glEnable(cap);
else
glDisable(cap);
}
inline void glSetPolygonMode(GLenum mode) {
glPolygonMode(GL_FRONT_AND_BACK, mode);
}
inline void deleteGLTexture(QOpenGLExtraFunctions * f, GLuint & tex) {
if (tex != 0) f->glDeleteTextures(1, &tex);
tex = 0;
}
void glEnableDepth(); void glEnableDepth();
void glDisableDepth(); void glDisableDepth();
void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true); void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true);
void glDrawQuad(QOpenGLShaderProgram * prog = nullptr, QVector4D * corner_dirs = nullptr, GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f); void glDrawQuad(QOpenGLShaderProgram * prog = nullptr,
void createGLTexture(QOpenGLExtraFunctions * f, GLuint & tex, int width, int height, const GLenum & format = GL_RGBA, const GLenum & target = GL_TEXTURE_2D); QVector4D * corner_dirs = nullptr,
void createGLTexture(QOpenGLExtraFunctions * f, GLuint & tex, const QImage & image, const GLenum & format = GL_RGBA, const GLenum & target = GL_TEXTURE_2D); GLfloat x = -1.f,
GLfloat y = -1.f,
GLfloat w = 2.f,
GLfloat h = 2.f);
void createGLTexture(QOpenGLExtraFunctions * f,
GLuint & tex,
int width,
int height,
const GLenum & format = GL_RGBA,
const GLenum & target = GL_TEXTURE_2D);
void createGLTexture(QOpenGLExtraFunctions * f,
GLuint & tex,
const QImage & image,
const GLenum & format = GL_RGBA,
const GLenum & target = GL_TEXTURE_2D);
QMatrix4x4 glMatrixPerspective(float angle, float aspect, float near_); QMatrix4x4 glMatrixPerspective(float angle, float aspect, float near_);
QImage rotateQImageLeft(const QImage & im); QImage rotateQImageLeft(const QImage & im);
QImage rotateQImageRight(const QImage & im); QImage rotateQImageRight(const QImage & im);
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);} inline QImage rotateQImage180(const QImage & im) {
return im.mirrored(true, true);
}
class QGLView; class QGLView;
class MouseController; class MouseController;
@@ -192,7 +271,7 @@ enum RenderPass {
rpTransparent, rpTransparent,
}; };
typedef QList<ObjectBase*> ObjectBaseList; typedef QList<ObjectBase *> ObjectBaseList;
struct Box3D { struct Box3D {
GLfloat x; GLfloat x;
@@ -204,101 +283,215 @@ struct Box3D {
GLfloat angle_z; GLfloat angle_z;
GLfloat angle_xy; GLfloat angle_xy;
GLfloat angle_roll; GLfloat angle_roll;
Box3D() {x = y = z = width = length = height = angle_z = angle_xy = angle_roll = 0.f;} Box3D() { x = y = z = width = length = height = angle_z = angle_xy = angle_roll = 0.f; }
Box3D(const QVector3D & center, GLfloat hwid, GLfloat hlen, GLfloat hhei) {x = center.x() - hwid; y = center.y() - hlen; z = center.z() - hhei; width = 2 * hwid; length = 2 * hlen; height = 2 * hhei; angle_z = angle_xy = angle_roll = 0.f;} Box3D(const QVector3D & center, GLfloat hwid, GLfloat hlen, GLfloat hhei) {
x = center.x() - hwid;
y = center.y() - hlen;
z = center.z() - hhei;
width = 2 * hwid;
length = 2 * hlen;
height = 2 * hhei;
angle_z = angle_xy = angle_roll = 0.f;
}
Box3D(const QVector<QVector3D> & points); Box3D(const QVector<QVector3D> & points);
bool isEmpty() const {return (qAbs(width) < 1E-6f) && (qAbs(length) < 1E-6f) && (qAbs(height) < 1E-6f);} bool isEmpty() const { return (qAbs(width) < 1E-6f) && (qAbs(length) < 1E-6f) && (qAbs(height) < 1E-6f); }
QVector3D randomPoint() const {return QVector3D(uprand(length) + x, uprand(width) + y, uprand(height) + z);} QVector3D randomPoint() const { return QVector3D(uprand(length) + x, uprand(width) + y, uprand(height) + z); }
QVector3D pos() const {return QVector3D(x, y, z);} QVector3D pos() const { return QVector3D(x, y, z); }
QVector3D size() const {return QVector3D(length, width, height);} QVector3D size() const { return QVector3D(length, width, height); }
QVector3D center() const {return QVector3D(length / 2.f + x, width / 2.f + y, height / 2.f + z);} QVector3D center() const { return QVector3D(length / 2.f + x, width / 2.f + y, height / 2.f + z); }
QVector3D angles() const {return QVector3D(angle_xy, angle_roll, angle_z);} QVector3D angles() const { return QVector3D(angle_xy, angle_roll, angle_z); }
QVector<QVector3D> corners() const; QVector<QVector3D> corners() const;
void setPos(const QVector3D & p) {x = p.x(); y = p.y(); z = p.z();} void setPos(const QVector3D & p) {
void setAngles(const QVector3D & a) {angle_xy = a.x(); angle_roll = a.y(); angle_z = a.z();} x = p.x();
void setSize(const QVector3D & s) {length = s.x(); width = s.y(); height = s.z();} y = p.y();
Box3D & moveTo(const QVector3D & v) {x = v.x(); y = v.y(); z = v.z(); return *this;} z = p.z();
Box3D & move(const QVector3D & v) {x += v.x(); y += v.y(); z += v.z(); return *this;} }
Box3D movedTo(const QVector3D & v) const {Box3D t(*this); t.x = v.x(); t.y = v.y(); t.z = v.z(); return t;} void setAngles(const QVector3D & a) {
Box3D moved(const QVector3D & v) const {Box3D t(*this); t.x += v.x(); t.y += v.y(); t.z += v.z(); return t;} angle_xy = a.x();
Box3D & operator |=(const Box3D & o); angle_roll = a.y();
angle_z = a.z();
}
void setSize(const QVector3D & s) {
length = s.x();
width = s.y();
height = s.z();
}
Box3D & moveTo(const QVector3D & v) {
x = v.x();
y = v.y();
z = v.z();
return *this;
}
Box3D & move(const QVector3D & v) {
x += v.x();
y += v.y();
z += v.z();
return *this;
}
Box3D movedTo(const QVector3D & v) const {
Box3D t(*this);
t.x = v.x();
t.y = v.y();
t.z = v.z();
return t;
}
Box3D moved(const QVector3D & v) const {
Box3D t(*this);
t.x += v.x();
t.y += v.y();
t.z += v.z();
return t;
}
Box3D & operator|=(const Box3D & o);
}; };
inline QDebug operator <<(QDebug d, const Box3D & v) {d << "Box3D {start (" << v.x << "," << v.y << "," << v.z << "), size (" << v.length << "," << v.width << "," << v.height << ")}"; return d;} inline QDebug operator<<(QDebug d, const Box3D & v) {
d << "Box3D {start (" << v.x << "," << v.y << "," << v.z << "), size (" << v.length << "," << v.width << "," << v.height << ")}";
return d;
}
#pragma pack(push, 1) #pragma pack(push, 1)
struct Vector2i { struct Vector2i {
Vector2i(int p0_ = 0, int p1_ = 0) {p0 = p0_; p1 = p1_;} Vector2i(int p0_ = 0, int p1_ = 0) {
p0 = p0_;
p1 = p1_;
}
Vector2i(const QString & str); Vector2i(const QString & str);
Vector2i movedX(const int & o) {return Vector2i(p0 + o, p1);} Vector2i movedX(const int & o) { return Vector2i(p0 + o, p1); }
Vector2i movedY(const int & o) {return Vector2i(p0, p1 + o);} Vector2i movedY(const int & o) { return Vector2i(p0, p1 + o); }
Vector2i moved(const int & x, const int & y) {return Vector2i(p0 + x, p1 + y);} Vector2i moved(const int & x, const int & y) { return Vector2i(p0 + x, p1 + y); }
GLint p0; GLint p0;
GLint p1; GLint p1;
bool operator ==(const Vector2i & o) const {return p0 == o.p0 && p1 == o.p1;} bool operator==(const Vector2i & o) const { return p0 == o.p0 && p1 == o.p1; }
bool operator !=(const Vector2i & o) const {return p0 != o.p0 || p1 != o.p1;} bool operator!=(const Vector2i & o) const { return p0 != o.p0 || p1 != o.p1; }
void operator +=(int v) {p0 += v; p1 += v;} void operator+=(int v) {
QVector2D toQVector2D() const {return QVector2D(p0, p1);} p0 += v;
p1 += v;
}
QVector2D toQVector2D() const { return QVector2D(p0, p1); }
}; };
#pragma pack(pop) #pragma pack(pop)
inline Vector2i operator +(const Vector2i & f, const Vector2i & s) {return Vector2i(f.p0 + s.p0, f.p1 + s.p1);} inline Vector2i operator+(const Vector2i & f, const Vector2i & s) {
inline Vector2i operator -(const Vector2i & f, const Vector2i & s) {return Vector2i(f.p0 - s.p0, f.p1 - s.p1);} return Vector2i(f.p0 + s.p0, f.p1 + s.p1);
inline Vector2i operator /(const Vector2i & f, const int & s) {return Vector2i(f.p0 / s, f.p1 / s);} }
inline uint qHash(const Vector2i & v) {return v.p0 ^ ((v.p1 << 8) | (v.p1 >> 24));} inline Vector2i operator-(const Vector2i & f, const Vector2i & s) {
inline QDebug operator <<(QDebug d, const Vector2i & v) {d.nospace() << "{" << v.p0 << ", " << v.p1 << "}"; return d.space();} return Vector2i(f.p0 - s.p0, f.p1 - s.p1);
}
inline Vector2i operator/(const Vector2i & f, const int & s) {
return Vector2i(f.p0 / s, f.p1 / s);
}
inline uint qHash(const Vector2i & v) {
return v.p0 ^ ((v.p1 << 8) | (v.p1 >> 24));
}
inline QDebug operator<<(QDebug d, const Vector2i & v) {
d.nospace() << "{" << v.p0 << ", " << v.p1 << "}";
return d.space();
}
inline QDataStream & operator <<(QDataStream & s, const Vector2i & v) {s << v.p0 << v.p1; return s;} inline QDataStream & operator<<(QDataStream & s, const Vector2i & v) {
inline QDataStream & operator >>(QDataStream & s, Vector2i & v) {s >> v.p0 >> v.p1; return s;} s << v.p0 << v.p1;
return s;
}
inline QDataStream & operator>>(QDataStream & s, Vector2i & v) {
s >> v.p0 >> v.p1;
return s;
}
#pragma pack(push, 1) #pragma pack(push, 1)
struct Vector3i { struct Vector3i {
Vector3i(int p0_ = 0, int p1_ = 0, int p2_ = 0) {p0 = p0_; p1 = p1_; p2 = p2_;} Vector3i(int p0_ = 0, int p1_ = 0, int p2_ = 0) {
p0 = p0_;
p1 = p1_;
p2 = p2_;
}
Vector3i(const QString & str); Vector3i(const QString & str);
Vector3i movedX(const int & o) {return Vector3i(p0 + o, p1, p2);} Vector3i movedX(const int & o) { return Vector3i(p0 + o, p1, p2); }
Vector3i movedY(const int & o) {return Vector3i(p0, p1 + o, p2);} Vector3i movedY(const int & o) { return Vector3i(p0, p1 + o, p2); }
Vector3i movedZ(const int & o) {return Vector3i(p0, p1, p2 + o);} Vector3i movedZ(const int & o) { return Vector3i(p0, p1, p2 + o); }
Vector3i moved(const int & x, const int & y, const int & z) {return Vector3i(p0 + x, p1 + y, p2 + z);} Vector3i moved(const int & x, const int & y, const int & z) { return Vector3i(p0 + x, p1 + y, p2 + z); }
GLint p0; GLint p0;
GLint p1; GLint p1;
GLint p2; GLint p2;
bool operator ==(const Vector3i & o) const {return p0 == o.p0 && p1 == o.p1 && p2 == o.p2;} bool operator==(const Vector3i & o) const { return p0 == o.p0 && p1 == o.p1 && p2 == o.p2; }
bool operator !=(const Vector3i & o) const {return p0 != o.p0 || p1 != o.p1 || p2 != o.p2;} bool operator!=(const Vector3i & o) const { return p0 != o.p0 || p1 != o.p1 || p2 != o.p2; }
void operator +=(int v) {p0 += v; p1 += v; p2 += v;} void operator+=(int v) {
QVector3D toQVector3D() const {return QVector3D(p0, p1, p2);} p0 += v;
p1 += v;
p2 += v;
}
QVector3D toQVector3D() const { return QVector3D(p0, p1, p2); }
}; };
#pragma pack(pop) #pragma pack(pop)
inline Vector3i operator +(const Vector3i & f, const Vector3i & s) {return Vector3i(f.p0 + s.p0, f.p1 + s.p1, f.p2 + s.p2);} inline Vector3i operator+(const Vector3i & f, const Vector3i & s) {
inline Vector3i operator -(const Vector3i & f, const Vector3i & s) {return Vector3i(f.p0 - s.p0, f.p1 - s.p1, f.p2 - s.p2);} return Vector3i(f.p0 + s.p0, f.p1 + s.p1, f.p2 + s.p2);
inline Vector3i operator /(const Vector3i & f, const int & s) {return Vector3i(f.p0 / s, f.p1 / s, f.p2 / s);} }
inline uint qHash(const Vector3i & v) {return v.p0 ^ ((v.p1 << 8) | (v.p1 >> 24)) ^ ((v.p2 << 16) | (v.p2 >> 16));} inline Vector3i operator-(const Vector3i & f, const Vector3i & s) {
inline QDebug operator <<(QDebug d, const Vector3i & v) {d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}"; return d.space();} return Vector3i(f.p0 - s.p0, f.p1 - s.p1, f.p2 - s.p2);
}
inline Vector3i operator/(const Vector3i & f, const int & s) {
return Vector3i(f.p0 / s, f.p1 / s, f.p2 / s);
}
inline uint qHash(const Vector3i & v) {
return v.p0 ^ ((v.p1 << 8) | (v.p1 >> 24)) ^ ((v.p2 << 16) | (v.p2 >> 16));
}
inline QDebug operator<<(QDebug d, const Vector3i & v) {
d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}";
return d.space();
}
inline QDataStream & operator <<(QDataStream & s, const Vector3i & v) {s << v.p0 << v.p1 << v.p2; return s;} inline QDataStream & operator<<(QDataStream & s, const Vector3i & v) {
inline QDataStream & operator >>(QDataStream & s, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; return s;} s << v.p0 << v.p1 << v.p2;
return s;
}
inline QDataStream & operator>>(QDataStream & s, Vector3i & v) {
s >> v.p0 >> v.p1 >> v.p2;
return s;
}
QVector3D vectorFromString(const QString & str); QVector3D vectorFromString(const QString & str);
QColor colorFromString(const QString & str); QColor colorFromString(const QString & str);
inline QVector4D QColor2QVector(const QColor & c) {return QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF());} inline QVector4D QColor2QVector(const QColor & c) {
return QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF());
}
inline float cosABV(const QVector3D & v0, const QVector3D & v1) { inline float cosABV(const QVector3D & v0, const QVector3D & v1) {
float l = v0.length() * v1.length(); float l = v0.length() * v1.length();
if (l == 0.f) return 0.; if (l == 0.f) return 0.;
return (QVector3D::dotProduct(v0, v1)) / l; return (QVector3D::dotProduct(v0, v1)) / l;
} }
inline void normalizeAngleRad(float & a) {while (a < 0.) a += M_2PI; while (a >= M_2PI) a -= M_2PI;} inline void normalizeAngleRad(float & a) {
inline void normalizeAngleDeg360(float & a) {while (a < 0.) a += 360. ; while (a >= 360. ) a -= 360. ;} while (a < 0.)
inline QVector3D projection(const QVector3D & v, const QVector3D & to) {return to.normalized() * v.length() * cosABV(v, to);} a += M_2PI;
while (a >= M_2PI)
a -= M_2PI;
}
inline void normalizeAngleDeg360(float & a) {
while (a < 0.)
a += 360.;
while (a >= 360.)
a -= 360.;
}
inline QVector3D projection(const QVector3D & v, const QVector3D & to) {
return to.normalized() * v.length() * cosABV(v, to);
}
QVector3D orthToVector(const QVector3D & v, const float & scale = 1.); QVector3D orthToVector(const QVector3D & v, const float & scale = 1.);
QVector3D rotateVector(const QVector3D & v, const QVector3D & a); QVector3D rotateVector(const QVector3D & v, const QVector3D & a);
void setVectorLength(QVector3D & v, const float & l); void setVectorLength(QVector3D & v, const float & l);
void lengthenVector(QVector3D & v, const float & l); void lengthenVector(QVector3D & v, const float & l);
inline float squareLength(const QVector3D & from, const QVector3D & to) {return (to.x() - from.x())*(to.x() - from.x()) + (to.y() - from.y())*(to.y() - from.y()) + (to.z() - from.z())*(to.z() - from.z());} inline float squareLength(const QVector3D & from, const QVector3D & to) {
inline QVector3D directionFromAngles(const QVector3D & a) {return rotateVector(QVector3D(1., 0., 0.), a);} return (to.x() - from.x()) * (to.x() - from.x()) + (to.y() - from.y()) * (to.y() - from.y()) +
inline float frac(const float & x, const float & b) {return x - int(x / b) * b;} (to.z() - from.z()) * (to.z() - from.z());
}
inline QVector3D directionFromAngles(const QVector3D & a) {
return rotateVector(QVector3D(1., 0., 0.), a);
}
inline float frac(const float & x, const float & b) {
return x - int(x / b) * b;
}
#endif // GLTYPES_H #endif // GLTYPES_H

View File

@@ -1,39 +1,37 @@
/* /*
QGL VertexObject QGL VertexObject
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "glvertexobject.h" #include "glvertexobject.h"
#include <QOpenGLExtraFunctions>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
VertexObject::VertexObject(): VertexObject::VertexObject(): buffer_obj(GL_ARRAY_BUFFER, GL_STREAM_DRAW), buffer_sel(GL_ARRAY_BUFFER, GL_STREAM_DRAW) {
buffer_obj (GL_ARRAY_BUFFER, GL_STREAM_DRAW), vao_ = 0;
buffer_sel (GL_ARRAY_BUFFER, GL_STREAM_DRAW) { buffers_binded = false;
vao_ = 0;
buffers_binded = false;
objects_changed = selected_changed = true; objects_changed = selected_changed = true;
} }
VertexObject::~VertexObject() { VertexObject::~VertexObject() {}
}
void VertexObject::init(QOpenGLExtraFunctions * f) { void VertexObject::init(QOpenGLExtraFunctions * f) {
@@ -59,13 +57,13 @@ void VertexObject::reinit() {
vao_ = 0; vao_ = 0;
buffer_obj.reinit(); buffer_obj.reinit();
buffer_sel.reinit(); buffer_sel.reinit();
buffers_binded = false; buffers_binded = false;
objects_changed = selected_changed = true; objects_changed = selected_changed = true;
} }
void VertexObject::bind(QOpenGLExtraFunctions * f) { void VertexObject::bind(QOpenGLExtraFunctions * f) {
//qDebug() << "bind" << target_ << buffer_; // qDebug() << "bind" << target_ << buffer_;
f->glBindVertexArray(vao_); f->glBindVertexArray(vao_);
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGL VertexObject QGL VertexObject
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLVERTEXOBJECT_H #ifndef GLVERTEXOBJECT_H
@@ -23,33 +23,32 @@
#include "glshaders_types.h" #include "glshaders_types.h"
class VertexObject class VertexObject {
{
public: public:
VertexObject(); VertexObject();
~VertexObject(); ~VertexObject();
void init (QOpenGLExtraFunctions * f); void init(QOpenGLExtraFunctions * f);
void destroy (QOpenGLExtraFunctions * f); void destroy(QOpenGLExtraFunctions * f);
void reinit(); void reinit();
void bind (QOpenGLExtraFunctions * f); void bind(QOpenGLExtraFunctions * f);
void release (QOpenGLExtraFunctions * f); void release(QOpenGLExtraFunctions * f);
void bindBuffers (QOpenGLExtraFunctions * f, Buffer & geom, Buffer & elem, bool force = false); void bindBuffers(QOpenGLExtraFunctions * f, Buffer & geom, Buffer & elem, bool force = false);
void loadObject (QOpenGLExtraFunctions * f, const QGLEngineShaders::Object & object); void loadObject(QOpenGLExtraFunctions * f, const QGLEngineShaders::Object & object);
void loadObjects (QOpenGLExtraFunctions * f, const QVector<QGLEngineShaders::Object> & objects); void loadObjects(QOpenGLExtraFunctions * f, const QVector<QGLEngineShaders::Object> & objects);
void loadSelections(QOpenGLExtraFunctions * f, const QVector<uchar> & sels); void loadSelections(QOpenGLExtraFunctions * f, const QVector<uchar> & sels);
void draw(QOpenGLExtraFunctions * f, GLenum geom_type, int vert_cout, int obj_count); void draw(QOpenGLExtraFunctions * f, GLenum geom_type, int vert_cout, int obj_count);
GLuint ID() const {return vao_;} GLuint ID() const { return vao_; }
bool isInit() const {return vao_ != 0;} bool isInit() const { return vao_ != 0; }
bool isObjectsChanged() const {return objects_changed;} bool isObjectsChanged() const { return objects_changed; }
bool isSelectionChanged() const {return selected_changed;} bool isSelectionChanged() const { return selected_changed; }
void setObjectsChanged(bool yes = true) {objects_changed = yes;} void setObjectsChanged(bool yes = true) { objects_changed = yes; }
void setSelectionChanged(bool yes = true) {selected_changed = yes;} void setSelectionChanged(bool yes = true) { selected_changed = yes; }
private: private:
void loadBuffer(QOpenGLExtraFunctions * f, Buffer & buf, const void * data, int size); void loadBuffer(QOpenGLExtraFunctions * f, Buffer & buf, const void * data, int size);

View File

@@ -1,41 +1,41 @@
/* /*
QGL HDR QGL HDR
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "hdr_p.h" #include "hdr_p.h"
#include <qmath.h>
#include <QByteArray> #include <QByteArray>
#include <qmath.h>
#define RGBE_DATA_RED 2 #define RGBE_DATA_RED 2
#define RGBE_DATA_GREEN 1 #define RGBE_DATA_GREEN 1
#define RGBE_DATA_BLUE 0 #define RGBE_DATA_BLUE 0
/* number of floats per pixel */ /* number of floats per pixel */
#define RGBE_DATA_SIZE 3 #define RGBE_DATA_SIZE 3
void rgbe2float(float *red, float *green, float *blue, uchar rgbe[4]) { void rgbe2float(float * red, float * green, float * blue, uchar rgbe[4]) {
float f; float f;
if (rgbe[3]) { if (rgbe[3]) {
f = static_cast<float>(ldexp(1.0,rgbe[3]-(int)(128+8))); f = static_cast<float>(ldexp(1.0, rgbe[3] - (int)(128 + 8)));
*red = rgbe[0] * f; *red = rgbe[0] * f;
*green = rgbe[1] * f; *green = rgbe[1] * f;
*blue = rgbe[2] * f; *blue = rgbe[2] * f;
} } else
else
*red = *green = *blue = 0.0; *red = *green = *blue = 0.0;
} }
@@ -43,10 +43,9 @@ void rgbe2float(float *red, float *green, float *blue, uchar rgbe[4]) {
/* simple read routine. will not correctly handle run length encoding */ /* simple read routine. will not correctly handle run length encoding */
bool RGBE_ReadPixels(QDataStream * fp, float * data, int numpixels) { bool RGBE_ReadPixels(QDataStream * fp, float * data, int numpixels) {
uchar rgbe[4]; uchar rgbe[4];
while(numpixels-- > 0) { while (numpixels-- > 0) {
if (fp->readRawData((char*)rgbe, sizeof(rgbe)) < 1) if (fp->readRawData((char *)rgbe, sizeof(rgbe)) < 1) return false;
return false; rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe);
rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE],rgbe);
data += RGBE_DATA_SIZE; data += RGBE_DATA_SIZE;
} }
return true; return true;
@@ -59,50 +58,48 @@ bool RGBE_ReadPixels_RLE(QDataStream * fp, float * data, int scanline_width, int
uchar buf[2]; uchar buf[2];
QByteArray scanline_buffer; QByteArray scanline_buffer;
if ((scanline_width < 8)||(scanline_width > 0x7fff)) if ((scanline_width < 8) || (scanline_width > 0x7fff)) /* run length encoding is not allowed so read flat*/
/* run length encoding is not allowed so read flat*/ return RGBE_ReadPixels(fp, data, scanline_width * num_scanlines);
return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines); scanline_buffer.resize(4 * scanline_width);
scanline_buffer.resize(4*scanline_width);
/* read in each successive scanline */ /* read in each successive scanline */
while(num_scanlines > 0) { while (num_scanlines > 0) {
if (fp->readRawData((char*)rgbe,sizeof(rgbe)) < 1) { if (fp->readRawData((char *)rgbe, sizeof(rgbe)) < 1) {
return false; return false;
} }
if ((rgbe[0] != 2)||(rgbe[1] != 2)||(rgbe[2] & 0x80)) { if ((rgbe[0] != 2) || (rgbe[1] != 2) || (rgbe[2] & 0x80)) {
/* this file is not run length encoded */ /* this file is not run length encoded */
rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN],&data[RGBE_DATA_BLUE],rgbe); rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe);
data += RGBE_DATA_SIZE; data += RGBE_DATA_SIZE;
return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines-1); return RGBE_ReadPixels(fp, data, scanline_width * num_scanlines - 1);
} }
if ((((int)rgbe[2])<<8 | rgbe[3]) != scanline_width) { if ((((int)rgbe[2]) << 8 | rgbe[3]) != scanline_width) {
return false; return false;
} }
ptr = (uchar*)scanline_buffer.data(); ptr = (uchar *)scanline_buffer.data();
/* read each of the four channels for the scanline into the buffer */ /* read each of the four channels for the scanline into the buffer */
for(i=0;i<4;i++) { for (i = 0; i < 4; i++) {
ptr_end = (uchar*)scanline_buffer.data() + ((i+1)*scanline_width); ptr_end = (uchar *)scanline_buffer.data() + ((i + 1) * scanline_width);
while(ptr < ptr_end) { while (ptr < ptr_end) {
if (fp->readRawData((char*)buf,sizeof(buf[0])*2) < 1) { if (fp->readRawData((char *)buf, sizeof(buf[0]) * 2) < 1) {
return false; return false;
} }
if (buf[0] > 128) { if (buf[0] > 128) {
/* a run of the same value */ /* a run of the same value */
count = buf[0]-128; count = buf[0] - 128;
if ((count == 0)||(count > ptr_end - ptr)) { if ((count == 0) || (count > ptr_end - ptr)) {
return false; return false;
} }
while(count-- > 0) while (count-- > 0)
*ptr++ = buf[1]; *ptr++ = buf[1];
} } else {
else {
/* a non-run */ /* a non-run */
count = buf[0]; count = buf[0];
if ((count == 0)||(count > ptr_end - ptr)) { if ((count == 0) || (count > ptr_end - ptr)) {
return false; return false;
} }
*ptr++ = buf[1]; *ptr++ = buf[1];
if (--count > 0) { if (--count > 0) {
if (fp->readRawData((char*)ptr,sizeof(*ptr)*count) < 1) { if (fp->readRawData((char *)ptr, sizeof(*ptr) * count) < 1) {
return false; return false;
} }
ptr += count; ptr += count;
@@ -111,13 +108,12 @@ bool RGBE_ReadPixels_RLE(QDataStream * fp, float * data, int scanline_width, int
} }
} }
/* now convert data from buffer into floats */ /* now convert data from buffer into floats */
for(i=0;i<scanline_width;i++) { for (i = 0; i < scanline_width; i++) {
rgbe[0] = scanline_buffer[i]; rgbe[0] = scanline_buffer[i];
rgbe[1] = scanline_buffer[i+scanline_width]; rgbe[1] = scanline_buffer[i + scanline_width];
rgbe[2] = scanline_buffer[i+2*scanline_width]; rgbe[2] = scanline_buffer[i + 2 * scanline_width];
rgbe[3] = scanline_buffer[i+3*scanline_width]; rgbe[3] = scanline_buffer[i + 3 * scanline_width];
rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN], rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe);
&data[RGBE_DATA_BLUE],rgbe);
data += RGBE_DATA_SIZE; data += RGBE_DATA_SIZE;
} }
num_scanlines--; num_scanlines--;

View File

@@ -1,19 +1,19 @@
/* /*
QGL HDR QGL HDR
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef HDR_P_H #ifndef HDR_P_H

View File

@@ -1,41 +1,52 @@
/* /*
QGL Loader Assimp QGL Loader Assimp
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "loader_assimp.h" #include "loader_assimp.h"
#include "glscene.h"
#include "glmesh.h"
#include "glmaterial.h" #include "glmaterial.h"
#include "glmesh.h"
#include "globject.h" #include "globject.h"
#include "glscene.h"
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/material.h>
#include <assimp/mesh.h>
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/mesh.h>
#include <assimp/material.h>
QString fromAiString (const aiString & s) {return QString::fromLocal8Bit(s.C_Str());} QString fromAiString(const aiString & s) {
QColor fromAiColor (const aiColor4D & c) {return QColor::fromRgbF(piClamp(c.r, 0.f, 1.f), piClamp(c.g, 0.f, 1.f), piClamp(c.b, 0.f, 1.f));} return QString::fromLocal8Bit(s.C_Str());
QVector3D fromAiVector3D(const aiVector3D & v) {return QVector3D(v.x, v.y, v.z);} }
Vector3i fromAiFace (const aiFace & v) {return Vector3i(v.mIndices[0], v.mIndices[1], v.mIndices[2]);} QColor fromAiColor(const aiColor4D & c) {
QMatrix4x4 fromAiMatrix4D(const aiMatrix4x4 & v) {return QMatrix4x4(v.a1, v.a2, v.a3, v.a4, return QColor::fromRgbF(piClamp(c.r, 0.f, 1.f), piClamp(c.g, 0.f, 1.f), piClamp(c.b, 0.f, 1.f));
v.b1, v.b2, v.b3, v.b4, }
v.c1, v.c2, v.c3, v.c4, QVector3D fromAiVector3D(const aiVector3D & v) {
v.d1, v.d2, v.d3, v.d4);} return QVector3D(v.x, v.y, v.z);
bool isAiMeshTriangles(const aiMesh * m) {return (m->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) == aiPrimitiveType_TRIANGLE;} }
Vector3i fromAiFace(const aiFace & v) {
return Vector3i(v.mIndices[0], v.mIndices[1], v.mIndices[2]);
}
QMatrix4x4 fromAiMatrix4D(const aiMatrix4x4 & v) {
return QMatrix4x4(v.a1, v.a2, v.a3, v.a4, v.b1, v.b2, v.b3, v.b4, v.c1, v.c2, v.c3, v.c4, v.d1, v.d2, v.d3, v.d4);
}
bool isAiMeshTriangles(const aiMesh * m) {
return (m->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) == aiPrimitiveType_TRIANGLE;
}
Mesh * assimpMesh(const aiMesh * m) { Mesh * assimpMesh(const aiMesh * m) {
@@ -44,9 +55,11 @@ Mesh * assimpMesh(const aiMesh * m) {
Mesh * ret = new Mesh(); Mesh * ret = new Mesh();
int vcnt = m->mNumVertices, tcnt = m->mNumFaces; int vcnt = m->mNumVertices, tcnt = m->mNumFaces;
QVector<QVector3D> & v(ret->vertices()); v.resize(vcnt); QVector<QVector3D> & v(ret->vertices());
QVector<QVector2D> & t(ret->texcoords()); t.resize(vcnt); v.resize(vcnt);
QVector< Vector3i> & ind(ret->indicesTriangles()); QVector<QVector2D> & t(ret->texcoords());
t.resize(vcnt);
QVector<Vector3i> & ind(ret->indicesTriangles());
for (int i = 0; i < vcnt; ++i) for (int i = 0; i < vcnt; ++i)
v[i] = fromAiVector3D(m->mVertices[i]); v[i] = fromAiVector3D(m->mVertices[i]);
@@ -72,12 +85,12 @@ Mesh * assimpMesh(const aiMesh * m) {
ind.resize(tcnt); ind.resize(tcnt);
int si = 0; int si = 0;
for (int i = 0; i < tcnt; ++i) { for (int i = 0; i < tcnt; ++i) {
si = i+i+i; si = i + i + i;
ind[i] = Vector3i(si, si+1, si+2); ind[i] = Vector3i(si, si + 1, si + 2);
} }
} }
//qDebug() << "add mesh" << v.size() << ret->normals().size() << ret->texcoords().size() << ret->indices().size(); // qDebug() << "add mesh" << v.size() << ret->normals().size() << ret->texcoords().size() << ret->indices().size();
return ret; return ret;
} }
@@ -86,7 +99,7 @@ Mesh * assimpMesh(const aiMesh * m) {
QColor aiMatColor(const aiMaterial * m, const char * key, uint s0, uint s1, const QColor & def = Qt::white) { QColor aiMatColor(const aiMaterial * m, const char * key, uint s0, uint s1, const QColor & def = Qt::white) {
aiColor4D col; aiColor4D col;
aiReturn r = m->Get(key, s0, s1, col); aiReturn r = m->Get(key, s0, s1, col);
//qDebug() << key << r << col.r << col.g << col.b; // qDebug() << key << r << col.r << col.g << col.b;
if (r != aiReturn_SUCCESS) return def; if (r != aiReturn_SUCCESS) return def;
return fromAiColor(col); return fromAiColor(col);
} }
@@ -98,36 +111,36 @@ float aiMatFloat(const aiMaterial * m, const char * key, uint s0, uint s1, float
} }
QString aiMatString(const aiMaterial * m, const char * key, uint s0, uint s1) { QString aiMatString(const aiMaterial * m, const char * key, uint s0, uint s1) {
aiString p; aiString p;
aiReturn r = const_cast<aiMaterial*>(m)->Get(key, s0, s1, p); aiReturn r = const_cast<aiMaterial *>(m)->Get(key, s0, s1, p);
//qDebug() << "GetTexture" << key << s0 << r << fromAiString(p); // qDebug() << "GetTexture" << key << s0 << r << fromAiString(p);
if (r != aiReturn_SUCCESS) return QString(); if (r != aiReturn_SUCCESS) return QString();
return fromAiString(p); return fromAiString(p);
} }
Material * assimpMaterial(const aiMaterial * m) { Material * assimpMaterial(const aiMaterial * m) {
if (!m) return 0; if (!m) return 0;
Material * ret = new Material(); Material * ret = new Material();
///WARNING: no function GetName() in aiMaterial in stable release /// WARNING: no function GetName() in aiMaterial in stable release
//ret->name = fromAiString(const_cast<aiMaterial*>(m)->GetName()); // ret->name = fromAiString(const_cast<aiMaterial*>(m)->GetName());
aiString name; aiString name;
const_cast<aiMaterial*>(m)->Get(AI_MATKEY_NAME,name); const_cast<aiMaterial *>(m)->Get(AI_MATKEY_NAME, name);
ret->name = fromAiString(name); ret->name = fromAiString(name);
//qDebug() << "mat" << ret->name; // qDebug() << "mat" << ret->name;
//for (int i = 0; i < m->mNumProperties; ++i) { // for (int i = 0; i < m->mNumProperties; ++i) {
// qDebug()<< fromAiString(m->mProperties[i]->mKey);// << "=" << aiMatFloat(m, m->mProperties[i]->mKey.C_Str(), 0, 0); // qDebug()<< fromAiString(m->mProperties[i]->mKey);// << "=" << aiMatFloat(m, m->mProperties[i]->mKey.C_Str(), 0, 0);
//} // }
ret->color_diffuse = aiMatColor(m, AI_MATKEY_COLOR_DIFFUSE); ret->color_diffuse = aiMatColor(m, AI_MATKEY_COLOR_DIFFUSE);
ret->color_emission = aiMatColor(m, AI_MATKEY_COLOR_EMISSIVE); ret->color_emission = aiMatColor(m, AI_MATKEY_COLOR_EMISSIVE);
float shine = aiMatFloat(m, AI_MATKEY_SHININESS, -1.f); float shine = aiMatFloat(m, AI_MATKEY_SHININESS, -1.f);
if (shine >= 0) { if (shine >= 0) {
ret->map_roughness.color_amount = 0.8f - (shine / 100.f * 0.6f); ret->map_roughness.color_amount = 0.8f - (shine / 100.f * 0.6f);
//qDebug() << "shine" << shine; // qDebug() << "shine" << shine;
} }
ret->map_diffuse .bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_DIFFUSE(0)); ret->map_diffuse.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_DIFFUSE(0));
ret->map_normal .bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_NORMALS(0)); ret->map_normal.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_NORMALS(0));
//ret->map_metalness.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_SPECULAR(0)); // ret->map_metalness.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_SPECULAR(0));
ret->map_roughness.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_SHININESS(0)); ret->map_roughness.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_SHININESS(0));
ret->map_emission .bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_EMISSIVE(0)); ret->map_emission.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_EMISSIVE(0));
ret->transparency = 1.f - aiMatFloat(m, AI_MATKEY_OPACITY, 1.f); ret->transparency = 1.f - aiMatFloat(m, AI_MATKEY_OPACITY, 1.f);
ret->detectMaps(); ret->detectMaps();
ret->setTypes(); ret->setTypes();
return ret; return ret;
@@ -136,19 +149,17 @@ Material * assimpMaterial(const aiMaterial * m) {
Light * assimpLight(const aiLight * l) { Light * assimpLight(const aiLight * l) {
if (!l) return 0; if (!l) return 0;
if (l->mType != aiLightSource_POINT && l->mType != aiLightSource_SPOT) if (l->mType != aiLightSource_POINT && l->mType != aiLightSource_SPOT) return 0;
return 0;
Light * ret = new Light(); Light * ret = new Light();
ret->setName(fromAiString(l->mName)); ret->setName(fromAiString(l->mName));
ret->setPos(fromAiVector3D(l->mPosition)); ret->setPos(fromAiVector3D(l->mPosition));
ret->setDirection(fromAiVector3D(l->mDirection)); ret->setDirection(fromAiVector3D(l->mDirection));
ret->decay_const = l->mAttenuationConstant ; ret->decay_const = l->mAttenuationConstant;
ret->decay_linear = l->mAttenuationLinear ; ret->decay_linear = l->mAttenuationLinear;
ret->decay_quadratic = l->mAttenuationQuadratic; ret->decay_quadratic = l->mAttenuationQuadratic;
ret->angle_start = l->mAngleInnerCone * rad2deg; ret->angle_start = l->mAngleInnerCone * rad2deg;
ret->angle_end = l->mAngleOuterCone * rad2deg; ret->angle_end = l->mAngleOuterCone * rad2deg;
if (l->mType == aiLightSource_SPOT) if (l->mType == aiLightSource_SPOT) ret->light_type = Light::Cone;
ret->light_type = Light::Cone;
QVector3D col(l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b); QVector3D col(l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b);
ret->intensity = col.length(); ret->intensity = col.length();
col /= ret->intensity; col /= ret->intensity;
@@ -157,25 +168,28 @@ Light * assimpLight(const aiLight * l) {
} }
ObjectBaseList assimpObject(const aiNode * n, const QVector<Mesh * > & meshes, aiMesh ** ai_meshes, ObjectBaseList assimpObject(const aiNode * n,
const QVector<Material*> & materials, const QVector<Mesh *> & meshes,
const QMap<QString, Light * > & light_by_name, QVector<Light*> & out_lights) { aiMesh ** ai_meshes,
const QVector<Material *> & materials,
const QMap<QString, Light *> & light_by_name,
QVector<Light *> & out_lights) {
if (!n) return ObjectBaseList(); if (!n) return ObjectBaseList();
ObjectBaseList ret; ObjectBaseList ret;
ObjectBase * obj = 0; ObjectBase * obj = 0;
QString name = fromAiString(n->mName); QString name = fromAiString(n->mName);
Light * light = light_by_name.value(name, 0); Light * light = light_by_name.value(name, 0);
if (light) { if (light) {
obj = light->clone(); obj = light->clone();
out_lights << (Light*)obj; out_lights << (Light *)obj;
} else } else
obj = new ObjectBase(); obj = new ObjectBase();
obj->setName(name); obj->setName(name);
obj->setMatrix(fromAiMatrix4D(n->mTransformation)); obj->setMatrix(fromAiMatrix4D(n->mTransformation));
ret << obj; ret << obj;
//qDebug() << "add object" << ret << ret->name(); // qDebug() << "add object" << ret << ret->name();
if (!light) { if (!light) {
//qDebug() << name << "has" << n->mNumMeshes << "meshes"; // qDebug() << name << "has" << n->mNumMeshes << "meshes";
for (uint i = 0; i < n->mNumMeshes; ++i) { for (uint i = 0; i < n->mNumMeshes; ++i) {
int mi = n->mMeshes[i]; int mi = n->mMeshes[i];
if (meshes[mi]) { if (meshes[mi]) {
@@ -185,17 +199,16 @@ ObjectBaseList assimpObject(const aiNode * n, const QVector<Mesh * > & meshes, a
} }
obj->setMesh(meshes[mi]); obj->setMesh(meshes[mi]);
int mati = ai_meshes[mi]->mMaterialIndex; int mati = ai_meshes[mi]->mMaterialIndex;
if (mati >= 0 || mati < materials.size()) if (mati >= 0 || mati < materials.size()) obj->setMaterial(materials[mati]);
obj->setMaterial(materials[mati]); // ret->setMesh(meshes[mi]);
//ret->setMesh(meshes[mi]); // qDebug() << "set mesh" << mi << ret->mesh();
//qDebug() << "set mesh" << mi << ret->mesh(); // break;
//break;
} }
} }
} }
for (uint i = 0; i < n->mNumChildren; ++i) { for (uint i = 0; i < n->mNumChildren; ++i) {
ObjectBaseList cl = assimpObject(n->mChildren[i], meshes, ai_meshes, materials, light_by_name, out_lights); ObjectBaseList cl = assimpObject(n->mChildren[i], meshes, ai_meshes, materials, light_by_name, out_lights);
foreach (ObjectBase * c, cl) foreach(ObjectBase * c, cl)
obj->addChild(c); obj->addChild(c);
} }
@@ -207,38 +220,36 @@ Scene * loadScene(const QString & filepath) {
if (filepath.isEmpty()) return 0; if (filepath.isEmpty()) return 0;
qDebug() << "[Loader Assimp] Import" << filepath << "..."; qDebug() << "[Loader Assimp] Import" << filepath << "...";
Assimp::Importer importer; Assimp::Importer importer;
const aiScene * ais = importer.ReadFile(filepath.toUtf8(), aiProcess_Triangulate | const aiScene * ais =
aiProcess_SortByPType | importer.ReadFile(filepath.toUtf8(),
aiProcess_GenUVCoords | aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_GenUVCoords | aiProcess_TransformUVCoords);
aiProcess_TransformUVCoords);
if (!ais) { if (!ais) {
qDebug() << "[Loader Assimp] Error: \"" + QString(importer.GetErrorString()) + "\""; qDebug() << "[Loader Assimp] Error: \"" + QString(importer.GetErrorString()) + "\"";
return 0; return 0;
} }
qDebug() << "[Loader Assimp] Imported" << ais->mNumMeshes << "meshes"; qDebug() << "[Loader Assimp] Imported" << ais->mNumMeshes << "meshes";
QVector<Mesh * > meshes; QVector<Mesh *> meshes;
for (uint i = 0; i < ais->mNumMeshes; ++i) for (uint i = 0; i < ais->mNumMeshes; ++i)
meshes << assimpMesh(ais->mMeshes[i]); meshes << assimpMesh(ais->mMeshes[i]);
QVector<Material * > materials; QVector<Material *> materials;
for (uint i = 0; i < ais->mNumMaterials; ++i) for (uint i = 0; i < ais->mNumMaterials; ++i)
materials << assimpMaterial(ais->mMaterials[i]); materials << assimpMaterial(ais->mMaterials[i]);
QVector<Light * > lights; QVector<Light *> lights;
for (uint i = 0; i < ais->mNumLights; ++i) for (uint i = 0; i < ais->mNumLights; ++i)
lights << assimpLight(ais->mLights[i]); lights << assimpLight(ais->mLights[i]);
QMap<QString, Light * > light_by_name; QMap<QString, Light *> light_by_name;
foreach (Light * l, lights) foreach(Light * l, lights)
if (l) if (l) light_by_name[l->name()] = l;
light_by_name[l->name()] = l;
QVector<Light*> out_lights; QVector<Light *> out_lights;
ObjectBaseList rootl = assimpObject(ais->mRootNode, meshes, ais->mMeshes, materials, light_by_name, out_lights); ObjectBaseList rootl = assimpObject(ais->mRootNode, meshes, ais->mMeshes, materials, light_by_name, out_lights);
if (rootl.isEmpty()) return 0; if (rootl.isEmpty()) return 0;
ObjectBase * root = rootl[0]; ObjectBase * root = rootl[0];
root->transferTransformToChildren(true); root->transferTransformToChildren(true);
ObjectBaseList rcl = root->children(true); ObjectBaseList rcl = root->children(true);
foreach (ObjectBase * c, rcl) { foreach(ObjectBase * c, rcl) {
foreach (Light * l, out_lights) { foreach(Light * l, out_lights) {
if (c->name() == (l->name() + ".Target")) { if (c->name() == (l->name() + ".Target")) {
l->setDistance((l->worldPos() - c->worldPos()).length()); l->setDistance((l->worldPos() - c->worldPos()).length());
delete c; delete c;
@@ -250,7 +261,7 @@ Scene * loadScene(const QString & filepath) {
Scene * scene = new Scene(); Scene * scene = new Scene();
scene->setName(root->name()); scene->setName(root->name());
foreach (ObjectBase * o, root->children()) foreach(ObjectBase * o, root->children())
scene->addObject(o); scene->addObject(o);
lights.removeAll(nullptr); lights.removeAll(nullptr);
qDeleteAll(lights); qDeleteAll(lights);

View File

@@ -1,19 +1,19 @@
/* /*
QGL Loader Assimp QGL Loader Assimp
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef LOADER_ASSIMP_H #ifndef LOADER_ASSIMP_H

View File

@@ -1,23 +1,25 @@
/* /*
QGL Loader QGL QGL Loader QGL
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "loader_qgl.h" #include "loader_qgl.h"
#include "glscene.h" #include "glscene.h"
#include <chunkstream.h> #include <chunkstream.h>
@@ -37,7 +39,7 @@ Scene * loadFromQGLFile(const QString & filepath) {
return 0; return 0;
} }
ushort version = 0x1; ushort version = 0x1;
f.peek((char*)&version, 2); f.peek((char *)&version, 2);
if (version != 1) { if (version != 1) {
qDebug() << "[Loader QGL] Error: \"" + filepath + "\" unsupported version!"; qDebug() << "[Loader QGL] Error: \"" + filepath + "\" unsupported version!";
return 0; return 0;
@@ -45,7 +47,7 @@ Scene * loadFromQGLFile(const QString & filepath) {
Scene * ret = 0; Scene * ret = 0;
s.skipRawData(2); s.skipRawData(2);
s >> ret; s >> ret;
//root->buildTransform(); // root->buildTransform();
qDebug() << "[Loader QGL] Loaded" << ret->objectsCount(true) << "objects from" << filepath; qDebug() << "[Loader QGL] Loaded" << ret->objectsCount(true) << "objects from" << filepath;
return ret; return ret;
} }
@@ -53,15 +55,14 @@ Scene * loadFromQGLFile(const QString & filepath) {
bool saveToQGLFile(const QString & filepath, const Scene * scene) { bool saveToQGLFile(const QString & filepath, const Scene * scene) {
QFile f(filepath); QFile f(filepath);
if (!f.open(QIODevice::ReadWrite)) if (!f.open(QIODevice::ReadWrite)) return false;
return false;
f.resize(0); f.resize(0);
QDataStream s(&f); QDataStream s(&f);
s.setVersion(QDataStream::Qt_5_0); s.setVersion(QDataStream::Qt_5_0);
char sign[4] = {'Q', 'G', 'L', 'E'}; char sign[4] = {'Q', 'G', 'L', 'E'};
ushort version = 0x1; ushort version = 0x1;
s.writeRawData(sign, 4); s.writeRawData(sign, 4);
s.writeRawData((char*)&version, 2); s.writeRawData((char *)&version, 2);
s << scene; s << scene;
return true; return true;
} }

View File

@@ -1,25 +1,26 @@
/* /*
QGL Loader QGL QGL Loader QGL
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef LOADER_QGL_H #ifndef LOADER_QGL_H
#define LOADER_QGL_H #define LOADER_QGL_H
#include "gltypes.h" #include "gltypes.h"
#include <QFileInfo> #include <QFileInfo>
Scene * loadFromQGLFile(const QString & filepath); Scene * loadFromQGLFile(const QString & filepath);

View File

@@ -1,19 +1,19 @@
/* /*
QGL Camera QGL Camera
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "gltypes.h" #include "gltypes.h"
@@ -21,9 +21,9 @@
Camera::Camera() { Camera::Camera() {
type_ = glCamera; type_ = glCamera;
fov_ = 60.; fov_ = 60.;
roll_ = 0.; roll_ = 0.;
depth_start = 0.1f; depth_start = 0.1f;
mirror_x = mirror_y = false; mirror_x = mirror_y = false;
} }
@@ -37,11 +37,11 @@ QMatrix4x4 Camera::offsetMatrix() const {
void Camera::assign(const Camera & c) { void Camera::assign(const Camera & c) {
trans = c.trans; trans = c.trans;
aim_dist = c.aim_dist; aim_dist = c.aim_dist;
fov_ = c.fov_; fov_ = c.fov_;
mirror_x = c.mirror_x; mirror_x = c.mirror_x;
mirror_y = c.mirror_y; mirror_y = c.mirror_y;
depth_start = c.depth_start; depth_start = c.depth_start;
buildTransform(); buildTransform();
} }
@@ -50,34 +50,34 @@ void Camera::assign(const Camera & c) {
ObjectBase * Camera::clone(bool withChildren) { ObjectBase * Camera::clone(bool withChildren) {
Camera * o = new Camera(*this); Camera * o = new Camera(*this);
o->is_init = false; o->is_init = false;
o->name_ = name_; o->name_ = name_;
o->scene_ = nullptr; o->scene_ = nullptr;
o->children_.clear(); o->children_.clear();
if (withChildren) { if (withChildren) {
for (int i = 0; i < children_.size(); ++i) for (int i = 0; i < children_.size(); ++i)
o->addChild(children_[i]->clone(withChildren)); o->addChild(children_[i]->clone(withChildren));
} }
o->trans = trans; o->trans = trans;
o->aim_dist = aim_dist; o->aim_dist = aim_dist;
o->fov_ = fov_; o->fov_ = fov_;
o->roll_ = roll_; o->roll_ = roll_;
o->mirror_x = mirror_x; o->mirror_x = mirror_x;
o->mirror_y = mirror_y; o->mirror_y = mirror_y;
o->depth_start = depth_start; o->depth_start = depth_start;
o->meta = meta; o->meta = meta;
return o; return o;
} }
QMatrix4x4 Camera::viewMatrix() const { QMatrix4x4 Camera::viewMatrix() const {
QMatrix4x4 ret; QMatrix4x4 ret;
//qDebug() << pos() << aim(); // qDebug() << pos() << aim();
ret.translate(0., 0., -distance()); ret.translate(0., 0., -distance());
ret.rotate(-roll_, 0., 0., 1.); ret.rotate(-roll_, 0., 0., 1.);
ret *= trans.matrixRotateScale().inverted(); ret *= trans.matrixRotateScale().inverted();
if (parent_) { if (parent_) {
QMatrix4x4 pmat = parent_->worldTransform(); QMatrix4x4 pmat = parent_->worldTransform();
offset_ = pmat.column(3).toVector3D(); offset_ = pmat.column(3).toVector3D();
pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.; pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
pmat.translate(aim()); pmat.translate(aim());
ret *= pmat.inverted(); ret *= pmat.inverted();

View File

@@ -1,19 +1,19 @@
/* /*
QGL Camera QGL Camera
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLCAMERA_H #ifndef GLCAMERA_H
@@ -22,29 +22,29 @@
#include "globject.h" #include "globject.h"
class Camera: public AimedObject class Camera: public AimedObject {
{ friend QDataStream & operator<<(QDataStream & s, const ObjectBase * p);
friend QDataStream & operator <<(QDataStream & s, const ObjectBase * p); friend QDataStream & operator>>(QDataStream & s, ObjectBase *& p);
friend QDataStream & operator >>(QDataStream & s, ObjectBase *& p);
public: public:
Camera(); Camera();
void setFOV(const float & f) {fov_ = f;} void setFOV(const float & f) { fov_ = f; }
void setAngles(const QVector3D & a) {setRotation(a);} void setAngles(const QVector3D & a) { setRotation(a); }
void setAngleZ(const float & a) {setRotationZ(a);} void setAngleZ(const float & a) { setRotationZ(a); }
void setAngleXY(const float & a) {setRotationX(a);} void setAngleXY(const float & a) { setRotationX(a); }
void setAngleRoll(const float & a) {roll_ = a;} void setAngleRoll(const float & a) { roll_ = a; }
void setDepthStart(const float & d) {depth_start = d;} void setDepthStart(const float & d) { depth_start = d; }
void setMirrorX(bool yes) {mirror_x = yes;} void setMirrorX(bool yes) { mirror_x = yes; }
void setMirrorY(bool yes) {mirror_y = yes;} void setMirrorY(bool yes) { mirror_y = yes; }
float FOV() const {return fov_;} float FOV() const { return fov_; }
float angleZ() const {return rotationZ();} float angleZ() const { return rotationZ(); }
float angleXY() const {return rotationX();} float angleXY() const { return rotationX(); }
float angleRoll() const {return roll_;} float angleRoll() const { return roll_; }
float depthStart() const {return depth_start;} float depthStart() const { return depth_start; }
bool isMirrorX() const {return mirror_x;} bool isMirrorX() const { return mirror_x; }
bool isMirrorY() const {return mirror_y;} bool isMirrorY() const { return mirror_y; }
void assign(const Camera & c); void assign(const Camera & c);
virtual ObjectBase * clone(bool withChildren = true); virtual ObjectBase * clone(bool withChildren = true);
@@ -52,7 +52,7 @@ public:
QMatrix4x4 projectionMatrix(double aspect) const; QMatrix4x4 projectionMatrix(double aspect) const;
QMatrix4x4 offsetMatrix() const; QMatrix4x4 offsetMatrix() const;
QMatrix4x4 fullViewMatrix() const {return viewMatrix() * offsetMatrix();} QMatrix4x4 fullViewMatrix() const { return viewMatrix() * offsetMatrix(); }
private: private:
mutable QVector3D offset_; mutable QVector3D offset_;

View File

@@ -1,59 +1,61 @@
/* /*
QGL ObjectBase & Light QGL ObjectBase & Light
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "globject.h" #include "globject.h"
#include "glcamera.h" #include "glcamera.h"
#include "glscene.h"
#include "glmesh.h" #include "glmesh.h"
#include "glscene.h"
#include <chunkstream.h> #include <chunkstream.h>
//static int _count = 0; // static int _count = 0;
ObjectBase::ObjectBase(Mesh * geom, Material * mat) { ObjectBase::ObjectBase(Mesh * geom, Material * mat) {
type_ = glMesh; type_ = glMesh;
render_mode = View; render_mode = View;
prev_pass = rpSolid; prev_pass = rpSolid;
parent_ = nullptr; parent_ = nullptr;
color_ = Qt::white; color_ = Qt::white;
is_root = is_init = selected_ = false; is_root = is_init = selected_ = false;
visible_ = accept_fog = accept_light = cast_shadow = rec_shadow = select_ = true; visible_ = accept_fog = accept_light = cast_shadow = rec_shadow = select_ = true;
line_width = -1.; line_width = -1.;
id_ = 0; id_ = 0;
blend_src = GL_SRC_ALPHA; blend_src = GL_SRC_ALPHA;
blend_dest = GL_ONE_MINUS_SRC_ALPHA; blend_dest = GL_ONE_MINUS_SRC_ALPHA;
type_ = glMesh; type_ = glMesh;
raw_matrix = selected_aim = false; raw_matrix = selected_aim = false;
mat_.setToIdentity(); mat_.setToIdentity();
scene_ = nullptr; scene_ = nullptr;
mesh_ = geom; mesh_ = geom;
material_ = mat; material_ = mat;
//qDebug() << "ObjectBase, now" << ++_count; // qDebug() << "ObjectBase, now" << ++_count;
} }
ObjectBase::~ObjectBase() { ObjectBase::~ObjectBase() {
//qDebug() << "~ObjectBase, now" << --_count; // qDebug() << "~ObjectBase, now" << --_count;
if (parent_) parent_->children_.removeAll(this); if (parent_) parent_->children_.removeAll(this);
if (scene_) { if (scene_) {
scene_->__objectDeleted(this); scene_->__objectDeleted(this);
scene_->setTreeChanged(); scene_->setTreeChanged();
scene_->setTreeStructChanged(); scene_->setTreeStructChanged();
} }
foreach (ObjectBase * c, children_) { foreach(ObjectBase * c, children_) {
c->parent_ = nullptr; c->parent_ = nullptr;
delete c; delete c;
} }
@@ -61,27 +63,27 @@ ObjectBase::~ObjectBase() {
ObjectBase * ObjectBase::clone(bool withChildren) { ObjectBase * ObjectBase::clone(bool withChildren) {
ObjectBase * o = new ObjectBase(); ObjectBase * o = new ObjectBase();
o->prev_pass = prev_pass; o->prev_pass = prev_pass;
o->is_init = false; o->is_init = false;
o->accept_light = accept_light; o->accept_light = accept_light;
o->accept_fog = accept_fog; o->accept_fog = accept_fog;
o->visible_ = visible_; o->visible_ = visible_;
o->color_ = color_; o->color_ = color_;
o->type_ = type_; o->type_ = type_;
o->raw_matrix = raw_matrix; o->raw_matrix = raw_matrix;
o->mat_ = mat_; o->mat_ = mat_;
o->trans = trans; o->trans = trans;
o->itransform_ = itransform_; o->itransform_ = itransform_;
o->bound = bound; o->bound = bound;
o->name_ = name_;// + "_copy"; o->name_ = name_; // + "_copy";
o->blend_src = blend_src; o->blend_src = blend_src;
o->blend_dest = blend_dest; o->blend_dest = blend_dest;
o->pos_h = pos_h; o->pos_h = pos_h;
o->material_ = material_; o->material_ = material_;
o->mesh_ = mesh_; o->mesh_ = mesh_;
o->meta = meta; o->meta = meta;
o->scene_ = nullptr; o->scene_ = nullptr;
if (withChildren) { if (withChildren) {
for (int i = 0; i < children_.size(); ++i) for (int i = 0; i < children_.size(); ++i)
o->addChild(children_[i]->clone(withChildren)); o->addChild(children_[i]->clone(withChildren));
@@ -97,8 +99,8 @@ void ObjectBase::destroy() {
void ObjectBase::init() { void ObjectBase::init() {
calculateBoundingBox(); calculateBoundingBox();
//material_.reflection.create(); // material_.reflection.create();
//qDebug() << "init" << vbo.buffer_; // qDebug() << "init" << vbo.buffer_;
is_init = true; is_init = true;
} }
@@ -106,33 +108,31 @@ void ObjectBase::init() {
RenderPass ObjectBase::pass() const { RenderPass ObjectBase::pass() const {
RenderPass ret = rpSolid; RenderPass ret = rpSolid;
if (material_) if (material_)
if (material_->hasTransparency()) if (material_->hasTransparency()) ret = rpTransparent;
ret = rpTransparent;
return ret; return ret;
} }
void ObjectBase::setScene(Scene * v) { void ObjectBase::setScene(Scene * v) {
scene_ = v; scene_ = v;
foreach (ObjectBase * c, children_) foreach(ObjectBase * c, children_)
c->setScene(v); c->setScene(v);
} }
void ObjectBase::addChild(ObjectBase * o) { void ObjectBase::addChild(ObjectBase * o) {
if (o == this) return; if (o == this) return;
if (o->parent_) if (o->parent_) o->parent_->children_.removeAll(o);
o->parent_->children_.removeAll(o);
children_ << o; children_ << o;
o->parent_ = this; o->parent_ = this;
o->setScene(scene_); o->setScene(scene_);
o->buildTransform(); o->buildTransform();
/*if (scene_) { /*if (scene_) {
ObjectBaseList cl = o->children(true); ObjectBaseList cl = o->children(true);
cl << o; cl << o;
//foreach (ObjectBase * i, cl) { //foreach (ObjectBase * i, cl) {
// emit view_->objectAdded(i); // emit view_->objectAdded(i);
//} //}
}*/ }*/
setSceneTreeChanged(); setSceneTreeChanged();
} }
@@ -156,8 +156,8 @@ void ObjectBase::removeChild(int index) {
void ObjectBase::clearChildren(bool deleteAll) { void ObjectBase::clearChildren(bool deleteAll) {
foreach (ObjectBase * i, children_) { foreach(ObjectBase * i, children_) {
i->scene_ = nullptr; i->scene_ = nullptr;
i->parent_ = nullptr; i->parent_ = nullptr;
i->clearChildren(deleteAll); i->clearChildren(deleteAll);
if (deleteAll) { if (deleteAll) {
@@ -178,7 +178,7 @@ ObjectBase * ObjectBase::child(int index) {
ObjectBase * ObjectBase::child(const QString & name) { ObjectBase * ObjectBase::child(const QString & name) {
foreach (ObjectBase * i, children_) foreach(ObjectBase * i, children_)
if (i->name_ == name) return i; if (i->name_ == name) return i;
return nullptr; return nullptr;
} }
@@ -191,7 +191,7 @@ const ObjectBase * ObjectBase::child(int index) const {
const ObjectBase * ObjectBase::child(const QString & name) const { const ObjectBase * ObjectBase::child(const QString & name) const {
foreach (ObjectBase * i, children_) foreach(ObjectBase * i, children_)
if (i->name_ == name) return i; if (i->name_ == name) return i;
return nullptr; return nullptr;
} }
@@ -226,9 +226,9 @@ void ObjectBase::setVisible(bool v) {
void ObjectBase::rotateZ(GLfloat a) { void ObjectBase::rotateZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
trans.setRotationZ(trans.rotationZ() + a); trans.setRotationZ(trans.rotationZ() + a);
//angles_.setZ(angles_.z() + a); // angles_.setZ(angles_.z() + a);
//while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f); // while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
//while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f); // while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
buildTransform(); buildTransform();
} }
@@ -236,9 +236,9 @@ void ObjectBase::rotateZ(GLfloat a) {
void ObjectBase::setRotationZ(GLfloat a) { void ObjectBase::setRotationZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
trans.setRotationZ(a); trans.setRotationZ(a);
//angles_.setZ(a); // angles_.setZ(a);
//while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f); // while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
//while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f); // while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
buildTransform(); buildTransform();
} }
@@ -250,7 +250,7 @@ void ObjectBase::setTransform(const Transform & t) {
void ObjectBase::addChildren(ObjectBaseList & list, ObjectBase * where) { void ObjectBase::addChildren(ObjectBaseList & list, ObjectBase * where) {
foreach (ObjectBase * i, where->children_) { foreach(ObjectBase * i, where->children_) {
list << i; list << i;
addChildren(list, i); addChildren(list, i);
} }
@@ -260,13 +260,13 @@ void ObjectBase::addChildren(ObjectBaseList & list, ObjectBase * where) {
void ObjectBase::calculateBoundingBox() { void ObjectBase::calculateBoundingBox() {
bound = Box3D(); bound = Box3D();
if (mesh_) { if (mesh_) {
bound = mesh_->boundingBox(); bound = mesh_->boundingBox();
QVector<QVector3D> c = bound.corners(), tc; QVector<QVector3D> c = bound.corners(), tc;
foreach (QVector3D p, c) foreach(QVector3D p, c)
tc << (itransform_ * QVector4D(p, 1)).toVector3D(); tc << (itransform_ * QVector4D(p, 1)).toVector3D();
bound = Box3D(tc); bound = Box3D(tc);
} }
foreach (ObjectBase * i, children_) { foreach(ObjectBase * i, children_) {
i->calculateBoundingBox(); i->calculateBoundingBox();
bound |= i->boundingBox(); bound |= i->boundingBox();
} }
@@ -300,10 +300,10 @@ void ObjectBase::removeProperty(const QString & pn) {
void ObjectBase::setMatrix(const QMatrix4x4 & t) { void ObjectBase::setMatrix(const QMatrix4x4 & t) {
//raw_matrix = true; // raw_matrix = true;
//mat_ = t; // mat_ = t;
//pos_ = mat_.column(3).toVector3D(); // pos_ = mat_.column(3).toVector3D();
//mat_.setColumn(3, QVector4D(0., 0., 0., 1.)); // mat_.setColumn(3, QVector4D(0., 0., 0., 1.));
raw_matrix = false; raw_matrix = false;
trans.setMatrix(t); trans.setMatrix(t);
buildTransform(); buildTransform();
@@ -324,10 +324,12 @@ QVector3D ObjectBase::inParentSpace(const QVector3D & v) const {
void ObjectBase::transferTransformToChildren(bool only_scale) { void ObjectBase::transferTransformToChildren(bool only_scale) {
QMatrix4x4 m = trans.matrix(); QMatrix4x4 m = trans.matrix();
if (only_scale) m = trans.matrixScale(); if (only_scale) m = trans.matrixScale();
foreach (ObjectBase * i, children_) foreach(ObjectBase * i, children_)
i->trans.setMatrix(m * i->trans.matrix()); i->trans.setMatrix(m * i->trans.matrix());
if (only_scale) resetScale(); if (only_scale)
else setMatrix(QMatrix4x4()); resetScale();
else
setMatrix(QMatrix4x4());
} }
@@ -356,11 +358,9 @@ bool ObjectBase::isSelected(bool check_parents) const {
void ObjectBase::setSelected(bool yes) { void ObjectBase::setSelected(bool yes) {
//qDebug() << "select" << name() << view_; // qDebug() << "select" << name() << view_;
if (select_) if (select_) selected_ = yes;
selected_ = yes; if (!selected_) selected_aim = false;
if (!selected_)
selected_aim = false;
} }
@@ -377,7 +377,8 @@ ObjectBase * ObjectBase::selectedParent() const {
void ObjectBase::setMaterial(Material * m, bool with_children) { void ObjectBase::setMaterial(Material * m, bool with_children) {
material_ = m; material_ = m;
if (with_children) if (with_children)
foreach (ObjectBase * i, children_) i->setMaterial(m, true); foreach(ObjectBase * i, children_)
i->setMaterial(m, true);
setObjectsChanged(); setObjectsChanged();
if (scene_) scene_->mat_changed = scene_->tree_changed = true; if (scene_) scene_->mat_changed = scene_->tree_changed = true;
} }
@@ -386,14 +387,14 @@ void ObjectBase::setMaterial(Material * m, bool with_children) {
void ObjectBase::setColor(QColor c, bool with_children) { void ObjectBase::setColor(QColor c, bool with_children) {
color_ = c; color_ = c;
if (with_children) if (with_children)
foreach (ObjectBase * i, children_) i->setColor(c, true); foreach(ObjectBase * i, children_)
i->setColor(c, true);
setObjectsChanged(); setObjectsChanged();
} }
void ObjectBase::setMesh(Mesh * v) { void ObjectBase::setMesh(Mesh * v) {
if (scene_) if (scene_) v = scene_->attachMesh(v);
v = scene_->attachMesh(v);
mesh_ = v; mesh_ = v;
setSceneTreeChanged(); setSceneTreeChanged();
setObjectsChanged(); setObjectsChanged();
@@ -404,16 +405,15 @@ void ObjectBase::buildTransform(bool force) {
if (force) trans.setDirty(); if (force) trans.setDirty();
itransform_.setToIdentity(); itransform_.setToIdentity();
ObjectBase * p = parent_; ObjectBase * p = parent_;
if (p) if (p) itransform_ = p->itransform_;
itransform_ = p->itransform_; // if (raw_matrix) {
//if (raw_matrix) {
// itransform_.translate(pos_); // itransform_.translate(pos_);
// itransform_ *= mat_; // itransform_ *= mat_;
// //qDebug() << "raw_matrix" << itransform_; // //qDebug() << "raw_matrix" << itransform_;
//} else // } else
localTransform(itransform_); localTransform(itransform_);
//qDebug() << name_ << itransform_; // qDebug() << name_ << itransform_;
foreach (ObjectBase * i, children_) foreach(ObjectBase * i, children_)
i->buildTransform(force); i->buildTransform(force);
setObjectsChanged(); setObjectsChanged();
} }
@@ -421,7 +421,8 @@ void ObjectBase::buildTransform(bool force) {
void ObjectBase::initInternal() { void ObjectBase::initInternal() {
init(); init();
foreach (ObjectBase * i, children_) i->initInternal(); foreach(ObjectBase * i, children_)
i->initInternal();
} }
@@ -442,10 +443,10 @@ void ObjectBase::setSceneTreeChanged() {
void ObjectBase::setObjectsChanged() { void ObjectBase::setObjectsChanged() {
int p = pass(); int p = pass();
if (mesh_) { if (mesh_) {
mesh_->setObjectsChanged (p, true); mesh_->setObjectsChanged(p, true);
mesh_->setSelectionChanged(p, true); mesh_->setSelectionChanged(p, true);
if (prev_pass != p) { if (prev_pass != p) {
mesh_->setObjectsChanged (prev_pass, true); mesh_->setObjectsChanged(prev_pass, true);
mesh_->setSelectionChanged(prev_pass, true); mesh_->setSelectionChanged(prev_pass, true);
} }
} }
@@ -455,22 +456,20 @@ void ObjectBase::setObjectsChanged() {
QMatrix4x4 ObjectBase::worldMatrix(QMatrix4x4 parent) const { QMatrix4x4 ObjectBase::worldMatrix(QMatrix4x4 parent) const {
QMatrix4x4 mat; QMatrix4x4 mat;
//mat.translate(pos_); // mat.translate(pos_);
//if (raw_matrix) { // if (raw_matrix) {
// mat *= mat_; // mat *= mat_;
//} else { // } else {
// if (angles_.z() != 0.f) mat.rotate(angles_.z(), 0., 0., 1.); // if (angles_.z() != 0.f) mat.rotate(angles_.z(), 0., 0., 1.);
// if (angles_.y() != 0.f) mat.rotate(angles_.y(), 0., 1., 0.); // if (angles_.y() != 0.f) mat.rotate(angles_.y(), 0., 1., 0.);
// if (angles_.x() != 0.f) mat.rotate(angles_.x(), 1., 0., 0.); // if (angles_.x() != 0.f) mat.rotate(angles_.x(), 1., 0., 0.);
// mat.scale(scale_); // mat.scale(scale_);
//} // }
mat = trans.matrix(); mat = trans.matrix();
return parent * mat; return parent * mat;
} }
AimedObject::AimedObject() { AimedObject::AimedObject() {
aim_dist = 1.; aim_dist = 1.;
} }
@@ -487,8 +486,8 @@ void AimedObject::setAim(const QVector3D & p) {
trans.setRotation(Transform::fromDirection(dir, trans.rotationY())); trans.setRotation(Transform::fromDirection(dir, trans.rotationY()));
aim_dist = dir.length(); aim_dist = dir.length();
buildTransform(); buildTransform();
//if (!p.isNull()) // if (!p.isNull())
//qDebug() << "setAim" << p << aim() << worldAim(); // qDebug() << "setAim" << p << aim() << worldAim();
} }
@@ -498,8 +497,8 @@ QVector3D AimedObject::direction() const {
void AimedObject::setDirection(const QVector3D & d) { void AimedObject::setDirection(const QVector3D & d) {
//double len = qMax(aim_.length(), 0.001f); // double len = qMax(aim_.length(), 0.001f);
//aim_ = d.normalized() * len; // aim_ = d.normalized() * len;
buildTransform(); buildTransform();
} }
@@ -521,7 +520,7 @@ void AimedObject::flyFarer(double s) {
void AimedObject::flyToDistance(double d) { void AimedObject::flyToDistance(double d) {
move(direction() * (aim_dist - d)); move(direction() * (aim_dist - d));
aim_dist = d; aim_dist = d;
//qDebug() << d << (aim() - pos()).length() << aim(); // qDebug() << d << (aim() - pos()).length() << aim();
} }
@@ -560,17 +559,13 @@ void AimedObject::orbitXY(const float & a) {
} }
void AimedObject::transformChanged() { void AimedObject::transformChanged() {}
}
Light::Light(): AimedObject(), shadow_map(0, true, GL_R16F) { Light::Light(): AimedObject(), shadow_map(0, true, GL_R16F) {
type_ = glLight; type_ = glLight;
light_type = Omni; light_type = Omni;
intensity = 1.; intensity = 1.;
angle_start = angle_end = 180.; angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.; decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.; decay_const = decay_end = 1.;
@@ -579,10 +574,10 @@ Light::Light(): AimedObject(), shadow_map(0, true, GL_R16F) {
Light::Light(const QVector3D & p, const QColor & c, float i): AimedObject(), shadow_map(0, true, GL_R16F) { Light::Light(const QVector3D & p, const QColor & c, float i): AimedObject(), shadow_map(0, true, GL_R16F) {
type_ = glLight; type_ = glLight;
light_type = Omni; light_type = Omni;
intensity = i; intensity = i;
color_ = c; color_ = c;
angle_start = angle_end = 180.; angle_start = angle_end = 180.;
decay_linear = decay_quadratic = decay_start = 0.; decay_linear = decay_quadratic = decay_start = 0.;
decay_const = decay_end = 1.; decay_const = decay_end = 1.;
@@ -592,27 +587,27 @@ Light::Light(const QVector3D & p, const QColor & c, float i): AimedObject(), sha
ObjectBase * Light::clone(bool withChildren) { ObjectBase * Light::clone(bool withChildren) {
Light * o = new Light(*this); Light * o = new Light(*this);
//GLObjectBase::clone(withChildren); // GLObjectBase::clone(withChildren);
o->is_init = false; o->is_init = false;
o->name_ = name_;// + "_copy"; o->name_ = name_; // + "_copy";
o->scene_ = nullptr; o->scene_ = nullptr;
o->children_.clear(); o->children_.clear();
if (withChildren) { if (withChildren) {
for (int i = 0; i < children_.size(); ++i) for (int i = 0; i < children_.size(); ++i)
o->addChild(children_[i]->clone(withChildren)); o->addChild(children_[i]->clone(withChildren));
} }
o->color_ = color_; o->color_ = color_;
o->light_type = light_type; o->light_type = light_type;
o->trans = trans; o->trans = trans;
o->aim_dist = aim_dist; o->aim_dist = aim_dist;
o->angle_start = angle_start; o->angle_start = angle_start;
o->angle_end = angle_end; o->angle_end = angle_end;
o->intensity = intensity; o->intensity = intensity;
o->decay_const = decay_const; o->decay_const = decay_const;
o->decay_linear = decay_linear; o->decay_linear = decay_linear;
o->decay_quadratic = decay_quadratic; o->decay_quadratic = decay_quadratic;
o->meta = meta; o->meta = meta;
return o; return o;
} }
@@ -622,89 +617,180 @@ void Light::apply() {
} }
QDataStream & operator <<(QDataStream & s, const ObjectBase * p) { QDataStream & operator<<(QDataStream & s, const ObjectBase * p) {
ChunkStream cs; ChunkStream cs;
//qDebug() << "place" << p->name() << "..."; // qDebug() << "place" << p->name() << "...";
cs.add(1, int(p->type_)).add(2, p->accept_light).add(3, p->accept_fog).add(4, p->visible_) cs.add(1, int(p->type_))
.add(5, p->cast_shadow).add(6, p->rec_shadow).add(7, p->raw_matrix).add(8, p->line_width) .add(2, p->accept_light)
.add(9, int(p->render_mode)).add(14, p->mat_).add(16, p->children_.size()) .add(3, p->accept_fog)
.add(17, p->name_).add(18, p->meta).add(19, p->color_).add(20, p->trans); .add(4, p->visible_)
//qDebug() << "place self done"; .add(5, p->cast_shadow)
.add(6, p->rec_shadow)
.add(7, p->raw_matrix)
.add(8, p->line_width)
.add(9, int(p->render_mode))
.add(14, p->mat_)
.add(16, p->children_.size())
.add(17, p->name_)
.add(18, p->meta)
.add(19, p->color_)
.add(20, p->trans);
// qDebug() << "place self done";
if (p->type_ == ObjectBase::glLight) { if (p->type_ == ObjectBase::glLight) {
//qDebug() << "place light ..."; // qDebug() << "place light ...";
const Light * l = (const Light*)p; const Light * l = (const Light *)p;
cs.add(101, l->angle_start).add(102, l->angle_end).add(103, l->intensity) cs.add(101, l->angle_start)
.add(104, l->decay_const).add(105, l->decay_linear).add(106, l->decay_quadratic) .add(102, l->angle_end)
.add(107, l->decay_start).add(108, l->decay_end).add(109, int(l->light_type)) .add(103, l->intensity)
.add(111, l->distance()); .add(104, l->decay_const)
.add(105, l->decay_linear)
.add(106, l->decay_quadratic)
.add(107, l->decay_start)
.add(108, l->decay_end)
.add(109, int(l->light_type))
.add(111, l->distance());
} }
if (p->type_ == ObjectBase::glCamera) { if (p->type_ == ObjectBase::glCamera) {
//qDebug() << "place camera ..."; // qDebug() << "place camera ...";
const Camera * c = (const Camera*)p; const Camera * c = (const Camera *)p;
cs.add(200, c->aim()).add(201, c->fov_).add(202, c->depth_start) cs.add(200, c->aim())
.add(206, c->mirror_x).add(207, c->mirror_y).add(208, c->distance()) .add(201, c->fov_)
.add(209, c->roll_); .add(202, c->depth_start)
.add(206, c->mirror_x)
.add(207, c->mirror_y)
.add(208, c->distance())
.add(209, c->roll_);
} }
//qDebug() << "place" << p->name() << cs.data().size() << s.device()->size(); // qDebug() << "place" << p->name() << cs.data().size() << s.device()->size();
s << cs.data(); s << cs.data();
foreach (const ObjectBase * c, p->children_) foreach(const ObjectBase * c, p->children_)
s << c; s << c;
return s; return s;
} }
QDataStream & operator >>(QDataStream & s, ObjectBase *& p) { QDataStream & operator>>(QDataStream & s, ObjectBase *& p) {
ChunkStream cs(s); ChunkStream cs(s);
p = nullptr; p = nullptr;
int ccnt = 0; int ccnt = 0;
Light * l = nullptr; Light * l = nullptr;
Camera * c = nullptr; Camera * c = nullptr;
//qDebug() << "read obj ..."; // qDebug() << "read obj ...";
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
case 1: { case 1: {
ObjectBase::Type type = (ObjectBase::Type)cs.getData<int>(); ObjectBase::Type type = (ObjectBase::Type)cs.getData<int>();
switch (type) { switch (type) {
case ObjectBase::glMesh: p = new ObjectBase(); break; case ObjectBase::glMesh: p = new ObjectBase(); break;
case ObjectBase::glLight: p = new Light(); l = (Light*)p; break; case ObjectBase::glLight:
case ObjectBase::glCamera: p = new Camera(); c = (Camera*)p; break; p = new Light();
default : break; l = (Light *)p;
break;
case ObjectBase::glCamera:
p = new Camera();
c = (Camera *)p;
break;
default: break;
} }
if (p) p->type_ = type; if (p) p->type_ = type;
} break; } break;
case 2: if (p) p->accept_light = cs.getData<bool>(); break; case 2:
case 3: if (p) p->accept_fog = cs.getData<bool>(); break; if (p) p->accept_light = cs.getData<bool>();
case 4: if (p) p->visible_ = cs.getData<bool>(); break; break;
case 5: if (p) p->cast_shadow = cs.getData<bool>(); break; case 3:
case 6: if (p) p->rec_shadow = cs.getData<bool>(); break; if (p) p->accept_fog = cs.getData<bool>();
case 7: if (p) p->raw_matrix = cs.getData<bool>(); break; break;
case 8: if (p) p->line_width = cs.getData<float>(); break; case 4:
case 9: if (p) p->render_mode = (ObjectBase::RenderMode)cs.getData<int>(); break; if (p) p->visible_ = cs.getData<bool>();
case 14: if (p) p->mat_ = cs.getData<QMatrix4x4>(); break; break;
case 16: if (p) ccnt = cs.getData<int>(); break; case 5:
case 17: if (p) p->name_ = cs.getData<QString>(); break; if (p) p->cast_shadow = cs.getData<bool>();
case 18: if (p) p->meta = cs.getData<QVariantMap>(); break; break;
case 19: if (p) p->color_ = cs.getData<QColor>(); break; case 6:
case 20: if (p) p->trans = cs.getData<Transform>(); break; if (p) p->rec_shadow = cs.getData<bool>();
case 100: if (l) l->setAim(cs.getData<QVector3D>()); break; break;
case 101: if (l) l->angle_start = cs.getData<GLfloat>(); break; case 7:
case 102: if (l) l->angle_end = cs.getData<GLfloat>(); break; if (p) p->raw_matrix = cs.getData<bool>();
case 103: if (l) l->intensity = cs.getData<GLfloat>(); break; break;
case 104: if (l) l->decay_const = cs.getData<GLfloat>(); break; case 8:
case 105: if (l) l->decay_linear = cs.getData<GLfloat>(); break; if (p) p->line_width = cs.getData<float>();
case 106: if (l) l->decay_quadratic = cs.getData<GLfloat>(); break; break;
case 107: if (l) l->decay_start = cs.getData<GLfloat>(); break; case 9:
case 108: if (l) l->decay_end = cs.getData<GLfloat>(); break; if (p) p->render_mode = (ObjectBase::RenderMode)cs.getData<int>();
case 109: if (l) l->light_type = (Light::Type)cs.getData<int>(); break; break;
case 111: if (l) l->setDistance(cs.getData<double>()); break; case 14:
case 200: if (c) c->setAim(cs.getData<QVector3D>()); break; if (p) p->mat_ = cs.getData<QMatrix4x4>();
case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break; break;
case 202: if (c) c->setDepthStart(cs.getData<GLfloat>()); break; case 16:
case 206: if (c) c->mirror_x = cs.getData<bool>(); break; if (p) ccnt = cs.getData<int>();
case 207: if (c) c->mirror_y = cs.getData<bool>(); break; break;
case 208: if (c) c->setDistance(cs.getData<double>()); break; case 17:
case 209: if (c) c->roll_ = cs.getData<GLfloat>(); break; if (p) p->name_ = cs.getData<QString>();
break;
case 18:
if (p) p->meta = cs.getData<QVariantMap>();
break;
case 19:
if (p) p->color_ = cs.getData<QColor>();
break;
case 20:
if (p) p->trans = cs.getData<Transform>();
break;
case 100:
if (l) l->setAim(cs.getData<QVector3D>());
break;
case 101:
if (l) l->angle_start = cs.getData<GLfloat>();
break;
case 102:
if (l) l->angle_end = cs.getData<GLfloat>();
break;
case 103:
if (l) l->intensity = cs.getData<GLfloat>();
break;
case 104:
if (l) l->decay_const = cs.getData<GLfloat>();
break;
case 105:
if (l) l->decay_linear = cs.getData<GLfloat>();
break;
case 106:
if (l) l->decay_quadratic = cs.getData<GLfloat>();
break;
case 107:
if (l) l->decay_start = cs.getData<GLfloat>();
break;
case 108:
if (l) l->decay_end = cs.getData<GLfloat>();
break;
case 109:
if (l) l->light_type = (Light::Type)cs.getData<int>();
break;
case 111:
if (l) l->setDistance(cs.getData<double>());
break;
case 200:
if (c) c->setAim(cs.getData<QVector3D>());
break;
case 201:
if (c) c->setFOV(cs.getData<GLfloat>());
break;
case 202:
if (c) c->setDepthStart(cs.getData<GLfloat>());
break;
case 206:
if (c) c->mirror_x = cs.getData<bool>();
break;
case 207:
if (c) c->mirror_y = cs.getData<bool>();
break;
case 208:
if (c) c->setDistance(cs.getData<double>());
break;
case 209:
if (c) c->roll_ = cs.getData<GLfloat>();
break;
} }
} }
//qDebug() << p->name() << ccnt; // qDebug() << p->name() << ccnt;
for (int i = 0; i < ccnt; ++i) { for (int i = 0; i < ccnt; ++i) {
ObjectBase * c = nullptr; ObjectBase * c = nullptr;
s >> c; s >> c;

View File

@@ -1,19 +1,19 @@
/* /*
QGL ObjectBase & Light QGL ObjectBase & Light
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLOBJECT_H #ifndef GLOBJECT_H
@@ -21,20 +21,30 @@
#include "glframebuffer.h" #include "glframebuffer.h"
#include "glmaterial.h" #include "glmaterial.h"
#include "gltypes.h"
#include "gltransform.h" #include "gltransform.h"
#include "gltypes.h"
class ObjectBase class ObjectBase {
{
friend class Scene; friend class Scene;
friend class RendererSelection; friend class RendererSelection;
friend QDataStream & operator <<(QDataStream & s, const ObjectBase * p); friend QDataStream & operator<<(QDataStream & s, const ObjectBase * p);
friend QDataStream & operator >>(QDataStream & s, ObjectBase *& p); friend QDataStream & operator>>(QDataStream & s, ObjectBase *& p);
friend QDataStream & operator >>(QDataStream & s, Scene *& p); friend QDataStream & operator>>(QDataStream & s, Scene *& p);
public: public:
enum Type {glMesh, glLight, glCamera, glParticlesSystem}; enum Type {
enum RenderMode {View = 0, Point = GL_POINT, Line = GL_LINE, Fill = GL_FILL}; glMesh,
glLight,
glCamera,
glParticlesSystem
};
enum RenderMode {
View = 0,
Point = GL_POINT,
Line = GL_LINE,
Fill = GL_FILL
};
explicit ObjectBase(Mesh * geom = 0, Material * mat = 0); explicit ObjectBase(Mesh * geom = 0, Material * mat = 0);
virtual ~ObjectBase(); virtual ~ObjectBase();
@@ -42,32 +52,32 @@ public:
virtual ObjectBase * clone(bool withChildren = true); virtual ObjectBase * clone(bool withChildren = true);
void destroy(); void destroy();
QString name() const {return name_;} QString name() const { return name_; }
void setName(const QString & name) {name_ = name;} void setName(const QString & name) { name_ = name; }
virtual void init(); virtual void init();
virtual void update() {} virtual void update() {}
bool isInit() const {return is_init;} bool isInit() const { return is_init; }
Type type() const {return type_;} Type type() const { return type_; }
RenderPass pass() const; RenderPass pass() const;
uint id() const {return id_;} uint id() const { return id_; }
RenderMode renderMode() const {return render_mode;} RenderMode renderMode() const { return render_mode; }
void setRenderMode(RenderMode mode) {render_mode = mode;} void setRenderMode(RenderMode mode) { render_mode = mode; }
float lineWidth() const {return line_width;} float lineWidth() const { return line_width; }
void setLineWidth(const float & width) {line_width = width;} void setLineWidth(const float & width) { line_width = width; }
ObjectBase * parent() {return parent_;} ObjectBase * parent() { return parent_; }
void setParent(ObjectBase * o) {parent_ = o;} void setParent(ObjectBase * o) { parent_ = o; }
bool hasParent() const {return parent_ != nullptr;} bool hasParent() const { return parent_ != nullptr; }
bool hasChildren() const {return !children_.isEmpty();} bool hasChildren() const { return !children_.isEmpty(); }
void setScene(Scene * v); void setScene(Scene * v);
void addChild(ObjectBase * o); void addChild(ObjectBase * o);
void removeChild(ObjectBase * o); void removeChild(ObjectBase * o);
void removeChild(int index); void removeChild(int index);
void clearChildren(bool deleteAll = false); void clearChildren(bool deleteAll = false);
int childCount() const {return children_.size();} int childCount() const { return children_.size(); }
ObjectBase * child(int index); ObjectBase * child(int index);
ObjectBase * child(const QString & name); ObjectBase * child(const QString & name);
const ObjectBase * child(int index) const; const ObjectBase * child(int index) const;
@@ -75,109 +85,224 @@ public:
ObjectBaseList children(bool all_ = false); ObjectBaseList children(bool all_ = false);
bool isVisible(bool check_parents = false) const; bool isVisible(bool check_parents = false) const;
bool isHidden(bool check_parents = false) const {return !isVisible(check_parents);} bool isHidden(bool check_parents = false) const { return !isVisible(check_parents); }
void setVisible(bool v); void setVisible(bool v);
void setHidden(bool v) {setVisible(!v);} void setHidden(bool v) { setVisible(!v); }
void show() {setVisible(true);} void show() { setVisible(true); }
void hide() {setVisible(false);} void hide() { setVisible(false); }
bool isReceiveShadows() const {return rec_shadow;} bool isReceiveShadows() const { return rec_shadow; }
bool isCastShadows() const {return cast_shadow;} bool isCastShadows() const { return cast_shadow; }
void setReceiveShadows(bool on) {rec_shadow = on;} void setReceiveShadows(bool on) { rec_shadow = on; }
void setCastShadows(bool on) {cast_shadow = on;} void setCastShadows(bool on) { cast_shadow = on; }
void move(const QVector3D & dv) {trans.setTranslation(pos() + dv); buildTransform();} void move(const QVector3D & dv) {
void moveTo(const QVector3D & dv) {trans.setTranslation(dv); buildTransform();} trans.setTranslation(pos() + dv);
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {move(QVector3D(dx, dy, dz)); buildTransform();} buildTransform();
void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {moveTo(QVector3D(dx, dy, dz)); buildTransform();} }
void moveX(GLfloat o) {trans.setTranslationX(posX() + o); buildTransform();} void moveTo(const QVector3D & dv) {
void moveY(GLfloat o) {trans.setTranslationY(posY() + o); buildTransform();} trans.setTranslation(dv);
void moveZ(GLfloat o) {trans.setTranslationZ(posZ() + o); buildTransform();} buildTransform();
void setPosX(GLfloat o) {trans.setTranslationX(o); buildTransform();} }
void setPosY(GLfloat o) {trans.setTranslationY(o); buildTransform();} void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
void setPosZ(GLfloat o) {trans.setTranslationZ(o); buildTransform();} move(QVector3D(dx, dy, dz));
void setPos(GLfloat x, GLfloat y, GLfloat z) {trans.setTranslation(QVector3D(x, y, z)); buildTransform();} buildTransform();
void setPos(const QVector3D & p) {trans.setTranslation(p); buildTransform();} }
void resetPos() {trans.setTranslation(QVector3D()); buildTransform();} void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
moveTo(QVector3D(dx, dy, dz));
buildTransform();
}
void moveX(GLfloat o) {
trans.setTranslationX(posX() + o);
buildTransform();
}
void moveY(GLfloat o) {
trans.setTranslationY(posY() + o);
buildTransform();
}
void moveZ(GLfloat o) {
trans.setTranslationZ(posZ() + o);
buildTransform();
}
void setPosX(GLfloat o) {
trans.setTranslationX(o);
buildTransform();
}
void setPosY(GLfloat o) {
trans.setTranslationY(o);
buildTransform();
}
void setPosZ(GLfloat o) {
trans.setTranslationZ(o);
buildTransform();
}
void setPos(GLfloat x, GLfloat y, GLfloat z) {
trans.setTranslation(QVector3D(x, y, z));
buildTransform();
}
void setPos(const QVector3D & p) {
trans.setTranslation(p);
buildTransform();
}
void resetPos() {
trans.setTranslation(QVector3D());
buildTransform();
}
QVector3D pos() const {return trans.translation();} QVector3D pos() const { return trans.translation(); }
float posX() const {return trans.translation().x();} float posX() const { return trans.translation().x(); }
float posY() const {return trans.translation().y();} float posY() const { return trans.translation().y(); }
float posZ() const {return trans.translation().z();} float posZ() const { return trans.translation().z(); }
QVector3D worldPos() const {return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D();} QVector3D worldPos() const { return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D(); }
QMatrix4x4 worldTransform() const {return itransform_;} QMatrix4x4 worldTransform() const { return itransform_; }
QVector3D rotation() const {return trans.rotation();} QVector3D rotation() const { return trans.rotation(); }
float rotationX() const {return rotation().x();} float rotationX() const { return rotation().x(); }
float rotationY() const {return rotation().y();} float rotationY() const { return rotation().y(); }
float rotationZ() const {return rotation().z();} float rotationZ() const { return rotation().z(); }
void rotateX(GLfloat a) {raw_matrix = false; trans.setRotationX(trans.rotationX() + a); buildTransform();} void rotateX(GLfloat a) {
void rotateY(GLfloat a) {raw_matrix = false; trans.setRotationY(trans.rotationY() + a); buildTransform();} raw_matrix = false;
trans.setRotationX(trans.rotationX() + a);
buildTransform();
}
void rotateY(GLfloat a) {
raw_matrix = false;
trans.setRotationY(trans.rotationY() + a);
buildTransform();
}
void rotateZ(GLfloat a); void rotateZ(GLfloat a);
void setRotationX(GLfloat a) {raw_matrix = false; trans.setRotationX(a); buildTransform();} void setRotationX(GLfloat a) {
void setRotationY(GLfloat a) {raw_matrix = false; trans.setRotationY(a); buildTransform();} raw_matrix = false;
trans.setRotationX(a);
buildTransform();
}
void setRotationY(GLfloat a) {
raw_matrix = false;
trans.setRotationY(a);
buildTransform();
}
void setRotationZ(GLfloat a); void setRotationZ(GLfloat a);
void setRotation(const QVector3D & a) {raw_matrix = false; trans.setRotation(a); buildTransform();} void setRotation(const QVector3D & a) {
void resetRotation() {raw_matrix = false; trans.setRotation(QVector3D()); buildTransform();} raw_matrix = false;
trans.setRotation(a);
buildTransform();
}
void resetRotation() {
raw_matrix = false;
trans.setRotation(QVector3D());
buildTransform();
}
QVector3D scale() {return trans.scale3D();} QVector3D scale() { return trans.scale3D(); }
float scaleX() {return trans.scale3D().x();} float scaleX() { return trans.scale3D().x(); }
float scaleY() {return trans.scale3D().y();} float scaleY() { return trans.scale3D().y(); }
float scaleZ() {return trans.scale3D().z();} float scaleZ() { return trans.scale3D().z(); }
void scale(const QVector3D & sv) {raw_matrix = false; trans.setScale(trans.scale3D() * sv); buildTransform();} void scale(const QVector3D & sv) {
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {raw_matrix = false; scale(QVector3D(sx, sy, sz)); buildTransform();} raw_matrix = false;
void scale(GLfloat sx, GLfloat sy) {raw_matrix = false; scale(QVector3D(sx, sy, sy)); buildTransform();} trans.setScale(trans.scale3D() * sv);
void scale(GLfloat sx) {raw_matrix = false; scale(QVector3D(sx, sx, sx)); buildTransform();} buildTransform();
void scaleX(GLfloat a) {raw_matrix = false; trans.setScaleX(trans.scale3D().x() + a); buildTransform();} }
void scaleY(GLfloat a) {raw_matrix = false; trans.setScaleY(trans.scale3D().y() + a); buildTransform();} void scale(GLfloat sx, GLfloat sy, GLfloat sz) {
void scaleZ(GLfloat a) {raw_matrix = false; trans.setScaleZ(trans.scale3D().z() + a); buildTransform();} raw_matrix = false;
void setScale(const QVector3D & a) {raw_matrix = false; trans.setScale(a); buildTransform();} scale(QVector3D(sx, sy, sz));
void setScale(GLfloat a) {raw_matrix = false; trans.setScale(a); buildTransform();} buildTransform();
void setScaleX(GLfloat a) {raw_matrix = false; trans.setScaleX(a); buildTransform();} }
void setScaleY(GLfloat a) {raw_matrix = false; trans.setScaleY(a); buildTransform();} void scale(GLfloat sx, GLfloat sy) {
void setScaleZ(GLfloat a) {raw_matrix = false; trans.setScaleZ(a); buildTransform();} raw_matrix = false;
void resetScale() {raw_matrix = false; trans.setScale(1.f); buildTransform();} scale(QVector3D(sx, sy, sy));
buildTransform();
Transform transform() {return trans;} }
void scale(GLfloat sx) {
raw_matrix = false;
scale(QVector3D(sx, sx, sx));
buildTransform();
}
void scaleX(GLfloat a) {
raw_matrix = false;
trans.setScaleX(trans.scale3D().x() + a);
buildTransform();
}
void scaleY(GLfloat a) {
raw_matrix = false;
trans.setScaleY(trans.scale3D().y() + a);
buildTransform();
}
void scaleZ(GLfloat a) {
raw_matrix = false;
trans.setScaleZ(trans.scale3D().z() + a);
buildTransform();
}
void setScale(const QVector3D & a) {
raw_matrix = false;
trans.setScale(a);
buildTransform();
}
void setScale(GLfloat a) {
raw_matrix = false;
trans.setScale(a);
buildTransform();
}
void setScaleX(GLfloat a) {
raw_matrix = false;
trans.setScaleX(a);
buildTransform();
}
void setScaleY(GLfloat a) {
raw_matrix = false;
trans.setScaleY(a);
buildTransform();
}
void setScaleZ(GLfloat a) {
raw_matrix = false;
trans.setScaleZ(a);
buildTransform();
}
void resetScale() {
raw_matrix = false;
trans.setScale(1.f);
buildTransform();
}
Transform transform() { return trans; }
void setTransform(const Transform & t); void setTransform(const Transform & t);
void setMatrix(const QMatrix4x4 & t); void setMatrix(const QMatrix4x4 & t);
QMatrix4x4 matrix() const; QMatrix4x4 matrix() const;
bool isRawMatrix() {return raw_matrix;} bool isRawMatrix() { return raw_matrix; }
QVector3D inParentSpace(const QVector3D & v) const; QVector3D inParentSpace(const QVector3D & v) const;
void transferTransformToChildren(bool only_scale = false); void transferTransformToChildren(bool only_scale = false);
void cleanTree(); void cleanTree();
bool isAcceptLight() const {return accept_light;} bool isAcceptLight() const { return accept_light; }
void setAcceptLight(bool yes) {accept_light = yes;} void setAcceptLight(bool yes) { accept_light = yes; }
bool isAcceptFog() const {return accept_fog;} bool isAcceptFog() const { return accept_fog; }
void setAcceptFog(bool yes) {accept_fog = yes;} void setAcceptFog(bool yes) { accept_fog = yes; }
bool isSelected(bool check_parents = false) const; bool isSelected(bool check_parents = false) const;
void setSelected(bool yes); void setSelected(bool yes);
void select() {setSelected(true);} void select() { setSelected(true); }
void deselect() {setSelected(false);} void deselect() { setSelected(false); }
ObjectBase * selectedParent() const; ObjectBase * selectedParent() const;
void setAimSelected(bool yes) {selected_aim = yes;} void setAimSelected(bool yes) { selected_aim = yes; }
bool isAimSelected() const {return selected_aim;} bool isAimSelected() const { return selected_aim; }
bool isSelectable() const {return select_;} bool isSelectable() const { return select_; }
void setSelectable(bool yes) {select_ = yes;} void setSelectable(bool yes) { select_ = yes; }
GLenum srcAlpha() const {return blend_src;} GLenum srcAlpha() const { return blend_src; }
GLenum destAlpha() const {return blend_dest;} GLenum destAlpha() const { return blend_dest; }
void setSrcAlpha(GLenum mode) {blend_src = mode;} void setSrcAlpha(GLenum mode) { blend_src = mode; }
void setDestAlpha(GLenum mode) {blend_dest = mode;} void setDestAlpha(GLenum mode) { blend_dest = mode; }
void setMaterial(Material * m, bool with_children = false); void setMaterial(Material * m, bool with_children = false);
Material * material() {return material_;} Material * material() { return material_; }
void setColor(QColor c, bool with_children = false); void setColor(QColor c, bool with_children = false);
QColor color() {return color_;} QColor color() { return color_; }
const Box3D & boundingBox() const {return bound;} const Box3D & boundingBox() const { return bound; }
void setMesh(Mesh * v); void setMesh(Mesh * v);
Mesh * mesh() {return mesh_;} Mesh * mesh() { return mesh_; }
void calculateBoundingBox(); void calculateBoundingBox();
void updateTransform(); void updateTransform();
@@ -220,7 +345,9 @@ protected:
QVariantMap meta; QVariantMap meta;
}; };
inline bool operator <(const ObjectBase & f, const ObjectBase & s) {return f.pos_h.z() < s.pos_h.z();} inline bool operator<(const ObjectBase & f, const ObjectBase & s) {
return f.pos_h.z() < s.pos_h.z();
}
class AimedObject: public ObjectBase { class AimedObject: public ObjectBase {
@@ -228,31 +355,32 @@ class AimedObject: public ObjectBase {
friend class GLRendererBase; friend class GLRendererBase;
friend class Light; friend class Light;
friend class Camera; friend class Camera;
public: public:
AimedObject(); AimedObject();
~AimedObject() {} ~AimedObject() {}
QVector3D aim() const {return pos() + (direction() * aim_dist);} QVector3D aim() const { return pos() + (direction() * aim_dist); }
QVector3D worldAim() const; QVector3D worldAim() const;
void setAim(const QVector3D & p); void setAim(const QVector3D & p);
QVector3D direction() const; QVector3D direction() const;
QVector3D worldDirection() const {return (itransform_ * QVector4D(QVector3D(0,0,-1), 0.)).toVector3D().normalized();} QVector3D worldDirection() const { return (itransform_ * QVector4D(QVector3D(0, 0, -1), 0.)).toVector3D().normalized(); }
void setDirection(const QVector3D & d); void setDirection(const QVector3D & d);
void setDirection(double x, double y, double z) {setDirection(QVector3D(x, y, z));} void setDirection(double x, double y, double z) { setDirection(QVector3D(x, y, z)); }
double distance() const {return aim_dist;} double distance() const { return aim_dist; }
void setDistance(double d) {aim_dist = d;} void setDistance(double d) { aim_dist = d; }
void flyCloser(double s); void flyCloser(double s);
void flyFarer(double s); void flyFarer(double s);
void flyToDistance(double d); void flyToDistance(double d);
void moveForward(const float & x, bool withZ = true); void moveForward(const float & x, bool withZ = true);
void moveBackward(const float & x, bool withZ = true) {moveForward(-x, withZ);} void moveBackward(const float & x, bool withZ = true) { moveForward(-x, withZ); }
void moveLeft(const float & x, bool withZ = true); void moveLeft(const float & x, bool withZ = true);
void moveRight(const float & x, bool withZ = true) {moveLeft(-x, withZ);} void moveRight(const float & x, bool withZ = true) { moveLeft(-x, withZ); }
void moveUp(const float & x, bool onlyZ = false); void moveUp(const float & x, bool onlyZ = false);
void moveDown(const float & x, bool onlyZ = false) {moveUp(-x, onlyZ);} void moveDown(const float & x, bool onlyZ = false) { moveUp(-x, onlyZ); }
void rotateRoll(const float & a) {rotateY(a);} void rotateRoll(const float & a) { rotateY(a); }
void orbitZ(const float & a); void orbitZ(const float & a);
void orbitXY(const float & a); void orbitXY(const float & a);
@@ -265,13 +393,21 @@ protected:
class Light: public AimedObject { class Light: public AimedObject {
friend class QGLView; friend class QGLView;
friend class RendererBase; friend class RendererBase;
public: public:
enum Type {Omni, Cone, Directional}; enum Type {
Omni,
Cone,
Directional
};
Light(); Light();
Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.); Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.);
virtual ObjectBase * clone(bool withChildren = true); virtual ObjectBase * clone(bool withChildren = true);
virtual void init() {shadow_map.resize(512, 512); is_init = true;} virtual void init() {
shadow_map.resize(512, 512);
is_init = true;
}
void apply(); void apply();
float angle_start; float angle_start;
@@ -287,17 +423,31 @@ public:
QMatrix4x4 shadow_matrix; QMatrix4x4 shadow_matrix;
}; };
template <class T> template<class T>
inline T globject_cast(ObjectBase * object) {return reinterpret_cast<T>(object);} inline T globject_cast(ObjectBase * object) {
return reinterpret_cast<T>(object);
}
template <class T> template<class T>
inline T globject_cast(const ObjectBase * object) {return reinterpret_cast<T>(object);} inline T globject_cast(const ObjectBase * object) {
return reinterpret_cast<T>(object);
}
QDataStream & operator <<(QDataStream & s, const ObjectBase * p); QDataStream & operator<<(QDataStream & s, const ObjectBase * p);
QDataStream & operator >>(QDataStream & s, ObjectBase *& p); QDataStream & operator>>(QDataStream & s, ObjectBase *& p);
inline ObjectBaseList lights2objectList(const QList<Light*> & v) {ObjectBaseList ret; foreach (Light*i, v) ret << (ObjectBase*)i; return ret;} inline ObjectBaseList lights2objectList(const QList<Light *> & v) {
inline ObjectBaseList cameras2objectList(const QList<Camera*> & v) {ObjectBaseList ret; foreach (Camera*i, v) ret << (ObjectBase*)i; return ret;} ObjectBaseList ret;
foreach(Light * i, v)
ret << (ObjectBase *)i;
return ret;
}
inline ObjectBaseList cameras2objectList(const QList<Camera *> & v) {
ObjectBaseList ret;
foreach(Camera * i, v)
ret << (ObjectBase *)i;
return ret;
}
#endif // GLOBJECT_H #endif // GLOBJECT_H

View File

@@ -1,25 +1,27 @@
/* /*
QGL Scene QGL Scene
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "glscene.h" #include "glscene.h"
#include "glcamera.h" #include "glcamera.h"
#include "glmesh.h" #include "glmesh.h"
#include "qglview.h" #include "qglview.h"
#include <chunkstream.h> #include <chunkstream.h>
@@ -27,9 +29,9 @@ Scene::Scene() {
root_ = new ObjectBase(); root_ = new ObjectBase();
root_->setScene(this); root_->setScene(this);
tree_changed = mat_changed = lights_changed = true; tree_changed = mat_changed = lights_changed = true;
destroying = false; destroying = false;
need_reload_materials = tree_struct_changed = true; need_reload_materials = tree_struct_changed = true;
sel_mode_ = smSingleSelection; sel_mode_ = smSingleSelection;
} }
@@ -41,9 +43,9 @@ Scene::~Scene() {
Scene * Scene::clone() { Scene * Scene::clone() {
Scene * ret = new Scene(); Scene * ret = new Scene();
ObjectBase * o = root_->clone(); ObjectBase * o = root_->clone();
foreach (ObjectBase * co, o->children()) foreach(ObjectBase * co, o->children())
ret->addObject(co); ret->addObject(co);
o->clearChildren(); o->clearChildren();
delete o; delete o;
@@ -54,7 +56,7 @@ Scene * Scene::clone() {
void Scene::addObject(ObjectBase * o) { void Scene::addObject(ObjectBase * o) {
ObjectBaseList aol = o->children(true); ObjectBaseList aol = o->children(true);
attachObject(o); attachObject(o);
foreach (ObjectBase * c, aol) foreach(ObjectBase * c, aol)
attachObject(c); attachObject(c);
root_->addChild(o); root_->addChild(o);
tree_changed = tree_struct_changed = true; tree_changed = tree_struct_changed = true;
@@ -63,13 +65,13 @@ void Scene::addObject(ObjectBase * o) {
void Scene::addScene(const Scene * s) { void Scene::addScene(const Scene * s) {
if (!s) return; if (!s) return;
//qDebug() << "addScene clone ..."; // qDebug() << "addScene clone ...";
ObjectBase * o = s->root_->clone(); ObjectBase * o = s->root_->clone();
o->setName(s->name()); o->setName(s->name());
//qDebug() << "addScene clone ok" << o << o->children(true).size(); // qDebug() << "addScene clone ok" << o << o->children(true).size();
addObject(o); addObject(o);
makeMaterialsUniqueNames(); makeMaterialsUniqueNames();
//qDebug() << "addScene add ok" << o; // qDebug() << "addScene add ok" << o;
} }
@@ -77,16 +79,16 @@ void Scene::assignFrom(const Scene * s) {
clear(); clear();
if (!s) return; if (!s) return;
setName(s->name()); setName(s->name());
foreach (Material * m, s->materials) { foreach(Material * m, s->materials) {
Material * nm = new Material(); Material * nm = new Material();
*nm = *m; *nm = *m;
nm->_changed = true; nm->_changed = true;
nm->setMapsChanged(); nm->setMapsChanged();
materials << nm; materials << nm;
} }
for (int i = 0; i < s->root_->childCount(); ++i) { for (int i = 0; i < s->root_->childCount(); ++i) {
addObject(s->root_->child(i)->clone()); addObject(s->root_->child(i)->clone());
//qDebug() << i << o->child(i)->pos(); // qDebug() << i << o->child(i)->pos();
} }
tree_changed = mat_changed = lights_changed = need_reload_materials = tree_struct_changed = true; tree_changed = mat_changed = lights_changed = need_reload_materials = tree_struct_changed = true;
} }
@@ -113,14 +115,14 @@ void Scene::reinitAll() {
i->reinit(); i->reinit();
setTreeChanged(); setTreeChanged();
mat_changed = lights_changed = true; mat_changed = lights_changed = true;
need_reload_materials = true; need_reload_materials = true;
tree_struct_changed = true; tree_struct_changed = true;
} }
void Scene::objectsCountInternal(int * cnt, ObjectBase * where) { void Scene::objectsCountInternal(int * cnt, ObjectBase * where) {
++(*cnt); ++(*cnt);
foreach (ObjectBase * i, where->children()) foreach(ObjectBase * i, where->children())
objectsCountInternal(cnt, i); objectsCountInternal(cnt, i);
} }
int Scene::objectsCount(bool all) { int Scene::objectsCount(bool all) {
@@ -133,7 +135,7 @@ int Scene::objectsCount(bool all) {
void Scene::removeObjectInternal(ObjectBase * o, ObjectBase * where) { void Scene::removeObjectInternal(ObjectBase * o, ObjectBase * where) {
if (destroying) return; if (destroying) return;
foreach (ObjectBase * i, where->children()) { foreach(ObjectBase * i, where->children()) {
if (o == i) { if (o == i) {
where->removeChild(i); where->removeChild(i);
setObjectMeshChanged(i); setObjectMeshChanged(i);
@@ -145,30 +147,29 @@ void Scene::removeObjectInternal(ObjectBase * o, ObjectBase * where) {
void Scene::emitSelectionChanged() { void Scene::emitSelectionChanged() {
selected_top.clear(); selected_top.clear();
foreach (ObjectBase * o, selected_) { foreach(ObjectBase * o, selected_) {
ObjectBase * po = o->selectedParent(); ObjectBase * po = o->selectedParent();
if (!po) po = o; if (!po) po = o;
if (!selected_top.contains(po)) if (!selected_top.contains(po)) selected_top << po;
selected_top << po;
} }
foreach (Mesh * m, geometries) foreach(Mesh * m, geometries)
m->setAllSelectionChanged(true); m->setAllSelectionChanged(true);
selectionChanged(); selectionChanged();
} }
QString Scene::uniqueName(QString n, const QSet<QString> & names) { QString Scene::uniqueName(QString n, const QSet<QString> & names) {
if (!names.contains(n)) if (!names.contains(n)) return n;
return n;
QString num; QString num;
while (!n.isEmpty()) { while (!n.isEmpty()) {
if (n.right(1)[0].isDigit()) { if (n.right(1)[0].isDigit()) {
num.push_front(n.right(1)); num.push_front(n.right(1));
n.chop(1); n.chop(1);
} else break; } else
break;
} }
if (!n.endsWith('_')) n += '_'; if (!n.endsWith('_')) n += '_';
int in = num.toInt() + 1; int in = num.toInt() + 1;
QString nn = n + QString::number(in).rightJustified(3, '0'); QString nn = n + QString::number(in).rightJustified(3, '0');
while (names.contains(nn)) while (names.contains(nn))
nn = n + QString::number(++in).rightJustified(3, '0'); nn = n + QString::number(++in).rightJustified(3, '0');
@@ -176,7 +177,6 @@ QString Scene::uniqueName(QString n, const QSet<QString> & names) {
} }
void Scene::removeObject(ObjectBase * o, bool inChildren) { void Scene::removeObject(ObjectBase * o, bool inChildren) {
if (destroying) return; if (destroying) return;
o->setScene(nullptr); o->setScene(nullptr);
@@ -205,11 +205,13 @@ void Scene::clearObjects(bool deleteAll) {
void Scene::selectObject(ObjectBase * o, bool add_to_selection) { void Scene::selectObject(ObjectBase * o, bool add_to_selection) {
//qDebug() << "selectObject" << o << add_to_selection; // qDebug() << "selectObject" << o << add_to_selection;
if (!add_to_selection || (sel_mode_ == smSingleSelection)) clearSelection(); if (!add_to_selection || (sel_mode_ == smSingleSelection)) clearSelection();
if (o) { if (o) {
if (!add_to_selection) o->setSelected(true); if (!add_to_selection)
else o->setSelected(!o->isSelected()); o->setSelected(true);
else
o->setSelected(!o->isSelected());
gatherSelection(); gatherSelection();
} }
emitSelectionChanged(); emitSelectionChanged();
@@ -218,7 +220,7 @@ void Scene::selectObject(ObjectBase * o, bool add_to_selection) {
void Scene::selectObjects(ObjectBaseList ol, bool add_to_selection) { void Scene::selectObjects(ObjectBaseList ol, bool add_to_selection) {
if (!add_to_selection || (sel_mode_ == smSingleSelection)) clearSelection(); if (!add_to_selection || (sel_mode_ == smSingleSelection)) clearSelection();
foreach (ObjectBase * o, ol) { foreach(ObjectBase * o, ol) {
if (!o) continue; if (!o) continue;
o->setSelected(true); o->setSelected(true);
} }
@@ -229,14 +231,12 @@ void Scene::selectObjects(ObjectBaseList ol, bool add_to_selection) {
void Scene::selectObjectsByMesh() { void Scene::selectObjectsByMesh() {
ObjectBaseList csl = selected_; ObjectBaseList csl = selected_;
QSet<Mesh*> sml; QSet<Mesh *> sml;
foreach (ObjectBase * o, csl) foreach(ObjectBase * o, csl)
if (o->mesh()) if (o->mesh()) sml << o->mesh();
sml << o->mesh();
ObjectBaseList ol = root_->children(true); ObjectBaseList ol = root_->children(true);
foreach (ObjectBase * o, ol) { foreach(ObjectBase * o, ol) {
if (sml.contains(o->mesh())) if (sml.contains(o->mesh())) o->setSelected(true);
o->setSelected(true);
} }
gatherSelection(); gatherSelection();
emitSelectionChanged(); emitSelectionChanged();
@@ -245,14 +245,12 @@ void Scene::selectObjectsByMesh() {
void Scene::selectObjectsByMaterial() { void Scene::selectObjectsByMaterial() {
ObjectBaseList csl = selected_; ObjectBaseList csl = selected_;
QSet<Material*> sml; QSet<Material *> sml;
foreach (ObjectBase * o, csl) foreach(ObjectBase * o, csl)
if (o->material()) if (o->material()) sml << o->material();
sml << o->material();
ObjectBaseList ol = root_->children(true); ObjectBaseList ol = root_->children(true);
foreach (ObjectBase * o, ol) { foreach(ObjectBase * o, ol) {
if (sml.contains(o->material())) if (sml.contains(o->material())) o->setSelected(true);
o->setSelected(true);
} }
gatherSelection(); gatherSelection();
emitSelectionChanged(); emitSelectionChanged();
@@ -263,7 +261,7 @@ void Scene::clearSelection() {
selected_.clear(); selected_.clear();
selected_top.clear(); selected_top.clear();
ObjectBaseList ol = root_->children(true); ObjectBaseList ol = root_->children(true);
foreach (ObjectBase * o, ol) { foreach(ObjectBase * o, ol) {
o->setSelected(false); o->setSelected(false);
o->setAimSelected(false); o->setAimSelected(false);
} }
@@ -282,13 +280,13 @@ ObjectBase * Scene::selectedObject() const {
} }
void gatherMeshes(ObjectBase * o, QSet<Mesh*> & ums) { void gatherMeshes(ObjectBase * o, QSet<Mesh *> & ums) {
if (o->mesh()) ums << o->mesh(); if (o->mesh()) ums << o->mesh();
for (int i = 0; i < o->childCount(); ++i) for (int i = 0; i < o->childCount(); ++i)
gatherMeshes(o->child(i), ums); gatherMeshes(o->child(i), ums);
} }
void Scene::cleanUnused() { void Scene::cleanUnused() {
QSet<Mesh*> ums; QSet<Mesh *> ums;
gatherMeshes(root_, ums); gatherMeshes(root_, ums);
for (int i = 0; i < geometries.size(); ++i) { for (int i = 0; i < geometries.size(); ++i) {
if (ums.contains(geometries[i])) continue; if (ums.contains(geometries[i])) continue;
@@ -316,9 +314,8 @@ Material * Scene::newMaterial(const QString & name) {
void Scene::removeMaterial(Material * m) { void Scene::removeMaterial(Material * m) {
if (!m || !materials.contains(m)) return; if (!m || !materials.contains(m)) return;
ObjectBaseList ol = root_->children(true); ObjectBaseList ol = root_->children(true);
foreach (ObjectBase * o, ol) foreach(ObjectBase * o, ol)
if (o->material_ == m) if (o->material_ == m) o->setMaterial(0);
o->setMaterial(0);
materials.removeAll(m); materials.removeAll(m);
changed_materials.removeAll(m); changed_materials.removeAll(m);
mat_changed = true; mat_changed = true;
@@ -327,7 +324,7 @@ void Scene::removeMaterial(Material * m) {
void Scene::makeMaterialsUniqueNames() { void Scene::makeMaterialsUniqueNames() {
QSet<QString> names; QSet<QString> names;
foreach (Material * m, materials) { foreach(Material * m, materials) {
if (m->name.isEmpty()) m->name = "default_000"; if (m->name.isEmpty()) m->name = "default_000";
m->name = uniqueName(m->name, names); m->name = uniqueName(m->name, names);
names << m->name; names << m->name;
@@ -355,9 +352,8 @@ void Scene::dump() {
void Scene::gatherSelection() { void Scene::gatherSelection() {
selected_.clear(); selected_.clear();
ObjectBaseList ol = root_->children(true); ObjectBaseList ol = root_->children(true);
foreach (ObjectBase * o, ol) foreach(ObjectBase * o, ol)
if (o->isSelected()) if (o->isSelected()) selected_ << o;
selected_ << o;
} }
@@ -369,9 +365,9 @@ void Scene::attachObject(ObjectBase * o) {
setObjectMeshChanged(o); setObjectMeshChanged(o);
} }
if (o->material()) { // search suitable material in this scene if (o->material()) { // search suitable material in this scene
uint ohash = o->material()->hash(); uint ohash = o->material()->hash();
bool need_new = true; bool need_new = true;
foreach (Material * m, materials) { foreach(Material * m, materials) {
if (m == o->material()) { // already exists by ptr if (m == o->material()) { // already exists by ptr
need_new = false; need_new = false;
break; break;
@@ -384,7 +380,7 @@ void Scene::attachObject(ObjectBase * o) {
} }
if (need_new) { // need to clone material and add to scene if (need_new) { // need to clone material and add to scene
Material * nmat = new Material(); Material * nmat = new Material();
*nmat = *(o->material()); *nmat = *(o->material());
nmat->setMapsChanged(); nmat->setMapsChanged();
o->setMaterial(nmat); o->setMaterial(nmat);
materials << nmat; materials << nmat;
@@ -397,7 +393,7 @@ void Scene::attachObject(ObjectBase * o) {
Mesh * Scene::attachMesh(Mesh * mesh) { Mesh * Scene::attachMesh(Mesh * mesh) {
if (!mesh) return 0; if (!mesh) return 0;
uint mhash = mesh->hash(); uint mhash = mesh->hash();
foreach (Mesh * m, geometries) { foreach(Mesh * m, geometries) {
if (m == mesh) { // already exists by ptr if (m == mesh) { // already exists by ptr
return m; return m;
} }
@@ -415,7 +411,7 @@ Mesh * Scene::attachMesh(Mesh * mesh) {
void Scene::setTreeChanged() { void Scene::setTreeChanged() {
if (destroying) return; if (destroying) return;
tree_changed = true; tree_changed = true;
foreach (Mesh * m, geometries) { foreach(Mesh * m, geometries) {
m->setAllObjectsChanged(true); m->setAllObjectsChanged(true);
m->setAllSelectionChanged(true); m->setAllSelectionChanged(true);
} }
@@ -434,22 +430,20 @@ void Scene::setObjectMeshChanged(ObjectBase * o) {
void Scene::prepareTree(ObjectBase * o) { void Scene::prepareTree(ObjectBase * o) {
foreach (ObjectBase * co, o->children_) { foreach(ObjectBase * co, o->children_) {
if (co->isHidden()) continue; if (co->isHidden()) continue;
switch (co->type_) { switch (co->type_) {
case ObjectBase::glLight: { case ObjectBase::glLight: {
Light * l = globject_cast<Light * >(co); Light * l = globject_cast<Light *>(co);
lights_used[l->light_type] << l; lights_used[l->light_type] << l;
} break; } break;
case ObjectBase::glMesh: case ObjectBase::glMesh:
if (co->mesh()) { if (co->mesh()) {
geometries_used[co->pass()][co->mesh()] << co; geometries_used[co->pass()][co->mesh()] << co;
co->setObjectsChanged(); co->setObjectsChanged();
} }
break; break;
case ObjectBase::glCamera: case ObjectBase::glCamera: cameras_used << globject_cast<Camera *>(co); break;
cameras_used << globject_cast<Camera * >(co);
break;
default: break; default: break;
} }
prepareTree(co); prepareTree(co);
@@ -459,7 +453,7 @@ void Scene::prepareTree(ObjectBase * o) {
bool Scene::prepare() { bool Scene::prepare() {
changed_materials.clear(); changed_materials.clear();
foreach (Material * m, materials) { foreach(Material * m, materials) {
if (m->_changed) { if (m->_changed) {
need_reload_materials = tree_changed = true; need_reload_materials = tree_changed = true;
changed_materials << m; changed_materials << m;
@@ -470,7 +464,7 @@ bool Scene::prepare() {
if (!tree_changed && !mat_changed) return false; if (!tree_changed && !mat_changed) return false;
aol = root_->children(true); aol = root_->children(true);
if (tree_changed) { if (tree_changed) {
geometries_used[rpSolid ].clear(); geometries_used[rpSolid].clear();
geometries_used[rpTransparent].clear(); geometries_used[rpTransparent].clear();
lights_used.clear(); lights_used.clear();
cameras_used.clear(); cameras_used.clear();
@@ -480,7 +474,7 @@ bool Scene::prepare() {
cleanUnused(); cleanUnused();
QMetaObject::invokeMethod(this, "treeChanged", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "treeChanged", Qt::QueuedConnection);
} }
tree_changed = false; tree_changed = false;
lights_changed = true; lights_changed = true;
} }
mat_changed = false; mat_changed = false;
@@ -489,36 +483,35 @@ bool Scene::prepare() {
void Scene::destroy(QOpenGLExtraFunctions * f) { void Scene::destroy(QOpenGLExtraFunctions * f) {
foreach (Mesh * g, geometries) foreach(Mesh * g, geometries)
g->destroy(f); g->destroy(f);
} }
void Scene::destroyUnused(QOpenGLExtraFunctions * f) { void Scene::destroyUnused(QOpenGLExtraFunctions * f) {
foreach (Mesh * i, td_geometries) foreach(Mesh * i, td_geometries)
i->destroy(f); i->destroy(f);
qDeleteAll(td_geometries); qDeleteAll(td_geometries);
td_geometries.clear(); td_geometries.clear();
} }
QDataStream & operator <<(QDataStream & s, const Scene * p) { QDataStream & operator<<(QDataStream & s, const Scene * p) {
ChunkStream cs; ChunkStream cs;
//qDebug() << "place" << p->name() << "..."; // qDebug() << "place" << p->name() << "...";
QVector<short> geom_ind, mat_ind; QVector<short> geom_ind, mat_ind;
ObjectBaseList cl = p->root_->children(true); ObjectBaseList cl = p->root_->children(true);
geom_ind.reserve(cl.size()); geom_ind.reserve(cl.size());
mat_ind.reserve(cl.size()); mat_ind.reserve(cl.size());
foreach (ObjectBase * c, cl) { foreach(ObjectBase * c, cl) {
geom_ind << p->geometries.indexOf(c->mesh()); geom_ind << p->geometries.indexOf(c->mesh());
mat_ind << p->materials.indexOf(c->material()); mat_ind << p->materials.indexOf(c->material());
} }
cs.add(1, p->name_).add(10, p->geometries).add(11, p->materials) cs.add(1, p->name_).add(10, p->geometries).add(11, p->materials).add(20, p->root_).add(21, geom_ind).add(22, mat_ind);
.add(20, p->root_).add(21, geom_ind).add(22, mat_ind);
s << qCompress(cs.data()); s << qCompress(cs.data());
return s; return s;
} }
QDataStream & operator >>(QDataStream & s, Scene *& p) { QDataStream & operator>>(QDataStream & s, Scene *& p) {
p = new Scene(); p = new Scene();
QByteArray ba; QByteArray ba;
s >> ba; s >> ba;
@@ -527,21 +520,24 @@ QDataStream & operator >>(QDataStream & s, Scene *& p) {
QVector<short> geom_ind, mat_ind; QVector<short> geom_ind, mat_ind;
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
case 1 : cs.get(p->name_); break; case 1: cs.get(p->name_); break;
case 10: cs.get(p->geometries); break; case 10: cs.get(p->geometries); break;
case 11: cs.get(p->materials); break; case 11: cs.get(p->materials); break;
case 20: cs.get(p->root_); p->root_->setScene(p); break; case 20:
cs.get(p->root_);
p->root_->setScene(p);
break;
case 21: cs.get(geom_ind); break; case 21: cs.get(geom_ind); break;
case 22: cs.get(mat_ind); break; case 22: cs.get(mat_ind); break;
} }
} }
p->makeMaterialsUniqueNames(); p->makeMaterialsUniqueNames();
ObjectBaseList cl = p->root_->children(true); ObjectBaseList cl = p->root_->children(true);
int cnt = qMin(qMin(cl.size(), geom_ind.size()), mat_ind.size()); int cnt = qMin(qMin(cl.size(), geom_ind.size()), mat_ind.size());
for (int i = 0; i < cnt; ++i) { for (int i = 0; i < cnt; ++i) {
ObjectBase * c(cl[i]); ObjectBase * c(cl[i]);
if (geom_ind[i] >= 0) c->mesh_ = p->geometries[geom_ind[i]]; if (geom_ind[i] >= 0) c->mesh_ = p->geometries[geom_ind[i]];
if (mat_ind [i] >= 0) c->material_ = p->materials [mat_ind [i]]; if (mat_ind[i] >= 0) c->material_ = p->materials[mat_ind[i]];
} }
return s; return s;
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGL Scene QGL Scene
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLSCENE_H #ifndef GLSCENE_H
@@ -31,8 +31,9 @@ class Scene: public QObject {
friend class RendererSelection; friend class RendererSelection;
friend class ObjectBase; friend class ObjectBase;
friend class Light; friend class Light;
friend QDataStream & operator <<(QDataStream & s, const Scene * p); friend QDataStream & operator<<(QDataStream & s, const Scene * p);
friend QDataStream & operator >>(QDataStream & s, Scene *& p); friend QDataStream & operator>>(QDataStream & s, Scene *& p);
public: public:
explicit Scene(); explicit Scene();
virtual ~Scene(); virtual ~Scene();
@@ -45,8 +46,8 @@ public:
Q_ENUMS(SelectionMode) Q_ENUMS(SelectionMode)
QString name() const {return name_;} QString name() const { return name_; }
void setName(const QString & name) {name_ = name;} void setName(const QString & name) { name_ = name; }
bool prepare(); bool prepare();
@@ -64,13 +65,13 @@ public:
int objectsCount(bool all = false); int objectsCount(bool all = false);
ObjectBaseList objects(bool all = false); ObjectBaseList objects(bool all = false);
ObjectBase * rootObject() {return root_;} ObjectBase * rootObject() { return root_; }
void removeObject(ObjectBase * o, bool inChildren = true); void removeObject(ObjectBase * o, bool inChildren = true);
void removeObject(ObjectBase & o, bool inChildren = true); void removeObject(ObjectBase & o, bool inChildren = true);
void clearObjects(bool deleteAll = false); void clearObjects(bool deleteAll = false);
SelectionMode selectionMode() const {return sel_mode_;} SelectionMode selectionMode() const { return sel_mode_; }
void setSelectionMode(SelectionMode mode) {sel_mode_ = mode;} void setSelectionMode(SelectionMode mode) { sel_mode_ = mode; }
void selectObject(ObjectBase * o, bool add_to_selection = false); void selectObject(ObjectBase * o, bool add_to_selection = false);
void selectObjects(ObjectBaseList ol, bool add_to_selection = false); void selectObjects(ObjectBaseList ol, bool add_to_selection = false);
void selectObjectsByMesh(); void selectObjectsByMesh();
@@ -82,7 +83,7 @@ public:
const Box3D & boundingBox() const; const Box3D & boundingBox() const;
QVector<Material*> getMaterials() const {return materials;} QVector<Material *> getMaterials() const { return materials; }
Material * newMaterial(const QString & name = QString()); Material * newMaterial(const QString & name = QString());
void removeMaterial(Material * m); void removeMaterial(Material * m);
void makeMaterialsUniqueNames(); void makeMaterialsUniqueNames();
@@ -105,8 +106,8 @@ protected:
Mesh * attachMesh(Mesh * mesh); Mesh * attachMesh(Mesh * mesh);
void setTreeChanged(); void setTreeChanged();
void setTreeStructChanged(); void setTreeStructChanged();
void setMaterialsChanged() {mat_changed = true;} void setMaterialsChanged() { mat_changed = true; }
void setLightsChanged() {lights_changed = tree_changed = true;} void setLightsChanged() { lights_changed = tree_changed = true; }
void setObjectMeshChanged(ObjectBase * o); void setObjectMeshChanged(ObjectBase * o);
@@ -116,13 +117,13 @@ protected:
bool need_reload_materials, tree_struct_changed; bool need_reload_materials, tree_struct_changed;
QVector<bool> mat_map_changed; QVector<bool> mat_map_changed;
QVector<Mesh*> geometries, td_geometries; QVector<Mesh *> geometries, td_geometries;
QVector<Material*> materials; QVector<Material *> materials;
QMap<int, QMap<Mesh*, ObjectBaseList>> geometries_used; QMap<int, QMap<Mesh *, ObjectBaseList>> geometries_used;
QMap<int, QList<Light*>> lights_used; QMap<int, QList<Light *>> lights_used;
QList<Camera*> cameras_used; QList<Camera *> cameras_used;
QVector<Material*> changed_materials; QVector<Material *> changed_materials;
SelectionMode sel_mode_; SelectionMode sel_mode_;
ObjectBaseList selected_, selected_top; ObjectBaseList selected_, selected_top;
@@ -137,7 +138,7 @@ signals:
}; };
QDataStream & operator <<(QDataStream & s, const Scene * p); QDataStream & operator<<(QDataStream & s, const Scene * p);
QDataStream & operator >>(QDataStream & s, Scene *& p); QDataStream & operator>>(QDataStream & s, Scene *& p);
#endif // GLSCENE_H #endif // GLSCENE_H

View File

@@ -1,29 +1,30 @@
/* /*
QGL TextureManager QGL TextureManager
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "gltexture_manager.h" #include "gltexture_manager.h"
#include "gltypes.h" #include "gltypes.h"
QStringList TextureManager::search_pathes("."); QStringList TextureManager::search_pathes(".");
QVector3D colorVector(QRgb c) { QVector3D colorVector(QRgb c) {
return QVector3D(((uchar*)(&c))[0] / 255.f, ((uchar*)(&c))[1] / 255.f, ((uchar*)(&c))[2] / 255.f); return QVector3D(((uchar *)(&c))[0] / 255.f, ((uchar *)(&c))[1] / 255.f, ((uchar *)(&c))[2] / 255.f);
} }
@@ -37,12 +38,12 @@ GLuint TextureManager::loadTexture(const QString & path, bool ownership, bool bu
if (p.isEmpty()) return 0; if (p.isEmpty()) return 0;
int tid = textureID(p, bump); int tid = textureID(p, bump);
if (tid > 0) { if (tid > 0) {
//qDebug() << "[TextureManager] Found" << path << "as" << tid; // qDebug() << "[TextureManager] Found" << path << "as" << tid;
return tid; return tid;
} }
QImage image(p); QImage image(p);
if (bump) convertToNormal(image); if (bump) convertToNormal(image);
//qDebug() << p << image.width() << image.height() << image.format() << bump; // qDebug() << p << image.width() << image.height() << image.format() << bump;
GLuint tid_ = tid; GLuint tid_ = tid;
createGLTexture(f, tid_, image); createGLTexture(f, tid_, image);
tid = tid_; tid = tid_;
@@ -53,7 +54,7 @@ GLuint TextureManager::loadTexture(const QString & path, bool ownership, bool bu
qDebug() << "[TextureManager] Loaded" << p << "as" << tid; qDebug() << "[TextureManager] Loaded" << p << "as" << tid;
if (ownership) { if (ownership) {
tex_ids[bump ? 1 : 0].insert(p, tid); tex_ids[bump ? 1 : 0].insert(p, tid);
tex_im [bump ? 1 : 0].insert(p, image); tex_im[bump ? 1 : 0].insert(p, image);
} }
return tid; return tid;
} }
@@ -69,7 +70,7 @@ GLuint TextureManager::loadTexture(const QImage & im, bool ownership, bool bump)
qDebug() << "[TextureManager] Can`t load image"; qDebug() << "[TextureManager] Can`t load image";
return tid; return tid;
} }
//qDebug() << "[TextureManager] Loaded image as" << tid; // qDebug() << "[TextureManager] Loaded image as" << tid;
return tid; return tid;
} }
@@ -109,15 +110,18 @@ void TextureManager::reloadTexture(GLuint tid, const QImage & im) {
void TextureManager::convertToNormal(QImage & im) { void TextureManager::convertToNormal(QImage & im) {
if (im.isNull()) return; if (im.isNull()) return;
QImage sim = im.convertToFormat(QImage::Format_ARGB32); QImage sim = im.convertToFormat(QImage::Format_ARGB32);
float sum[3] = {0., 0., 0.}; float sum[3] = {0., 0., 0.};
llong a = 0; llong a = 0;
const uchar * sd = sim.constBits(); const uchar * sd = sim.constBits();
for (int i = 0; i < sim.height(); i++) { for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) { for (int j = 0; j < sim.width(); j++) {
sum[2] += sd[a] / 255.f - 0.5f; ++a; sum[2] += sd[a] / 255.f - 0.5f;
sum[1] += sd[a] / 255.f - 0.5f; ++a; ++a;
sum[0] += sd[a] / 255.f - 0.5f; ++a; sum[1] += sd[a] / 255.f - 0.5f;
++a;
sum[0] += sd[a] / 255.f - 0.5f;
++a;
++a; ++a;
} }
} }
@@ -125,13 +129,13 @@ void TextureManager::convertToNormal(QImage & im) {
sum[0] /= wh; sum[0] /= wh;
sum[1] /= wh; sum[1] /= wh;
sum[2] /= wh; sum[2] /= wh;
//qDebug() << sum[0] << sum[1] << sum[2]; // qDebug() << sum[0] << sum[1] << sum[2];
if ((qAbs(sum[0]) <= 0.05f) && (qAbs(sum[1]) <= 0.05f) && (sum[2] >= 0.25f)) /// already normal if ((qAbs(sum[0]) <= 0.05f) && (qAbs(sum[1]) <= 0.05f) && (sum[2] >= 0.25f)) /// already normal
return; return;
//qDebug() << "convert to normal"; // qDebug() << "convert to normal";
QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32); QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32);
int tx, ty, w = sim.width(), h = sim.height(); int tx, ty, w = sim.width(), h = sim.height();
a = 0; a = 0;
uchar * dd = dim.bits(); uchar * dd = dim.bits();
for (int i = 0; i < sim.height(); i++) { for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) { for (int j = 0; j < sim.width(); j++) {
@@ -145,27 +149,31 @@ void TextureManager::convertToNormal(QImage & im) {
p[2] = colorVector(sim.pixel(tx, i)); p[2] = colorVector(sim.pixel(tx, i));
res.setY(piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f)); res.setY(piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f));
res.setX(piClamp(0.5f - (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f)); res.setX(piClamp(0.5f - (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f));
tx = (j + 1) % w; tx = (j + 1) % w;
ty = (i + 1) % h; ty = (i + 1) % h;
p[1] = colorVector(sim.pixel(j, ty)); p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i)); p[2] = colorVector(sim.pixel(tx, i));
res.setY(piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f)); res.setY(piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f));
res.setX(piClamp(0.5f - (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f)); res.setX(piClamp(0.5f - (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f));
res.setZ(1.f); res.setZ(1.f);
dd[a] = res.z() * 255; ++a; dd[a] = res.z() * 255;
dd[a] = res.y() * 255; ++a; ++a;
dd[a] = res.x() * 255; ++a; dd[a] = res.y() * 255;
dd[a] = 255; ++a; ++a;
dd[a] = res.x() * 255;
++a;
dd[a] = 255;
++a;
} }
} }
im = dim; im = dim;
//im.save("_normal.png"); // im.save("_normal.png");
} }
bool TextureManager::loadTextures() { bool TextureManager::loadTextures() {
QFileInfoList fil; QFileInfoList fil;
foreach (const QString & i, tex_pathes) foreach(const QString & i, tex_pathes)
loadTexture(i, true); loadTexture(i, true);
tex_pathes.clear(); tex_pathes.clear();
return true; return true;
@@ -178,7 +186,7 @@ void TextureManager::deleteTextures() {
qDebug() << "[TextureManager] Delete" << texs.size() << "textures"; qDebug() << "[TextureManager] Delete" << texs.size() << "textures";
if (!texs.isEmpty()) f->glDeleteTextures(texs.size(), &texs[0]); if (!texs.isEmpty()) f->glDeleteTextures(texs.size(), &texs[0]);
tex_ids[i].clear(); tex_ids[i].clear();
tex_im [i].clear(); tex_im[i].clear();
} }
} }
@@ -189,7 +197,7 @@ void TextureManager::deleteTexture(const QString & name) {
GLuint id = tex_ids[i][name]; GLuint id = tex_ids[i][name];
f->glDeleteTextures(1, &id); f->glDeleteTextures(1, &id);
tex_ids[i].remove(name); tex_ids[i].remove(name);
tex_im [i].remove(name); tex_im[i].remove(name);
} }
} }
} }

View File

@@ -1,29 +1,29 @@
/* /*
QGL TextureManager QGL TextureManager
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLTEXTUREMANAGER_H #ifndef GLTEXTUREMANAGER_H
#define GLTEXTUREMANAGER_H #define GLTEXTUREMANAGER_H
#include <QOpenGLExtraFunctions>
#include <QDir> #include <QDir>
#include <QMap>
#include <QFileInfo> #include <QFileInfo>
#include <QImage> #include <QImage>
#include <QMap>
#include <QOpenGLExtraFunctions>
class TextureManager { class TextureManager {
@@ -31,18 +31,20 @@ public:
TextureManager(QOpenGLExtraFunctions * f_): f(f_) {} TextureManager(QOpenGLExtraFunctions * f_): f(f_) {}
virtual ~TextureManager() {} virtual ~TextureManager() {}
static void addSearchPath(const QString & path) {if (!search_pathes.contains(path)) search_pathes << path;} static void addSearchPath(const QString & path) {
static void clearSearchPathes() {search_pathes.clear();} if (!search_pathes.contains(path)) search_pathes << path;
static QStringList searchPathes() {return search_pathes;} }
static void clearSearchPathes() { search_pathes.clear(); }
static QStringList searchPathes() { return search_pathes; }
static QString findFile(const QString & path); static QString findFile(const QString & path);
GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false); GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false);
GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false); GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false);
QImage loadTextureImage(const QString & path, bool bump = false); QImage loadTextureImage(const QString & path, bool bump = false);
void reloadTexture(GLuint tid, const QString & path); void reloadTexture(GLuint tid, const QString & path);
void reloadTexture(GLuint tid, const QImage & image); void reloadTexture(GLuint tid, const QImage & image);
int textureID (const QString & path, bool bump = false) {return tex_ids[bump ? 1 : 0][path];} int textureID(const QString & path, bool bump = false) { return tex_ids[bump ? 1 : 0][path]; }
QImage textureImage(const QString & path, bool bump = false) {return tex_im [bump ? 1 : 0][path];} QImage textureImage(const QString & path, bool bump = false) { return tex_im[bump ? 1 : 0][path]; }
void addTexture(const QString & path) {tex_pathes << path;} void addTexture(const QString & path) { tex_pathes << path; }
bool loadTextures(); bool loadTextures();
void deleteTextures(); void deleteTextures();
void deleteTexture(const QString & name); void deleteTexture(const QString & name);
@@ -54,7 +56,7 @@ protected:
static QStringList search_pathes; static QStringList search_pathes;
QMap<QString, GLuint> tex_ids[2]; QMap<QString, GLuint> tex_ids[2];
QMap<QString, QImage> tex_im [2]; QMap<QString, QImage> tex_im[2];
QStringList tex_pathes; QStringList tex_pathes;
QOpenGLExtraFunctions * f; QOpenGLExtraFunctions * f;
}; };

View File

@@ -1,31 +1,33 @@
/* /*
QGL GLWidget QGL GLWidget
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "glwidget.h" #include "glwidget.h"
#include "qglview.h" #include "qglview.h"
#include <QVBoxLayout> #include <QVBoxLayout>
GLWidget::GLWidget(QWidget *parent) : QWidget(parent) { GLWidget::GLWidget(QWidget * parent): QWidget(parent) {
view_ = new QGLView(); view_ = new QGLView();
//view_->setFlags(windowFlags() | Qt::FramelessWindowHint); // view_->setFlags(windowFlags() | Qt::FramelessWindowHint);
container = QWidget::createWindowContainer(view_, this); container = QWidget::createWindowContainer(view_, this);
lay = new QVBoxLayout(this); lay = new QVBoxLayout(this);
lay->addWidget(container); lay->addWidget(container);
lay->setContentsMargins(0, 0, 0, 0); lay->setContentsMargins(0, 0, 0, 0);
lay->setSpacing(0); lay->setSpacing(0);
@@ -70,8 +72,7 @@ bool GLWidget::isMouseSelectionEnabled() const {
} }
bool GLWidget::isCameraOrbit() const bool GLWidget::isCameraOrbit() const {
{
return view_->isCameraOrbit(); return view_->isCameraOrbit();
} }
@@ -121,7 +122,7 @@ QByteArray GLWidget::saveCamera() {
} }
void GLWidget::restoreCamera(const QByteArray &ba) { void GLWidget::restoreCamera(const QByteArray & ba) {
view_->restoreCamera(ba); view_->restoreCamera(ba);
} }

View File

@@ -1,19 +1,19 @@
/* /*
QGL GLWidget QGL GLWidget
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef GLWIDGET_H #ifndef GLWIDGET_H
@@ -26,25 +26,25 @@ class QGLView;
class ObjectBase; class ObjectBase;
class Scene; class Scene;
class GLWidget : public QWidget class GLWidget: public QWidget {
{
Q_OBJECT Q_OBJECT
Q_PROPERTY (qreal lineWidth READ lineWidth WRITE setLineWidth) Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth)
Q_PROPERTY (qreal FOV READ FOV WRITE setFOV) Q_PROPERTY(qreal FOV READ FOV WRITE setFOV)
Q_PROPERTY (qreal depthStart READ depthStart WRITE setDepthStart) Q_PROPERTY(qreal depthStart READ depthStart WRITE setDepthStart)
Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) Q_PROPERTY(bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) Q_PROPERTY(bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) Q_PROPERTY(bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) Q_PROPERTY(bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) Q_PROPERTY(QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
Q_PROPERTY (qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) Q_PROPERTY(qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) Q_PROPERTY(bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) Q_PROPERTY(QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
Q_PROPERTY (qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) Q_PROPERTY(qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
public: public:
explicit GLWidget(QWidget *parent = nullptr); explicit GLWidget(QWidget * parent = nullptr);
QGLView * view() {return view_;} QGLView * view() { return view_; }
QColor backColor() const; QColor backColor() const;
qreal lineWidth() const; qreal lineWidth() const;

View File

@@ -1,49 +1,50 @@
/* /*
QGL MouseController QGL MouseController
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "mouse_controller.h" #include "mouse_controller.h"
#include "glmesh.h" #include "glmesh.h"
#include "qglview.h" #include "qglview.h"
#include <qad_types.h>
#include <QApplication> #include <QApplication>
#include <QKeyEvent> #include <QKeyEvent>
#include <qad_types.h>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
MouseController::MouseController(QGLView * view_): view(view_) { MouseController::MouseController(QGLView * view_): view(view_) {
app_scale = 1; app_scale = 1;
lastPos = QPoint(-1, -1); lastPos = QPoint(-1, -1);
cur_action = RendererService::haNoAction; cur_action = RendererService::haNoAction;
sel_button = Qt::LeftButton; sel_button = Qt::LeftButton;
sel_mod = Qt::ControlModifier; sel_mod = Qt::ControlModifier;
mouse_first = mouseSelect_ = mouseRotate_ = cameraOrbit_ = canSelect_ = true; mouse_first = mouseSelect_ = mouseRotate_ = cameraOrbit_ = canSelect_ = true;
grabMouse_ = mouse_sec = selecting_ = customMouseMove_ = false; grabMouse_ = mouse_sec = selecting_ = customMouseMove_ = false;
} }
MouseController::~MouseController() { MouseController::~MouseController() {}
}
void MouseController::resize() { void MouseController::resize() {
mouse_first = true; mouse_first = true;
app_scale = appScale(); app_scale = appScale();
} }
@@ -54,8 +55,8 @@ void MouseController::mouseReleaseEvent(QMouseEvent * e) {
} }
bool add_ts = e->modifiers().testFlag(sel_mod); bool add_ts = e->modifiers().testFlag(sel_mod);
if (selecting_) { if (selecting_) {
selecting_ = false; selecting_ = false;
canSelect_ = true; canSelect_ = true;
view->renderer_.mouse_rect = QRect(); view->renderer_.mouse_rect = QRect();
view->scene()->selectObjects(hov_objects.toList(), add_ts); view->scene()->selectObjects(hov_objects.toList(), add_ts);
return; return;
@@ -63,12 +64,11 @@ void MouseController::mouseReleaseEvent(QMouseEvent * e) {
if (canSelect_ && mouseSelect_) { if (canSelect_ && mouseSelect_) {
if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance()) { if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance()) {
if (e->button() == Qt::LeftButton) { if (e->button() == Qt::LeftButton) {
//qDebug() << hov_objects << hov_aims; // qDebug() << hov_objects << hov_aims;
if (hov_objects.isEmpty() && hov_aims.isEmpty()) { if (hov_objects.isEmpty() && hov_aims.isEmpty()) {
view->scene()->clearSelection(); view->scene()->clearSelection();
} else { } else {
if (!hov_objects.isEmpty()) if (!hov_objects.isEmpty()) view->scene()->selectObject(hov_objects[0], add_ts);
view->scene()->selectObject(hov_objects[0], add_ts);
if (!hov_aims.isEmpty()) { if (!hov_aims.isEmpty()) {
view->scene()->selectObject(hov_aims[0], add_ts); view->scene()->selectObject(hov_aims[0], add_ts);
hov_aims[0]->setAimSelected(true); hov_aims[0]->setAimSelected(true);
@@ -79,11 +79,11 @@ void MouseController::mouseReleaseEvent(QMouseEvent * e) {
if (view->renderer_.edit_mode && !view->scene()->selectedObjects().isEmpty()) if (view->renderer_.edit_mode && !view->scene()->selectedObjects().isEmpty())
view->popupMenu( view->popupMenu(
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
((QMouseEvent*)e)->globalPos() ((QMouseEvent *)e)->globalPos()
#else #else
((QMouseEvent*)e)->globalPosition().toPoint() ((QMouseEvent *)e)->globalPosition().toPoint()
#endif #endif
); );
} }
} }
} }
@@ -98,7 +98,7 @@ void MouseController::mousePressEvent(QMouseEvent * e) {
return; return;
} }
if (selecting_) { if (selecting_) {
selecting_ = false; selecting_ = false;
view->renderer_.mouse_rect = QRect(); view->renderer_.mouse_rect = QRect();
return; return;
} }
@@ -134,11 +134,12 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
default: break; default: break;
} }
QVector<QVector3D> scales; QVector<QVector3D> scales;
foreach (int a, axis) { foreach(int a, axis) {
QVector3D axe_vector; axe_vector[a] = 1.; QVector3D axe_vector;
QMatrix4x4 axis_mat = view->camera()->fullViewMatrix() * rs.axis_mat; axe_vector[a] = 1.;
QMatrix4x4 axis_mat = view->camera()->fullViewMatrix() * rs.axis_mat;
QVector3D center_screen = axis_mat.map(rs.selection_center); QVector3D center_screen = axis_mat.map(rs.selection_center);
QVector3D axe_screen = (axis_mat.map(rs.selection_center + axe_vector) - center_screen).normalized(); QVector3D axe_screen = (axis_mat.map(rs.selection_center + axe_vector) - center_screen).normalized();
QVector3D mouse_vector(cpos - lastPos); QVector3D mouse_vector(cpos - lastPos);
mouse_vector[1] *= -1.; mouse_vector[1] *= -1.;
if (cur_action == RendererService::haMove) { if (cur_action == RendererService::haMove) {
@@ -147,13 +148,12 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
mouse_vector *= -center_screen.z() * len_scl; mouse_vector *= -center_screen.z() * len_scl;
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector); axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
QMatrix4x4 pmat; QMatrix4x4 pmat;
foreach (ObjectBase * o, objects) { foreach(ObjectBase * o, objects) {
pmat.setToIdentity(); pmat.setToIdentity();
if (o->parent()) if (o->parent()) pmat = o->parent()->worldTransform().inverted();
pmat = o->parent()->worldTransform().inverted();
QVector3D dv = pmat.mapVector(axe_vector); QVector3D dv = pmat.mapVector(axe_vector);
if (o->isAimSelected()) { if (o->isAimSelected()) {
AimedObject * ao = (AimedObject*)o; AimedObject * ao = (AimedObject *)o;
ao->setAim(ao->aim() + dv); ao->setAim(ao->aim() + dv);
} else } else
o->move(dv); o->move(dv);
@@ -164,7 +164,7 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
axe_screen.normalize(); axe_screen.normalize();
QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.); QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.);
axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale; axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale;
foreach (ObjectBase * o, objects) foreach(ObjectBase * o, objects)
o->setRotation(o->rotation() + axe_vector); o->setRotation(o->rotation() + axe_vector);
} }
if (cur_action == RendererService::haScale) { if (cur_action == RendererService::haScale) {
@@ -176,17 +176,17 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
} }
if (cur_action == RendererService::haScale) { if (cur_action == RendererService::haScale) {
double sc = 0., max = 0.; double sc = 0., max = 0.;
foreach (const QVector3D & s, scales) { foreach(const QVector3D & s, scales) {
double v = QVector3D::dotProduct(s, QVector3D(1,1,1)); double v = QVector3D::dotProduct(s, QVector3D(1, 1, 1));
sc += v; sc += v;
max = qMax(max, qAbs(v)); max = qMax(max, qAbs(v));
} }
sc = max * (sc > 0. ? 1. : -1); sc = max * (sc > 0. ? 1. : -1);
QVector3D axe_vector; QVector3D axe_vector;
foreach (int a, axis) foreach(int a, axis)
axe_vector[a] = 1.; axe_vector[a] = 1.;
foreach (ObjectBase * o, objects) foreach(ObjectBase * o, objects)
o->scale(QVector3D(1,1,1) + (axe_vector * sc)); o->scale(QVector3D(1, 1, 1) + (axe_vector * sc));
QCursor::setPos(view->mapToGlobal(downPos)); QCursor::setPos(view->mapToGlobal(downPos));
} else } else
lastPos = e->pos(); lastPos = e->pos();
@@ -215,7 +215,7 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
#endif #endif
if (e->buttons().testFlag(QT_MID_BUTTON)) { if (e->buttons().testFlag(QT_MID_BUTTON)) {
if (cameraOrbit_) { if (cameraOrbit_) {
view->camera()->orbitZ (dx / 4.f); view->camera()->orbitZ(dx / 4.f);
view->camera()->orbitXY(dy / 4.f); view->camera()->orbitXY(dy / 4.f);
} else { } else {
view->camera()->rotateZ(-dx / 4.f); view->camera()->rotateZ(-dx / 4.f);
@@ -225,34 +225,33 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
} else if (e->buttons().testFlag(Qt::RightButton)) { } else if (e->buttons().testFlag(Qt::RightButton)) {
float ad = view->camera()->distance(); float ad = view->camera()->distance();
view->camera()->moveLeft(dx / 1000.f * ad); view->camera()->moveLeft(dx / 1000.f * ad);
view->camera()->moveUp (dy / 1000.f * ad); view->camera()->moveUp(dy / 1000.f * ad);
emit view->cameraPosChanged(view->camera()->pos()); emit view->cameraPosChanged(view->camera()->pos());
} }
} }
if (customMouseMove_) emit view->customMouseMoveEvent(e->pos(), lastPos, e->buttons()); if (customMouseMove_) emit view->customMouseMoveEvent(e->pos(), lastPos, e->buttons());
lastPos = e->pos(); lastPos = e->pos();
if (e->buttons() == 0) { if (e->buttons() == 0) {
cur_handle = QFlags<RendererService::HandleMesh>(); cur_handle = QFlags<RendererService::HandleMesh>();
cur_action = RendererService::haNoAction; cur_action = RendererService::haNoAction;
Qt::CursorShape cs = Qt::CrossCursor; Qt::CursorShape cs = Qt::CrossCursor;
if (view->renderer_.edit_mode) { if (view->renderer_.edit_mode) {
uint hid = view->renderer_.rend_selection.id_hover; uint hid = view->renderer_.rend_selection.id_hover;
cur_handle = (RendererService::HandleMesh)hid; cur_handle = (RendererService::HandleMesh)hid;
if (hid >= RendererService::hmMoveX && hid <= RendererService::hmMaxMove ) { if (hid >= RendererService::hmMoveX && hid <= RendererService::hmMaxMove) {
cur_action = RendererService::haMove; cur_action = RendererService::haMove;
cs = Qt::SizeAllCursor; cs = Qt::SizeAllCursor;
} }
if (hid >= RendererService::hmRotateX && hid <= RendererService::hmMaxRotate) { if (hid >= RendererService::hmRotateX && hid <= RendererService::hmMaxRotate) {
cur_action = RendererService::haRotate; cur_action = RendererService::haRotate;
cs = Qt::PointingHandCursor; cs = Qt::PointingHandCursor;
} }
if (hid >= RendererService::hmScaleX && hid <= RendererService::hmMaxScale ) { if (hid >= RendererService::hmScaleX && hid <= RendererService::hmMaxScale) {
cur_action = RendererService::haScale; cur_action = RendererService::haScale;
cs = Qt::SplitHCursor; cs = Qt::SplitHCursor;
} }
} }
if (cur_action == RendererService::haNoAction) if (cur_action == RendererService::haNoAction) cur_handle = QFlags<RendererService::HandleMesh>();
cur_handle = QFlags<RendererService::HandleMesh>();
view->setCursor(cs); view->setCursor(cs);
view->renderer_.rend_service.current_handle = cur_handle; view->renderer_.rend_service.current_handle = cur_handle;
} }
@@ -264,7 +263,7 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
} }
if (mouse_first) { if (mouse_first) {
mouse_first = false; mouse_first = false;
mouse_sec = true; mouse_sec = true;
return; return;
} }
lastPos = g_rect.center(); lastPos = g_rect.center();
@@ -272,8 +271,8 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
int dx = e->x() - lastPos.x(); int dx = e->x() - lastPos.x();
int dy = e->y() - lastPos.y(); int dy = e->y() - lastPos.y();
#else #else
int dx = e->position().toPoint().x() - lastPos.x(); int dx = e->position().toPoint().x() - lastPos.x();
int dy = e->position().toPoint().y() - lastPos.y(); int dy = e->position().toPoint().y() - lastPos.y();
#endif #endif
emit view->glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers())); emit view->glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers()));
return; return;
@@ -286,9 +285,9 @@ void MouseController::wheelEvent(QWheelEvent * e) {
if (mouseRotate_) { if (mouseRotate_) {
double ang = double ang =
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
e->delta(); e->delta();
#else #else
e->angleDelta().y(); e->angleDelta().y();
#endif #endif
if (ang > 0) view->camera()->flyCloser(0.1f); if (ang > 0) view->camera()->flyCloser(0.1f);
if (ang < 0) view->camera()->flyFarer(0.1f); if (ang < 0) view->camera()->flyFarer(0.1f);
@@ -298,13 +297,12 @@ void MouseController::wheelEvent(QWheelEvent * e) {
} }
void MouseController::leaveEvent(QEvent * ) { void MouseController::leaveEvent(QEvent *) {
lastPos = QPoint(-1, -1); lastPos = QPoint(-1, -1);
//qDebug() << lastPos; // qDebug() << lastPos;
} }
void MouseController::mouseDoubleClickEvent(QMouseEvent * e) { void MouseController::mouseDoubleClickEvent(QMouseEvent * e) {
if (e->buttons().testFlag(QT_MID_BUTTON)) if (e->buttons().testFlag(QT_MID_BUTTON)) emit view->doubleClick();
emit view->doubleClick();
} }

View File

@@ -1,50 +1,51 @@
/* /*
QGL MouseController QGL MouseController
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef MOUSE_CONTROLLER_H #ifndef MOUSE_CONTROLLER_H
#define MOUSE_CONTROLLER_H #define MOUSE_CONTROLLER_H
#include "glprimitives.h"
#include "glcamera.h" #include "glcamera.h"
#include "glprimitives.h"
#include "renderer_service.h" #include "renderer_service.h"
#include <QMouseEvent> #include <QMouseEvent>
#include <QTime> #include <QTime>
class MouseController: public QObject class MouseController: public QObject {
{
friend class QGLView; friend class QGLView;
friend class RendererSelection; friend class RendererSelection;
Q_OBJECT Q_OBJECT
public: public:
MouseController(QGLView * view_); MouseController(QGLView * view_);
virtual ~MouseController(); virtual ~MouseController();
bool isGrabMouseEnabled() const {return grabMouse_;} bool isGrabMouseEnabled() const { return grabMouse_; }
bool isMouseRotateEnabled() const {return mouseRotate_;} bool isMouseRotateEnabled() const { return mouseRotate_; }
bool isMouseSelectionEnabled() const {return mouseSelect_;} bool isMouseSelectionEnabled() const { return mouseSelect_; }
bool isCameraOrbit() const {return cameraOrbit_;} bool isCameraOrbit() const { return cameraOrbit_; }
Qt::MouseButton selectionButton() const {return sel_button;} Qt::MouseButton selectionButton() const { return sel_button; }
Qt::KeyboardModifier selectionModifier() const {return sel_mod;} Qt::KeyboardModifier selectionModifier() const { return sel_mod; }
void setSelectionButton(Qt::MouseButton v) {sel_button = v;} void setSelectionButton(Qt::MouseButton v) { sel_button = v; }
void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;} void setSelectionModifier(Qt::KeyboardModifier v) { sel_mod = v; }
protected: protected:
void resize(); void resize();
@@ -52,14 +53,14 @@ protected:
void mouseMoveEvent(QMouseEvent * e); void mouseMoveEvent(QMouseEvent * e);
void mouseReleaseEvent(QMouseEvent * e); void mouseReleaseEvent(QMouseEvent * e);
void wheelEvent(QWheelEvent * e); void wheelEvent(QWheelEvent * e);
void leaveEvent(QEvent * ); void leaveEvent(QEvent *);
void mouseDoubleClickEvent(QMouseEvent * e); void mouseDoubleClickEvent(QMouseEvent * e);
private: private:
QGLView * view; QGLView * view;
QPoint lastPos, downPos; QPoint lastPos, downPos;
QSet<int> keys_; QSet<int> keys_;
QVector<ObjectBase * > hov_objects, hov_aims; QVector<ObjectBase *> hov_objects, hov_aims;
Qt::MouseButton sel_button; Qt::MouseButton sel_button;
Qt::KeyboardModifier sel_mod; Qt::KeyboardModifier sel_mod;
RendererService::HandleAction cur_action; RendererService::HandleAction cur_action;
@@ -71,14 +72,16 @@ private:
private slots: private slots:
public slots: public slots:
void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;} void setGrabMouseEnabled(const bool & arg) {
void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;} grabMouse_ = arg;
void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;} mouse_first = true;
void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;} }
void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;} void setMouseRotateEnabled(const bool & arg) { mouseRotate_ = arg; }
void setMouseSelectionEnabled(const bool & arg) { mouseSelect_ = arg; }
void setCustomMouseMove(const bool & arg) { customMouseMove_ = arg; }
void setCameraOrbit(const bool & arg) { cameraOrbit_ = arg; }
signals: signals:
}; };
#endif // QGLVIEW_H #endif // QGLVIEW_H

View File

@@ -1,4 +1,5 @@
#include "openglwindow.h" #include "openglwindow.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QOpenGLContext> #include <QOpenGLContext>
#include <QOpenGLPaintDevice> #include <QOpenGLPaintDevice>
@@ -6,7 +7,7 @@
#include <qopenglext.h> #include <qopenglext.h>
OpenGLWindow::OpenGLWindow(QWindow *parent) : QWindow(parent) { OpenGLWindow::OpenGLWindow(QWindow * parent): QWindow(parent) {
setFlags(flags() | Qt::FramelessWindowHint); setFlags(flags() | Qt::FramelessWindowHint);
setSurfaceType(QWindow::OpenGLSurface); setSurfaceType(QWindow::OpenGLSurface);
QSurfaceFormat format = QSurfaceFormat::defaultFormat(); QSurfaceFormat format = QSurfaceFormat::defaultFormat();
@@ -29,18 +30,15 @@ void OpenGLWindow::renderLater() {
} }
bool OpenGLWindow::event(QEvent *event) { bool OpenGLWindow::event(QEvent * event) {
switch (event->type()) { switch (event->type()) {
case QEvent::UpdateRequest: case QEvent::UpdateRequest: renderNow(); return true;
renderNow(); default: return QWindow::event(event);
return true;
default:
return QWindow::event(event);
} }
} }
void OpenGLWindow::exposeEvent(QExposeEvent *event) { void OpenGLWindow::exposeEvent(QExposeEvent * event) {
if (isExposed()) renderNow(); if (isExposed()) renderNow();
} }
@@ -68,19 +66,19 @@ bool OpenGLWindow::getVSync() const {
} }
//void OpenGLWindow::setSamples(int samples) { // void OpenGLWindow::setSamples(int samples) {
// QSurfaceFormat f = requestedFormat(); // QSurfaceFormat f = requestedFormat();
// if (f.samples() != samples) { // if (f.samples() != samples) {
// f.setSamples(samples); // f.setSamples(samples);
// setFormat(f); // setFormat(f);
// format_change = true; // format_change = true;
// } // }
//} // }
//int OpenGLWindow::getSamples() const { // int OpenGLWindow::getSamples() const {
// return requestedFormat().samples(); // return requestedFormat().samples();
//} // }
void OpenGLWindow::renderNow() { void OpenGLWindow::renderNow() {
@@ -92,7 +90,7 @@ void OpenGLWindow::renderNow() {
m_context->setFormat(requestedFormat()); m_context->setFormat(requestedFormat());
m_context->create(); m_context->create();
needsInitialize = true; needsInitialize = true;
format_change = false; format_change = false;
} }
m_context->makeCurrent(this); m_context->makeCurrent(this);
if (needsInitialize) { if (needsInitialize) {
@@ -103,4 +101,3 @@ void OpenGLWindow::renderNow() {
m_context->swapBuffers(this); m_context->swapBuffers(this);
frame_cnt++; frame_cnt++;
} }

View File

@@ -1,38 +1,40 @@
#include <QWindow>
#include <QOpenGLExtraFunctions> #include <QOpenGLExtraFunctions>
#include <QWindow>
class QPainter; class QPainter;
class QOpenGLContext; class QOpenGLContext;
class QOpenGLPaintDevice; class QOpenGLPaintDevice;
class OpenGLWindow : public QWindow, public QOpenGLExtraFunctions { class OpenGLWindow
: public QWindow
, public QOpenGLExtraFunctions {
Q_OBJECT Q_OBJECT
public: public:
explicit OpenGLWindow(QWindow *parent = nullptr); explicit OpenGLWindow(QWindow * parent = nullptr);
virtual ~OpenGLWindow() {} virtual ~OpenGLWindow() {}
virtual void render() {} virtual void render() {}
virtual void initialize() {} virtual void initialize() {}
QOpenGLContext * context() {return m_context;} QOpenGLContext * context() { return m_context; }
void setVSync(bool on); void setVSync(bool on);
bool getVSync() const; bool getVSync() const;
// void setSamples(int samples); // void setSamples(int samples);
// int getSamples() const; // int getSamples() const;
int getFrameCounter() const {return frame_cnt;} int getFrameCounter() const { return frame_cnt; }
public slots: public slots:
void renderLater(); void renderLater();
void renderNow(); void renderNow();
protected: protected:
bool event(QEvent *event) override; bool event(QEvent * event) override;
void exposeEvent(QExposeEvent *event) override; void exposeEvent(QExposeEvent * event) override;
private: private:
QOpenGLContext * m_context = nullptr; QOpenGLContext * m_context = nullptr;
bool format_change = false; bool format_change = false;
int frame_cnt = 0; int frame_cnt = 0;
}; };

View File

@@ -1,14 +1,13 @@
#include "qglview_designerplugin.h" #include "qglview_designerplugin.h"
#include "qglviewplugin.h" #include "qglviewplugin.h"
QGLViewDesignerPlugin::QGLViewDesignerPlugin(QObject * parent): QObject(parent) QGLViewDesignerPlugin::QGLViewDesignerPlugin(QObject * parent): QObject(parent) {
{
m_widgets.append(new QGLViewPlugin(this)); m_widgets.append(new QGLViewPlugin(this));
} }
QList<QDesignerCustomWidgetInterface * > QGLViewDesignerPlugin::customWidgets() const { QList<QDesignerCustomWidgetInterface *> QGLViewDesignerPlugin::customWidgets() const {
return m_widgets; return m_widgets;
} }

View File

@@ -1,22 +1,23 @@
#ifndef QGLVIEW_DESIGNERPLUGIN_H #ifndef QGLVIEW_DESIGNERPLUGIN_H
#define QGLVIEW_DESIGNERPLUGIN_H #define QGLVIEW_DESIGNERPLUGIN_H
#include <QtDesigner/QtDesigner>
#include <QtCore/qplugin.h> #include <QtCore/qplugin.h>
#include <QtDesigner/QtDesigner>
class QGLViewDesignerPlugin: public QObject, public QDesignerCustomWidgetCollectionInterface class QGLViewDesignerPlugin
{ : public QObject
, public QDesignerCustomWidgetCollectionInterface {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID "qad.qglview") Q_PLUGIN_METADATA(IID "qad.qglview")
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
public: public:
QGLViewDesignerPlugin(QObject * parent = 0); QGLViewDesignerPlugin(QObject * parent = 0);
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const; virtual QList<QDesignerCustomWidgetInterface *> customWidgets() const;
private: private:
QList<QDesignerCustomWidgetInterface * > m_widgets; QList<QDesignerCustomWidgetInterface *> m_widgets;
}; };
#endif // QGLVIEW_DESIGNERPLUGIN_H #endif // QGLVIEW_DESIGNERPLUGIN_H

View File

@@ -1,9 +1,11 @@
#include "../glwidget.h"
#include "qglviewplugin.h" #include "qglviewplugin.h"
#include <QtCore/QtPlugin>
#include "../glwidget.h"
#include "glprimitives.h" #include "glprimitives.h"
#include "qglview.h" #include "qglview.h"
#include <QtCore/QtPlugin>
QGLViewPlugin::QGLViewPlugin(QObject * parent): QObject(parent) { QGLViewPlugin::QGLViewPlugin(QObject * parent): QObject(parent) {
m_initialized = false; m_initialized = false;
@@ -11,8 +13,7 @@ QGLViewPlugin::QGLViewPlugin(QObject * parent): QObject(parent) {
void QGLViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) { void QGLViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized) if (m_initialized) return;
return;
// Add extension registrations, etc. here // Add extension registrations, etc. here
@@ -30,21 +31,24 @@ QWidget * QGLViewPlugin::createWidget(QWidget * parent) {
if (m_initialized) { if (m_initialized) {
auto axis = new GLObjectBase(); auto axis = new GLObjectBase();
GLObjectBase * obj; GLObjectBase * obj;
float al = 1.; float al = 1.;
obj = new GLPrimitiveLine(QVector3D(0, 0, -al), QVector3D(0, 0, al)); obj = new GLPrimitiveLine(QVector3D(0, 0, -al), QVector3D(0, 0, al));
obj->material().color_diffuse = Qt::darkBlue; obj->setAcceptLight(false); obj->material().color_diffuse = Qt::darkBlue;
obj->setAcceptLight(false);
obj->setSelectable(false); obj->setSelectable(false);
axis->addChild(obj); axis->addChild(obj);
obj = new GLPrimitiveLine(QVector3D(-al, 0, 0), QVector3D(al, 0, 0)); obj = new GLPrimitiveLine(QVector3D(-al, 0, 0), QVector3D(al, 0, 0));
obj->material().color_diffuse = Qt::darkRed; obj->setAcceptLight(false); obj->material().color_diffuse = Qt::darkRed;
obj->setAcceptLight(false);
obj->setSelectable(false); obj->setSelectable(false);
axis->addChild(obj); axis->addChild(obj);
obj = new GLPrimitiveLine(QVector3D(0, -al, 0), QVector3D(0, al, 0)); obj = new GLPrimitiveLine(QVector3D(0, -al, 0), QVector3D(0, al, 0));
obj->material().color_diffuse = Qt::darkGreen; obj->setAcceptLight(false); obj->material().color_diffuse = Qt::darkGreen;
obj->setAcceptLight(false);
obj->setSelectable(false); obj->setSelectable(false);
axis->addChild(obj); axis->addChild(obj);
w->view()->addObject(axis); w->view()->addObject(axis);
auto cam_light = new Light(); auto cam_light = new Light();
cam_light->intensity = 0.5; cam_light->intensity = 0.5;
cam_light->setName("Camera_Light"); cam_light->setName("Camera_Light");
w->view()->camera()->addChild(cam_light); w->view()->camera()->addChild(cam_light);
@@ -92,4 +96,3 @@ QString QGLViewPlugin::domXml() const {
QString QGLViewPlugin::includeFile() const { QString QGLViewPlugin::includeFile() const {
return QLatin1String("glwidget.h"); return QLatin1String("glwidget.h");
} }

View File

@@ -5,8 +5,9 @@
#include <QtUiPlugin/QDesignerCustomWidgetInterface> #include <QtUiPlugin/QDesignerCustomWidgetInterface>
class QGLViewPlugin: public QObject, public QDesignerCustomWidgetInterface class QGLViewPlugin
{ : public QObject
, public QDesignerCustomWidgetInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface) Q_INTERFACES(QDesignerCustomWidgetInterface)
@@ -27,7 +28,6 @@ public:
private: private:
bool m_initialized; bool m_initialized;
}; };
#endif //QGLVIEWPLUGIN_H #endif // QGLVIEWPLUGIN_H

View File

@@ -1,51 +1,53 @@
/* /*
QGLView QGLView
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "qglview.h" #include "qglview.h"
#include "glmesh.h" #include "glmesh.h"
#include "gltexture_manager.h" #include "gltexture_manager.h"
#include <QApplication>
#include <QKeyEvent>
#include <QOpenGLTexture>
#include <chunkstream.h> #include <chunkstream.h>
#include <qad_types.h> #include <qad_types.h>
#include <QApplication>
#include <QOpenGLTexture>
#include <QKeyEvent>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) { QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
setIcon(QIcon(":/icons/qglview.png")); setIcon(QIcon(":/icons/qglview.png"));
is_init = false; is_init = false;
timer = 0; timer = 0;
hoverHaloColor_ = QColor(195, 140, 255); hoverHaloColor_ = QColor(195, 140, 255);
selectionHaloColor_ = QColor(175, 255, 140); selectionHaloColor_ = QColor(175, 255, 140);
lineWidth_ = 1.; lineWidth_ = 1.;
max_anisotropic = 1; max_anisotropic = 1;
max_texture_chanels = 8; max_texture_chanels = 8;
lightEnabled_ = true; lightEnabled_ = true;
shaders_supported = false; shaders_supported = false;
fps_cnt = 0; fps_cnt = 0;
fps_tm = fps_ = 0.; fps_tm = fps_ = 0.;
fogColor_ = Qt::darkGray; fogColor_ = Qt::darkGray;
fogDensity_ = 0.; fogDensity_ = 0.;
fogDecay_ = 10.; fogDecay_ = 10.;
hoverHaloFill_ = selectionHaloFill_ = 0.15f; hoverHaloFill_ = selectionHaloFill_ = 0.15f;
//lmode = Simple; // lmode = Simple;
setFeature(qglFXAA, false); setFeature(qglFXAA, false);
setFeature(qglAnisotropicLevel, 8); setFeature(qglAnisotropicLevel, 8);
setFeature(qglEyeAccomodationEnabled, false); setFeature(qglEyeAccomodationEnabled, false);
@@ -72,16 +74,16 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
setFeature(qglDepthOfFieldDiaphragm, 8.); setFeature(qglDepthOfFieldDiaphragm, 8.);
hoverHalo_ = selectionHalo_ = true; hoverHalo_ = selectionHalo_ = true;
fogEnabled_ = shaders_bind = false; fogEnabled_ = shaders_bind = false;
rmode = ObjectBase::Fill; rmode = ObjectBase::Fill;
scene_ = new Scene(); scene_ = new Scene();
connect(scene_, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); connect(scene_, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed())); connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed()));
connect(scene_, SIGNAL(__objectDeleted(ObjectBase*)), this, SLOT(__objectDeleted(ObjectBase*))); connect(scene_, SIGNAL(__objectDeleted(ObjectBase *)), this, SLOT(__objectDeleted(ObjectBase *)));
default_camera = new Camera(); default_camera = new Camera();
default_camera->setPos(QVector3D(2, 2, 2)); default_camera->setPos(QVector3D(2, 2, 2));
default_camera->setAim(QVector3D()); default_camera->setAim(QVector3D());
camera_ = default_camera; camera_ = default_camera;
// qDebug() << camera_->aim(); // qDebug() << camera_->aim();
default_camera->setName("Camera"); default_camera->setName("Camera");
emit cameraPosChanged(default_camera->pos()); emit cameraPosChanged(default_camera->pos());
@@ -112,27 +114,25 @@ void QGLView::start(float freq) {
} }
QList<Light * > QGLView::selectedLights() const { QList<Light *> QGLView::selectedLights() const {
QList<Light * > ret; QList<Light *> ret;
ObjectBaseList sol = scene_->selectedObjects(); ObjectBaseList sol = scene_->selectedObjects();
foreach (ObjectBase * o, sol) foreach(ObjectBase * o, sol)
if (o->type() == ObjectBase::glLight) if (o->type() == ObjectBase::glLight) ret << (Light *)o;
ret << (Light*)o;
return ret; return ret;
} }
QList<Camera * > QGLView::selectedCameras() const { QList<Camera *> QGLView::selectedCameras() const {
QList<Camera * > ret; QList<Camera *> ret;
ObjectBaseList sol = scene_->selectedObjects(); ObjectBaseList sol = scene_->selectedObjects();
for (ObjectBase * o : sol) { for (ObjectBase * o: sol) {
if (o->type() == ObjectBase::glCamera) ret << (Camera*)o; if (o->type() == ObjectBase::glCamera) ret << (Camera *)o;
} }
return ret; return ret;
} }
void QGLView::resizeEvent(QResizeEvent * e) { void QGLView::resizeEvent(QResizeEvent * e) {
renderLater(); renderLater();
mouse.resize(); mouse.resize();
@@ -142,7 +142,7 @@ void QGLView::resizeEvent(QResizeEvent * e) {
void QGLView::timerEvent(QTimerEvent *) { void QGLView::timerEvent(QTimerEvent *) {
renderNow(); renderNow();
Qt::KeyboardModifiers km = QApplication::keyboardModifiers(); Qt::KeyboardModifiers km = QApplication::keyboardModifiers();
foreach (int i, keys_) foreach(int i, keys_)
emit keyEvent((Qt::Key)i, km); emit keyEvent((Qt::Key)i, km);
} }
@@ -157,8 +157,8 @@ void QGLView::render() {
fps_cnt++; fps_cnt++;
if (fps_tm < 1000.) return; if (fps_tm < 1000.) return;
time.restart(); time.restart();
fps_ = fps_cnt / fps_tm * 1000.; fps_ = fps_cnt / fps_tm * 1000.;
fps_tm = 0.; fps_tm = 0.;
fps_cnt = 0; fps_cnt = 0;
} }
@@ -179,7 +179,7 @@ void QGLView::initialize() {
renderer_.reloadShaders(); renderer_.reloadShaders();
renderer_.init(width(), height()); renderer_.init(width(), height());
scene_->reinitAll(); scene_->reinitAll();
is_init = true; is_init = true;
prev_size = QSize(); prev_size = QSize();
emit glInitializeDone(); emit glInitializeDone();
} }
@@ -207,9 +207,9 @@ void QGLView::resizeGL(int width, int height) {
if (width <= 0 || height <= 0) return; if (width <= 0 || height <= 0) return;
if (prev_size == QSize(width, height)) return; if (prev_size == QSize(width, height)) return;
prev_size = QSize(width, height); prev_size = QSize(width, height);
aspect = float(width) / float(height); aspect = float(width) / float(height);
renderer_.resize(width, height); renderer_.resize(width, height);
//qDebug() << "resize" << width << height; // qDebug() << "resize" << width << height;
iaspect = (aspect == 0.f) ? 0. : 1 / aspect; iaspect = (aspect == 0.f) ? 0. : 1 / aspect;
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
emit glResize(width, height); emit glResize(width, height);

272
qglview.h
View File

@@ -1,62 +1,62 @@
/* /*
QGLView QGLView
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef QGLVIEW_H #ifndef QGLVIEW_H
#define QGLVIEW_H #define QGLVIEW_H
#include "openglwindow.h" #include "glcamera.h"
#include "glframebuffer.h" #include "glframebuffer.h"
#include "glprimitives.h" #include "glprimitives.h"
#include "glcamera.h"
#include "glscene.h" #include "glscene.h"
#include "renderer.h"
#include "mouse_controller.h" #include "mouse_controller.h"
#include "openglwindow.h"
#include "renderer.h"
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QMenu> #include <QMenu>
class QGLView: public OpenGLWindow class QGLView: public OpenGLWindow {
{
friend class RendererSelection; friend class RendererSelection;
Q_OBJECT Q_OBJECT
Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth) Q_PROPERTY(float lineWidth READ lineWidth WRITE setLineWidth)
Q_PROPERTY (float FOV READ FOV WRITE setFOV) Q_PROPERTY(float FOV READ FOV WRITE setFOV)
Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart) Q_PROPERTY(float depthStart READ depthStart WRITE setDepthStart)
Q_PROPERTY (float gamma READ gamma WRITE setGamma) Q_PROPERTY(float gamma READ gamma WRITE setGamma)
Q_PROPERTY (bool autoExposure READ autoExposure WRITE setAutoExposure) Q_PROPERTY(bool autoExposure READ autoExposure WRITE setAutoExposure)
Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor) Q_PROPERTY(QColor fogColor READ fogColor WRITE setFogColor)
Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled) Q_PROPERTY(bool fogEnabled READ isFogEnabled WRITE setFogEnabled)
Q_PROPERTY (float fogDensity READ fogDensity WRITE setFogDensity) Q_PROPERTY(float fogDensity READ fogDensity WRITE setFogDensity)
Q_PROPERTY (float fogDecay READ fogDecay WRITE setFogDecay) Q_PROPERTY(float fogDecay READ fogDecay WRITE setFogDecay)
Q_PROPERTY (int renderMode READ renderMode WRITE setRenderMode) Q_PROPERTY(int renderMode READ renderMode WRITE setRenderMode)
Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled) Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled) Q_PROPERTY(bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled) Q_PROPERTY(bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit) Q_PROPERTY(bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled) Q_PROPERTY(bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor) Q_PROPERTY(QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
Q_PROPERTY (float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha) Q_PROPERTY(float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled) Q_PROPERTY(bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor) Q_PROPERTY(QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
Q_PROPERTY (float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha) Q_PROPERTY(float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
Q_PROPERTY (Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton) Q_PROPERTY(Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton)
Q_PROPERTY (Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier) Q_PROPERTY(Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier)
Q_PROPERTY (Scene::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) Q_PROPERTY(Scene::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
public: public:
QGLView(); QGLView();
@@ -100,82 +100,89 @@ public:
void stop(); void stop();
void start(float freq = 0.); void start(float freq = 0.);
float lineWidth() const {return lineWidth_;} float lineWidth() const { return lineWidth_; }
float FOV() const {return camera()->FOV();} float FOV() const { return camera()->FOV(); }
float depthStart() const {return camera()->depthStart();} float depthStart() const { return camera()->depthStart(); }
float currentFPS() const {return fps_;} float currentFPS() const { return fps_; }
float gamma() const {return renderer_.gamma_;} float gamma() const { return renderer_.gamma_; }
bool autoExposure() const {return renderer_.tone_proc.enabled;} bool autoExposure() const { return renderer_.tone_proc.enabled; }
int maxAnisotropicLevel() const {return max_anisotropic;} int maxAnisotropicLevel() const { return max_anisotropic; }
QString environmentMapFile() const {return renderer_.tex_env.fileHDR();} QString environmentMapFile() const { return renderer_.tex_env.fileHDR(); }
QColor fogColor() const {return fogColor_;} QColor fogColor() const { return fogColor_; }
float fogDensity() const {return fogDensity_;} float fogDensity() const { return fogDensity_; }
float fogDecay() const {return fogDecay_;} float fogDecay() const { return fogDecay_; }
bool isFogEnabled() const {return fogEnabled_;} bool isFogEnabled() const { return fogEnabled_; }
bool isLightEnabled() const {return lightEnabled_;} bool isLightEnabled() const { return lightEnabled_; }
bool isGrabMouseEnabled() const {return mouse.isGrabMouseEnabled();} bool isGrabMouseEnabled() const { return mouse.isGrabMouseEnabled(); }
bool isMouseRotateEnabled() const {return mouse.isMouseRotateEnabled();} bool isMouseRotateEnabled() const { return mouse.isMouseRotateEnabled(); }
bool isMouseSelectionEnabled() const {return mouse.isMouseSelectionEnabled();} bool isMouseSelectionEnabled() const { return mouse.isMouseSelectionEnabled(); }
bool isCameraOrbit() const {return mouse.isCameraOrbit();} bool isCameraOrbit() const { return mouse.isCameraOrbit(); }
bool isHoverHaloEnabled() const {return hoverHalo_;} bool isHoverHaloEnabled() const { return hoverHalo_; }
QColor hoverHaloColor() const {return hoverHaloColor_;} QColor hoverHaloColor() const { return hoverHaloColor_; }
float hoverHaloFillAlpha() const {return hoverHaloFill_;} float hoverHaloFillAlpha() const { return hoverHaloFill_; }
bool isSelectionHaloEnabled() const {return selectionHalo_;} bool isSelectionHaloEnabled() const { return selectionHalo_; }
QColor selectionHaloColor() const {return selectionHaloColor_;} QColor selectionHaloColor() const { return selectionHaloColor_; }
float selectionHaloFillAlpha() const {return selectionHaloFill_;} float selectionHaloFillAlpha() const { return selectionHaloFill_; }
QVariant feature(Feature f) const {return features_.value(int(f));} QVariant feature(Feature f) const { return features_.value(int(f)); }
QVariant setFeature(Feature f, const QVariant & value) {QVariant ret = features_.value(int(f)); features_[int(f)] = value; return ret;} QVariant setFeature(Feature f, const QVariant & value) {
bool isFeatureEnabled(Feature f) const {return features_[int(f)].toBool();} QVariant ret = features_.value(int(f));
features_[int(f)] = value;
return ret;
}
bool isFeatureEnabled(Feature f) const { return features_[int(f)].toBool(); }
int renderMode() const {return (int)rmode;} int renderMode() const { return (int)rmode; }
void setRenderMode(int mode) {rmode = (ObjectBase::RenderMode)mode;} void setRenderMode(int mode) { rmode = (ObjectBase::RenderMode)mode; }
bool isServiceMode() const {return renderer_.edit_mode;} bool isServiceMode() const { return renderer_.edit_mode; }
void setServiceMode(bool yes) {renderer_.edit_mode = yes;} void setServiceMode(bool yes) { renderer_.edit_mode = yes; }
Scene::SelectionMode selectionMode() const {return scene_->selectionMode();} Scene::SelectionMode selectionMode() const { return scene_->selectionMode(); }
Qt::MouseButton selectionButton() const {return mouse.selectionButton();} Qt::MouseButton selectionButton() const { return mouse.selectionButton(); }
Qt::KeyboardModifier selectionModifier() const {return mouse.selectionModifier();} Qt::KeyboardModifier selectionModifier() const { return mouse.selectionModifier(); }
void setSelectionMode(Scene::SelectionMode m) {scene_->setSelectionMode(m);} void setSelectionMode(Scene::SelectionMode m) { scene_->setSelectionMode(m); }
void setSelectionButton(Qt::MouseButton v) {mouse.setSelectionButton(v);} void setSelectionButton(Qt::MouseButton v) { mouse.setSelectionButton(v); }
void setSelectionModifier(Qt::KeyboardModifier v) {mouse.setSelectionModifier(v);} void setSelectionModifier(Qt::KeyboardModifier v) { mouse.setSelectionModifier(v); }
void selectObject(ObjectBase * o, bool add_to_selection = false) {scene_->selectObject(o, add_to_selection);} void selectObject(ObjectBase * o, bool add_to_selection = false) { scene_->selectObject(o, add_to_selection); }
void clearSelection() {scene_->clearSelection();} void clearSelection() { scene_->clearSelection(); }
ObjectBaseList selectedObjects(bool top_only = false) const {return scene_->selectedObjects(top_only);} ObjectBaseList selectedObjects(bool top_only = false) const { return scene_->selectedObjects(top_only); }
QList<Light * > selectedLights() const; QList<Light *> selectedLights() const;
QList<Camera * > selectedCameras() const; QList<Camera *> selectedCameras() const;
ObjectBase * selectedObject() const {return scene_->selectedObject();} ObjectBase * selectedObject() const { return scene_->selectedObject(); }
TextureManager * textureManager() {return renderer_.textures_manager;} TextureManager * textureManager() { return renderer_.textures_manager; }
void reloadTextures() {renderer_.markReloadTextures();} void reloadTextures() { renderer_.markReloadTextures(); }
Scene * scene() {return scene_;} Scene * scene() { return scene_; }
void focusOn(const Box3D & bb); void focusOn(const Box3D & bb);
void setCameraLightMode(CameraLightMode m) {renderer_.setCameraLightMode(m);} void setCameraLightMode(CameraLightMode m) { renderer_.setCameraLightMode(m); }
CameraLightMode cameraLightMode() const {return (CameraLightMode)renderer_.cameraLightMode();} CameraLightMode cameraLightMode() const { return (CameraLightMode)renderer_.cameraLightMode(); }
Camera * camera() {return camera_;} Camera * camera() { return camera_; }
const Camera * camera() const {return camera_;} const Camera * camera() const { return camera_; }
void setCamera(Camera * camera) {camera_ = camera;} void setCamera(Camera * camera) { camera_ = camera; }
void setDefaultCamera() {camera_ = default_camera;} void setDefaultCamera() { camera_ = default_camera; }
bool isDefaultCamera() const {return camera_ == default_camera;} bool isDefaultCamera() const { return camera_ == default_camera; }
QByteArray saveCamera(); QByteArray saveCamera();
void restoreCamera(const QByteArray & ba); void restoreCamera(const QByteArray & ba);
QByteArray saveFeatures(); QByteArray saveFeatures();
void restoreFeatures(const QByteArray & ba); void restoreFeatures(const QByteArray & ba);
QImage materialThumbnail(Material * m) {return renderer_.materialThumbnail(m);} QImage materialThumbnail(Material * m) { return renderer_.materialThumbnail(m); }
void setCurrentAction(RendererService::HandleAction ha) {renderer_.rend_service.setCurrentAction(ha);} void setCurrentAction(RendererService::HandleAction ha) { renderer_.rend_service.setCurrentAction(ha); }
void setContextActions(QList<QAction*> al) {context_menu.clear(); context_menu.addActions(al);} void setContextActions(QList<QAction *> al) {
void popupMenu(const QPoint &pos, QAction *at = nullptr) {context_menu.popup(pos, at);} context_menu.clear();
void setGrabImage(bool on) {renderer_.setGrabImage(on);} context_menu.addActions(al);
bool isGrabImage() const {return renderer_.isGrabImage();} }
QImage getImage() const {return renderer_.getImage();} void popupMenu(const QPoint & pos, QAction * at = nullptr) { context_menu.popup(pos, at); }
void setGrabImage(bool on) { renderer_.setGrabImage(on); }
bool isGrabImage() const { return renderer_.isGrabImage(); }
QImage getImage() const { return renderer_.getImage(); }
GLfloat aspect, iaspect; GLfloat aspect, iaspect;
Renderer renderer_; Renderer renderer_;
@@ -184,15 +191,15 @@ protected:
void render(); void render();
void resizeEvent(QResizeEvent * e); void resizeEvent(QResizeEvent * e);
void timerEvent(QTimerEvent * ); void timerEvent(QTimerEvent *);
void initialize(); void initialize();
void resizeGL(int width, int height); void resizeGL(int width, int height);
void mousePressEvent(QMouseEvent * e) {mouse.mousePressEvent(e);} void mousePressEvent(QMouseEvent * e) { mouse.mousePressEvent(e); }
void mouseMoveEvent(QMouseEvent * e) {mouse.mouseMoveEvent(e);} void mouseMoveEvent(QMouseEvent * e) { mouse.mouseMoveEvent(e); }
void mouseReleaseEvent(QMouseEvent * e) {mouse.mouseReleaseEvent(e);} void mouseReleaseEvent(QMouseEvent * e) { mouse.mouseReleaseEvent(e); }
void wheelEvent(QWheelEvent * e) {mouse.wheelEvent(e);} void wheelEvent(QWheelEvent * e) { mouse.wheelEvent(e); }
void mouseDoubleClickEvent(QMouseEvent * e) {mouse.mouseDoubleClickEvent(e);} void mouseDoubleClickEvent(QMouseEvent * e) { mouse.mouseDoubleClickEvent(e); }
void leaveEvent(QEvent * ); void leaveEvent(QEvent *);
void keyPressEvent(QKeyEvent * e); void keyPressEvent(QKeyEvent * e);
void keyReleaseEvent(QKeyEvent * e); void keyReleaseEvent(QKeyEvent * e);
@@ -205,7 +212,7 @@ private:
bool setupViewport(); bool setupViewport();
Scene * scene_; Scene * scene_;
Camera * camera_, * default_camera; Camera *camera_, *default_camera;
MouseController mouse; MouseController mouse;
QMenu context_menu; QMenu context_menu;
QSet<int> keys_; QSet<int> keys_;
@@ -229,30 +236,33 @@ private slots:
void __objectDeleted(ObjectBase * o); void __objectDeleted(ObjectBase * o);
public slots: public slots:
void setLineWidth(const float & arg) {lineWidth_ = arg;} void setLineWidth(const float & arg) { lineWidth_ = arg; }
void setFOV(const float & arg) {camera()->setFOV(arg);} void setFOV(const float & arg) { camera()->setFOV(arg); }
void setDepthStart(const float & arg) {camera()->setDepthStart(arg);} void setDepthStart(const float & arg) { camera()->setDepthStart(arg); }
void setGamma(const float & arg) {renderer_.gamma_ = arg;} void setGamma(const float & arg) { renderer_.gamma_ = arg; }
void setAutoExposure(bool arg) {renderer_.tone_proc.enabled = arg;} void setAutoExposure(bool arg) { renderer_.tone_proc.enabled = arg; }
void setEnvironmentMapFile(QString file) {renderer_.tex_env.setFileHDR(file); renderer_.recreateMaterialThumbnails(true);} void setEnvironmentMapFile(QString file) {
void setFogColor(const QColor & arg) {fogColor_ = arg;} renderer_.tex_env.setFileHDR(file);
void setFogDensity(const float & arg) {fogDensity_ = arg;} renderer_.recreateMaterialThumbnails(true);
void setFogDecay(const float & arg) {fogDecay_ = arg;} }
void setFogEnabled(const bool & arg) {fogEnabled_ = arg;} void setFogColor(const QColor & arg) { fogColor_ = arg; }
void setLightEnabled(const bool & arg) {lightEnabled_ = arg;} void setFogDensity(const float & arg) { fogDensity_ = arg; }
void setGrabMouseEnabled(const bool & arg) {mouse.setGrabMouseEnabled(arg);} void setFogDecay(const float & arg) { fogDecay_ = arg; }
void setMouseRotateEnabled(const bool & arg) {mouse.setMouseRotateEnabled(arg);} void setFogEnabled(const bool & arg) { fogEnabled_ = arg; }
void setMouseSelectionEnabled(const bool & arg) {mouse.setMouseSelectionEnabled(arg);} void setLightEnabled(const bool & arg) { lightEnabled_ = arg; }
void setCustomMouseMove(const bool & arg) {mouse.setCustomMouseMove(arg);} void setGrabMouseEnabled(const bool & arg) { mouse.setGrabMouseEnabled(arg); }
void setCameraOrbit(const bool & arg) {mouse.setCameraOrbit(arg);} void setMouseRotateEnabled(const bool & arg) { mouse.setMouseRotateEnabled(arg); }
void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;} void setMouseSelectionEnabled(const bool & arg) { mouse.setMouseSelectionEnabled(arg); }
void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;} void setCustomMouseMove(const bool & arg) { mouse.setCustomMouseMove(arg); }
void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;} void setCameraOrbit(const bool & arg) { mouse.setCameraOrbit(arg); }
void setSelectionHaloEnabled(const bool & arg) {selectionHalo_ = arg;} void setHoverHaloEnabled(const bool & arg) { hoverHalo_ = arg; }
void setSelectionHaloColor(const QColor & arg) {selectionHaloColor_ = arg;} void setHoverHaloColor(const QColor & arg) { hoverHaloColor_ = arg; }
void setSelectionHaloFillAlpha(const float & arg) {selectionHaloFill_ = arg;} void setHoverHaloFillAlpha(const float & arg) { hoverHaloFill_ = arg; }
void setSelectionHaloEnabled(const bool & arg) { selectionHalo_ = arg; }
void setSelectionHaloColor(const QColor & arg) { selectionHaloColor_ = arg; }
void setSelectionHaloFillAlpha(const float & arg) { selectionHaloFill_ = arg; }
void reloadShaders() {renderer_.reloadShaders();} void reloadShaders() { renderer_.reloadShaders(); }
signals: signals:
void glBeginPaint(); void glBeginPaint();
@@ -273,7 +283,7 @@ signals:
void selectionChanged(); void selectionChanged();
void objectsPositionChanged(); void objectsPositionChanged();
void materialsChanged(); void materialsChanged();
void materialThumbnailCreated(Material*); void materialThumbnailCreated(Material *);
void doubleClick(); void doubleClick();
}; };

View File

@@ -1,25 +1,26 @@
/* /*
QGLViewWindow QGLViewWindow
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "qglview_window.h"
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include "qglview_window.h"
int main(int argc, char ** argv) { int main(int argc, char ** argv) {
QApplication a(argc, argv); QApplication a(argc, argv);
@@ -28,7 +29,7 @@ int main(int argc, char ** argv) {
w.show(); w.show();
QStringList al(a.arguments()); QStringList al(a.arguments());
al.pop_front(); al.pop_front();
foreach (QString s, al) foreach(QString s, al)
w.loadFile(s); w.loadFile(s);
return a.exec(); return a.exec();
} }

View File

@@ -1,29 +1,31 @@
/* /*
QGLViewWindow QGLViewWindow
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "qglview_window.h" #include "qglview_window.h"
#include "renderer.h"
#include "glwidget.h"
#include "gltexture_manager.h" #include "gltexture_manager.h"
#include "glwidget.h"
#include "qad_types.h"
#include "renderer.h"
#include <QGraphicsRectItem> #include <QGraphicsRectItem>
#include <QImageReader> #include <QImageReader>
#include <QMessageBox> #include <QMessageBox>
#include "qad_types.h"
QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLViewWindow() { QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLViewWindow() {
@@ -33,11 +35,11 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
extensions = "All(" + supportedFormats().join(" ") + " *.qgl)"; extensions = "All(" + supportedFormats().join(" ") + " *.qgl)";
extensions += ";;QGLEngine(*.qgl)"; extensions += ";;QGLEngine(*.qgl)";
//view->view()->camera()->setPos(QVector3D(2, 2, 2)); // view->view()->camera()->setPos(QVector3D(2, 2, 2));
//view->view()->camera()->setAim(QVector3D()); // view->view()->camera()->setAim(QVector3D());
//view->view()->camera()->flyToDistance(2.); // view->view()->camera()->flyToDistance(2.);
// view->setFrameShape(QFrame::NoFrame); // view->setFrameShape(QFrame::NoFrame);
view->view()->setMouseRotateEnabled(true); view->view()->setMouseRotateEnabled(true);
view->view()->setMouseSelectionEnabled(true); view->view()->setMouseSelectionEnabled(true);
view->view()->setSelectionHaloEnabled(true); view->view()->setSelectionHaloEnabled(true);
@@ -70,10 +72,10 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
spinDOFSpeed->setValue(view->view()->feature(QGLView::qglDepthOfFieldAutoFocusSpeed).toDouble()); spinDOFSpeed->setValue(view->view()->feature(QGLView::qglDepthOfFieldAutoFocusSpeed).toDouble());
view->view()->start(-1); view->view()->start(-1);
startTimer(1000/60); startTimer(1000 / 60);
connect(view->view(), SIGNAL(keyEvent(Qt::Key, Qt::KeyboardModifiers)), this, SLOT(view_keyEvent(Qt::Key, Qt::KeyboardModifiers))); connect(view->view(), SIGNAL(keyEvent(Qt::Key, Qt::KeyboardModifiers)), this, SLOT(view_keyEvent(Qt::Key, Qt::KeyboardModifiers)));
//connect(matEditor, SIGNAL(changed()), this, SLOT(materialChanged())); // connect(matEditor, SIGNAL(changed()), this, SLOT(materialChanged()));
sceneTree->assignQGLView(view->view()); sceneTree->assignQGLView(view->view());
matEditor->assignQGLView(view->view()); matEditor->assignQGLView(view->view());
objectEditor->assignQGLView(view->view()); objectEditor->assignQGLView(view->view());
@@ -82,14 +84,14 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
session.load(); session.load();
//loadFile("axis.DAE.qgl"); // loadFile("axis.DAE.qgl");
//matEditor->setMaterial(const_cast<ObjectBase*>(view->view()->scene()->rootObject()->child(0))->material()); // matEditor->setMaterial(const_cast<ObjectBase*>(view->view()->scene()->rootObject()->child(0))->material());
/*Scene * sc = loadScene("truck.obj"); /*Scene * sc = loadScene("truck.obj");
//view->view()->scene()->addScene(sc); //view->view()->scene()->addScene(sc);
sc->rootObject()->moveY(-8); sc->rootObject()->moveY(-8);
for (int i = 0; i < 7; ++i) { for (int i = 0; i < 7; ++i) {
sc->rootObject()->moveY(2); sc->rootObject()->moveY(2);
view->view()->scene()->addScene(sc); view->view()->scene()->addScene(sc);
} }
//view->view()->scene()->dump(); //view->view()->scene()->dump();
delete sc;*/ delete sc;*/
@@ -98,7 +100,7 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
QGLViewWindow::~QGLViewWindow() { QGLViewWindow::~QGLViewWindow() {
session.save(); session.save();
//delete ps; // delete ps;
} }
@@ -111,8 +113,8 @@ void QGLViewWindow::changeEvent(QEvent * e) {
} }
void QGLViewWindow::timerEvent(QTimerEvent * ) { void QGLViewWindow::timerEvent(QTimerEvent *) {
//static double t = 0.; // static double t = 0.;
//((RendererSimple*)(view->view()->renderer()))->mpos = view->view()->mapFromGlobal(QCursor::pos()); //((RendererSimple*)(view->view()->renderer()))->mpos = view->view()->mapFromGlobal(QCursor::pos());
statusBar()->showMessage(QString("FPS: %1").arg(QString::number(view->view()->currentFPS(), 'f', 2))); statusBar()->showMessage(QString("FPS: %1").arg(QString::number(view->view()->currentFPS(), 'f', 2)));
} }
@@ -123,15 +125,18 @@ void QGLViewWindow::loadFile(const QString & path, bool import) {
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
QFileInfo fi(path); QFileInfo fi(path);
Scene * s = nullptr; Scene * s = nullptr;
if (fi.suffix().toLower() == "qgl") s = loadFromQGLFile(path); if (fi.suffix().toLower() == "qgl")
else s = loadScene(path); s = loadFromQGLFile(path);
else
s = loadScene(path);
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
if (!s) { if (!s) {
QMessageBox::critical(this, "Import", "Can`t load " + path + "!"); QMessageBox::critical(this, "Import", "Can`t load " + path + "!");
return; return;
} }
s->setName(fi.baseName()); s->setName(fi.baseName());
if (import) view->scene()->addScene(s); if (import)
view->scene()->addScene(s);
else { else {
TextureManager::clearSearchPathes(); TextureManager::clearSearchPathes();
view->scene()->assignFrom(s); view->scene()->assignFrom(s);
@@ -143,9 +148,9 @@ void QGLViewWindow::loadFile(const QString & path, bool import) {
void QGLViewWindow::on_actionReset_triggered() { void QGLViewWindow::on_actionReset_triggered() {
///view->view()->removeObject(axis, false); /// view->view()->removeObject(axis, false);
view->view()->scene()->clear(); view->view()->scene()->clear();
///view->view()->addObject(axis); /// view->view()->addObject(axis);
} }
@@ -153,7 +158,7 @@ void QGLViewWindow::on_actionImport_triggered() {
QStringList fl = QFileDialog::getOpenFileNames(this, "Select files", prev_path, extensions); QStringList fl = QFileDialog::getOpenFileNames(this, "Select files", prev_path, extensions);
if (fl.isEmpty()) return; if (fl.isEmpty()) return;
prev_path = fl.back(); prev_path = fl.back();
foreach (QString f, fl) foreach(QString f, fl)
loadFile(f, true); loadFile(f, true);
} }
@@ -161,8 +166,7 @@ void QGLViewWindow::on_actionImport_triggered() {
void QGLViewWindow::on_actionSave_triggered() { void QGLViewWindow::on_actionSave_triggered() {
QString f = QFileDialog::getSaveFileName(this, "Select file", prev_path, "QGLView(*.qgl)"); QString f = QFileDialog::getSaveFileName(this, "Select file", prev_path, "QGLView(*.qgl)");
if (f.isEmpty()) return; if (f.isEmpty()) return;
if (f.right(4).toLower() != ".qgl") if (f.right(4).toLower() != ".qgl") f += ".qgl";
f += ".qgl";
prev_path = f; prev_path = f;
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
saveToQGLFile(f, view->scene()); saveToQGLFile(f, view->scene());
@@ -175,11 +179,10 @@ void QGLViewWindow::on_actionSaveSelected_triggered() {
if (!sel_obj) return; if (!sel_obj) return;
QString f = QFileDialog::getSaveFileName(this, "Select file", prev_path, "QGLView(*.qgl)"); QString f = QFileDialog::getSaveFileName(this, "Select file", prev_path, "QGLView(*.qgl)");
if (f.isEmpty()) return; if (f.isEmpty()) return;
if (f.right(4).toLower() != ".qgl") if (f.right(4).toLower() != ".qgl") f += ".qgl";
f += ".qgl";
prev_path = f; prev_path = f;
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
///saveToQGLFile(f, sel_obj); /// saveToQGLFile(f, sel_obj);
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
} }
@@ -193,10 +196,9 @@ void QGLViewWindow::on_actionOpen_triggered() {
void QGLViewWindow::view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m) { void QGLViewWindow::view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m) {
//qDebug() << k; // qDebug() << k;
double spd = 0.2; double spd = 0.2;
if (m.testFlag(Qt::ShiftModifier)) if (m.testFlag(Qt::ShiftModifier)) spd = 0.5;
spd = 0.5;
switch (k) { switch (k) {
case Qt::Key_W: view->view()->camera()->moveForward(spd); break; case Qt::Key_W: view->view()->camera()->moveForward(spd); break;
case Qt::Key_S: view->view()->camera()->moveBackward(spd); break; case Qt::Key_S: view->view()->camera()->moveBackward(spd); break;
@@ -208,37 +210,37 @@ void QGLViewWindow::view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m) {
void QGLViewWindow::on_actionArrow_triggered(bool on) { void QGLViewWindow::on_actionArrow_triggered(bool on) {
actionArrow ->setChecked(true); actionArrow->setChecked(true);
actionMove ->setChecked(false); actionMove->setChecked(false);
actionRotate->setChecked(false); actionRotate->setChecked(false);
actionScale ->setChecked(false); actionScale->setChecked(false);
view->view()->setCurrentAction(RendererService::haNoAction); view->view()->setCurrentAction(RendererService::haNoAction);
} }
void QGLViewWindow::on_actionMove_triggered(bool on) { void QGLViewWindow::on_actionMove_triggered(bool on) {
actionArrow ->setChecked(false); actionArrow->setChecked(false);
actionMove ->setChecked(true); actionMove->setChecked(true);
actionRotate->setChecked(false); actionRotate->setChecked(false);
actionScale ->setChecked(false); actionScale->setChecked(false);
view->view()->setCurrentAction(RendererService::haMove); view->view()->setCurrentAction(RendererService::haMove);
} }
void QGLViewWindow::on_actionRotate_triggered(bool on) { void QGLViewWindow::on_actionRotate_triggered(bool on) {
actionArrow ->setChecked(false); actionArrow->setChecked(false);
actionMove ->setChecked(false); actionMove->setChecked(false);
actionRotate->setChecked(true); actionRotate->setChecked(true);
actionScale ->setChecked(false); actionScale->setChecked(false);
view->view()->setCurrentAction(RendererService::haRotate); view->view()->setCurrentAction(RendererService::haRotate);
} }
void QGLViewWindow::on_actionScale_triggered(bool on) { void QGLViewWindow::on_actionScale_triggered(bool on) {
actionArrow ->setChecked(false); actionArrow->setChecked(false);
actionMove ->setChecked(false); actionMove->setChecked(false);
actionRotate->setChecked(false); actionRotate->setChecked(false);
actionScale ->setChecked(true); actionScale->setChecked(true);
view->view()->setCurrentAction(RendererService::haScale); view->view()->setCurrentAction(RendererService::haScale);
} }

View File

@@ -1,47 +1,50 @@
/* /*
QGLViewWindow QGLViewWindow
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef QGLVIEWWINDOW_H #ifndef QGLVIEWWINDOW_H
#define QGLVIEWWINDOW_H #define QGLVIEWWINDOW_H
#include <QTranslator> #include "formats/loader_assimp.h"
#include <QInputDialog> #include "formats/loader_qgl.h"
#include <QFileDialog> #include "session_manager.h"
#include <QColorDialog> #include "ui_qglview_window.h"
#include <QCloseEvent>
#include <QClipboard> #include <QClipboard>
#include <QCloseEvent>
#include <QColorDialog>
#include <QFileDialog>
#include <QInputDialog>
#include <QRadioButton> #include <QRadioButton>
#include <QUrl> #include <QSplitter>
#include <QThread> #include <QThread>
#include <QTime> #include <QTime>
#include <QSplitter> #include <QTranslator>
#include "ui_qglview_window.h" #include <QUrl>
#include "formats/loader_qgl.h" // #include "renderer_rt.h"
#include "formats/loader_assimp.h"
#include "session_manager.h"
//#include "renderer_rt.h"
#include "qglview.h" #include "qglview.h"
#include "ui_qglview_window.h" #include "ui_qglview_window.h"
class QGLViewWindow: public QMainWindow, public Ui::QGLViewWindow class QGLViewWindow
{ : public QMainWindow
, public Ui::QGLViewWindow {
Q_OBJECT Q_OBJECT
public: public:
QGLViewWindow(QWidget * parent = 0); QGLViewWindow(QWidget * parent = 0);
~QGLViewWindow(); ~QGLViewWindow();
@@ -51,41 +54,41 @@ public:
private: private:
// Qt`s overloaded // Qt`s overloaded
void changeEvent(QEvent * e); void changeEvent(QEvent * e);
void timerEvent(QTimerEvent * ); void timerEvent(QTimerEvent *);
QString extensions; QString extensions;
QTranslator translator; QTranslator translator;
QString prev_path; QString prev_path;
//GLPrimitiveCube * box; // GLPrimitiveCube * box;
Material m; Material m;
SessionManager session; SessionManager session;
bool isChanged; bool isChanged;
private slots: private slots:
void on_groupShadows_clicked(bool val) {view->view()->setFeature(QGLView::qglShadowsEnabled, val);} void on_groupShadows_clicked(bool val) { view->view()->setFeature(QGLView::qglShadowsEnabled, val); }
void on_groupEyeAccomodation_clicked(bool val) {view->view()->setFeature(QGLView::qglEyeAccomodationEnabled, val);} void on_groupEyeAccomodation_clicked(bool val) { view->view()->setFeature(QGLView::qglEyeAccomodationEnabled, val); }
void on_groupBloom_clicked(bool val) {view->view()->setFeature(QGLView::qglBloomEnabled, val);} void on_groupBloom_clicked(bool val) { view->view()->setFeature(QGLView::qglBloomEnabled, val); }
void on_groupMotionBlur_clicked(bool val) {view->view()->setFeature(QGLView::qglMotionBlurEnabled, val);} void on_groupMotionBlur_clicked(bool val) { view->view()->setFeature(QGLView::qglMotionBlurEnabled, val); }
void on_groupReflections_clicked(bool val) {view->view()->setFeature(QGLView::qglReflectionsEnabled, val);} void on_groupReflections_clicked(bool val) { view->view()->setFeature(QGLView::qglReflectionsEnabled, val); }
void on_checkSoftShadows_clicked(bool val) {view->view()->setFeature(QGLView::qglShadowsSoftEnabled, val);} void on_checkSoftShadows_clicked(bool val) { view->view()->setFeature(QGLView::qglShadowsSoftEnabled, val); }
void on_groupSSAO_clicked(bool val) {view->view()->setFeature(QGLView::qglSSAOEnabled, val);} void on_groupSSAO_clicked(bool val) { view->view()->setFeature(QGLView::qglSSAOEnabled, val); }
void on_groupDOF_clicked(bool val) {view->view()->setFeature(QGLView::qglDepthOfFieldEnabled, val);} void on_groupDOF_clicked(bool val) { view->view()->setFeature(QGLView::qglDepthOfFieldEnabled, val); }
void on_checkDOFAutoFocus_clicked(bool val) {view->view()->setFeature(QGLView::qglDepthOfFieldAutoFocusEnabled, val);} void on_checkDOFAutoFocus_clicked(bool val) { view->view()->setFeature(QGLView::qglDepthOfFieldAutoFocusEnabled, val); }
void on_spinDOFFocus_valueChanged(double val) {view->view()->setFeature(QGLView::qglDepthOfFieldFocus, val);} void on_spinDOFFocus_valueChanged(double val) { view->view()->setFeature(QGLView::qglDepthOfFieldFocus, val); }
void on_spinDOFDiaphragm_valueChanged(double val) {view->view()->setFeature(QGLView::qglDepthOfFieldDiaphragm, val);} void on_spinDOFDiaphragm_valueChanged(double val) { view->view()->setFeature(QGLView::qglDepthOfFieldDiaphragm, val); }
void on_spinDOFSpeed_valueChanged(double val) {view->view()->setFeature(QGLView::qglDepthOfFieldAutoFocusSpeed, val);} void on_spinDOFSpeed_valueChanged(double val) { view->view()->setFeature(QGLView::qglDepthOfFieldAutoFocusSpeed, val); }
void on_spinAccom_valueChanged(double val) {view->view()->setFeature(QGLView::qglEyeAccomodationTime, val);} void on_spinAccom_valueChanged(double val) { view->view()->setFeature(QGLView::qglEyeAccomodationTime, val); }
void on_spinAccomMS_valueChanged(double val) {view->view()->setFeature(QGLView::qglEyeAccomodationMaxSpeed, val);} void on_spinAccomMS_valueChanged(double val) { view->view()->setFeature(QGLView::qglEyeAccomodationMaxSpeed, val); }
void on_checkReflectionsBlur_clicked(bool val) {view->view()->setFeature(QGLView::qglReflectionsBlur, val);} void on_checkReflectionsBlur_clicked(bool val) { view->view()->setFeature(QGLView::qglReflectionsBlur, val); }
void on_spinShadowmapSize_valueChanged(double val) {view->view()->setFeature(QGLView::qglShadowsMapSize, val);} void on_spinShadowmapSize_valueChanged(double val) { view->view()->setFeature(QGLView::qglShadowsMapSize, val); }
void on_spinMotionBlurFactor_valueChanged(double val) {view->view()->setFeature(QGLView::qglMotionBlurFactor, val);} void on_spinMotionBlurFactor_valueChanged(double val) { view->view()->setFeature(QGLView::qglMotionBlurFactor, val); }
void on_spinMotionBlurSteps_valueChanged(int val) {view->view()->setFeature(QGLView::qglMotionBlurSteps, val);} void on_spinMotionBlurSteps_valueChanged(int val) { view->view()->setFeature(QGLView::qglMotionBlurSteps, val); }
void on_spinBloomFactor_valueChanged(double val) {view->view()->setFeature(QGLView::qglBloomFactor, val);} void on_spinBloomFactor_valueChanged(double val) { view->view()->setFeature(QGLView::qglBloomFactor, val); }
void on_spinBloomRadius_valueChanged(int val) {view->view()->setFeature(QGLView::qglBloomRadius, val);} void on_spinBloomRadius_valueChanged(int val) { view->view()->setFeature(QGLView::qglBloomRadius, val); }
void on_spinBloomThreshold_valueChanged(double val) {view->view()->setFeature(QGLView::qglBloomThreshold, val);} void on_spinBloomThreshold_valueChanged(double val) { view->view()->setFeature(QGLView::qglBloomThreshold, val); }
void on_spinSSAORadius_valueChanged(int val) {view->view()->setFeature(QGLView::qglSSAORadius, val);} void on_spinSSAORadius_valueChanged(int val) { view->view()->setFeature(QGLView::qglSSAORadius, val); }
void on_actionExit_triggered() {close();} void on_actionExit_triggered() { close(); }
void on_actionReset_triggered(); void on_actionReset_triggered();
void on_actionImport_triggered(); void on_actionImport_triggered();
void on_actionSave_triggered(); void on_actionSave_triggered();
@@ -94,16 +97,16 @@ private slots:
void view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m); void view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m);
void on_pushButton_2_clicked() {view->view()->reloadShaders();} void on_pushButton_2_clicked() { view->view()->reloadShaders(); }
void on_actionArrow_triggered(bool on); void on_actionArrow_triggered(bool on);
void on_actionMove_triggered(bool on); void on_actionMove_triggered(bool on);
void on_actionRotate_triggered(bool on); void on_actionRotate_triggered(bool on);
void on_actionScale_triggered(bool on); void on_actionScale_triggered(bool on);
void on_colorFogBack_colorChanged(const QColor & v) {view->view()->setFogColor(v);} void on_colorFogBack_colorChanged(const QColor & v) { view->view()->setFogColor(v); }
void on_spinFogDensity_valueChanged(double v) {view->view()->setFogDensity(v);} void on_spinFogDensity_valueChanged(double v) { view->view()->setFogDensity(v); }
void on_spinFogDecay_valueChanged(double v) {view->view()->setFogDecay(v);} void on_spinFogDecay_valueChanged(double v) { view->view()->setFogDecay(v); }
void on_pushButton_3_clicked(); void on_pushButton_3_clicked();
@@ -113,7 +116,6 @@ signals:
private: private:
QMatrix4x4 cam_mat; QMatrix4x4 cam_mat;
}; };
#endif // QGLVIEWWINDOW_H #endif // QGLVIEWWINDOW_H

View File

@@ -1,60 +1,68 @@
/* /*
QGL Renderer QGL Renderer
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include "renderer.h"
#include "glmesh.h"
#include "glshaders.h"
#include "gltexture_manager.h"
#include "qglview.h"
#include <QOpenGLExtraFunctions> #include <QOpenGLExtraFunctions>
#include <qad_types.h> #include <qad_types.h>
#include "renderer.h"
#include "qglview.h"
#include "glmesh.h"
#include "gltexture_manager.h"
#include "glshaders.h"
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
Renderer::Renderer(QGLView * view_): RendererBase(view_), Renderer::Renderer(QGLView * view_)
fbo_ds (view_, QVector<GLenum>() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F), : RendererBase(view_)
fbo_out (view_, obrBuffersCount, false, GL_RGBA16F), , fbo_ds(view_, QVector<GLenum>() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F)
rend_mat(this), rend_service(this), rend_selection(this), tone_proc(this), tex_env(view_, 512) { , fbo_out(view_, obrBuffersCount, false, GL_RGBA16F)
quad = Primitive::plane(2., 2.); , rend_mat(this)
cam_light = new Light(); , rend_service(this)
, rend_selection(this)
, tone_proc(this)
, tex_env(view_, 512) {
quad = Primitive::plane(2., 2.);
cam_light = new Light();
cam_light->intensity = 0.75; cam_light->intensity = 0.75;
cam_light->setName("Camera_Light"); cam_light->setName("Camera_Light");
shader_files[srSelectionFill ] = "selection.glsl"; shader_files[srSelectionFill] = "selection.glsl";
shader_files[srSelectionHalo ] = "selection_halo.glsl"; shader_files[srSelectionHalo] = "selection_halo.glsl";
shader_files[srSelectionApply] = "selection_apply.glsl"; shader_files[srSelectionApply] = "selection_apply.glsl";
shader_files[srSelectionFrame] = "selection_frame.glsl"; shader_files[srSelectionFrame] = "selection_frame.glsl";
shader_files[srServiceFill ] = "service_fill.glsl"; shader_files[srServiceFill] = "service_fill.glsl";
shader_files[srServiceFrame] = "service_frame.glsl"; shader_files[srServiceFrame] = "service_frame.glsl";
shader_files[srServiceLine ] = "service_line.glsl"; shader_files[srServiceLine] = "service_line.glsl";
shader_files[srGeometryPass ] = "ds_geom.glsl"; shader_files[srGeometryPass] = "ds_geom.glsl";
shader_files[srLightOmniPass] = "ds_light.glsl"; shader_files[srLightOmniPass] = "ds_light.glsl";
shader_files[srLightSpotPass] = "ds_light.glsl"; shader_defines[srLightSpotPass] << "SPOT"; shader_files[srLightSpotPass] = "ds_light.glsl";
shader_files[srFinalPass ] = "ds_final.glsl"; shader_defines[srLightSpotPass] << "SPOT";
shader_files[srTonemapPass ] = "ds_tonemap.glsl"; shader_files[srFinalPass] = "ds_final.glsl";
shader_files[srTonemapPass] = "ds_tonemap.glsl";
edit_mode = need_init_shaders = true; edit_mode = need_init_shaders = true;
camera_light_mode = QGLView::clmAuto; camera_light_mode = QGLView::clmAuto;
} }
@@ -94,8 +102,8 @@ void Renderer::resize(int width, int height) {
rend_mat.resize(width, height); rend_mat.resize(width, height);
rend_service.resize(width, height); rend_service.resize(width, height);
rend_selection.resize(width, height); rend_selection.resize(width, height);
fbo_ds .resize(width, height); fbo_ds.resize(width, height);
fbo_out .resize(width, height); fbo_out.resize(width, height);
tone_proc.resize(); tone_proc.resize();
} }
@@ -108,14 +116,16 @@ void Renderer::reloadShaders() {
shader_fxaa = nullptr; shader_fxaa = nullptr;
if (tone_proc.shader_sum) delete tone_proc.shader_sum; if (tone_proc.shader_sum) delete tone_proc.shader_sum;
tone_proc.shader_sum = nullptr; tone_proc.shader_sum = nullptr;
QString dir = ":shaders/"; QString dir = ":shaders/";
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key())); loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key()));
} }
loadShadersMulti(tone_proc.shader_sum, dir + "sum.glsl", false); loadShadersMulti(tone_proc.shader_sum, dir + "sum.glsl", false);
QStringList fxaa_defs; QStringList fxaa_defs;
fxaa_defs << "FXAA_PC 1" << "FXAA_GLSL_130 1" << "FXAA_QUALITY__PRESET 15"; fxaa_defs << "FXAA_PC 1"
<< "FXAA_GLSL_130 1"
<< "FXAA_QUALITY__PRESET 15";
loadShaders(shader_fxaa, QStringList() << (dir + "fxaa.vert") << (dir + "fxaa.frag"), true, fxaa_defs); loadShaders(shader_fxaa, QStringList() << (dir + "fxaa.vert") << (dir + "fxaa.frag"), true, fxaa_defs);
need_init_shaders = true; need_init_shaders = true;
view->scene()->setLightsChanged(); view->scene()->setLightsChanged();
@@ -145,24 +155,24 @@ bool Renderer::bindShader(QOpenGLShaderProgram * sp) {
void Renderer::initShaders() { void Renderer::initShaders() {
if (!need_init_shaders) return; if (!need_init_shaders) return;
need_init_shaders = false; need_init_shaders = false;
initUniformBuffer(shaders.value(srGeometryPass ), &buffer_materials , bpMaterials , "QGLMaterialData" ); initUniformBuffer(shaders.value(srGeometryPass), &buffer_materials, bpMaterials, "QGLMaterialData");
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_materials , bpMaterials , "QGLMaterialData" ); initUniformBuffer(shaders.value(srLightOmniPass), &buffer_materials, bpMaterials, "QGLMaterialData");
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights , bpLightParameters, "QGLLightParameterData"); initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights, bpLightParameters, "QGLLightParameterData");
initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" ); initUniformBuffer(shaders.value(srLightOmniPass), &buffer_lights_pos, bpLightPositions, "QGLLightPositionData");
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_materials , bpMaterials , "QGLMaterialData" ); initUniformBuffer(shaders.value(srLightSpotPass), &buffer_materials, bpMaterials, "QGLMaterialData");
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights , bpLightParameters, "QGLLightParameterData"); initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights, bpLightParameters, "QGLLightParameterData");
initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights_pos, bpLightPositions , "QGLLightPositionData" ); initUniformBuffer(shaders.value(srLightSpotPass), &buffer_lights_pos, bpLightPositions, "QGLLightPositionData");
ShaderRole roles[] = {srLightOmniPass, srLightSpotPass}; ShaderRole roles[] = {srLightOmniPass, srLightSpotPass};
QOpenGLShaderProgram * prog = 0; QOpenGLShaderProgram * prog = 0;
for (int p = 0; p < 2; ++p) { for (int p = 0; p < 2; ++p) {
if (!bindShader(roles[p], &prog)) continue; if (!bindShader(roles[p], &prog)) continue;
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i); prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount); prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount);
prog->setUniformValue("tex_env", (int)Renderer::dbrBuffersCount+1); prog->setUniformValue("tex_env", (int)Renderer::dbrBuffersCount + 1);
} }
if (bindShader(srFinalPass, &prog)) { if (bindShader(srFinalPass, &prog)) {
prog->setUniformValue("tex_g1" , 0); prog->setUniformValue("tex_g1", 0);
prog->setUniformValue("tex_s_0", 1); prog->setUniformValue("tex_s_0", 1);
prog->setUniformValue("tex_s_1", 2); prog->setUniformValue("tex_s_1", 2);
prog->setUniformValue("tex_t_0", 3); prog->setUniformValue("tex_t_0", 3);
@@ -190,23 +200,22 @@ void Renderer::fillObjectsBuffer(const ObjectBaseList & ol, RenderPass pass) {
ObjectBase * o = ol[i]; ObjectBase * o = ol[i];
if (o->material()) { if (o->material()) {
so.material = o->material()->_index; so.material = o->material()->_index;
so.color = QVector4D(1,1,1,1); so.color = QVector4D(1, 1, 1, 1);
} else { } else {
so.material = 0; so.material = 0;
so.color = QColor2QVector(o->color()); so.color = QColor2QVector(o->color());
} }
so.object_id = o->id(); so.object_id = o->id();
o->worldTransform().transposed().copyDataTo(so.modelmatrix); o->worldTransform().transposed().copyDataTo(so.modelmatrix);
//qDebug() << "load obj" << o->name() << o->worldTransform(); // qDebug() << "load obj" << o->name() << o->worldTransform();
} }
//qDebug() << "fillObjectsBuffer" << ol.size(); // qDebug() << "fillObjectsBuffer" << ol.size();
} }
void Renderer::renderObjects(Scene & scene, RenderPass pass) { void Renderer::renderObjects(Scene & scene, RenderPass pass) {
QOpenGLExtraFunctions * f = view; QOpenGLExtraFunctions * f = view;
QMapIterator<Mesh*, ObjectBaseList> it(scene.geometries_used[pass]); QMapIterator<Mesh *, ObjectBaseList> it(scene.geometries_used[pass]);
bool emit_pos_change = false; bool emit_pos_change = false;
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
@@ -215,16 +224,16 @@ void Renderer::renderObjects(Scene & scene, RenderPass pass) {
mesh->setObjectsChanged(pass, false); mesh->setObjectsChanged(pass, false);
emit_pos_change = true; emit_pos_change = true;
fillObjectsBuffer(it.value(), pass); fillObjectsBuffer(it.value(), pass);
//qDebug() << "loadObjects" << pass << cur_objects_.size(); // qDebug() << "loadObjects" << pass << cur_objects_.size();
mesh->loadObjects(f, cur_objects_, pass); mesh->loadObjects(f, cur_objects_, pass);
} }
if (mesh->isSelectionChanged(pass) && edit_mode) { if (mesh->isSelectionChanged(pass) && edit_mode) {
mesh->setSelectionChanged(pass, false); mesh->setSelectionChanged(pass, false);
fillSelectionsBuffer(rend_selection.cur_selections_, it.value()); fillSelectionsBuffer(rend_selection.cur_selections_, it.value());
//qDebug() << "fillSelectionsBuffer" << pass << rend_selection.cur_selections_.size(); // qDebug() << "fillSelectionsBuffer" << pass << rend_selection.cur_selections_.size();
mesh->loadSelections(f, rend_selection.cur_selections_, pass); mesh->loadSelections(f, rend_selection.cur_selections_, pass);
} }
//qDebug() << "draw" << pass << it.value().size(); // qDebug() << "draw" << pass << it.value().size();
mesh->draw(f, it.value().size(), pass); mesh->draw(f, it.value().size(), pass);
} }
if (emit_pos_change) emit view->objectsPositionChanged(); if (emit_pos_change) emit view->objectsPositionChanged();
@@ -233,20 +242,20 @@ void Renderer::renderObjects(Scene & scene, RenderPass pass) {
void Renderer::renderLight(int first_wr_buff, bool clear_only) { void Renderer::renderLight(int first_wr_buff, bool clear_only) {
QOpenGLShaderProgram * prog = 0; QOpenGLShaderProgram * prog = 0;
Camera * cam = view->camera(); Camera * cam = view->camera();
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
view->glActiveTexture(GL_TEXTURE0 + Renderer::dbrBuffersCount + i); view->glActiveTexture(GL_TEXTURE0 + Renderer::dbrBuffersCount + i);
view->glBindTexture(GL_TEXTURE_2D, tex_coeff[i]); view->glBindTexture(GL_TEXTURE_2D, tex_coeff[i]);
} }
fbo_ds.bindColorTextures(); fbo_ds.bindColorTextures();
fbo_out.bind(); fbo_out.bind();
tex_env.bind((int)Renderer::dbrBuffersCount+1); tex_env.bind((int)Renderer::dbrBuffersCount + 1);
typedef QPair<Renderer::ShaderRole, Light::Type> PassPair; typedef QPair<Renderer::ShaderRole, Light::Type> PassPair;
QVector<PassPair> passes; QVector<PassPair> passes;
passes << PassPair(srLightOmniPass, Light::Omni) << PassPair(srLightSpotPass, Light::Cone); passes << PassPair(srLightOmniPass, Light::Omni) << PassPair(srLightSpotPass, Light::Cone);
QColor back = view->fogColor(); QColor back = view->fogColor();
back.setAlpha(0); back.setAlpha(0);
foreach (PassPair pass, passes) { foreach(PassPair pass, passes) {
if (bindShader(pass.first, &prog)) { if (bindShader(pass.first, &prog)) {
fbo_out.setWriteBuffer(first_wr_buff + pass.second); fbo_out.setWriteBuffer(first_wr_buff + pass.second);
glClearFramebuffer(back, false); glClearFramebuffer(back, false);
@@ -258,7 +267,7 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
prog->setUniformValue("fog_color", view->fogColor()); prog->setUniformValue("fog_color", view->fogColor());
prog->setUniformValue("fog_decay", qMax(view->fogDecay(), 0.001f)); prog->setUniformValue("fog_decay", qMax(view->fogDecay(), 0.001f));
prog->setUniformValue("fog_density", view->fogDensity()); prog->setUniformValue("fog_density", view->fogDensity());
prog->setUniformValue("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3,3>()); prog->setUniformValue("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3, 3>());
renderQuad(prog, quad, cam); renderQuad(prog, quad, cam);
} }
} }
@@ -270,17 +279,16 @@ void Renderer::renderScene() {
tex_env.load(); tex_env.load();
QOpenGLExtraFunctions * f = view; QOpenGLExtraFunctions * f = view;
Scene & scene(*(view->scene())); Scene & scene(*(view->scene()));
Camera * cam = view->camera(); Camera * cam = view->camera();
QOpenGLShaderProgram * prog = 0; QOpenGLShaderProgram * prog = 0;
bool scene_changed = scene.prepare(); bool scene_changed = scene.prepare();
scene.destroyUnused(f); scene.destroyUnused(f);
/// reload materials on change /// reload materials on change
if (scene_changed || scene.need_reload_materials) { if (scene_changed || scene.need_reload_materials) {
rend_selection.generateObjectsID(scene); rend_selection.generateObjectsID(scene);
reloadMaterials(scene); reloadMaterials(scene);
if (edit_mode) if (edit_mode) recreateMaterialThumbnails();
recreateMaterialThumbnails();
emit view->materialsChanged(); emit view->materialsChanged();
} }
@@ -290,7 +298,7 @@ void Renderer::renderScene() {
} }
/// lights /// lights
cur_lights = scene.lights_used; cur_lights = scene.lights_used;
bool use_camlight = (camera_light_mode == QGLView::clmOn); bool use_camlight = (camera_light_mode == QGLView::clmOn);
if ((camera_light_mode == QGLView::clmAuto) && cur_lights.isEmpty()) { if ((camera_light_mode == QGLView::clmAuto) && cur_lights.isEmpty()) {
use_camlight = true; use_camlight = true;
@@ -317,7 +325,7 @@ void Renderer::renderScene() {
if (bindShader(srGeometryPass, &prog)) { if (bindShader(srGeometryPass, &prog)) {
setUniformCamera(prog, cam); setUniformCamera(prog, cam);
textures_empty.bind(f, tarEmpty); textures_empty.bind(f, tarEmpty);
textures_maps .bind(f, tarMaps ); textures_maps.bind(f, tarMaps);
renderObjects(scene, rpSolid); renderObjects(scene, rpSolid);
} }
fbo_ds.release(); fbo_ds.release();
@@ -339,8 +347,8 @@ void Renderer::renderScene() {
/// blending layers /// blending layers
if (bindShader(srFinalPass, &prog)) { if (bindShader(srFinalPass, &prog)) {
fbo_out.bindColorTexture(obrSolidOmni , 1); fbo_out.bindColorTexture(obrSolidOmni, 1);
fbo_out.bindColorTexture(obrSolidSpot , 2); fbo_out.bindColorTexture(obrSolidSpot, 2);
fbo_out.bindColorTexture(obrTransparentOmni, 3); fbo_out.bindColorTexture(obrTransparentOmni, 3);
fbo_out.bindColorTexture(obrTransparentSpot, 4); fbo_out.bindColorTexture(obrTransparentSpot, 4);
fbo_out.setWriteBuffer(obrSum); fbo_out.setWriteBuffer(obrSum);
@@ -371,7 +379,7 @@ void Renderer::renderScene() {
if (is_grabbing) { if (is_grabbing) {
fbo_out.queryImage(0); fbo_out.queryImage(0);
last_img = fbo_out.getImage().mirrored(); last_img = fbo_out.getImage().mirrored();
//qDebug() << last_img.size(); // qDebug() << last_img.size();
} }
} }
@@ -383,5 +391,5 @@ void Renderer::setCameraLightMode(int m) {
void Renderer::setGrabImage(bool on) { void Renderer::setGrabImage(bool on) {
is_grabbing = on; is_grabbing = on;
//fbo_out.enablePixelBuffer(); // fbo_out.enablePixelBuffer();
} }

View File

@@ -1,30 +1,31 @@
/* /*
QGL Renderer QGL Renderer
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef RENDERER_H #ifndef RENDERER_H
#define RENDERER_H #define RENDERER_H
#include "glcubemap.h"
#include "renderer_base.h" #include "renderer_base.h"
#include "renderer_material.h" #include "renderer_material.h"
#include "renderer_service.h"
#include "renderer_selection.h" #include "renderer_selection.h"
#include "renderer_service.h"
#include "tonemapping_proc.h" #include "tonemapping_proc.h"
#include "glcubemap.h"
#include <QQueue> #include <QQueue>
@@ -83,13 +84,13 @@ public:
void reloadShaders(); void reloadShaders();
void renderScene(); void renderScene();
void setCameraLightMode(int m); void setCameraLightMode(int m);
int cameraLightMode() const {return camera_light_mode;} int cameraLightMode() const { return camera_light_mode; }
void setGrabImage(bool on); void setGrabImage(bool on);
bool isGrabImage() const {return is_grabbing;} bool isGrabImage() const { return is_grabbing; }
QImage getImage() const {return last_img;} QImage getImage() const { return last_img; }
QImage materialThumbnail(Material * m) {return rend_mat.materialThumbnail(m);} QImage materialThumbnail(Material * m) { return rend_mat.materialThumbnail(m); }
void recreateMaterialThumbnails(bool force_all = false) {rend_mat.recreateMaterialThumbnails(force_all);} void recreateMaterialThumbnails(bool force_all = false) { rend_mat.recreateMaterialThumbnails(force_all); }
protected: protected:
void fillObjectsBuffer(const ObjectBaseList & ol, RenderPass pass); void fillObjectsBuffer(const ObjectBaseList & ol, RenderPass pass);
@@ -109,7 +110,7 @@ private:
Framebuffer fbo_ds, fbo_out; Framebuffer fbo_ds, fbo_out;
QMap<ShaderRole, QString> shader_files; QMap<ShaderRole, QString> shader_files;
QMap<ShaderRole, QStringList> shader_defines; QMap<ShaderRole, QStringList> shader_defines;
QMap<ShaderRole, QOpenGLShaderProgram*> shaders; QMap<ShaderRole, QOpenGLShaderProgram *> shaders;
QOpenGLShaderProgram * shader_fxaa = nullptr; QOpenGLShaderProgram * shader_fxaa = nullptr;
RendererMaterial rend_mat; RendererMaterial rend_mat;
@@ -127,7 +128,7 @@ private:
QMatrix3x3 nm; QMatrix3x3 nm;
QVector4D corner_dirs[4]; QVector4D corner_dirs[4];
QVector<QVector3D> hcontent; QVector<QVector3D> hcontent;
QMap<int, QList<Light*>> cur_lights; QMap<int, QList<Light *>> cur_lights;
QImage last_img; QImage last_img;
bool is_grabbing = false; bool is_grabbing = false;
}; };

View File

@@ -1,46 +1,46 @@
/* /*
QGL RendererBase QGL RendererBase
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "renderer_base.h" #include "renderer_base.h"
#include "renderer.h"
#include "qglview.h"
#include "glmesh.h" #include "glmesh.h"
#include "gltexture_manager.h"
#include "glshaders_headers.h" #include "glshaders_headers.h"
#include "gltexture_manager.h"
#include "qglview.h"
#include "renderer.h"
#include <QOpenGLExtraFunctions>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
RendererBase::RendererBase(QGLView * view_): RendererBase::RendererBase(QGLView * view_)
view(view_), : view(view_)
buffer_materials (GL_UNIFORM_BUFFER, GL_STREAM_DRAW), , buffer_materials(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
buffer_lights (GL_UNIFORM_BUFFER, GL_STREAM_DRAW), , buffer_lights(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
buffer_lights_pos(GL_UNIFORM_BUFFER, GL_STREAM_DRAW), , buffer_lights_pos(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
textures_empty(false), , textures_empty(false)
textures_maps(true) , textures_maps(true) {
{
textures_manager = new TextureManager(view); textures_manager = new TextureManager(view);
maps_size = QSize(512, 512); maps_size = QSize(512, 512);
maps_hash = 0; maps_hash = 0;
tex_coeff[0] = tex_coeff[1] = 0; tex_coeff[0] = tex_coeff[1] = 0;
} }
@@ -68,23 +68,23 @@ void RendererBase::initUniformBuffer(QOpenGLShaderProgram * prog, Buffer * buffe
if (!prog->isLinked()) return; if (!prog->isLinked()) return;
QOpenGLExtraFunctions * f = view; QOpenGLExtraFunctions * f = view;
buffer->init(f); buffer->init(f);
//glClearError(); // glClearError();
GLint ubo_ind = f->glGetUniformBlockIndex(prog->programId(), blockName); GLint ubo_ind = f->glGetUniformBlockIndex(prog->programId(), blockName);
f->glUniformBlockBinding(prog->programId(), ubo_ind, bind_point); f->glUniformBlockBinding(prog->programId(), ubo_ind, bind_point);
f->glBindBufferBase(GL_UNIFORM_BUFFER, bind_point, buffer->ID()); f->glBindBufferBase(GL_UNIFORM_BUFFER, bind_point, buffer->ID());
//qDebug() << "initUBO" << QString::number(f->glGetError(), 16); // qDebug() << "initUBO" << QString::number(f->glGetError(), 16);
} }
void RendererBase::setUniformHalo(QOpenGLShaderProgram * prog, const char * type, QColor color, float fill) { void RendererBase::setUniformHalo(QOpenGLShaderProgram * prog, const char * type, QColor color, float fill) {
prog->setUniformValue((QString(type) + "_color").toLatin1().constData(), color); prog->setUniformValue((QString(type) + "_color").toLatin1().constData(), color);
prog->setUniformValue((QString(type) + "_fill" ).toLatin1().constData(), fill); prog->setUniformValue((QString(type) + "_fill").toLatin1().constData(), fill);
} }
void RendererBase::setUniformMaps(QOpenGLShaderProgram * prog) { void RendererBase::setUniformMaps(QOpenGLShaderProgram * prog) {
prog->setUniformValue("qgl_texture_array[0]", (int)tarEmpty); prog->setUniformValue("qgl_texture_array[0]", (int)tarEmpty);
prog->setUniformValue("qgl_texture_array[1]", (int)tarMaps ); prog->setUniformValue("qgl_texture_array[1]", (int)tarMaps);
} }
@@ -103,7 +103,7 @@ void RendererBase::setUniformCamera(QOpenGLShaderProgram * prog, Camera * cam, b
prog->setUniformValue("z_near", cam->depthStart()); prog->setUniformValue("z_near", cam->depthStart());
} }
prog->setUniformValue("dt", QVector2D(1. / w, 1. / h)); prog->setUniformValue("dt", QVector2D(1. / w, 1. / h));
prog->setUniformValue("qgl_ViewMatrix" , mat_view); prog->setUniformValue("qgl_ViewMatrix", mat_view);
prog->setUniformValue("qgl_ViewProjMatrix", mat_proj * mat_view); prog->setUniformValue("qgl_ViewProjMatrix", mat_proj * mat_view);
} }
@@ -118,9 +118,9 @@ void RendererBase::setUniformViewCorners(QOpenGLShaderProgram * prog, Camera * c
QMatrix4x4 mviewi = cam->viewMatrix().inverted(); QMatrix4x4 mviewi = cam->viewMatrix().inverted();
QVector4D corner_dirs[4], world_dirs[4]; QVector4D corner_dirs[4], world_dirs[4];
corner_dirs[0] = (mproji * QVector4D(-1, -1, 0, 1)); corner_dirs[0] = (mproji * QVector4D(-1, -1, 0, 1));
corner_dirs[1] = (mproji * QVector4D(-1, 1, 0, 1)); corner_dirs[1] = (mproji * QVector4D(-1, 1, 0, 1));
corner_dirs[2] = (mproji * QVector4D( 1, 1, 0, 1)); corner_dirs[2] = (mproji * QVector4D(1, 1, 0, 1));
corner_dirs[3] = (mproji * QVector4D( 1, -1, 0, 1)); corner_dirs[3] = (mproji * QVector4D(1, -1, 0, 1));
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
world_dirs[i] = QVector4D(mviewi.mapVector(corner_dirs[i].toVector3D())); world_dirs[i] = QVector4D(mviewi.mapVector(corner_dirs[i].toVector3D()));
prog->setUniformValue(QString("view_corners[%1]").arg(i).toLatin1().constData(), corner_dirs[i]); prog->setUniformValue(QString("view_corners[%1]").arg(i).toLatin1().constData(), corner_dirs[i]);
@@ -145,19 +145,19 @@ void RendererBase::fillSelectionsBuffer(QVector<uchar> & buffer, bool yes, int s
void RendererBase::reloadMaterials(Scene & scene) { void RendererBase::reloadMaterials(Scene & scene) {
//qDebug() << "reloadMaterias"; // qDebug() << "reloadMaterias";
QList<Map*> maps[2]; QList<Map *> maps[2];
QMap<QString, int> tex_layers[2]; QMap<QString, int> tex_layers[2];
foreach (Material * m, scene.materials) { foreach(Material * m, scene.materials) {
if (m->map_diffuse .hasBitmap()) maps[0] << &(m->map_diffuse ); if (m->map_diffuse.hasBitmap()) maps[0] << &(m->map_diffuse);
if (m->map_normal .hasBitmap()) maps[1] << &(m->map_normal ); if (m->map_normal.hasBitmap()) maps[1] << &(m->map_normal);
if (m->map_metalness.hasBitmap()) maps[0] << &(m->map_metalness); if (m->map_metalness.hasBitmap()) maps[0] << &(m->map_metalness);
if (m->map_roughness.hasBitmap()) maps[0] << &(m->map_roughness); if (m->map_roughness.hasBitmap()) maps[0] << &(m->map_roughness);
if (m->map_emission .hasBitmap()) maps[0] << &(m->map_emission ); if (m->map_emission.hasBitmap()) maps[0] << &(m->map_emission);
if (m->map_relief .hasBitmap()) maps[0] << &(m->map_relief ); if (m->map_relief.hasBitmap()) maps[0] << &(m->map_relief);
} }
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
foreach (Map * m, maps[i]) foreach(Map * m, maps[i])
tex_layers[i][m->bitmap_path] = 0; tex_layers[i][m->bitmap_path] = 0;
} }
int layers_count = tex_layers[0].size() + tex_layers[1].size(), cl = -1; int layers_count = tex_layers[0].size() + tex_layers[1].size(), cl = -1;
@@ -174,52 +174,51 @@ void RendererBase::reloadMaterials(Scene & scene) {
textures_maps.load(view, im, ++cl); textures_maps.load(view, im, ++cl);
it.value() = cl; it.value() = cl;
} }
foreach (Map * m, maps[i]) { foreach(Map * m, maps[i]) {
m->_layer = tex_layers[i].value(m->bitmap_path); m->_layer = tex_layers[i].value(m->bitmap_path);
//qDebug() << "assign" << m->bitmap_path << "layer" << m->_layer; // qDebug() << "assign" << m->bitmap_path << "layer" << m->_layer;
} }
} }
textures_maps.mipmaps(view); textures_maps.mipmaps(view);
// qDebug() << "load" << (cl+1) << "bitmaps"; // qDebug() << "load" << (cl+1) << "bitmaps";
} }
QGLMaterial glm; QGLMaterial glm;
cur_materials_.clear(); cur_materials_.clear();
cur_materials_ << glm; cur_materials_ << glm;
foreach (Material * m, scene.materials) { foreach(Material * m, scene.materials) {
if (cur_materials_.size() >= max_materials) { if (cur_materials_.size() >= max_materials) {
qDebug() << "[QGLEngine] Warning: Too many materials! Maximum" << max_materials; qDebug() << "[QGLEngine] Warning: Too many materials! Maximum" << max_materials;
break; break;
} }
m->_index = cur_materials_.size(); m->_index = cur_materials_.size();
m->_changed = false; m->_changed = false;
glm.color_diffuse = QColor2QVector(m->color_diffuse ); glm.color_diffuse = QColor2QVector(m->color_diffuse);
glm.color_emission = QColor2QVector(m->color_emission); glm.color_emission = QColor2QVector(m->color_emission);
glm.transparency = m->transparency; glm.transparency = m->transparency;
glm.reflectivity = m->reflectivity; glm.reflectivity = m->reflectivity;
glm.iof = m->iof ; glm.iof = m->iof;
glm.dispersion = m->dispersion ; glm.dispersion = m->dispersion;
m->map_diffuse .copyToQGLMap(glm.map[mtDiffuse ]); m->map_diffuse.copyToQGLMap(glm.map[mtDiffuse]);
m->map_normal .copyToQGLMap(glm.map[mtNormal ]); m->map_normal.copyToQGLMap(glm.map[mtNormal]);
m->map_metalness.copyToQGLMap(glm.map[mtMetalness ]); m->map_metalness.copyToQGLMap(glm.map[mtMetalness]);
m->map_roughness.copyToQGLMap(glm.map[mtRoughness]); m->map_roughness.copyToQGLMap(glm.map[mtRoughness]);
m->map_emission .copyToQGLMap(glm.map[mtEmission ]); m->map_emission.copyToQGLMap(glm.map[mtEmission]);
m->map_relief .copyToQGLMap(glm.map[mtRelief ]); m->map_relief.copyToQGLMap(glm.map[mtRelief]);
cur_materials_ << glm; cur_materials_ << glm;
} }
//qDebug() << "load" << cur_materials_.size() << "materials"; // qDebug() << "load" << cur_materials_.size() << "materials";
buffer_materials.bind(view); buffer_materials.bind(view);
buffer_materials.resize(view, cur_materials_.size() * sizeof(QGLMaterial)); buffer_materials.resize(view, cur_materials_.size() * sizeof(QGLMaterial));
buffer_materials.load(view, cur_materials_.constData(), cur_materials_.size() * sizeof(QGLMaterial)); buffer_materials.load(view, cur_materials_.constData(), cur_materials_.size() * sizeof(QGLMaterial));
scene.need_reload_materials = false; scene.need_reload_materials = false;
} }
void RendererBase::reloadLightsParameters(const QMap<int, QList<Light*>> & lights) { void RendererBase::reloadLightsParameters(const QMap<int, QList<Light *>> & lights) {
lights_start.clear(); lights_start.clear();
lights_start[Light::Omni] = 0; lights_start[Light::Omni] = 0;
QMapIterator<int, QList<Light*>> it(lights); QMapIterator<int, QList<Light *>> it(lights);
current_lights.clear(); current_lights.clear();
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
@@ -227,19 +226,18 @@ void RendererBase::reloadLightsParameters(const QMap<int, QList<Light*>> & light
current_lights.append(it.value()); current_lights.append(it.value());
} }
cur_lights_params_.resize(qMin(current_lights.size(), max_lights)); cur_lights_params_.resize(qMin(current_lights.size(), max_lights));
//qDebug() << "reloadLightsParameters" << cur_lights_params_.size(); // qDebug() << "reloadLightsParameters" << cur_lights_params_.size();
for (int i = 0; i < cur_lights_params_.size(); ++i) { for (int i = 0; i < cur_lights_params_.size(); ++i) {
QGLLightParameter & so(cur_lights_params_[i]); QGLLightParameter & so(cur_lights_params_[i]);
Light * l = current_lights[i]; Light * l = current_lights[i];
double ang_start = l->angle_start / 2.f, ang_end = l->angle_end / 2.f; double ang_start = l->angle_start / 2.f, ang_end = l->angle_end / 2.f;
if (l->light_type == Light::Omni) if (l->light_type == Light::Omni) ang_start = ang_end = 180.;
ang_start = ang_end = 180.; // qDebug() << "light" << light->name() << ulightn << pos;
//qDebug() << "light" << light->name() << ulightn << pos; so.color = QColor2QVector(l->color_);
so.color = QColor2QVector(l->color_); so.angles[0] = ang_start;
so.angles[0] = ang_start; so.angles[1] = cos(ang_start * deg2rad);
so.angles[1] = cos(ang_start * deg2rad); so.angles[2] = ang_end;
so.angles[2] = ang_end; so.angles[3] = cos(ang_end * deg2rad);
so.angles[3] = cos(ang_end * deg2rad);
so.decay_intensity[0] = l->decay_const; so.decay_intensity[0] = l->decay_const;
so.decay_intensity[1] = l->decay_linear; so.decay_intensity[1] = l->decay_linear;
so.decay_intensity[2] = l->decay_quadratic; so.decay_intensity[2] = l->decay_quadratic;
@@ -256,12 +254,12 @@ void RendererBase::reloadLightsPositions(Camera * cam) {
QMatrix4x4 mat = cam->viewMatrix() * cam->offsetMatrix(); QMatrix4x4 mat = cam->viewMatrix() * cam->offsetMatrix();
for (int i = 0; i < cur_lights_pos_.size(); ++i) { for (int i = 0; i < cur_lights_pos_.size(); ++i) {
QGLLightPosition & so(cur_lights_pos_[i]); QGLLightPosition & so(cur_lights_pos_[i]);
Light * l = current_lights[i]; Light * l = current_lights[i];
QMatrix4x4 m = mat * l->worldTransform(); QMatrix4x4 m = mat * l->worldTransform();
QVector4D pos(0, 0, 0, 1.), dir(QVector3D(0,0,-1), 1); QVector4D pos(0, 0, 0, 1.), dir(QVector3D(0, 0, -1), 1);
pos = m * pos; pos = m * pos;
dir = (m * QVector4D(QVector3D(0,0,-1),0)).normalized(); dir = (m * QVector4D(QVector3D(0, 0, -1), 0)).normalized();
so.position = pos; so.position = pos;
so.direction = dir; so.direction = dir;
} }
buffer_lights_pos.bind(view); buffer_lights_pos.bind(view);
@@ -293,8 +291,7 @@ void RendererBase::initQuad(Mesh * mesh, QMatrix4x4 mat) {
void RendererBase::renderQuad(QOpenGLShaderProgram * prog, Mesh * mesh, Camera * cam, bool uniforms) { void RendererBase::renderQuad(QOpenGLShaderProgram * prog, Mesh * mesh, Camera * cam, bool uniforms) {
glDisableDepth(); glDisableDepth();
if (uniforms) if (uniforms) setUniformCamera(prog, cam, false);
setUniformCamera(prog, cam, false);
mesh->draw(view, 1); mesh->draw(view, 1);
} }
@@ -312,20 +309,20 @@ float RadicalInverse_VdC(uint bits) {
QVector2D Hammersley(uint i, uint N) { QVector2D Hammersley(uint i, uint N) {
return QVector2D(float(i)/float(N), RadicalInverse_VdC(i)); return QVector2D(float(i) / float(N), RadicalInverse_VdC(i));
} }
QVector3D ImportanceSampleGGX(QVector2D Xi, QVector3D N, float roughness) { QVector3D ImportanceSampleGGX(QVector2D Xi, QVector3D N, float roughness) {
float a = roughness*roughness; float a = roughness * roughness;
float phi = 2.0 * M_PI * Xi[0]; float phi = 2.0 * M_PI * Xi[0];
float cosTheta = sqrt((1.0 - Xi[1]) / (1.0 + (a*a - 1.0) * Xi[1])); float cosTheta = sqrt((1.0 - Xi[1]) / (1.0 + (a * a - 1.0) * Xi[1]));
float sinTheta = sqrt(1.0 - cosTheta*cosTheta); float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
// преобразование из сферических в декартовы координаты // преобразование из сферических в декартовы координаты
QVector3D H; QVector3D H;
H[0] = cos(phi) * sinTheta; H[0] = cos(phi) * sinTheta;
H[1] = sin(phi) * sinTheta; H[1] = sin(phi) * sinTheta;
H[2] = cosTheta; H[2] = cosTheta;
// преобразование из касательного пространства в мировые координаты // преобразование из касательного пространства в мировые координаты
QVector3D up = qAbs(N[2]) < 0.999 ? QVector3D(0.0, 0.0, 1.0) : QVector3D(1.0, 0.0, 0.0); QVector3D up = qAbs(N[2]) < 0.999 ? QVector3D(0.0, 0.0, 1.0) : QVector3D(1.0, 0.0, 0.0);
QVector3D tangent = QVector3D::crossProduct(up, N).normalized(); QVector3D tangent = QVector3D::crossProduct(up, N).normalized();
@@ -336,7 +333,7 @@ QVector3D ImportanceSampleGGX(QVector2D Xi, QVector3D N, float roughness) {
float GeometrySchlickGGX(float NdotV, float roughness) { float GeometrySchlickGGX(float NdotV, float roughness) {
float k = (roughness * roughness) / 2.0; float k = (roughness * roughness) / 2.0;
float nom = NdotV; float nom = NdotV;
float denom = NdotV * (1.0 - k) + k; float denom = NdotV * (1.0 - k) + k;
return nom / denom; return nom / denom;
@@ -346,32 +343,32 @@ float GeometrySchlickGGX(float NdotV, float roughness) {
float GeometrySmith(QVector3D N, QVector3D V, QVector3D L, float roughness) { float GeometrySmith(QVector3D N, QVector3D V, QVector3D L, float roughness) {
float NdotV = piMax(QVector3D::dotProduct(N, V), 0.f); float NdotV = piMax(QVector3D::dotProduct(N, V), 0.f);
float NdotL = piMax(QVector3D::dotProduct(N, L), 0.f); float NdotL = piMax(QVector3D::dotProduct(N, L), 0.f);
float ggx2 = GeometrySchlickGGX(NdotV, roughness); float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness); float ggx1 = GeometrySchlickGGX(NdotL, roughness);
return ggx1 * ggx2; return ggx1 * ggx2;
} }
QVector2D IntegrateBRDF(float NdotV, float roughness) { QVector2D IntegrateBRDF(float NdotV, float roughness) {
QVector3D V; QVector3D V;
V[0] = sqrt(1.f - NdotV*NdotV); V[0] = sqrt(1.f - NdotV * NdotV);
V[1] = 0.f; V[1] = 0.f;
V[2] = NdotV; V[2] = NdotV;
float A = 0.f; float A = 0.f;
float B = 0.f; float B = 0.f;
QVector3D N = QVector3D(0.f, 0.f, 1.f); QVector3D N = QVector3D(0.f, 0.f, 1.f);
const uint SAMPLE_COUNT = 256u; const uint SAMPLE_COUNT = 256u;
for(uint i = 0u; i < SAMPLE_COUNT; ++i) { for (uint i = 0u; i < SAMPLE_COUNT; ++i) {
QVector2D Xi = Hammersley(i, SAMPLE_COUNT); QVector2D Xi = Hammersley(i, SAMPLE_COUNT);
QVector3D H = ImportanceSampleGGX(Xi, N, roughness); QVector3D H = ImportanceSampleGGX(Xi, N, roughness);
QVector3D L = (2.f * QVector3D::dotProduct(V, H) * H - V).normalized(); QVector3D L = (2.f * QVector3D::dotProduct(V, H) * H - V).normalized();
float NdotL = piMax(L[2], 0.f); float NdotL = piMax(L[2], 0.f);
float NdotH = piMax(H[2], 0.f); float NdotH = piMax(H[2], 0.f);
float VdotH = piMax(QVector3D::dotProduct(V, H), 0.f); float VdotH = piMax(QVector3D::dotProduct(V, H), 0.f);
if(NdotL > 0.f) { if (NdotL > 0.f) {
float G = GeometrySmith(N, V, L, roughness); float G = GeometrySmith(N, V, L, roughness);
float G_Vis = (G * VdotH) / (NdotH * NdotV); float G_Vis = (G * VdotH) / (NdotH * NdotV);
float Fc = pow(1.f - VdotH, 5.f); float Fc = pow(1.f - VdotH, 5.f);
A += (1.f - Fc) * G_Vis; A += (1.f - Fc) * G_Vis;
B += Fc * G_Vis; B += Fc * G_Vis;
} }
@@ -384,12 +381,12 @@ QVector2D IntegrateBRDF(float NdotV, float roughness) {
void RendererBase::initCoeffTextures() { void RendererBase::initCoeffTextures() {
QImage im = QImage(":/coeffs_brdf.png").mirrored(); QImage im = QImage(":/coeffs_brdf.png").mirrored();
int size = im.width(); int size = im.width();
QVector<QVector2D> data(size*size); QVector<QVector2D> data(size * size);
int ind = -1; int ind = -1;
for (int x = 0; x < size; ++x) { for (int x = 0; x < size; ++x) {
for (int y = 0; y < size; ++y) { for (int y = 0; y < size; ++y) {
QColor p = im.pixelColor(x, y); QColor p = im.pixelColor(x, y);
data[++ind] = QVector2D(p.redF(), p.greenF()); data[++ind] = QVector2D(p.redF(), p.greenF());
} }
} }
@@ -408,8 +405,17 @@ void RendererBase::createCoeffTexture(GLuint & id, const void * data, int size,
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLenum iformat = GL_R16F, format = GL_RED; GLenum iformat = GL_R16F, format = GL_RED;
if (channels == 2) {iformat = GL_RG16F; format = GL_RG;} if (channels == 2) {
if (channels == 3) {iformat = GL_RGB16F; format = GL_RGB;} iformat = GL_RG16F;
if (channels == 4) {iformat = GL_RGBA16F; format = GL_RGBA;} format = GL_RG;
}
if (channels == 3) {
iformat = GL_RGB16F;
format = GL_RGB;
}
if (channels == 4) {
iformat = GL_RGBA16F;
format = GL_RGBA;
}
f->glTexImage2D(GL_TEXTURE_2D, 0, iformat, size, size, 0, format, GL_FLOAT, data); f->glTexImage2D(GL_TEXTURE_2D, 0, iformat, size, size, 0, format, GL_FLOAT, data);
} }

View File

@@ -1,27 +1,27 @@
/* /*
QGL RendererBase QGL RendererBase
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef RENDERER_BASE_H #ifndef RENDERER_BASE_H
#define RENDERER_BASE_H #define RENDERER_BASE_H
#include "glbuffer.h"
#include "glshaders_types.h" #include "glshaders_types.h"
#include "gltexturearray.h" #include "gltexturearray.h"
#include "glbuffer.h"
class RendererBase { class RendererBase {
@@ -31,16 +31,16 @@ public:
protected: protected:
void initTextureArrays(); void initTextureArrays();
void initUniformBuffer (QOpenGLShaderProgram * prog, Buffer * buffer, int bind_point, const char * blockName); void initUniformBuffer(QOpenGLShaderProgram * prog, Buffer * buffer, int bind_point, const char * blockName);
void setUniformHalo (QOpenGLShaderProgram * prog, const char * type, QColor color, float fill); void setUniformHalo(QOpenGLShaderProgram * prog, const char * type, QColor color, float fill);
void setUniformMaps (QOpenGLShaderProgram * prog); void setUniformMaps(QOpenGLShaderProgram * prog);
void setUniformCamera (QOpenGLShaderProgram * prog, Camera * cam, bool matrices = true, QSize viewport = QSize()); void setUniformCamera(QOpenGLShaderProgram * prog, Camera * cam, bool matrices = true, QSize viewport = QSize());
void setUniformViewCorners(QOpenGLShaderProgram * prog, Camera * cam, QSize viewport = QSize()); void setUniformViewCorners(QOpenGLShaderProgram * prog, Camera * cam, QSize viewport = QSize());
void fillSelectionsBuffer(QVector<uchar> & buffer, const ObjectBaseList & ol); void fillSelectionsBuffer(QVector<uchar> & buffer, const ObjectBaseList & ol);
void fillSelectionsBuffer(QVector<uchar> & buffer, bool yes, int size); void fillSelectionsBuffer(QVector<uchar> & buffer, bool yes, int size);
void reloadMaterials(Scene & scene); void reloadMaterials(Scene & scene);
void reloadLightsParameters(const QMap<int, QList<Light*>> & lights); void reloadLightsParameters(const QMap<int, QList<Light *>> & lights);
void reloadLightsPositions (Camera * cam); void reloadLightsPositions(Camera * cam);
void markReloadTextures(); void markReloadTextures();
void setMapsSize(QSize sz); void setMapsSize(QSize sz);
void initQuad(Mesh * mesh, QMatrix4x4 mat = QMatrix4x4()); void initQuad(Mesh * mesh, QMatrix4x4 mat = QMatrix4x4());
@@ -61,7 +61,7 @@ protected:
uint maps_hash; uint maps_hash;
GLuint tex_coeff[2]; GLuint tex_coeff[2];
QMap<int, int> lights_start; QMap<int, int> lights_start;
QList<Light*> current_lights; QList<Light *> current_lights;
}; };
#endif // RENDERER_BASE_H #endif // RENDERER_BASE_H

View File

@@ -1,35 +1,36 @@
/* /*
QGL RendererMaterial QGL RendererMaterial
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "renderer_material.h" #include "renderer_material.h"
#include "renderer.h"
#include "qglview.h"
#include "glmesh.h" #include "glmesh.h"
#include "gltexture_manager.h" #include "gltexture_manager.h"
#include "qglview.h"
#include "renderer.h"
#include <QOpenGLExtraFunctions>
#include <qad_types.h> #include <qad_types.h>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
RendererMaterial::RendererMaterial(Renderer * r_) RendererMaterial::RendererMaterial(Renderer * r_): r(r_), fbo_mat_thumb(r->view, 6, true, GL_RGBA16F) {
: r(r_), fbo_mat_thumb(r->view, 6, true , GL_RGBA16F) {
mat_sphere = Primitive::ellipsoid(16, 16); mat_sphere = Primitive::ellipsoid(16, 16);
mat_camera = new Camera(); mat_camera = new Camera();
mat_camera->setPos(QVector3D(2, 2, 2)); mat_camera->setPos(QVector3D(2, 2, 2));
@@ -62,19 +63,19 @@ void RendererMaterial::resize(int width, int height) {
void RendererMaterial::renderMaterial(Material * m) { void RendererMaterial::renderMaterial(Material * m) {
//qDebug() << "renderMaterial" << m; // qDebug() << "renderMaterial" << m;
last_thumb_material = m; last_thumb_material = m;
QOpenGLShaderProgram * prog = 0; QOpenGLShaderProgram * prog = 0;
QOpenGLExtraFunctions * f = r->view; QOpenGLExtraFunctions * f = r->view;
fbo_mat_thumb.bind(); fbo_mat_thumb.bind();
glEnableDepth(); glEnableDepth();
glClearFramebuffer(QColor(0,0,0,0)); glClearFramebuffer(QColor(0, 0, 0, 0));
if (r->bindShader(Renderer::srGeometryPass, &prog)) { if (r->bindShader(Renderer::srGeometryPass, &prog)) {
r->setUniformMaps(prog); r->setUniformMaps(prog);
r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size()); r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size());
//qDebug() << mat_camera->viewMatrix(); // qDebug() << mat_camera->viewMatrix();
r->textures_empty.bind(f, tarEmpty); r->textures_empty.bind(f, tarEmpty);
r->textures_maps .bind(f, tarMaps ); r->textures_maps.bind(f, tarMaps);
Object o; Object o;
o.material = m->_index; o.material = m->_index;
mat_sphere->loadObject(f, o); mat_sphere->loadObject(f, o);
@@ -91,7 +92,7 @@ void RendererMaterial::renderMaterial(Material * m) {
prog->setUniformValue("tex_d", 5); prog->setUniformValue("tex_d", 5);
prog->setUniformValue("lights_start", 0); prog->setUniformValue("lights_start", 0);
prog->setUniformValue("lights_count", 1); prog->setUniformValue("lights_count", 1);
QMap<int, QList<Light*>> mat_l; QMap<int, QList<Light *>> mat_l;
mat_l[Light::Omni] << mat_light; mat_l[Light::Omni] << mat_light;
r->reloadLightsParameters(mat_l); r->reloadLightsParameters(mat_l);
r->reloadLightsPositions(mat_camera); r->reloadLightsPositions(mat_camera);
@@ -110,8 +111,7 @@ void RendererMaterial::procQueue() {
emit r->view->materialThumbnailCreated(last_thumb_material); emit r->view->materialThumbnailCreated(last_thumb_material);
last_thumb_material = 0; last_thumb_material = 0;
} }
if (!mat_thumb_queue.isEmpty()) if (!mat_thumb_queue.isEmpty()) renderMaterial(mat_thumb_queue.dequeue());
renderMaterial(mat_thumb_queue.dequeue());
} }
@@ -123,12 +123,11 @@ QImage RendererMaterial::materialThumbnail(Material * m) {
void RendererMaterial::recreateMaterialThumbnails(bool force_all) { void RendererMaterial::recreateMaterialThumbnails(bool force_all) {
if (force_all) { if (force_all) {
mat_thumb_queue.clear(); mat_thumb_queue.clear();
//qDebug() << "recreateMaterialThumbnails" << view->scene_->materials; // qDebug() << "recreateMaterialThumbnails" << view->scene_->materials;
foreach (Material * m, r->view->scene()->materials) foreach(Material * m, r->view->scene()->materials)
mat_thumb_queue.enqueue(m); mat_thumb_queue.enqueue(m);
} else { } else {
foreach (Material * m, r->view->scene()->changed_materials) foreach(Material * m, r->view->scene()->changed_materials)
if (!mat_thumb_queue.contains(m)) if (!mat_thumb_queue.contains(m)) mat_thumb_queue.enqueue(m);
mat_thumb_queue.enqueue(m);
} }
} }

View File

@@ -1,30 +1,32 @@
/* /*
QGL RendererMaterial QGL RendererMaterial
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef RENDERER_MATERIAL_H #ifndef RENDERER_MATERIAL_H
#define RENDERER_MATERIAL_H #define RENDERER_MATERIAL_H
#include "glframebuffer.h" #include "glframebuffer.h"
#include <QQueue> #include <QQueue>
class RendererMaterial { class RendererMaterial {
friend class QGLView; friend class QGLView;
public: public:
RendererMaterial(Renderer * r_); RendererMaterial(Renderer * r_);
virtual ~RendererMaterial(); virtual ~RendererMaterial();
@@ -43,9 +45,9 @@ private:
Mesh * mat_sphere; Mesh * mat_sphere;
Camera * mat_camera; Camera * mat_camera;
Light * mat_light; Light * mat_light;
QMap<Material*, QImage> mat_thumbnails; QMap<Material *, QImage> mat_thumbnails;
Material * last_thumb_material; Material * last_thumb_material;
QQueue<Material*> mat_thumb_queue; QQueue<Material *> mat_thumb_queue;
}; };
#endif // RENDERER_MATERIAL_H #endif // RENDERER_MATERIAL_H

View File

@@ -1,37 +1,38 @@
/* /*
QGL RendererSelection QGL RendererSelection
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "renderer_selection.h" #include "renderer_selection.h"
#include "qglview.h"
#include "glmesh.h" #include "glmesh.h"
#include "qglview.h"
#include <QOpenGLExtraFunctions>
#include <qad_types.h> #include <qad_types.h>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
RendererSelection::RendererSelection(Renderer * r_) RendererSelection::RendererSelection(Renderer * r_): r(r_), fbo_selection(r->view, 6) {
: r(r_), fbo_selection(r->view, 6) { sel_frame = Primitive::plane(2., 2.);
sel_frame = Primitive::plane(2., 2.); id_hover = 0;
id_hover = 0;
line_thick_ = 2.; line_thick_ = 2.;
scale_ = 0.5; scale_ = 0.5;
} }
@@ -49,7 +50,7 @@ void RendererSelection::init(int width, int height) {
void RendererSelection::resize(int width, int height) { void RendererSelection::resize(int width, int height) {
line_thick_ = lineThickness() + 1.; line_thick_ = lineThickness() + 1.;
scale_ = 0.5 / appScale(); scale_ = 0.5 / appScale();
fbo_selection.enablePixelBuffer(); fbo_selection.enablePixelBuffer();
fbo_selection.resize(width * scale_, height * scale_); fbo_selection.resize(width * scale_, height * scale_);
} }
@@ -59,31 +60,31 @@ void RendererSelection::generateObjectsID(Scene & scene) {
ids.clear(); ids.clear();
aim_ids.clear(); aim_ids.clear();
QList<int> passes = scene.geometries_used.keys(); QList<int> passes = scene.geometries_used.keys();
foreach (int p, passes) { foreach(int p, passes) {
QMapIterator<Mesh*, ObjectBaseList> it(scene.geometries_used[p]); QMapIterator<Mesh *, ObjectBaseList> it(scene.geometries_used[p]);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
foreach (ObjectBase * o, it.value()) { foreach(ObjectBase * o, it.value()) {
uint id = qHash(o); uint id = qHash(o);
ids[id] = o; ids[id] = o;
o->id_ = id; o->id_ = id;
} }
} }
QMapIterator<int, QList<Light*>> lit(scene.lights_used); QMapIterator<int, QList<Light *>> lit(scene.lights_used);
while (lit.hasNext()) { while (lit.hasNext()) {
lit.next(); lit.next();
foreach (ObjectBase * o, lit.value()) { foreach(ObjectBase * o, lit.value()) {
uint id = qHash(o); uint id = qHash(o);
ids[id] = o; ids[id] = o;
aim_ids[id + 1] = o; aim_ids[id + 1] = o;
o->id_ = id; o->id_ = id;
} }
} }
foreach (Camera * o, scene.cameras_used) { foreach(Camera * o, scene.cameras_used) {
uint id = qHash(o); uint id = qHash(o);
ids[id] = o; ids[id] = o;
aim_ids[id + 1] = o; aim_ids[id + 1] = o;
o->id_ = id; o->id_ = id;
} }
} }
} }
@@ -91,7 +92,7 @@ void RendererSelection::generateObjectsID(Scene & scene) {
void RendererSelection::renderSelection(Scene & scene) { void RendererSelection::renderSelection(Scene & scene) {
QOpenGLShaderProgram * prog = 0; QOpenGLShaderProgram * prog = 0;
QGLView * view = r->view; QGLView * view = r->view;
MouseController & mc(view->mouse); MouseController & mc(view->mouse);
if (r->bindShader(Renderer::srSelectionFill, &prog)) { if (r->bindShader(Renderer::srSelectionFill, &prog)) {
mc.hov_objects.clear(); mc.hov_objects.clear();
@@ -99,28 +100,27 @@ void RendererSelection::renderSelection(Scene & scene) {
id_hover = 0; id_hover = 0;
if (fbo_selection.queriedPoints() > 0) { if (fbo_selection.queriedPoints() > 0) {
if (fbo_selection.queriedPoints() == 1) { if (fbo_selection.queriedPoints() == 1) {
id_hover = fbo_selection.getPoint(); id_hover = fbo_selection.getPoint();
ObjectBase * o = ids.value(id_hover); ObjectBase * o = ids.value(id_hover);
if (o) if (o)
mc.hov_objects << o; mc.hov_objects << o;
else { else {
o = aim_ids.value(id_hover); o = aim_ids.value(id_hover);
if (o) if (o) mc.hov_aims << o;
mc.hov_aims << o;
} }
//qDebug() << id_hover; // qDebug() << id_hover;
} else { } else {
QVector<uint> points = fbo_selection.getPointsByte(); QVector<uint> points = fbo_selection.getPointsByte();
QSet<uint> ids_hover; QSet<uint> ids_hover;
foreach (uint i, points) foreach(uint i, points)
ids_hover << i; ids_hover << i;
foreach (uint i, ids_hover) { foreach(uint i, ids_hover) {
ObjectBase * o = ids.value(i); ObjectBase * o = ids.value(i);
if (o) mc.hov_objects << o; if (o) mc.hov_objects << o;
o = aim_ids.value(i); o = aim_ids.value(i);
if (o) mc.hov_aims << o; if (o) mc.hov_aims << o;
} }
//qDebug() << ids_hover; // qDebug() << ids_hover;
} }
} }
@@ -128,7 +128,7 @@ void RendererSelection::renderSelection(Scene & scene) {
fbo_selection.setWriteBuffers(); fbo_selection.setWriteBuffers();
glEnableDepth(); glEnableDepth();
glClearFramebuffer(QColor(0,0,0,0)); glClearFramebuffer(QColor(0, 0, 0, 0));
r->setUniformCamera(prog, view->camera()); r->setUniformCamera(prog, view->camera());
r->renderObjects(scene, rpSolid); r->renderObjects(scene, rpSolid);
r->renderObjects(scene, rpTransparent); r->renderObjects(scene, rpTransparent);
@@ -141,27 +141,27 @@ void RendererSelection::renderSelection(Scene & scene) {
if (r->mouse_rect.isNull()) if (r->mouse_rect.isNull())
fbo_selection.queryPoint(0, r->mouse_pos * scale_); fbo_selection.queryPoint(0, r->mouse_pos * scale_);
else else
fbo_selection.queryPoints(0, QRect(r->mouse_rect.topLeft() * scale_, fbo_selection.queryPoints(0, QRect(r->mouse_rect.topLeft() * scale_, r->mouse_rect.size() * scale_));
r->mouse_rect.size() * scale_));
//qDebug() << id_hover; // qDebug() << id_hover;
fbo_selection.bindColorTexture(sbrSrcHover , sbrSrcHover ); fbo_selection.bindColorTexture(sbrSrcHover, sbrSrcHover);
fbo_selection.bindColorTexture(sbrSrcSelect, sbrSrcSelect); fbo_selection.bindColorTexture(sbrSrcSelect, sbrSrcSelect);
fbo_selection.setWriteBuffers(QVector<int>() << sbrHovered << sbrSelected); fbo_selection.setWriteBuffers(QVector<int>() << sbrHovered << sbrSelected);
if (!view->isHoverHaloEnabled() && !view->isSelectionHaloEnabled()) if (!view->isHoverHaloEnabled() && !view->isSelectionHaloEnabled())
glClearFramebuffer(QColor(0,0,0,0), false); glClearFramebuffer(QColor(0, 0, 0, 0), false);
else { else {
r->bindShader(Renderer::srSelectionHalo, &prog); r->bindShader(Renderer::srSelectionHalo, &prog);
r->setUniformHalo(prog, "hover" , view->hoverHaloColor() , view->hoverHaloFillAlpha()); r->setUniformHalo(prog, "hover", view->hoverHaloColor(), view->hoverHaloFillAlpha());
r->setUniformHalo(prog, "selection", view->selectionHaloColor(), view->selectionHaloFillAlpha()); r->setUniformHalo(prog, "selection", view->selectionHaloColor(), view->selectionHaloFillAlpha());
prog->setUniformValue("has_hover" , view->isHoverHaloEnabled() && (id_hover > 0) ? 1.f : 0.f); prog->setUniformValue("has_hover", view->isHoverHaloEnabled() && (id_hover > 0) ? 1.f : 0.f);
prog->setUniformValue("has_selection", view->isSelectionHaloEnabled() ? 1.f : 0.f); prog->setUniformValue("has_selection", view->isSelectionHaloEnabled() ? 1.f : 0.f);
prog->setUniformValue("fb_hover" , (int)sbrSrcHover); prog->setUniformValue("fb_hover", (int)sbrSrcHover);
prog->setUniformValue("fb_selection", (int)sbrSrcSelect); prog->setUniformValue("fb_selection", (int)sbrSrcSelect);
prog->setUniformValue("hover_id", QVector4D(float( id_hover & 0xFF) / 255.f, prog->setUniformValue("hover_id",
float((id_hover >> 8 ) & 0xFF) / 255.f, QVector4D(float(id_hover & 0xFF) / 255.f,
float((id_hover >> 16) & 0xFF) / 255.f, float((id_hover >> 8) & 0xFF) / 255.f,
float((id_hover >> 24) & 0xFF) / 255.f)); float((id_hover >> 16) & 0xFF) / 255.f,
float((id_hover >> 24) & 0xFF) / 255.f));
r->renderQuad(prog, r->quad, view->camera()); r->renderQuad(prog, r->quad, view->camera());
} }
@@ -184,9 +184,9 @@ void RendererSelection::renderSelectionFrame() {
QOpenGLShaderProgram * prog = 0; QOpenGLShaderProgram * prog = 0;
if (r->bindShader(Renderer::srSelectionFrame, &prog)) { if (r->bindShader(Renderer::srSelectionFrame, &prog)) {
QMatrix4x4 mat; QMatrix4x4 mat;
double mrx = r->mouse_rect.x(), mrw = r->mouse_rect.width() , vw = r->view->width(); double mrx = r->mouse_rect.x(), mrw = r->mouse_rect.width(), vw = r->view->width();
double mry = r->mouse_rect.y(), mrh = r->mouse_rect.height(), vh = r->view->height(); double mry = r->mouse_rect.y(), mrh = r->mouse_rect.height(), vh = r->view->height();
mat.translate(-1. + (mrw + mrx*2) / vw, 1. - (mrh + mry*2) / vh, 0.); mat.translate(-1. + (mrw + mrx * 2) / vw, 1. - (mrh + mry * 2) / vh, 0.);
mat.scale(mrw / vw, mrh / vh, 0.); mat.scale(mrw / vw, mrh / vh, 0.);
r->initQuad(sel_frame, mat); r->initQuad(sel_frame, mat);
prog->setUniformValue("size", QVector2D(mrw / vw, mrh / vh)); prog->setUniformValue("size", QVector2D(mrw / vw, mrh / vh));
@@ -204,8 +204,8 @@ void RendererSelection::drawSelection(Framebuffer & fbo_out, int index_out) {
if (r->bindShader(Renderer::srSelectionApply, &prog)) { if (r->bindShader(Renderer::srSelectionApply, &prog)) {
fbo_selection.bindColorTextures(); fbo_selection.bindColorTextures();
fbo_out.bindColorTexture(index_out); fbo_out.bindColorTexture(index_out);
prog->setUniformValue("fb_out" , 0); prog->setUniformValue("fb_out", 0);
prog->setUniformValue("fb_hover" , (int)sbrHoveredFXAA ); prog->setUniformValue("fb_hover", (int)sbrHoveredFXAA);
prog->setUniformValue("fb_select", (int)sbrSelectedFXAA); prog->setUniformValue("fb_select", (int)sbrSelectedFXAA);
r->renderQuad(prog, r->quad, r->view->camera()); r->renderQuad(prog, r->quad, r->view->camera());
if (!r->mouse_rect.isNull()) { if (!r->mouse_rect.isNull()) {

View File

@@ -1,25 +1,26 @@
/* /*
QGL RendererSelection QGL RendererSelection
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef RENDERER_SELECTION_H #ifndef RENDERER_SELECTION_H
#define RENDERER_SELECTION_H #define RENDERER_SELECTION_H
#include "renderer_service.h" #include "renderer_service.h"
#include <QHash> #include <QHash>
@@ -57,8 +58,8 @@ private:
Mesh * sel_frame; Mesh * sel_frame;
float line_thick_, scale_; float line_thick_, scale_;
QVector<uchar> cur_selections_; QVector<uchar> cur_selections_;
QHash<uint, ObjectBase * > ids; QHash<uint, ObjectBase *> ids;
QHash<uint, ObjectBase * > aim_ids; QHash<uint, ObjectBase *> aim_ids;
uint id_hover; uint id_hover;
}; };

View File

@@ -1,83 +1,86 @@
/* /*
QGL RendererService QGL RendererService
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "renderer_service.h" #include "renderer_service.h"
#include "renderer.h"
#include "qglview.h"
#include "glmesh.h" #include "glmesh.h"
#include "qglview.h"
#include "renderer.h"
#include <QOpenGLExtraFunctions>
#include <qad_types.h> #include <qad_types.h>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
RendererService::RendererService(Renderer * r_): r(r_) { RendererService::RendererService(Renderer * r_): r(r_) {
line_width = 1; line_width = 1;
current_action = haNoAction; current_action = haNoAction;
current_handle = QFlags<HandleMesh>(); current_handle = QFlags<HandleMesh>();
mat_xyz.resize(3); mat_ms2.resize(3); mat_xyz.resize(3);
color_xyz.resize(3); color_ms2.resize(3); mat_ms2.resize(3);
const QVector3D _rot [3] = {QVector3D(0,1,0), QVector3D(-1,0,0), QVector3D(0, 0,1)}; color_xyz.resize(3);
const QVector3D _rot2[3] = {QVector3D(0,0,0), QVector3D( 1,0,0), QVector3D(0,-1,0)}; color_ms2.resize(3);
const QVector3D _rot[3] = {QVector3D(0, 1, 0), QVector3D(-1, 0, 0), QVector3D(0, 0, 1)};
const QVector3D _rot2[3] = {QVector3D(0, 0, 0), QVector3D(1, 0, 0), QVector3D(0, -1, 0)};
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
QMatrix4x4 m; QMatrix4x4 m;
m.rotate(90., _rot[i]); m.rotate(90., _rot[i]);
mat_xyz[i] = m; mat_xyz[i] = m;
m.setToIdentity(); m.setToIdentity();
if (!_rot2[i].isNull()) if (!_rot2[i].isNull()) m.rotate(90., _rot2[i]);
m.rotate(90., _rot2[i]); mat_ms2[i] = m;
mat_ms2[i] = m; color_xyz[i] = color_ms2[i] = QVector4D(0, 0, 0, 0.8);
color_xyz[i] = color_ms2[i] = QVector4D(0,0,0,0.8); color_xyz[i][i] = 1.;
color_xyz[i][i] = 1.;
} }
color_ms2[0] = (color_xyz[0] + color_xyz[1]) / 2.; color_ms2[0] = (color_xyz[0] + color_xyz[1]) / 2.;
color_ms2[1] = (color_xyz[0] + color_xyz[2]) / 2.; color_ms2[1] = (color_xyz[0] + color_xyz[2]) / 2.;
color_ms2[2] = (color_xyz[1] + color_xyz[2]) / 2.; color_ms2[2] = (color_xyz[1] + color_xyz[2]) / 2.;
axis_camera = new Camera(); axis_camera = new Camera();
axis_camera->setAim(QVector3D()); axis_camera->setAim(QVector3D());
axis_camera->setFOV(45.); axis_camera->setFOV(45.);
axis_mesh = Primitive::arrow(12); axis_mesh = Primitive::arrow(12);
size_vp_scale = size_full_scale = 1.; size_vp_scale = size_full_scale = 1.;
box_mesh = Primitive::cube(0.8, 0.8, 0.8); box_mesh = Primitive::cube(0.8, 0.8, 0.8);
box_mesh_f = Primitive::cubeFrame(0.8, 0.8, 0.8); box_mesh_f = Primitive::cubeFrame(0.8, 0.8, 0.8);
omni_mesh = Primitive::ellipsoid(2, 1, 0.5); omni_mesh = Primitive::ellipsoid(2, 1, 0.5);
omni_mesh_f = Primitive::ellipsoidFrame(2, 1, 0.5); omni_mesh_f = Primitive::ellipsoidFrame(2, 1, 0.5);
omni_mesh ->scalePoints(1.5); omni_mesh->scalePoints(1.5);
omni_mesh_f ->scalePoints(1.5); omni_mesh_f->scalePoints(1.5);
cone_mesh = Primitive::cone(8, 0.5, 1.); cone_mesh = Primitive::cone(8, 0.5, 1.);
cone_mesh_f = Primitive::coneFrame(8, 0.5, 1.); cone_mesh_f = Primitive::coneFrame(8, 0.5, 1.);
QMatrix4x4 mat; QMatrix4x4 mat;
mat.translate(0,0,-1); mat.translate(0, 0, -1);
cone_mesh ->transformPoints(mat); cone_mesh->transformPoints(mat);
cone_mesh_f->transformPoints(mat); cone_mesh_f->transformPoints(mat);
cone_mesh_f->scalePoints(1.5); cone_mesh_f->scalePoints(1.5);
box_mesh ->scalePoints(1.3); box_mesh->scalePoints(1.3);
omni_mesh ->scalePoints(1.3); omni_mesh->scalePoints(1.3);
cone_mesh ->translatePoints(0,0,0.5); cone_mesh->translatePoints(0, 0, 0.5);
cone_mesh ->scalePoints(1.4); cone_mesh->scalePoints(1.4);
cone_mesh ->translatePoints(0,0,-0.5); cone_mesh->translatePoints(0, 0, -0.5);
cone_mesh ->scalePoints(1.5); cone_mesh->scalePoints(1.5);
camera_mesh = Primitive::cube(1.2, 1.2, 1.2); camera_mesh = Primitive::cube(1.2, 1.2, 1.2);
mat.translate(0,0,-0.5); mat.translate(0, 0, -0.5);
Mesh * m = Primitive::cone(6, 0.6, 1.); Mesh * m = Primitive::cone(6, 0.6, 1.);
m->scalePoints(1.4); m->scalePoints(1.4);
m->transformPoints(mat); m->transformPoints(mat);
@@ -88,34 +91,34 @@ RendererService::RendererService(Renderer * r_): r(r_) {
m->transformPoints(mat); m->transformPoints(mat);
camera_mesh_f->append(m); camera_mesh_f->append(m);
line_spot_f = Primitive::lineFrame(QVector3D(), QVector3D(0, 0, -1)); line_spot_f = Primitive::lineFrame(QVector3D(), QVector3D(0, 0, -1));
line_camera_f = Primitive::lineFrame(QVector3D(), QVector3D(0, 0, -1)); line_camera_f = Primitive::lineFrame(QVector3D(), QVector3D(0, 0, -1));
handle_move_mesh = Primitive::arrow(12, 0.06); handle_move_mesh = Primitive::arrow(12, 0.06);
handle_ms_2_mesh = Primitive::torus(8, 12, 0.5, 0.02, 90); handle_ms_2_mesh = Primitive::torus(8, 12, 0.5, 0.02, 90);
m = Primitive::disc(8, 0.5, 90); m = Primitive::disc(8, 0.5, 90);
handle_ms_2_mesh->append(m); handle_ms_2_mesh->append(m);
m->flipNormals(); m->flipNormals();
handle_ms_2_mesh->append(m); handle_ms_2_mesh->append(m);
delete m; delete m;
handle_rotate_mesh = Primitive::arrow(12, 0.03); handle_rotate_mesh = Primitive::arrow(12, 0.03);
m = Primitive::torus(30, 12, 0.5, 0.06); m = Primitive::torus(30, 12, 0.5, 0.06);
m->translatePoints(QVector3D(0., 0., 0.75)); m->translatePoints(QVector3D(0., 0., 0.75));
handle_rotate_mesh->append(m); handle_rotate_mesh->append(m);
delete m; delete m;
handle_scale_mesh = Primitive::cylinder(12, 0.03, 0.85); handle_scale_mesh = Primitive::cylinder(12, 0.03, 0.85);
m = Primitive::ellipsoid(12, 12, 0.15); m = Primitive::ellipsoid(12, 12, 0.15);
m->translatePoints(QVector3D(0., 0., 0.85)); m->translatePoints(QVector3D(0., 0., 0.85));
handle_scale_mesh->append(m); handle_scale_mesh->append(m);
delete m; delete m;
handle_scale_3_mesh = Primitive::ellipsoid(12, 12, 0.2); handle_scale_3_mesh = Primitive::ellipsoid(12, 12, 0.2);
handle_move_mesh ->scalePoints(7.5); handle_move_mesh->scalePoints(7.5);
handle_ms_2_mesh ->scalePoints(7.5); handle_ms_2_mesh->scalePoints(7.5);
handle_rotate_mesh ->scalePoints(7.5); handle_rotate_mesh->scalePoints(7.5);
handle_scale_mesh ->scalePoints(7.5); handle_scale_mesh->scalePoints(7.5);
handle_scale_3_mesh->scalePoints(7.5); handle_scale_3_mesh->scalePoints(7.5);
} }
@@ -142,23 +145,23 @@ RendererService::~RendererService() {
void RendererService::init(int width, int height) { void RendererService::init(int width, int height) {
box_mesh ->reinit(); box_mesh->reinit();
box_mesh_f ->reinit(); box_mesh_f->reinit();
omni_mesh ->reinit(); omni_mesh->reinit();
omni_mesh_f ->reinit(); omni_mesh_f->reinit();
cone_mesh ->reinit(); cone_mesh->reinit();
cone_mesh_f ->reinit(); cone_mesh_f->reinit();
camera_mesh ->reinit(); camera_mesh->reinit();
camera_mesh_f ->reinit(); camera_mesh_f->reinit();
line_spot_f ->reinit(); line_spot_f->reinit();
line_camera_f ->reinit(); line_camera_f->reinit();
axis_mesh ->reinit(); axis_mesh->reinit();
handle_move_mesh ->reinit(); handle_move_mesh->reinit();
handle_ms_2_mesh ->reinit(); handle_ms_2_mesh->reinit();
handle_rotate_mesh ->reinit(); handle_rotate_mesh->reinit();
handle_scale_mesh ->reinit(); handle_scale_mesh->reinit();
handle_scale_3_mesh->reinit(); handle_scale_3_mesh->reinit();
axis_mesh ->reinit(); axis_mesh->reinit();
fillXYZObjects(); fillXYZObjects();
axis_mesh->loadObjects(r->view, cur_objects); axis_mesh->loadObjects(r->view, cur_objects);
resize(width, height); resize(width, height);
@@ -167,15 +170,15 @@ void RendererService::init(int width, int height) {
void RendererService::resize(int width, int height) { void RendererService::resize(int width, int height) {
axis_viewport = preferredIconSize(10.); axis_viewport = preferredIconSize(10.);
line_width = lineThickness(); line_width = lineThickness();
size_vp_scale = 25. * appScale() / qMax(qMin(width, height), 1); size_vp_scale = 25. * appScale() / qMax(qMin(width, height), 1);
//qDebug() << axis_viewport; // qDebug() << axis_viewport;
} }
QMatrix4x4 RendererService::invariantSizeMatrix(QVector3D p, double * ret_scale) { QMatrix4x4 RendererService::invariantSizeMatrix(QVector3D p, double * ret_scale) {
QVector4D pos = QVector4D(p, 1.); QVector4D pos = QVector4D(p, 1.);
double dist = -(v_mat * pos).z(); double dist = -(v_mat * pos).z();
QMatrix4x4 m; QMatrix4x4 m;
m.translate(pos.toVector3D()); m.translate(pos.toVector3D());
m.scale(dist * size_full_scale); m.scale(dist * size_full_scale);
@@ -209,10 +212,10 @@ void RendererService::fillXYZObjects() {
void RendererService::fillOmniObjects() { void RendererService::fillOmniObjects() {
QList<Light*> ll = r->view->scene()->lights_used.value(Light::Omni); QList<Light *> ll = r->view->scene()->lights_used.value(Light::Omni);
Object o; Object o;
cur_objects.clear(); cur_objects.clear();
foreach (Light * l, ll) { foreach(Light * l, ll) {
QMatrix4x4 m = invariantSizeMatrix(l->worldPos()); QMatrix4x4 m = invariantSizeMatrix(l->worldPos());
m.transposed().copyDataTo(o.modelmatrix); m.transposed().copyDataTo(o.modelmatrix);
o.object_id = l->id(); o.object_id = l->id();
@@ -225,12 +228,12 @@ void RendererService::fillAimedObjects(const ObjectBaseList & objects, Mesh * li
Object o; Object o;
cur_objects.clear(); cur_objects.clear();
cur_aims.clear(); cur_aims.clear();
QVector<QVector3D> & lv (line_mesh->vertices ()); QVector<QVector3D> & lv(line_mesh->vertices());
QVector<QVector3D> & ln (line_mesh->normals ()); QVector<QVector3D> & ln(line_mesh->normals());
QVector<QVector2D> & lt (line_mesh->texcoords ()); QVector<QVector2D> & lt(line_mesh->texcoords());
QVector< Vector2i> & lind(line_mesh->indicesLines()); QVector<Vector2i> & lind(line_mesh->indicesLines());
lv.clear(); lv.clear();
foreach (ObjectBase * go, objects) { foreach(ObjectBase * go, objects) {
AimedObject * ao = (AimedObject *)go; AimedObject * ao = (AimedObject *)go;
QMatrix4x4 m; QMatrix4x4 m;
m = invariantSizeMatrix(ao->worldPos()) * parentRotationMatrix(ao); m = invariantSizeMatrix(ao->worldPos()) * parentRotationMatrix(ao);
@@ -249,20 +252,25 @@ void RendererService::fillAimedObjects(const ObjectBaseList & objects, Mesh * li
lt.resize(lv.size()); lt.resize(lv.size());
lind.resize(lv.size() / 2); lind.resize(lv.size() / 2);
for (int i = 0; i < lind.size(); ++i) { for (int i = 0; i < lind.size(); ++i) {
lind[i] = Vector2i(i*2, i*2 + 1); lind[i] = Vector2i(i * 2, i * 2 + 1);
} }
} }
void RendererService::fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count) { void RendererService::fillHandleObjects(QVector3D center,
HandleMesh ids[],
const QVector<QMatrix4x4> & mats,
const QVector<QVector4D> & colors,
QMatrix4x4 add_mat,
int count) {
QMatrix4x4 m = invariantSizeMatrix(center) * add_mat; QMatrix4x4 m = invariantSizeMatrix(center) * add_mat;
cur_objects.resize(count); cur_objects.resize(count);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
cur_objects[i].color = colors[i]; cur_objects[i].color = colors[i];
QMatrix4x4 omat = m * mats[i]; QMatrix4x4 omat = m * mats[i];
cur_objects[i].object_id = ids[i]; cur_objects[i].object_id = ids[i];
if (current_handle.testFlag(ids[i])) { if (current_handle.testFlag(ids[i])) {
cur_objects[i].color = QVector4D(0,1,1,1); cur_objects[i].color = QVector4D(0, 1, 1, 1);
} }
omat.transposed().copyDataTo(cur_objects[i].modelmatrix); omat.transposed().copyDataTo(cur_objects[i].modelmatrix);
} }
@@ -275,7 +283,7 @@ bool RendererService::calculateCenter() {
selection_center = sol[0]->worldPos(); selection_center = sol[0]->worldPos();
if (sol.size() > 1) { if (sol.size() > 1) {
Box3D bb; Box3D bb;
foreach (ObjectBase * o, sol) { foreach(ObjectBase * o, sol) {
o->calculateBoundingBox(); o->calculateBoundingBox();
bb |= o->boundingBox(); bb |= o->boundingBox();
} }
@@ -286,8 +294,7 @@ bool RendererService::calculateCenter() {
axis_mat = QMatrix4x4(); axis_mat = QMatrix4x4();
if ((sol.size() == 1)) { if ((sol.size() == 1)) {
if (current_action == haMove) { if (current_action == haMove) {
if (sol[0]->isAimSelected()) if (sol[0]->isAimSelected()) selection_center = ((AimedObject *)sol[0])->worldAim();
selection_center = ((AimedObject*)sol[0])->worldAim();
} else { } else {
axis_mat = parentRotationMatrix(sol[0]); axis_mat = parentRotationMatrix(sol[0]);
} }
@@ -301,9 +308,21 @@ void RendererService::drawCurrentHandleObjects() {
if (calculateCenter()) { if (calculateCenter()) {
HandleMesh ids[3]; HandleMesh ids[3];
switch (current_action) { switch (current_action) {
case haMove : ids[0] = hmMoveX ; ids[1] = hmMoveY ; ids[2] = hmMoveZ ; break; case haMove:
case haRotate: ids[0] = hmRotateX; ids[1] = hmRotateY; ids[2] = hmRotateZ; break; ids[0] = hmMoveX;
case haScale : ids[0] = hmScaleX ; ids[1] = hmScaleY ; ids[2] = hmScaleZ ; break; ids[1] = hmMoveY;
ids[2] = hmMoveZ;
break;
case haRotate:
ids[0] = hmRotateX;
ids[1] = hmRotateY;
ids[2] = hmRotateZ;
break;
case haScale:
ids[0] = hmScaleX;
ids[1] = hmScaleY;
ids[2] = hmScaleZ;
break;
default: break; default: break;
} }
fillHandleObjects(selection_center, ids, mat_xyz, color_xyz, axis_mat); fillHandleObjects(selection_center, ids, mat_xyz, color_xyz, axis_mat);
@@ -317,8 +336,16 @@ void RendererService::drawCurrentHandleObjects() {
} }
if (current_action == haMove || current_action == haScale) { if (current_action == haMove || current_action == haScale) {
switch (current_action) { switch (current_action) {
case haMove : ids[0] = hmMoveXY ; ids[1] = hmMoveXZ ; ids[2] = hmMoveYZ ; break; case haMove:
case haScale : ids[0] = hmScaleXY ; ids[1] = hmScaleXZ ; ids[2] = hmScaleYZ ; break; ids[0] = hmMoveXY;
ids[1] = hmMoveXZ;
ids[2] = hmMoveYZ;
break;
case haScale:
ids[0] = hmScaleXY;
ids[1] = hmScaleXZ;
ids[2] = hmScaleYZ;
break;
default: break; default: break;
} }
hm = handle_ms_2_mesh; hm = handle_ms_2_mesh;
@@ -328,8 +355,10 @@ void RendererService::drawCurrentHandleObjects() {
hm->draw(r->view, 3); hm->draw(r->view, 3);
if (current_action == haScale) { if (current_action == haScale) {
hm = handle_scale_3_mesh; hm = handle_scale_3_mesh;
QVector<QMatrix4x4> mv; mv.resize(1); QVector<QMatrix4x4> mv;
QVector<QVector4D> cv; cv.fill(QVector4D(1, 1, 0.5, 1), 1); mv.resize(1);
QVector<QVector4D> cv;
cv.fill(QVector4D(1, 1, 0.5, 1), 1);
ids[0] = hmMaxScale; ids[0] = hmMaxScale;
fillHandleObjects(selection_center, ids, mv, cv, axis_mat, 1); fillHandleObjects(selection_center, ids, mv, cv, axis_mat, 1);
hm->loadObjects(r->view, cur_objects); hm->loadObjects(r->view, cur_objects);
@@ -360,7 +389,6 @@ void RendererService::drawLights() {
box_mesh->loadObjects(v, cur_aims); box_mesh->loadObjects(v, cur_aims);
box_mesh->loadSelections(v, rs.cur_selections_); box_mesh->loadSelections(v, rs.cur_selections_);
box_mesh->draw(v, cur_aims.size()); box_mesh->draw(v, cur_aims.size());
} }
@@ -387,7 +415,6 @@ void RendererService::drawLightsFrame(QColor color) {
box_mesh_f->loadObjects(v, cur_aims); box_mesh_f->loadObjects(v, cur_aims);
box_mesh_f->loadSelections(v, rs.cur_selections_); box_mesh_f->loadSelections(v, rs.cur_selections_);
box_mesh_f->draw(v, cur_aims.size()); box_mesh_f->draw(v, cur_aims.size());
} }
@@ -405,7 +432,6 @@ void RendererService::drawCameras() {
box_mesh->loadObjects(v, cur_aims); box_mesh->loadObjects(v, cur_aims);
box_mesh->loadSelections(v, rs.cur_selections_); box_mesh->loadSelections(v, rs.cur_selections_);
box_mesh->draw(v, cur_aims.size()); box_mesh->draw(v, cur_aims.size());
} }
@@ -426,7 +452,6 @@ void RendererService::drawCamerasFrame(QColor color) {
box_mesh_f->loadObjects(v, cur_aims); box_mesh_f->loadObjects(v, cur_aims);
box_mesh_f->loadSelections(v, rs.cur_selections_); box_mesh_f->loadSelections(v, rs.cur_selections_);
box_mesh_f->draw(v, cur_aims.size()); box_mesh_f->draw(v, cur_aims.size());
} }
@@ -439,9 +464,9 @@ void RendererService::setObjectsColor(QVector<Object> & ol, QColor col) {
void RendererService::renderService() { void RendererService::renderService() {
QOpenGLShaderProgram * prog = 0; QOpenGLShaderProgram * prog = 0;
QOpenGLExtraFunctions * f = r->view; QOpenGLExtraFunctions * f = r->view;
size_full_scale = tan(r->view->camera()->FOV() / 2. * deg2rad) * size_vp_scale; size_full_scale = tan(r->view->camera()->FOV() / 2. * deg2rad) * size_vp_scale;
v_mat = r->view->camera()->fullViewMatrix(); v_mat = r->view->camera()->fullViewMatrix();
f->glEnable(GL_MULTISAMPLE); f->glEnable(GL_MULTISAMPLE);
glEnableDepth(); glEnableDepth();
f->glClear(GL_DEPTH_BUFFER_BIT); f->glClear(GL_DEPTH_BUFFER_BIT);
@@ -460,14 +485,13 @@ void RendererService::renderService() {
prog->setUniformValue("z_offset", -1.E-2f); prog->setUniformValue("z_offset", -1.E-2f);
drawLightsFrame(Qt::black); drawLightsFrame(Qt::black);
drawCamerasFrame(Qt::black); drawCamerasFrame(Qt::black);
} }
if (r->bindShader(Renderer::srServiceLine, &prog)) { if (r->bindShader(Renderer::srServiceLine, &prog)) {
r->setUniformCamera(prog, r->view->camera()); r->setUniformCamera(prog, r->view->camera());
line_object.color = QColor2QVector(Qt::white); line_object.color = QColor2QVector(Qt::white);
line_spot_f ->loadObject(f, line_object); line_spot_f->loadObject(f, line_object);
line_camera_f->loadObject(f, line_object); line_camera_f->loadObject(f, line_object);
line_spot_f ->draw(f, 1); line_spot_f->draw(f, 1);
line_camera_f->draw(f, 1); line_camera_f->draw(f, 1);
} }
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
@@ -488,7 +512,6 @@ void RendererService::renderService() {
r->setUniformCamera(prog, axis_camera, true, axis_viewport); r->setUniformCamera(prog, axis_camera, true, axis_viewport);
axis_mesh->draw(f, 3); axis_mesh->draw(f, 3);
f->glViewport(0, 0, r->view->width(), r->view->height()); f->glViewport(0, 0, r->view->width(), r->view->height());
} }
f->glDisable(GL_MULTISAMPLE); f->glDisable(GL_MULTISAMPLE);
} }
@@ -496,9 +519,9 @@ void RendererService::renderService() {
Mesh * RendererService::currentHandleMesh() { Mesh * RendererService::currentHandleMesh() {
switch (current_action) { switch (current_action) {
case haMove : return handle_move_mesh; case haMove: return handle_move_mesh;
case haRotate: return handle_rotate_mesh; case haRotate: return handle_rotate_mesh;
case haScale : return handle_scale_mesh; case haScale: return handle_scale_mesh;
default: break; default: break;
} }
return 0; return 0;

View File

@@ -1,19 +1,19 @@
/* /*
QGL RendererService QGL RendererService
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef RENDERER_SERVICE_H #ifndef RENDERER_SERVICE_H
@@ -21,6 +21,7 @@
#include "glframebuffer.h" #include "glframebuffer.h"
#include "glshaders_types.h" #include "glshaders_types.h"
#include <QQueue> #include <QQueue>
@@ -70,7 +71,12 @@ public:
void fillXYZObjects(); void fillXYZObjects();
void fillOmniObjects(); void fillOmniObjects();
void fillAimedObjects(const ObjectBaseList & objects, Mesh * line_mesh); void fillAimedObjects(const ObjectBaseList & objects, Mesh * line_mesh);
void fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count = 3); void fillHandleObjects(QVector3D center,
HandleMesh ids[],
const QVector<QMatrix4x4> & mats,
const QVector<QVector4D> & colors,
QMatrix4x4 add_mat,
int count = 3);
bool calculateCenter(); bool calculateCenter();
void drawCurrentHandleObjects(); void drawCurrentHandleObjects();
void drawLights(); void drawLights();
@@ -79,16 +85,16 @@ public:
void drawCamerasFrame(QColor color); void drawCamerasFrame(QColor color);
void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col); void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col);
void renderService(); void renderService();
void setCurrentAction(HandleAction ha) {current_action = ha;} void setCurrentAction(HandleAction ha) { current_action = ha; }
Mesh * currentHandleMesh(); Mesh * currentHandleMesh();
private: private:
Renderer * r; Renderer * r;
Mesh * axis_mesh, * handle_move_mesh, * handle_rotate_mesh, * handle_scale_mesh; Mesh *axis_mesh, *handle_move_mesh, *handle_rotate_mesh, *handle_scale_mesh;
Mesh * handle_ms_2_mesh, * handle_scale_3_mesh; Mesh *handle_ms_2_mesh, *handle_scale_3_mesh;
Mesh * box_mesh_f, * omni_mesh_f, * cone_mesh_f, * camera_mesh_f; Mesh *box_mesh_f, *omni_mesh_f, *cone_mesh_f, *camera_mesh_f;
Mesh * box_mesh, * omni_mesh, * cone_mesh, * camera_mesh; Mesh *box_mesh, *omni_mesh, *cone_mesh, *camera_mesh;
Mesh * line_spot_f, * line_camera_f; Mesh *line_spot_f, *line_camera_f;
QMatrix4x4 v_mat, axis_mat; QMatrix4x4 v_mat, axis_mat;
QVector3D selection_center; QVector3D selection_center;
QVector<QMatrix4x4> mat_xyz, mat_ms2; QVector<QMatrix4x4> mat_xyz, mat_ms2;

View File

@@ -1,47 +1,50 @@
/* /*
QGL TonemappingProc QGL TonemappingProc
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "tonemapping_proc.h" #include "tonemapping_proc.h"
#include "qglview.h" #include "qglview.h"
#include <QOpenGLExtraFunctions>
#include <qad_types.h> #include <qad_types.h>
using namespace QGLEngineShaders; using namespace QGLEngineShaders;
TonemappingProc::TonemappingProc(Renderer * rend): QThread(), r(rend), TonemappingProc::TonemappingProc(Renderer * rend)
fbo_1x1(r->view, 1, false, GL_RGB32F), : QThread()
fbomm(r->fbo_out, Renderer::obrSum, 3), , r(rend)
buffer_vbo(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW) { , fbo_1x1(r->view, 1, false, GL_RGB32F)
shader_sum = 0; , fbomm(r->fbo_out, Renderer::obrSum, 3)
, buffer_vbo(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW) {
shader_sum = 0;
timer_delim = 0; timer_delim = 0;
frame_max = cur_max = 1.; frame_max = cur_max = 1.;
need_render_sum = exit_ = false; need_render_sum = exit_ = false;
enabled = false; enabled = false;
timer_tone = startTimer(10); timer_tone = startTimer(10);
} }
TonemappingProc::~TonemappingProc() { TonemappingProc::~TonemappingProc() {
exit_ = true; exit_ = true;
if (!wait(1000)) if (!wait(1000)) terminate();
terminate();
killTimer(timer_tone); killTimer(timer_tone);
if (shader_sum) delete shader_sum; if (shader_sum) delete shader_sum;
} }
@@ -70,13 +73,13 @@ void TonemappingProc::init() {
void TonemappingProc::resize() { void TonemappingProc::resize() {
QOpenGLExtraFunctions * f = r->view; QOpenGLExtraFunctions * f = r->view;
fbomm.resize(); fbomm.resize();
int pcnt = fbomm.width(fbomm.lastLevel()) * fbomm.height(fbomm.lastLevel()); int pcnt = fbomm.width(fbomm.lastLevel()) * fbomm.height(fbomm.lastLevel());
QVector<Vector2i> _data; QVector<Vector2i> _data;
_data.resize(pcnt); _data.resize(pcnt);
pcnt = -1; pcnt = -1;
for (int x = 0; x < fbomm.width(fbomm.lastLevel()); ++x) for (int x = 0; x < fbomm.width(fbomm.lastLevel()); ++x)
for (int y = 0; y < fbomm.height(fbomm.lastLevel()); ++y) for (int y = 0; y < fbomm.height(fbomm.lastLevel()); ++y)
_data[++pcnt] = Vector2i(x,y); _data[++pcnt] = Vector2i(x, y);
buffer_vbo.bind(f); buffer_vbo.bind(f);
buffer_vbo.resize(f, _data.size() * sizeof(Vector2i)); buffer_vbo.resize(f, _data.size() * sizeof(Vector2i));
buffer_vbo.load(f, _data.constData(), _data.size() * sizeof(Vector2i)); buffer_vbo.load(f, _data.constData(), _data.size() * sizeof(Vector2i));
@@ -85,8 +88,7 @@ void TonemappingProc::resize() {
void TonemappingProc::timerEvent(QTimerEvent * e) { void TonemappingProc::timerEvent(QTimerEvent * e) {
if (!fbo_1x1.isInit() || !enabled) return; if (!fbo_1x1.isInit() || !enabled) return;
if (timer_delim == 0) if (timer_delim == 0) need_render_sum = true;
need_render_sum = true;
timer_delim = (timer_delim + 1) % 10; timer_delim = (timer_delim + 1) % 10;
mutex.lock(); mutex.lock();
float fmax = frame_max; float fmax = frame_max;
@@ -98,7 +100,7 @@ void TonemappingProc::timerEvent(QTimerEvent * e) {
void TonemappingProc::renderSum(Framebuffer & fbo_src, int index) { void TonemappingProc::renderSum(Framebuffer & fbo_src, int index) {
QOpenGLExtraFunctions * f = r->view; QOpenGLExtraFunctions * f = r->view;
int pcnt = fbo_src.width() * fbo_src.height(); int pcnt = fbo_src.width() * fbo_src.height();
fbo_src.bindColorTexture(index); fbo_src.bindColorTexture(index);
fbo_1x1.bind(); fbo_1x1.bind();
glClearFramebuffer(); glClearFramebuffer();
@@ -139,8 +141,7 @@ void TonemappingProc::run() {
mutex.unlock(); mutex.unlock();
float max = calcHistogram(data); float max = calcHistogram(data);
last_max << max; last_max << max;
if (last_max.size() > 5) if (last_max.size() > 5) last_max.removeAt(0);
last_max.removeAt(0);
float cm = last_max[0]; float cm = last_max[0];
for (int i = 1; i < last_max.size(); ++i) for (int i = 1; i < last_max.size(); ++i)
cm += last_max[i]; cm += last_max[i];
@@ -156,9 +157,9 @@ float TonemappingProc::calcHistogram(const QVector<QVector4D> & data) {
if (data.isEmpty()) return 1.f; if (data.isEmpty()) return 1.f;
float max = 0.; float max = 0.;
QVector3D luma(0.299, 0.587, 0.114); QVector3D luma(0.299, 0.587, 0.114);
foreach (const QVector4D & p, data) { foreach(const QVector4D & p, data) {
float l = QVector3D::dotProduct(p.toVector3D(), luma); float l = QVector3D::dotProduct(p.toVector3D(), luma);
max = qMax(max, l); max = qMax(max, l);
} }
return max; return max;
} }

View File

@@ -1,32 +1,33 @@
/* /*
QGL TonemappingProc QGL TonemappingProc
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef TONEMAPPING_PROC_H #ifndef TONEMAPPING_PROC_H
#define TONEMAPPING_PROC_H #define TONEMAPPING_PROC_H
#include "glframebuffer_mipmap.h" #include "glframebuffer_mipmap.h"
#include <QThread> #include <QThread>
class TonemappingProc: public QThread class TonemappingProc: public QThread {
{
friend class Renderer; friend class Renderer;
friend class QGLView; friend class QGLView;
public: public:
TonemappingProc(Renderer * rend); TonemappingProc(Renderer * rend);
virtual ~TonemappingProc(); virtual ~TonemappingProc();

View File

@@ -1,40 +1,41 @@
/* /*
QGL MaterialEditor QGL MaterialEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "material_editor.h" #include "material_editor.h"
#include "ui_material_editor.h"
#include "glmaterial.h" #include "glmaterial.h"
#include "ui_material_editor.h"
MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) { MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::MaterialEditor(); ui = new Ui::MaterialEditor();
ui->setupUi(this); ui->setupUi(this);
ui->mapDiffuse ->configure(tr("Diffuse"), true); ui->mapDiffuse->configure(tr("Diffuse"), true);
ui->mapNormal ->configure(tr("Normal")); ui->mapNormal->configure(tr("Normal"));
ui->mapMetalness->configure(tr("Metalness")); ui->mapMetalness->configure(tr("Metalness"));
ui->mapRoughness->configure(tr("Roughness")); ui->mapRoughness->configure(tr("Roughness"));
ui->mapEmission ->configure(tr("Emission"), true); ui->mapEmission->configure(tr("Emission"), true);
ui->mapRelief ->configure(tr("Relief")); ui->mapRelief->configure(tr("Relief"));
ui->checkGlass->hide(); ui->checkGlass->hide();
ui->frameReflection->hide(); ui->frameReflection->hide();
ui->label_13->hide(); ui->label_13->hide();
mat = 0; mat = 0;
active = true; active = true;
ignore_next = 0; ignore_next = 0;
} }
@@ -42,90 +43,94 @@ MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) {
void MaterialEditor::changeEvent(QEvent * e) { void MaterialEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this); default: break;
break;
default:
break;
} }
} }
void MaterialEditor::materialChanged() { void MaterialEditor::materialChanged() {
if (!active || !mat) return; if (!active || !mat) return;
ignore_next = 2; ignore_next = 2;
mat->_changed = true; mat->_changed = true;
mat->color_diffuse = ui->mapDiffuse ->color(); mat->color_diffuse = ui->mapDiffuse->color();
mat->color_emission = ui->mapEmission->color(); mat->color_emission = ui->mapEmission->color();
mat->transparency = ui->spinTransparent->value(); mat->transparency = ui->spinTransparent->value();
mat->reflectivity = ui->spinReflect->value(); mat->reflectivity = ui->spinReflect->value();
mat->iof = ui->spinIOF->value(); mat->iof = ui->spinIOF->value();
mat->dispersion = ui->spinDispersion->value(); mat->dispersion = ui->spinDispersion->value();
mat->glass = ui->checkGlass->isChecked(); mat->glass = ui->checkGlass->isChecked();
//emit changed(); // emit changed();
} }
void MaterialEditor::setMaterial(Material * m) { void MaterialEditor::setMaterial(Material * m) {
if (ignore_next > 0) { if (ignore_next > 0) {
//ignore_next = false; // ignore_next = false;
return; return;
} }
active = false; active = false;
mat = m; mat = m;
setEnabled(m); setEnabled(m);
if (!mat) return; if (!mat) return;
ui->mapDiffuse ->setColor(mat->color_diffuse ); ui->mapDiffuse->setColor(mat->color_diffuse);
ui->mapEmission->setColor(mat->color_emission); ui->mapEmission->setColor(mat->color_emission);
ui->spinTransparent->setValue(mat->transparency); ui->spinTransparent->setValue(mat->transparency);
ui->spinReflect->setValue(mat->reflectivity); ui->spinReflect->setValue(mat->reflectivity);
ui->spinIOF->setValue(mat->iof); ui->spinIOF->setValue(mat->iof);
ui->spinDispersion->setValue(mat->dispersion); ui->spinDispersion->setValue(mat->dispersion);
ui->checkGlass->setChecked(mat->glass); ui->checkGlass->setChecked(mat->glass);
ui->mapDiffuse ->setMap(&(mat->map_diffuse )); ui->mapDiffuse->setMap(&(mat->map_diffuse));
ui->mapNormal ->setMap(&(mat->map_normal )); ui->mapNormal->setMap(&(mat->map_normal));
ui->mapMetalness->setMap(&(mat->map_metalness)); ui->mapMetalness->setMap(&(mat->map_metalness));
ui->mapRoughness->setMap(&(mat->map_roughness)); ui->mapRoughness->setMap(&(mat->map_roughness));
ui->mapEmission ->setMap(&(mat->map_emission )); ui->mapEmission->setMap(&(mat->map_emission));
ui->mapRelief ->setMap(&(mat->map_relief )); ui->mapRelief->setMap(&(mat->map_relief));
/*ui->lineReflFront->setProperty("GLpath", mat->map_reflection.path(0)); ui->lineReflFront->setText(QFileInfo(mat->map_reflection.path(0)).fileName()); /*ui->lineReflFront->setProperty("GLpath", mat->map_reflection.path(0));
ui->lineReflBack->setProperty("GLpath", mat->map_reflection.path(1)); ui->lineReflBack->setText(QFileInfo(mat->map_reflection.path(1)).fileName()); ui->lineReflFront->setText(QFileInfo(mat->map_reflection.path(0)).fileName()); ui->lineReflBack->setProperty("GLpath",
ui->lineReflLeft->setProperty("GLpath", mat->map_reflection.path(2)); ui->lineReflLeft->setText(QFileInfo(mat->map_reflection.path(2)).fileName()); mat->map_reflection.path(1)); ui->lineReflBack->setText(QFileInfo(mat->map_reflection.path(1)).fileName());
ui->lineReflRight->setProperty("GLpath", mat->map_reflection.path(3)); ui->lineReflRight->setText(QFileInfo(mat->map_reflection.path(3)).fileName()); ui->lineReflLeft->setProperty("GLpath", mat->map_reflection.path(2));
ui->lineReflTop->setProperty("GLpath", mat->map_reflection.path(4)); ui->lineReflTop->setText(QFileInfo(mat->map_reflection.path(4)).fileName()); ui->lineReflLeft->setText(QFileInfo(mat->map_reflection.path(2)).fileName()); ui->lineReflRight->setProperty("GLpath",
ui->lineReflBottom->setProperty("GLpath", mat->map_reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(mat->map_reflection.path(5)).fileName()); mat->map_reflection.path(3)); ui->lineReflRight->setText(QFileInfo(mat->map_reflection.path(3)).fileName());
*/active = true; ui->lineReflTop->setProperty("GLpath", mat->map_reflection.path(4));
ui->lineReflTop->setText(QFileInfo(mat->map_reflection.path(4)).fileName()); ui->lineReflBottom->setProperty("GLpath",
mat->map_reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(mat->map_reflection.path(5)).fileName());
*/
active = true;
} }
/* /*
Material MaterialEditor::material() { Material MaterialEditor::material() {
Material m; Material m;
mat->color_diffuse = ui->colorDiffuse ->color(); mat->color_diffuse = ui->colorDiffuse ->color();
mat->color_specular = ui->colorSpecular->color(); mat->color_specular = ui->colorSpecular->color();
mat->color_emission = ui->colorEmission->color(); mat->color_emission = ui->colorEmission->color();
mat->transparency = ui->spinTransparent->value(); mat->transparency = ui->spinTransparent->value();
mat->reflectivity = ui->spinReflect->value(); mat->reflectivity = ui->spinReflect->value();
mat->iof = ui->spinIOF->value(); mat->iof = ui->spinIOF->value();
mat->dispersion = ui->spinDispersion->value(); mat->dispersion = ui->spinDispersion->value();
mat->glass = ui->checkGlass->isChecked(); mat->glass = ui->checkGlass->isChecked();
mat->map_diffuse = ui->mapDiffuse->map(); mat->map_diffuse = ui->mapDiffuse->map();
mat->map_normal = ui->mapNormal->map(); mat->map_normal = ui->mapNormal->map();
mat->map_specular = ui->mapSpecular->map(); mat->map_specular = ui->mapSpecular->map();
mat->map_roughness = ui->mapRoughness->map(); mat->map_roughness = ui->mapRoughness->map();
mat->map_emission = ui->mapEmission->map(); mat->map_emission = ui->mapEmission->map();
mat->map_relief = ui->mapRelief->map(); mat->map_relief = ui->mapRelief->map();
mat->map_reflection.setPath(0, ui->lineReflFront->property("GLpath").toString()); mat->map_reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
mat->map_reflection.setPath(1, ui->lineReflBack->property("GLpath").toString()); mat->map_reflection.setPath(1, ui->lineReflBack->property("GLpath").toString());
mat->map_reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString()); mat->map_reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString());
mat->map_reflection.setPath(3, ui->lineReflRight->property("GLpath").toString()); mat->map_reflection.setPath(3, ui->lineReflRight->property("GLpath").toString());
mat->map_reflection.setPath(4, ui->lineReflTop->property("GLpath").toString()); mat->map_reflection.setPath(4, ui->lineReflTop->property("GLpath").toString());
mat->map_reflection.setPath(5, ui->lineReflBottom->property("GLpath").toString()); mat->map_reflection.setPath(5, ui->lineReflBottom->property("GLpath").toString());
return m; return m;
} }
*/ */
void MaterialEditor::on_buttonReflFrontSelect_clicked() { void MaterialEditor::on_buttonReflFrontSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflFront->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)"); QString str = QFileDialog::getOpenFileName(this,
"Select image",
ui->lineReflFront->property("GLpath").toString(),
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return; if (str.isEmpty()) return;
ui->lineReflFront->setProperty("GLpath", str); ui->lineReflFront->setProperty("GLpath", str);
ui->lineReflFront->setText(QFileInfo(str).fileName()); ui->lineReflFront->setText(QFileInfo(str).fileName());
@@ -134,7 +139,10 @@ void MaterialEditor::on_buttonReflFrontSelect_clicked() {
void MaterialEditor::on_buttonReflBackSelect_clicked() { void MaterialEditor::on_buttonReflBackSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflBack->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)"); QString str = QFileDialog::getOpenFileName(this,
"Select image",
ui->lineReflBack->property("GLpath").toString(),
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return; if (str.isEmpty()) return;
ui->lineReflBack->setProperty("GLpath", str); ui->lineReflBack->setProperty("GLpath", str);
ui->lineReflBack->setText(QFileInfo(str).fileName()); ui->lineReflBack->setText(QFileInfo(str).fileName());
@@ -143,7 +151,10 @@ void MaterialEditor::on_buttonReflBackSelect_clicked() {
void MaterialEditor::on_buttonReflLeftSelect_clicked() { void MaterialEditor::on_buttonReflLeftSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflLeft->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)"); QString str = QFileDialog::getOpenFileName(this,
"Select image",
ui->lineReflLeft->property("GLpath").toString(),
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return; if (str.isEmpty()) return;
ui->lineReflLeft->setProperty("GLpath", str); ui->lineReflLeft->setProperty("GLpath", str);
ui->lineReflLeft->setText(QFileInfo(str).fileName()); ui->lineReflLeft->setText(QFileInfo(str).fileName());
@@ -152,7 +163,10 @@ void MaterialEditor::on_buttonReflLeftSelect_clicked() {
void MaterialEditor::on_buttonReflRightSelect_clicked() { void MaterialEditor::on_buttonReflRightSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflRight->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)"); QString str = QFileDialog::getOpenFileName(this,
"Select image",
ui->lineReflRight->property("GLpath").toString(),
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return; if (str.isEmpty()) return;
ui->lineReflRight->setProperty("GLpath", str); ui->lineReflRight->setProperty("GLpath", str);
ui->lineReflRight->setText(QFileInfo(str).fileName()); ui->lineReflRight->setText(QFileInfo(str).fileName());
@@ -161,7 +175,10 @@ void MaterialEditor::on_buttonReflRightSelect_clicked() {
void MaterialEditor::on_buttonReflTopSelect_clicked() { void MaterialEditor::on_buttonReflTopSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflTop->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)"); QString str = QFileDialog::getOpenFileName(this,
"Select image",
ui->lineReflTop->property("GLpath").toString(),
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return; if (str.isEmpty()) return;
ui->lineReflTop->setProperty("GLpath", str); ui->lineReflTop->setProperty("GLpath", str);
ui->lineReflTop->setText(QFileInfo(str).fileName()); ui->lineReflTop->setText(QFileInfo(str).fileName());
@@ -170,7 +187,10 @@ void MaterialEditor::on_buttonReflTopSelect_clicked() {
void MaterialEditor::on_buttonReflBottomSelect_clicked() { void MaterialEditor::on_buttonReflBottomSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflBottom->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)"); QString str = QFileDialog::getOpenFileName(this,
"Select image",
ui->lineReflBottom->property("GLpath").toString(),
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return; if (str.isEmpty()) return;
ui->lineReflBottom->setProperty("GLpath", str); ui->lineReflBottom->setProperty("GLpath", str);
ui->lineReflBottom->setText(QFileInfo(str).fileName()); ui->lineReflBottom->setText(QFileInfo(str).fileName());

View File

@@ -1,35 +1,36 @@
/* /*
QGL MaterialEditor QGL MaterialEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef MATERIAL_EDITOR_H #ifndef MATERIAL_EDITOR_H
#define MATERIAL_EDITOR_H #define MATERIAL_EDITOR_H
#include <QFileDialog>
#include "gltypes.h" #include "gltypes.h"
#include <QFileDialog>
namespace Ui { namespace Ui {
class MaterialEditor; class MaterialEditor;
} }
class MaterialEditor: public QWidget class MaterialEditor: public QWidget {
{
friend class MaterialsEditor; friend class MaterialsEditor;
Q_OBJECT Q_OBJECT
public: public:
explicit MaterialEditor(QWidget * parent = 0); explicit MaterialEditor(QWidget * parent = 0);
@@ -61,7 +62,6 @@ private slots:
signals: signals:
void changed(); void changed();
}; };
#endif // MATERIAL_EDITOR_H #endif // MATERIAL_EDITOR_H

View File

@@ -1,25 +1,27 @@
/* /*
QGL MaterialMapEditor QGL MaterialMapEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "material_map_editor.h" #include "material_map_editor.h"
#include "ui_material_map_editor.h"
#include "gltexture_manager.h"
#include "glmaterial.h" #include "glmaterial.h"
#include "gltexture_manager.h"
#include "ui_material_map_editor.h"
#include <qad_types.h> #include <qad_types.h>
@@ -34,11 +36,8 @@ MaterialMapEditor::MaterialMapEditor(QWidget * parent): QWidget(parent) {
void MaterialMapEditor::changeEvent(QEvent * e) { void MaterialMapEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this); default: break;
break;
default:
break;
} }
} }
@@ -57,7 +56,7 @@ void MaterialMapEditor::updateIcon() {
void MaterialMapEditor::mapChanged() { void MaterialMapEditor::mapChanged() {
if (!active || !map) return; if (!active || !map) return;
active = false; active = false;
map->use_bitmap = ui->checkMap->isChecked(); map->use_bitmap = ui->checkMap->isChecked();
if (ui->checkMap->isChecked()) { if (ui->checkMap->isChecked()) {
map->color_amount = ui->sliderAmount->value(); map->color_amount = ui->sliderAmount->value();
@@ -75,7 +74,7 @@ void MaterialMapEditor::mapChanged() {
void MaterialMapEditor::setMap(Map * m) { void MaterialMapEditor::setMap(Map * m) {
active = false; active = false;
map = m; map = m;
setEnabled(m); setEnabled(m);
if (!map) return; if (!map) return;
ui->stackedWidget->setCurrentIndex(map->use_bitmap ? 1 : 0); ui->stackedWidget->setCurrentIndex(map->use_bitmap ? 1 : 0);
@@ -85,7 +84,8 @@ void MaterialMapEditor::setMap(Map * m) {
ui->sliderOffset->setValue(map->color_offset); ui->sliderOffset->setValue(map->color_offset);
ui->spinScaleX->setValue(map->bitmap_scale.x()); ui->spinScaleX->setValue(map->bitmap_scale.x());
ui->spinScaleY->setValue(map->bitmap_scale.y()); ui->spinScaleY->setValue(map->bitmap_scale.y());
ui->linePath->setProperty("GLpath", map->bitmap_path); ui->linePath->setText(QFileInfo(map->bitmap_path).fileName()); ui->linePath->setProperty("GLpath", map->bitmap_path);
ui->linePath->setText(QFileInfo(map->bitmap_path).fileName());
updateIcon(); updateIcon();
active = true; active = true;
} }
@@ -110,18 +110,21 @@ QColor MaterialMapEditor::color() const {
/* /*
Map MaterialMapEditor::map() { Map MaterialMapEditor::map() {
Map m; Map m;
map->color_amount = ui->sliderAmount->value(); map->color_amount = ui->sliderAmount->value();
map->color_offset = ui->sliderOffset->value(); map->color_offset = ui->sliderOffset->value();
map->bitmap_scale.setX(ui->spinScaleX->value()); map->bitmap_scale.setX(ui->spinScaleX->value());
map->bitmap_scale.setY(ui->spinScaleY->value()); map->bitmap_scale.setY(ui->spinScaleY->value());
map->bitmap_path = ui->linePath->property("GLpath").toString(); map->bitmap_path = ui->linePath->property("GLpath").toString();
return m; return m;
} }
*/ */
void MaterialMapEditor::on_buttonSelect_clicked() { void MaterialMapEditor::on_buttonSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->linePath->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)"); QString str = QFileDialog::getOpenFileName(this,
"Select image",
ui->linePath->property("GLpath").toString(),
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return; if (str.isEmpty()) return;
ui->linePath->setProperty("GLpath", str); ui->linePath->setProperty("GLpath", str);
ui->linePath->setText(QFileInfo(str).fileName()); ui->linePath->setText(QFileInfo(str).fileName());

View File

@@ -1,34 +1,35 @@
/* /*
QGL MaterialMapEditor QGL MaterialMapEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef MATERIAL_MAP_EDITOR_H #ifndef MATERIAL_MAP_EDITOR_H
#define MATERIAL_MAP_EDITOR_H #define MATERIAL_MAP_EDITOR_H
#include <QFileDialog>
#include "gltypes.h" #include "gltypes.h"
#include <QFileDialog>
namespace Ui { namespace Ui {
class MaterialMapEditor; class MaterialMapEditor;
} }
class MaterialMapEditor: public QWidget class MaterialMapEditor: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit MaterialMapEditor(QWidget * parent = 0); explicit MaterialMapEditor(QWidget * parent = 0);
@@ -54,7 +55,6 @@ private slots:
signals: signals:
void changed(); void changed();
}; };
#endif // MATERIAL_MAP_EDITOR_H #endif // MATERIAL_MAP_EDITOR_H

View File

@@ -1,29 +1,31 @@
/* /*
QGL MaterialsEditor QGL MaterialsEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "materials_editor.h" #include "materials_editor.h"
#include "ui_materials_editor.h"
#include "glmaterial.h"
#include "material_editor.h" #include "material_editor.h"
#include "qglview.h" #include "qglview.h"
#include "glmaterial.h" #include "ui_materials_editor.h"
#include <qad_types.h>
#include <ecombobox.h>
#include <QInputDialog> #include <QInputDialog>
#include <ecombobox.h>
#include <qad_types.h>
MaterialsEditor::MaterialsEditor(QWidget * parent): QWidget(parent) { MaterialsEditor::MaterialsEditor(QWidget * parent): QWidget(parent) {
@@ -40,7 +42,7 @@ void MaterialsEditor::assignQGLView(QGLView * v) {
view = v; view = v;
connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
connect(view, SIGNAL(materialsChanged()), this, SLOT(materialsChanged())); connect(view, SIGNAL(materialsChanged()), this, SLOT(materialsChanged()));
connect(view, SIGNAL(materialThumbnailCreated(Material*)), this, SLOT(materialThumbnailCreated(Material*))); connect(view, SIGNAL(materialThumbnailCreated(Material *)), this, SLOT(materialThumbnailCreated(Material *)));
materialsChanged(); materialsChanged();
} }
@@ -50,11 +52,11 @@ bool MaterialsEditor::event(QEvent * e) {
QSize sz = preferredIconSize(1.5, this); QSize sz = preferredIconSize(1.5, this);
ui->comboMaterial->setIconSize(sz * 3); ui->comboMaterial->setIconSize(sz * 3);
ui->buttonRename->setIconSize(sz); ui->buttonRename->setIconSize(sz);
ui->buttonAdd ->setIconSize(sz); ui->buttonAdd->setIconSize(sz);
ui->buttonClone ->setIconSize(sz); ui->buttonClone->setIconSize(sz);
ui->buttonDelete->setIconSize(sz); ui->buttonDelete->setIconSize(sz);
ui->buttonAssign->setIconSize(sz); ui->buttonAssign->setIconSize(sz);
ui->buttonUnset ->setIconSize(sz); ui->buttonUnset->setIconSize(sz);
} }
return QWidget::event(e); return QWidget::event(e);
} }
@@ -63,19 +65,16 @@ bool MaterialsEditor::event(QEvent * e) {
void MaterialsEditor::changeEvent(QEvent * e) { void MaterialsEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this); default: break;
break;
default:
break;
} }
} }
Material * MaterialsEditor::currentMaterial() { Material * MaterialsEditor::currentMaterial() {
if (!view) return 0; if (!view) return 0;
int ind = ui->comboMaterial->currentIndex(); int ind = ui->comboMaterial->currentIndex();
QVector<Material*> mats = view->scene()->getMaterials(); QVector<Material *> mats = view->scene()->getMaterials();
if (ind < 0 || ind >= mats.size()) return 0; if (ind < 0 || ind >= mats.size()) return 0;
return mats[ind]; return mats[ind];
} }
@@ -87,7 +86,7 @@ void MaterialsEditor::selectMaterial(Material * m) {
return; return;
} }
for (int i = 0; i < ui->comboMaterial->count(); ++i) { for (int i = 0; i < ui->comboMaterial->count(); ++i) {
if ((Material*)(ui->comboMaterial->itemData(i, Qt::UserRole + 1).value<quintptr>()) == m) { if ((Material *)(ui->comboMaterial->itemData(i, Qt::UserRole + 1).value<quintptr>()) == m) {
ui->comboMaterial->setCurrentIndex(i); ui->comboMaterial->setCurrentIndex(i);
break; break;
} }
@@ -98,8 +97,7 @@ void MaterialsEditor::selectMaterial(Material * m) {
int MaterialsEditor::indexByMaterial(Material * m) { int MaterialsEditor::indexByMaterial(Material * m) {
if (!m) return -1; if (!m) return -1;
for (int i = 0; i < ui->comboMaterial->count(); ++i) { for (int i = 0; i < ui->comboMaterial->count(); ++i) {
if ((Material*)(ui->comboMaterial->itemData(i, Qt::UserRole + 1).value<quintptr>()) == m) if ((Material *)(ui->comboMaterial->itemData(i, Qt::UserRole + 1).value<quintptr>()) == m) return i;
return i;
} }
return -1; return -1;
} }
@@ -107,7 +105,7 @@ int MaterialsEditor::indexByMaterial(Material * m) {
void MaterialsEditor::selectionChanged() { void MaterialsEditor::selectionChanged() {
if (!view) return; if (!view) return;
//qDebug() << "selectionChanged"; // qDebug() << "selectionChanged";
ObjectBase * o = view->selectedObject(); ObjectBase * o = view->selectedObject();
if (o) selectMaterial(o->material()); if (o) selectMaterial(o->material());
} }
@@ -121,7 +119,7 @@ void MaterialsEditor::materialsChanged() {
Material * cm = currentMaterial(); Material * cm = currentMaterial();
ui->comboMaterial->clear(); ui->comboMaterial->clear();
if (!view) return; if (!view) return;
QVector<Material*> mats = view->scene()->getMaterials(); QVector<Material *> mats = view->scene()->getMaterials();
for (int i = 0; i < mats.size(); ++i) { for (int i = 0; i < mats.size(); ++i) {
Material * m = mats[i]; Material * m = mats[i];
ui->comboMaterial->addItem(QString("[%1] " + m->name).arg(i + 1), QVariant(m->name)); ui->comboMaterial->addItem(QString("[%1] " + m->name).arg(i + 1), QVariant(m->name));
@@ -129,15 +127,14 @@ void MaterialsEditor::materialsChanged() {
ui->comboMaterial->setItemIcon(i, QIcon(QPixmap::fromImage(view->materialThumbnail(m)))); ui->comboMaterial->setItemIcon(i, QIcon(QPixmap::fromImage(view->materialThumbnail(m))));
if (cm == m) ui->comboMaterial->setCurrentIndex(i); if (cm == m) ui->comboMaterial->setCurrentIndex(i);
} }
} }
void MaterialsEditor::materialThumbnailCreated(Material * m) { void MaterialsEditor::materialThumbnailCreated(Material * m) {
//qDebug() << "materialThumbnailCreated" << m; // qDebug() << "materialThumbnailCreated" << m;
int i = indexByMaterial(m); int i = indexByMaterial(m);
if (i < 0 || !view) return; if (i < 0 || !view) return;
//qDebug() << "materialThumbnailCreated set to" << i; // qDebug() << "materialThumbnailCreated set to" << i;
ui->comboMaterial->setItemIcon(i, QIcon(QPixmap::fromImage(view->materialThumbnail(m)))); ui->comboMaterial->setItemIcon(i, QIcon(QPixmap::fromImage(view->materialThumbnail(m))));
} }
@@ -172,10 +169,10 @@ void MaterialsEditor::on_buttonClone_clicked() {
Material * curm = currentMaterial(); Material * curm = currentMaterial();
if (!curm) return; if (!curm) return;
Material * m = view->scene()->newMaterial(curm->name); Material * m = view->scene()->newMaterial(curm->name);
QString nm = m->name; QString nm = m->name;
*m = *curm; *m = *curm;
m->name = nm; m->name = nm;
m->_changed = true; m->_changed = true;
materialsChanged(); materialsChanged();
selectMaterial(m); selectMaterial(m);
} }
@@ -192,9 +189,9 @@ void MaterialsEditor::on_buttonDelete_clicked() {
void MaterialsEditor::on_buttonAssign_clicked() { void MaterialsEditor::on_buttonAssign_clicked() {
if (!view) return; if (!view) return;
Material * m = currentMaterial(); Material * m = currentMaterial();
ObjectBaseList ol = view->selectedObjects(); ObjectBaseList ol = view->selectedObjects();
foreach (ObjectBase * o, ol) foreach(ObjectBase * o, ol)
o->setMaterial(m, true); o->setMaterial(m, true);
} }
@@ -202,6 +199,6 @@ void MaterialsEditor::on_buttonAssign_clicked() {
void MaterialsEditor::on_buttonUnset_clicked() { void MaterialsEditor::on_buttonUnset_clicked() {
if (!view) return; if (!view) return;
ObjectBaseList ol = view->selectedObjects(); ObjectBaseList ol = view->selectedObjects();
foreach (ObjectBase * o, ol) foreach(ObjectBase * o, ol)
o->setMaterial(0, true); o->setMaterial(0, true);
} }

View File

@@ -1,34 +1,35 @@
/* /*
QGL MaterialsEditor QGL MaterialsEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef MATERIALS_EDITOR_H #ifndef MATERIALS_EDITOR_H
#define MATERIALS_EDITOR_H #define MATERIALS_EDITOR_H
#include <QFileDialog>
#include "gltypes.h" #include "gltypes.h"
#include <QFileDialog>
namespace Ui { namespace Ui {
class MaterialsEditor; class MaterialsEditor;
} }
class MaterialsEditor: public QWidget class MaterialsEditor: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit MaterialsEditor(QWidget * parent = 0); explicit MaterialsEditor(QWidget * parent = 0);
@@ -60,7 +61,6 @@ private slots:
signals: signals:
void changed(); void changed();
}; };
#endif // MATERIALS_EDITOR_H #endif // MATERIALS_EDITOR_H

View File

@@ -1,33 +1,35 @@
/* /*
QGL ObjectEditor QGL ObjectEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "object_editor.h" #include "object_editor.h"
#include "ui_object_editor.h"
#include "qglview.h" #include "qglview.h"
#include <spinslider.h> #include "ui_object_editor.h"
#include <scroll_spin_box.h> #include <scroll_spin_box.h>
#include <spinslider.h>
ObjectEditor::ObjectEditor(QWidget * parent): QWidget(parent) { ObjectEditor::ObjectEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::ObjectEditor(); ui = new Ui::ObjectEditor();
ui->setupUi(this); ui->setupUi(this);
view = 0; view = 0;
active = true; active = true;
ignore_next = false; ignore_next = false;
on_comboLightType_currentIndexChanged(0); on_comboLightType_currentIndexChanged(0);
ui->widgetMain->setEnabled(false); ui->widgetMain->setEnabled(false);
@@ -35,31 +37,27 @@ ObjectEditor::ObjectEditor(QWidget * parent): QWidget(parent) {
ui->spinAimDist->hide(); ui->spinAimDist->hide();
QObjectList ol; QObjectList ol;
ol << ui->spinPosX << ui->spinPosY << ui->spinPosZ << ol << ui->spinPosX << ui->spinPosY << ui->spinPosZ << ui->spinRotationX << ui->spinRotationY << ui->spinRotationZ << ui->spinScaleX
ui->spinRotationX << ui->spinRotationY << ui->spinRotationZ << << ui->spinScaleY << ui->spinScaleZ;
ui->spinScaleX << ui->spinScaleY << ui->spinScaleZ; foreach(QObject * o, ol)
foreach (QObject * o, ol)
connect(o, SIGNAL(valueChanged(double)), this, SLOT(spinChanged(double))); connect(o, SIGNAL(valueChanged(double)), this, SLOT(spinChanged(double)));
ol.clear(); ol.clear();
ol << ui->spinLightIntensity << ui->spinLightDecayConst << ui->spinLightDecayLinear << ol << ui->spinLightIntensity << ui->spinLightDecayConst << ui->spinLightDecayLinear << ui->spinLightDecayQuadratic
ui->spinLightDecayQuadratic << ui->spinLightAngleStart << ui->spinLightAngleEnd << << ui->spinLightAngleStart << ui->spinLightAngleEnd << ui->spinAimDist;
ui->spinAimDist; foreach(QObject * o, ol)
foreach (QObject * o, ol)
connect(o, SIGNAL(valueChanged(double)), this, SLOT(spinLightChanged(double))); connect(o, SIGNAL(valueChanged(double)), this, SLOT(spinLightChanged(double)));
ol.clear(); ol.clear();
ol << ui->spinCameraFOV << ui->spinCameraDepthStart << ui->spinCameraRoll << ui->spinAimDist; ol << ui->spinCameraFOV << ui->spinCameraDepthStart << ui->spinCameraRoll << ui->spinAimDist;
foreach (QObject * o, ol) foreach(QObject * o, ol)
connect(o, SIGNAL(valueChanged(double)), this, SLOT(spinCameraChanged(double))); connect(o, SIGNAL(valueChanged(double)), this, SLOT(spinCameraChanged(double)));
ol.clear(); ol.clear();
ol << ui->checkVisible << ui->checkCastShadows << ui->checkReceiveShadows << ol << ui->checkVisible << ui->checkCastShadows << ui->checkReceiveShadows << ui->checkAcceptLight << ui->checkAcceptFog
ui->checkAcceptLight << ui->checkAcceptFog << << ui->checkCameraMirrorX << ui->checkCameraMirrorY;
ui->checkCameraMirrorX << ui->checkCameraMirrorY; foreach(QObject * o, ol)
foreach (QObject * o, ol)
connect(o, SIGNAL(toggled(bool)), this, SLOT(checkChanged(bool))); connect(o, SIGNAL(toggled(bool)), this, SLOT(checkChanged(bool)));
} }
@@ -75,11 +73,8 @@ void ObjectEditor::assignQGLView(QGLView * v) {
void ObjectEditor::changeEvent(QEvent * e) { void ObjectEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this); default: break;
break;
default:
break;
} }
} }
@@ -102,10 +97,10 @@ void ObjectEditor::selectionChanged() {
return; return;
} }
bool hl = !view->selectedLights().isEmpty(), hc = !view->selectedCameras().isEmpty(); bool hl = !view->selectedLights().isEmpty(), hc = !view->selectedCameras().isEmpty();
ui->groupLight ->setVisible(hl); ui->groupLight->setVisible(hl);
ui->groupCamera ->setVisible(hc); ui->groupCamera->setVisible(hc);
ui->labelAimDist->setVisible(hl || hc); ui->labelAimDist->setVisible(hl || hc);
ui->spinAimDist ->setVisible(hl || hc); ui->spinAimDist->setVisible(hl || hc);
ui->labelTitle->setText(tr("[%1 objects]").arg(sol.size())); ui->labelTitle->setText(tr("[%1 objects]").arg(sol.size()));
} }
@@ -131,12 +126,12 @@ void ObjectEditor::setObject(ObjectBase * o) {
bool is_l = o->type() == ObjectBase::glLight; bool is_l = o->type() == ObjectBase::glLight;
bool is_c = o->type() == ObjectBase::glCamera; bool is_c = o->type() == ObjectBase::glCamera;
ui->labelAimDist->setVisible(is_l || is_c); ui->labelAimDist->setVisible(is_l || is_c);
ui->spinAimDist ->setVisible(is_l || is_c); ui->spinAimDist->setVisible(is_l || is_c);
ui->groupLight ->setVisible(is_l); ui->groupLight->setVisible(is_l);
ui->groupCamera ->setVisible(is_c); ui->groupCamera->setVisible(is_c);
if (is_l) { if (is_l) {
Light * l = globject_cast<Light * >(o); Light * l = globject_cast<Light *>(o);
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone; // bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
ui->comboLightType->setCurrentIndex(l->light_type); ui->comboLightType->setCurrentIndex(l->light_type);
ui->spinLightIntensity->setValue(l->intensity); ui->spinLightIntensity->setValue(l->intensity);
ui->spinLightDecayConst->setValue(l->decay_const); ui->spinLightDecayConst->setValue(l->decay_const);
@@ -148,7 +143,7 @@ void ObjectEditor::setObject(ObjectBase * o) {
on_comboLightType_currentIndexChanged(ui->comboLightType->currentIndex()); on_comboLightType_currentIndexChanged(ui->comboLightType->currentIndex());
} }
if (is_c) { if (is_c) {
Camera * c = globject_cast<Camera * >(o); Camera * c = globject_cast<Camera *>(o);
ui->checkCameraMirrorX->setChecked(c->isMirrorX()); ui->checkCameraMirrorX->setChecked(c->isMirrorX());
ui->checkCameraMirrorY->setChecked(c->isMirrorY()); ui->checkCameraMirrorY->setChecked(c->isMirrorY());
ui->spinCameraFOV->setValue(c->FOV()); ui->spinCameraFOV->setValue(c->FOV());
@@ -161,26 +156,24 @@ void ObjectEditor::setObject(ObjectBase * o) {
void ObjectEditor::on_spinLightAngleStart_valueChanged(double v) { void ObjectEditor::on_spinLightAngleStart_valueChanged(double v) {
if (ui->spinLightAngleEnd->value() < v) if (ui->spinLightAngleEnd->value() < v) ui->spinLightAngleEnd->setValue(v);
ui->spinLightAngleEnd->setValue(v);
} }
void ObjectEditor::on_spinLightAngleEnd_valueChanged(double v) { void ObjectEditor::on_spinLightAngleEnd_valueChanged(double v) {
if (ui->spinLightAngleStart->value() > v) if (ui->spinLightAngleStart->value() > v) ui->spinLightAngleStart->setValue(v);
ui->spinLightAngleStart->setValue(v);
} }
void ObjectEditor::on_comboLightType_currentIndexChanged(int index) { void ObjectEditor::on_comboLightType_currentIndexChanged(int index) {
bool ang = (index == Light::Cone); bool ang = (index == Light::Cone);
ui->labelLightAngle ->setVisible(ang); ui->labelLightAngle->setVisible(ang);
ui->labelLightAngleDash->setVisible(ang); ui->labelLightAngleDash->setVisible(ang);
ui->spinLightAngleStart->setVisible(ang); ui->spinLightAngleStart->setVisible(ang);
ui->spinLightAngleEnd ->setVisible(ang); ui->spinLightAngleEnd->setVisible(ang);
if (!view || !active) return; if (!view || !active) return;
QList<Light*> sll = view->selectedLights(); QList<Light *> sll = view->selectedLights();
foreach (Light * o, sll) { foreach(Light * o, sll) {
o->light_type = (Light::Type)index; o->light_type = (Light::Type)index;
o->apply(); o->apply();
} }
@@ -190,10 +183,10 @@ void ObjectEditor::on_comboLightType_currentIndexChanged(int index) {
void ObjectEditor::on_buttonColor_colorChanged(const QColor & v) { void ObjectEditor::on_buttonColor_colorChanged(const QColor & v) {
if (!view || !active) return; if (!view || !active) return;
ObjectBaseList sol = view->selectedObjects(); ObjectBaseList sol = view->selectedObjects();
foreach (ObjectBase * o, sol) foreach(ObjectBase * o, sol)
o->setColor(v); o->setColor(v);
QList<Light*> sll = view->selectedLights(); QList<Light *> sll = view->selectedLights();
foreach (Light * o, sll) foreach(Light * o, sll)
o->apply(); o->apply();
} }
@@ -201,17 +194,17 @@ void ObjectEditor::on_buttonColor_colorChanged(const QColor & v) {
void ObjectEditor::spinChanged(double v) { void ObjectEditor::spinChanged(double v) {
if (!view || !active) return; if (!view || !active) return;
ObjectBaseList sol = view->selectedObjects(true); ObjectBaseList sol = view->selectedObjects(true);
QObject * s = sender(); QObject * s = sender();
foreach (ObjectBase * o, sol) { foreach(ObjectBase * o, sol) {
if (s == ui->spinPosX ) o->setPosX (v); if (s == ui->spinPosX) o->setPosX(v);
if (s == ui->spinPosY ) o->setPosY (v); if (s == ui->spinPosY) o->setPosY(v);
if (s == ui->spinPosZ ) o->setPosZ (v); if (s == ui->spinPosZ) o->setPosZ(v);
if (s == ui->spinRotationX) o->setRotationX(v); if (s == ui->spinRotationX) o->setRotationX(v);
if (s == ui->spinRotationY) o->setRotationY(v); if (s == ui->spinRotationY) o->setRotationY(v);
if (s == ui->spinRotationZ) o->setRotationZ(v); if (s == ui->spinRotationZ) o->setRotationZ(v);
if (s == ui->spinScaleX ) o->setScaleX (v); if (s == ui->spinScaleX) o->setScaleX(v);
if (s == ui->spinScaleY ) o->setScaleY (v); if (s == ui->spinScaleY) o->setScaleY(v);
if (s == ui->spinScaleZ ) o->setScaleZ (v); if (s == ui->spinScaleZ) o->setScaleZ(v);
} }
ignore_next = true; ignore_next = true;
} }
@@ -219,16 +212,16 @@ void ObjectEditor::spinChanged(double v) {
void ObjectEditor::spinLightChanged(double v) { void ObjectEditor::spinLightChanged(double v) {
if (!view || !active) return; if (!view || !active) return;
QList<Light*> sll = view->selectedLights(); QList<Light *> sll = view->selectedLights();
QObject * s = sender(); QObject * s = sender();
foreach (Light * o, sll) { foreach(Light * o, sll) {
if (s == ui->spinLightIntensity ) o->intensity = v; if (s == ui->spinLightIntensity) o->intensity = v;
if (s == ui->spinLightDecayConst ) o->decay_const = v; if (s == ui->spinLightDecayConst) o->decay_const = v;
if (s == ui->spinLightDecayLinear ) o->decay_linear = v; if (s == ui->spinLightDecayLinear) o->decay_linear = v;
if (s == ui->spinLightDecayQuadratic) o->decay_quadratic = v; if (s == ui->spinLightDecayQuadratic) o->decay_quadratic = v;
if (s == ui->spinLightAngleStart ) o->angle_start = v; if (s == ui->spinLightAngleStart) o->angle_start = v;
if (s == ui->spinLightAngleEnd ) o->angle_end = v; if (s == ui->spinLightAngleEnd) o->angle_end = v;
if (s == ui->spinAimDist ) o->setDistance(v); if (s == ui->spinAimDist) o->setDistance(v);
o->apply(); o->apply();
} }
ignore_next = true; ignore_next = true;
@@ -237,13 +230,13 @@ void ObjectEditor::spinLightChanged(double v) {
void ObjectEditor::spinCameraChanged(double v) { void ObjectEditor::spinCameraChanged(double v) {
if (!view || !active) return; if (!view || !active) return;
QList<Camera*> scl = view->selectedCameras(); QList<Camera *> scl = view->selectedCameras();
QObject * s = sender(); QObject * s = sender();
foreach (Camera * o, scl) { foreach(Camera * o, scl) {
if (s == ui->spinCameraFOV ) o->setFOV (v); if (s == ui->spinCameraFOV) o->setFOV(v);
if (s == ui->spinCameraRoll ) o->setAngleRoll (v); if (s == ui->spinCameraRoll) o->setAngleRoll(v);
if (s == ui->spinCameraDepthStart) o->setDepthStart(v); if (s == ui->spinCameraDepthStart) o->setDepthStart(v);
if (s == ui->spinAimDist ) o->setDistance (v); if (s == ui->spinAimDist) o->setDistance(v);
} }
ignore_next = true; ignore_next = true;
} }
@@ -251,18 +244,18 @@ void ObjectEditor::spinCameraChanged(double v) {
void ObjectEditor::checkChanged(bool v) { void ObjectEditor::checkChanged(bool v) {
if (!view || !active) return; if (!view || !active) return;
ObjectBaseList sol = view->selectedObjects(); ObjectBaseList sol = view->selectedObjects();
QList<Camera*> scl = view->selectedCameras(); QList<Camera *> scl = view->selectedCameras();
QObject * s = sender(); QObject * s = sender();
foreach (ObjectBase * o, sol) { foreach(ObjectBase * o, sol) {
if (s == ui->checkVisible ) o->setVisible (v); if (s == ui->checkVisible) o->setVisible(v);
if (s == ui->checkCastShadows ) o->setCastShadows (v); if (s == ui->checkCastShadows) o->setCastShadows(v);
if (s == ui->checkReceiveShadows) o->setReceiveShadows(v); if (s == ui->checkReceiveShadows) o->setReceiveShadows(v);
if (s == ui->checkAcceptLight ) o->setAcceptLight (v); if (s == ui->checkAcceptLight) o->setAcceptLight(v);
if (s == ui->checkAcceptFog ) o->setAcceptFog (v); if (s == ui->checkAcceptFog) o->setAcceptFog(v);
} }
foreach (Camera * o, scl) { foreach(Camera * o, scl) {
if (s == ui->checkCameraMirrorX ) o->setMirrorX(v); if (s == ui->checkCameraMirrorX) o->setMirrorX(v);
if (s == ui->checkCameraMirrorY ) o->setMirrorY(v); if (s == ui->checkCameraMirrorY) o->setMirrorY(v);
} }
} }

View File

@@ -1,34 +1,35 @@
/* /*
QGL ObjectEditor QGL ObjectEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef OBJECT_EDITOR_H #ifndef OBJECT_EDITOR_H
#define OBJECT_EDITOR_H #define OBJECT_EDITOR_H
#include <QWidget>
#include "globject.h" #include "globject.h"
#include <QWidget>
namespace Ui { namespace Ui {
class ObjectEditor; class ObjectEditor;
} }
class ObjectEditor: public QWidget class ObjectEditor: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit ObjectEditor(QWidget * parent = 0); explicit ObjectEditor(QWidget * parent = 0);
@@ -48,7 +49,7 @@ private slots:
void on_spinLightAngleEnd_valueChanged(double v); void on_spinLightAngleEnd_valueChanged(double v);
void on_comboLightType_currentIndexChanged(int index); void on_comboLightType_currentIndexChanged(int index);
void on_buttonColor_colorChanged(const QColor &v); void on_buttonColor_colorChanged(const QColor & v);
void spinChanged(double v); void spinChanged(double v);
void spinLightChanged(double v); void spinLightChanged(double v);
void spinCameraChanged(double v); void spinCameraChanged(double v);
@@ -56,7 +57,6 @@ private slots:
signals: signals:
void changed(); void changed();
}; };
#endif // OBJECT_EDITOR_H #endif // OBJECT_EDITOR_H

View File

@@ -1,34 +1,36 @@
/* /*
QGL PrimitiveEditor QGL PrimitiveEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "primitiveeditor.h" #include "primitiveeditor.h"
#include "glmesh.h"
#include "glprimitives.h"
#include "ui_primitiveeditor.h" #include "ui_primitiveeditor.h"
#include <QMetaEnum> #include <QMetaEnum>
#include <qad_types.h> #include <qad_types.h>
#include "glprimitives.h"
#include "glmesh.h"
PrimitiveEditor::PrimitiveEditor(QWidget *parent) : QWidget(parent), ui(new Ui::PrimitiveEditor) { PrimitiveEditor::PrimitiveEditor(QWidget * parent): QWidget(parent), ui(new Ui::PrimitiveEditor) {
view = 0; view = 0;
can_replace = false; can_replace = false;
ui->setupUi(this); ui->setupUi(this);
#if QT_VERSION >= QT_VERSION_CHECK(5,12,0) #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
ui->spinSegments->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType); ui->spinSegments->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType);
ui->spinSegments2->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType); ui->spinSegments2->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType);
#endif #endif
@@ -58,12 +60,12 @@ PrimitiveEditor::PrimitiveEditor(QWidget *parent) : QWidget(parent), ui(new Ui::
editors[Torus] << ui->widgetAngle; editors[Torus] << ui->widgetAngle;
QSet<QWidget *> all; QSet<QWidget *> all;
QMetaEnum me = metaObject()->enumerator(0); QMetaEnum me = metaObject()->enumerator(0);
for (int i=0; i<me.keyCount(); ++i) { for (int i = 0; i < me.keyCount(); ++i) {
ui->comboPrimitives->addItem(me.key(i)); ui->comboPrimitives->addItem(me.key(i));
all.unite(QList2QSet(editors[(PrimitiveType)me.value(i)])); all.unite(QList2QSet(editors[(PrimitiveType)me.value(i)]));
} }
all_editors = all.values(); all_editors = all.values();
foreach (QWidget * w, all_editors) { foreach(QWidget * w, all_editors) {
if (w->layout()) w->layout()->setContentsMargins(0, layout()->spacing(), 0, 0); if (w->layout()) w->layout()->setContentsMargins(0, layout()->spacing(), 0, 0);
} }
@@ -85,93 +87,65 @@ void PrimitiveEditor::assignQGLView(QGLView * v) {
Mesh * PrimitiveEditor::createMesh(QVariantList & params) { Mesh * PrimitiveEditor::createMesh(QVariantList & params) {
Mesh * m = 0; Mesh * m = 0;
PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex(); PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex();
params << pt; params << pt;
switch (pt) { switch (pt) {
case Plane: case Plane:
m = Primitive::plane(ui->spinWidth->value(), m = Primitive::plane(ui->spinWidth->value(), ui->spinLength->value());
ui->spinLength->value()); params << ui->spinWidth->value() << ui->spinLength->value();
params << ui->spinWidth->value() break;
<< ui->spinLength->value(); case Cube:
break; m = Primitive::cube(ui->spinWidth->value(), ui->spinLength->value(), ui->spinHeight->value());
case Cube: params << ui->spinWidth->value() << ui->spinLength->value() << ui->spinHeight->value();
m = Primitive::cube(ui->spinWidth->value(), break;
ui->spinLength->value(), case Ellipsoid:
ui->spinHeight->value()); m = Primitive::ellipsoid(ui->spinSegments->value(), ui->spinSegments2->value(), ui->spinRadius->value(), ui->spinAngle->value());
params << ui->spinWidth->value() params << ui->spinSegments->value() << ui->spinSegments2->value() << ui->spinRadius->value() << ui->spinAngle->value();
<< ui->spinLength->value() break;
<< ui->spinHeight->value(); case Disc:
break; m = Primitive::disc(ui->spinSegments->value(), ui->spinRadius->value(), ui->spinAngle->value());
case Ellipsoid: params << ui->spinSegments->value() << ui->spinRadius->value() << ui->spinAngle->value();
m = Primitive::ellipsoid(ui->spinSegments->value(), break;
ui->spinSegments2->value(), case Cone:
ui->spinRadius->value(), m = Primitive::cone(ui->spinSegments->value(), ui->spinRadius->value(), ui->spinHeight->value());
ui->spinAngle->value()); params << ui->spinSegments->value() << ui->spinRadius->value() << ui->spinHeight->value();
params << ui->spinSegments->value() break;
<< ui->spinSegments2->value() case Cylinder:
<< ui->spinRadius->value() m = Primitive::cylinder(ui->spinSegments->value(), ui->spinRadius->value(), ui->spinHeight->value(), ui->spinAngle->value());
<< ui->spinAngle->value(); params << ui->spinSegments->value() << ui->spinRadius->value() << ui->spinHeight->value() << ui->spinAngle->value();
break; break;
case Disc: case Torus:
m = Primitive::disc(ui->spinSegments->value(), m = Primitive::torus(ui->spinSegments->value(),
ui->spinRadius->value(), ui->spinSegments2->value(),
ui->spinAngle->value()); ui->spinRadius->value(),
params << ui->spinSegments->value() ui->spinRadius2->value(),
<< ui->spinRadius->value() ui->spinAngle->value());
<< ui->spinAngle->value(); params << ui->spinSegments->value() << ui->spinSegments2->value() << ui->spinRadius->value() << ui->spinRadius2->value()
break; << ui->spinAngle->value();
case Cone: break;
m = Primitive::cone(ui->spinSegments->value(), default: return 0;
ui->spinRadius->value(),
ui->spinHeight->value());
params << ui->spinSegments->value()
<< ui->spinRadius->value()
<< ui->spinHeight->value();
break;
case Cylinder:
m = Primitive::cylinder(ui->spinSegments->value(),
ui->spinRadius->value(),
ui->spinHeight->value(),
ui->spinAngle->value());
params << ui->spinSegments->value()
<< ui->spinRadius->value()
<< ui->spinHeight->value()
<< ui->spinAngle->value();
break;
case Torus:
m = Primitive::torus(ui->spinSegments->value(),
ui->spinSegments2->value(),
ui->spinRadius->value(),
ui->spinRadius2->value(),
ui->spinAngle->value());
params << ui->spinSegments->value()
<< ui->spinSegments2->value()
<< ui->spinRadius->value()
<< ui->spinRadius2->value()
<< ui->spinAngle->value();
break;
default: return 0;
} }
params << ui->flipNormals->isChecked(); params << ui->flipNormals->isChecked();
params << ui->colorButton->color(); params << ui->colorButton->color();
if (ui->flipNormals->isChecked()) if (ui->flipNormals->isChecked()) m->flipNormals();
m->flipNormals();
return m; return m;
} }
void PrimitiveEditor::showEditors() { void PrimitiveEditor::showEditors() {
foreach (QWidget * w, all_editors) w->hide(); foreach(QWidget * w, all_editors)
PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex(); w->hide();
PrimitiveType pt = (PrimitiveType)ui->comboPrimitives->currentIndex();
QList<QWidget *> wds = editors[pt]; QList<QWidget *> wds = editors[pt];
foreach (QWidget * w, wds) w->show(); foreach(QWidget * w, wds)
w->show();
} }
void PrimitiveEditor::selectionChanged() { void PrimitiveEditor::selectionChanged() {
ObjectBase * so = view->selectedObject();\ ObjectBase * so = view->selectedObject();
can_replace = false; can_replace = false;
if (so) { if (so) {
QVariantList vl = so->property("primitive", &can_replace).toList(); QVariantList vl = so->property("primitive", &can_replace).toList();
if (can_replace && !vl.isEmpty()) { if (can_replace && !vl.isEmpty()) {
@@ -181,41 +155,41 @@ void PrimitiveEditor::selectionChanged() {
case Plane: case Plane:
ui->spinWidth->setValue(vl.takeFirst().toDouble()); ui->spinWidth->setValue(vl.takeFirst().toDouble());
ui->spinLength->setValue(vl.takeFirst().toDouble()); ui->spinLength->setValue(vl.takeFirst().toDouble());
break; break;
case Cube: case Cube:
ui->spinWidth->setValue(vl.takeFirst().toDouble()); ui->spinWidth->setValue(vl.takeFirst().toDouble());
ui->spinLength->setValue(vl.takeFirst().toDouble()); ui->spinLength->setValue(vl.takeFirst().toDouble());
ui->spinHeight->setValue(vl.takeFirst().toDouble()); ui->spinHeight->setValue(vl.takeFirst().toDouble());
break; break;
case Ellipsoid: case Ellipsoid:
ui->spinSegments->setValue(vl.takeFirst().toDouble()); ui->spinSegments->setValue(vl.takeFirst().toDouble());
ui->spinSegments2->setValue(vl.takeFirst().toDouble()); ui->spinSegments2->setValue(vl.takeFirst().toDouble());
ui->spinRadius->setValue(vl.takeFirst().toDouble()); ui->spinRadius->setValue(vl.takeFirst().toDouble());
ui->spinAngle->setValue(vl.takeFirst().toDouble()); ui->spinAngle->setValue(vl.takeFirst().toDouble());
break; break;
case Disc: case Disc:
ui->spinSegments->setValue(vl.takeFirst().toDouble()); ui->spinSegments->setValue(vl.takeFirst().toDouble());
ui->spinRadius->setValue(vl.takeFirst().toDouble()); ui->spinRadius->setValue(vl.takeFirst().toDouble());
ui->spinAngle->setValue(vl.takeFirst().toDouble()); ui->spinAngle->setValue(vl.takeFirst().toDouble());
break; break;
case Cone: case Cone:
ui->spinSegments->setValue(vl.takeFirst().toDouble()); ui->spinSegments->setValue(vl.takeFirst().toDouble());
ui->spinRadius->setValue(vl.takeFirst().toDouble()); ui->spinRadius->setValue(vl.takeFirst().toDouble());
ui->spinHeight->setValue(vl.takeFirst().toDouble()); ui->spinHeight->setValue(vl.takeFirst().toDouble());
break; break;
case Cylinder: case Cylinder:
ui->spinSegments->setValue(vl.takeFirst().toDouble()); ui->spinSegments->setValue(vl.takeFirst().toDouble());
ui->spinRadius->setValue(vl.takeFirst().toDouble()); ui->spinRadius->setValue(vl.takeFirst().toDouble());
ui->spinHeight->setValue(vl.takeFirst().toDouble()); ui->spinHeight->setValue(vl.takeFirst().toDouble());
ui->spinAngle->setValue(vl.takeFirst().toDouble()); ui->spinAngle->setValue(vl.takeFirst().toDouble());
break; break;
case Torus: case Torus:
ui->spinSegments->setValue(vl.takeFirst().toDouble()); ui->spinSegments->setValue(vl.takeFirst().toDouble());
ui->spinSegments2->setValue(vl.takeFirst().toDouble()); ui->spinSegments2->setValue(vl.takeFirst().toDouble());
ui->spinRadius->setValue(vl.takeFirst().toDouble()); ui->spinRadius->setValue(vl.takeFirst().toDouble());
ui->spinRadius2->setValue(vl.takeFirst().toDouble()); ui->spinRadius2->setValue(vl.takeFirst().toDouble());
ui->spinAngle->setValue(vl.takeFirst().toDouble()); ui->spinAngle->setValue(vl.takeFirst().toDouble());
break; break;
} }
ui->flipNormals->setChecked(vl.takeFirst().toBool()); ui->flipNormals->setChecked(vl.takeFirst().toBool());
ui->colorButton->setColor(vl.takeFirst().value<QColor>()); ui->colorButton->setColor(vl.takeFirst().value<QColor>());

View File

@@ -1,35 +1,37 @@
/* /*
QGL PrimitiveEditor QGL PrimitiveEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PRIMITIVEEDITOR_H #ifndef PRIMITIVEEDITOR_H
#define PRIMITIVEEDITOR_H #define PRIMITIVEEDITOR_H
#include <QWidget>
#include "qglview.h" #include "qglview.h"
#include <QWidget>
namespace Ui { namespace Ui {
class PrimitiveEditor; class PrimitiveEditor;
} }
class PrimitiveEditor : public QWidget { class PrimitiveEditor: public QWidget {
Q_OBJECT Q_OBJECT
public: public:
enum PrimitiveType { enum PrimitiveType {
Plane, Plane,
@@ -42,7 +44,7 @@ public:
}; };
Q_ENUMS(PrimitiveType) Q_ENUMS(PrimitiveType)
explicit PrimitiveEditor(QWidget *parent = nullptr); explicit PrimitiveEditor(QWidget * parent = nullptr);
~PrimitiveEditor(); ~PrimitiveEditor();
void assignQGLView(QGLView * v); void assignQGLView(QGLView * v);
@@ -51,9 +53,9 @@ protected:
Mesh * createMesh(QVariantList & params); Mesh * createMesh(QVariantList & params);
void showEditors(); void showEditors();
Ui::PrimitiveEditor *ui; Ui::PrimitiveEditor * ui;
QGLView * view; QGLView * view;
QMap<PrimitiveType, QList<QWidget *> > editors; QMap<PrimitiveType, QList<QWidget *>> editors;
QList<QWidget *> all_editors; QList<QWidget *> all_editors;
bool can_replace; bool can_replace;

View File

@@ -1,57 +1,63 @@
/* /*
QGL PropertyEditor QGL PropertyEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "propertyeditor.h" #include "propertyeditor.h"
#include "clineedit.h"
#include "colorbutton.h"
#include "qpointedit.h" #include "qpointedit.h"
#include "qrectedit.h" #include "qrectedit.h"
#include "colorbutton.h"
#include "clineedit.h"
#include <QPainter>
#include <QCheckBox>
#include <QApplication> #include <QApplication>
#include <QCheckBox>
#include <QPainter>
QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & index) const { QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & index) const {
QWidget * w = nullptr; QWidget * w = nullptr;
int type = 0; int type = 0;
QVariant value = index.data(Qt::UserRole); QVariant value = index.data(Qt::UserRole);
if (index.data(Qt::UserRole + 2).toString() == "__flags") return nullptr; if (index.data(Qt::UserRole + 2).toString() == "__flags") return nullptr;
if (index.data(Qt::UserRole + 1).toString() == "__flag") { if (index.data(Qt::UserRole + 1).toString() == "__flag") {
qulonglong key = index.data(Qt::UserRole).toULongLong(); qulonglong key = index.data(Qt::UserRole).toULongLong();
value = index.parent().data(Qt::UserRole); value = index.parent().data(Qt::UserRole);
//QMetaProperty prop = index.parent().data(Qt::UserRole + 1).value<QMetaProperty>(); // QMetaProperty prop = index.parent().data(Qt::UserRole + 1).value<QMetaProperty>();
w = new QCheckBox(parent); type = 14; ((QCheckBox*)w)->setChecked(((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0)); w = new QCheckBox(parent);
((QCheckBox*)w)->setText("0x" + QString::number(key, 16).toUpper()); type = 14;
connect((QCheckBox*)w, SIGNAL(clicked(bool)), this, SLOT(changedFlag())); ((QCheckBox *)w)->setChecked(((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0));
//qDebug() << prop.enumerator().name(); ((QCheckBox *)w)->setText("0x" + QString::number(key, 16).toUpper());
connect((QCheckBox *)w, SIGNAL(clicked(bool)), this, SLOT(changedFlag()));
// qDebug() << prop.enumerator().name();
} else { } else {
if (value.canConvert<PropertyValuePair>()) { if (value.canConvert<PropertyValuePair>()) {
PropertyValuePair prop = value.value<PropertyValuePair>(); PropertyValuePair prop = value.value<PropertyValuePair>();
if (prop.first.isEnumType()) { if (prop.first.isEnumType()) {
w = new QComboBox(parent); type = 13; ((QComboBox*)w)->setCurrentIndex(value.toInt()); w = new QComboBox(parent);
type = 13;
((QComboBox *)w)->setCurrentIndex(value.toInt());
w->setProperty("__prop", QVariant::fromValue<QMetaProperty>(prop.first)); w->setProperty("__prop", QVariant::fromValue<QMetaProperty>(prop.first));
QMetaEnum menum = prop.first.enumerator(); QMetaEnum menum = prop.first.enumerator();
for (int i = 0; i < menum.keyCount(); ++i) { for (int i = 0; i < menum.keyCount(); ++i) {
((QComboBox*)w)->addItem(QString(menum.key(i)) + " (0x" + QString::number(menum.value(i), 16).toUpper() + ")", menum.value(i)); ((QComboBox *)w)
if (menum.value(i) == prop.second.toInt()) ->addItem(QString(menum.key(i)) + " (0x" + QString::number(menum.value(i), 16).toUpper() + ")", menum.value(i));
((QComboBox*)w)->setCurrentIndex(i); if (menum.value(i) == prop.second.toInt()) ((QComboBox *)w)->setCurrentIndex(i);
} }
connect((QComboBox*)w, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); connect((QComboBox *)w, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
} }
} else { } else {
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
@@ -64,73 +70,129 @@ QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & inde
#else #else
case QMetaType::Int: case QMetaType::Int:
#endif #endif
w = new QSpinBox(parent); type = 2; ((QSpinBox*)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break; w = new QSpinBox(parent);
type = 2;
((QSpinBox *)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF);
connect((QSpinBox *)w, SIGNAL(valueChanged(int)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::UInt: case QVariant::UInt:
#else #else
case QMetaType::UInt: case QMetaType::UInt:
#endif #endif
w = new QSpinBox(parent); type = 3; ((QSpinBox*)w)->setRange(0, 0xFFFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break; w = new QSpinBox(parent);
type = 3;
((QSpinBox *)w)->setRange(0, 0xFFFFFFFF);
connect((QSpinBox *)w, SIGNAL(valueChanged(int)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::LongLong: case QVariant::LongLong:
#else #else
case QMetaType::LongLong: case QMetaType::LongLong:
#endif #endif
w = new QSpinBox(parent); type = 4; ((QSpinBox*)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break; w = new QSpinBox(parent);
type = 4;
((QSpinBox *)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF);
connect((QSpinBox *)w, SIGNAL(valueChanged(int)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::ULongLong: case QVariant::ULongLong:
#else #else
case QMetaType::ULongLong: case QMetaType::ULongLong:
#endif #endif
w = new QSpinBox(parent); type = 5; ((QSpinBox*)w)->setRange(0, 0xFFFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break; w = new QSpinBox(parent);
type = 5;
((QSpinBox *)w)->setRange(0, 0xFFFFFFFF);
connect((QSpinBox *)w, SIGNAL(valueChanged(int)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::Double: case QVariant::Double:
#else #else
case QMetaType::Double: case QMetaType::Double:
#endif #endif
w = new QDoubleSpinBox(parent); type = 6; ((QDoubleSpinBox*)w)->setRange(-999999999, 999999999); ((QDoubleSpinBox*)w)->setDecimals(3); connect((QDoubleSpinBox*)w, SIGNAL(valueChanged(double)), this, SLOT(changed())); break; w = new QDoubleSpinBox(parent);
type = 6;
((QDoubleSpinBox *)w)->setRange(-999999999, 999999999);
((QDoubleSpinBox *)w)->setDecimals(3);
connect((QDoubleSpinBox *)w, SIGNAL(valueChanged(double)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::Bool: case QVariant::Bool:
#else #else
case QMetaType::Bool: case QMetaType::Bool:
#endif #endif
w = new QCheckBox(parent); type = 7; ((QCheckBox*)w)->setChecked(value.toBool()); connect((QCheckBox*)w, SIGNAL(toggled(bool)), this, SLOT(changed())); break; w = new QCheckBox(parent);
type = 7;
((QCheckBox *)w)->setChecked(value.toBool());
connect((QCheckBox *)w, SIGNAL(toggled(bool)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::Color: case QVariant::Color:
#else #else
case QMetaType::QColor: case QMetaType::QColor:
#endif #endif
w = new ColorButton(parent); type = 8; ((ColorButton*)w)->setUseAlphaChannel(true); ((ColorButton*)w)->setColor(value.value<QColor>()); connect((ColorButton*)w, SIGNAL(colorChanged(QColor)), this, SLOT(changed())); break; w = new ColorButton(parent);
type = 8;
((ColorButton *)w)->setUseAlphaChannel(true);
((ColorButton *)w)->setColor(value.value<QColor>());
connect((ColorButton *)w, SIGNAL(colorChanged(QColor)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::Point: case QVariant::Point:
#else #else
case QMetaType::QPoint: case QMetaType::QPoint:
#endif #endif
w = new QPointEdit(parent); type = 9; ((QPointEdit*)w)->setDecimals(0); ((QPointEdit*)w)->setValue(QPointF(value.toPoint())); connect((QPointEdit*)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed())); break; w = new QPointEdit(parent);
type = 9;
((QPointEdit *)w)->setDecimals(0);
((QPointEdit *)w)->setValue(QPointF(value.toPoint()));
connect((QPointEdit *)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::PointF: case QVariant::PointF:
#else #else
case QMetaType::QPointF: case QMetaType::QPointF:
#endif #endif
w = new QPointEdit(parent); type = 10; ((QPointEdit*)w)->setDecimals(3); ((QPointEdit*)w)->setValue(value.toPointF()); connect((QPointEdit*)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed())); break; w = new QPointEdit(parent);
type = 10;
((QPointEdit *)w)->setDecimals(3);
((QPointEdit *)w)->setValue(value.toPointF());
connect((QPointEdit *)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::Rect: case QVariant::Rect:
#else #else
case QMetaType::QRect: case QMetaType::QRect:
#endif #endif
w = new QRectEdit(parent); type = 11; ((QRectEdit*)w)->setDecimals(0); ((QRectEdit*)w)->setValue(QRectF(value.toRect())); connect((QRectEdit*)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed())); break; w = new QRectEdit(parent);
type = 11;
((QRectEdit *)w)->setDecimals(0);
((QRectEdit *)w)->setValue(QRectF(value.toRect()));
connect((QRectEdit *)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::RectF: case QVariant::RectF:
#else #else
case QMetaType::QRectF: case QMetaType::QRectF:
#endif #endif
w = new QRectEdit(parent); type = 12; ((QRectEdit*)w)->setDecimals(3); ((QRectEdit*)w)->setValue(value.toRectF()); connect((QRectEdit*)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed())); break; w = new QRectEdit(parent);
type = 12;
((QRectEdit *)w)->setDecimals(3);
((QRectEdit *)w)->setValue(value.toRectF());
connect((QRectEdit *)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed()));
break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::String: default: case QVariant::String:
default:
#else #else
case QMetaType::QString: default: case QMetaType::QString:
default:
#endif #endif
w = new CLineEdit(parent); type = 1; ((CLineEdit*)w)->setDefaultText(value.toString()); connect((CLineEdit*)w, SIGNAL(textChanged(QString)), this, SLOT(changed())); break; w = new CLineEdit(parent);
type = 1;
((CLineEdit *)w)->setDefaultText(value.toString());
connect((CLineEdit *)w, SIGNAL(textChanged(QString)), this, SLOT(changed()));
break;
} }
} }
} }
@@ -147,15 +209,18 @@ QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & inde
void Delegate::setWidgetProperty(QWidget * w, const QVariant & value) const { void Delegate::setWidgetProperty(QWidget * w, const QVariant & value) const {
if (w == 0) return; if (w == 0) return;
switch (w->property("__type").toInt()) { switch (w->property("__type").toInt()) {
case 1: ((CLineEdit*)w)->setText(value.toString()); break; case 1: ((CLineEdit *)w)->setText(value.toString()); break;
case 2: case 3: case 4: case 5: ((QSpinBox*)w)->setValue(value.toInt()); break; case 2:
case 6: ((QDoubleSpinBox*)w)->setValue(value.toDouble()); break; case 3:
case 7: ((QCheckBox*)w)->setChecked(value.toBool()); break; case 4:
case 8: ((ColorButton*)w)->setColor(value.value<QColor>()); break; case 5: ((QSpinBox *)w)->setValue(value.toInt()); break;
case 9: ((QPointEdit*)w)->setValue(value.value<QPoint>()); break; case 6: ((QDoubleSpinBox *)w)->setValue(value.toDouble()); break;
case 10: ((QPointEdit*)w)->setValue(value.value<QPointF>()); break; case 7: ((QCheckBox *)w)->setChecked(value.toBool()); break;
case 11: ((QRectEdit*)w)->setValue(value.value<QRect>()); break; case 8: ((ColorButton *)w)->setColor(value.value<QColor>()); break;
case 12: ((QRectEdit*)w)->setValue(value.value<QRectF>()); break; case 9: ((QPointEdit *)w)->setValue(value.value<QPoint>()); break;
case 10: ((QPointEdit *)w)->setValue(value.value<QPointF>()); break;
case 11: ((QRectEdit *)w)->setValue(value.value<QRect>()); break;
case 12: ((QRectEdit *)w)->setValue(value.value<QRectF>()); break;
} }
} }
@@ -163,19 +228,22 @@ void Delegate::setWidgetProperty(QWidget * w, const QVariant & value) const {
const QVariant Delegate::widgetProperty(QWidget * w) const { const QVariant Delegate::widgetProperty(QWidget * w) const {
if (w == 0) return QVariant(); if (w == 0) return QVariant();
switch (w->property("__type").toInt()) { switch (w->property("__type").toInt()) {
case 1: return QVariant::fromValue<QString>(((CLineEdit*)w)->text()); break; case 1: return QVariant::fromValue<QString>(((CLineEdit *)w)->text()); break;
case 2: return QVariant::fromValue<int>(((QSpinBox*)w)->value()); break; case 2: return QVariant::fromValue<int>(((QSpinBox *)w)->value()); break;
case 3: return QVariant::fromValue<uint>(((QSpinBox*)w)->value()); break; case 3: return QVariant::fromValue<uint>(((QSpinBox *)w)->value()); break;
case 4: return QVariant::fromValue<qlonglong>(((QSpinBox*)w)->value()); break; case 4: return QVariant::fromValue<qlonglong>(((QSpinBox *)w)->value()); break;
case 5: return QVariant::fromValue<qulonglong>(((QSpinBox*)w)->value()); break; case 5: return QVariant::fromValue<qulonglong>(((QSpinBox *)w)->value()); break;
case 6: return QVariant::fromValue<double>(((QDoubleSpinBox*)w)->value()); break; case 6: return QVariant::fromValue<double>(((QDoubleSpinBox *)w)->value()); break;
case 7: return QVariant::fromValue<bool>(((QCheckBox*)w)->isChecked()); break; case 7: return QVariant::fromValue<bool>(((QCheckBox *)w)->isChecked()); break;
case 8: return QVariant::fromValue<QColor>(((ColorButton*)w)->color()); break; case 8: return QVariant::fromValue<QColor>(((ColorButton *)w)->color()); break;
case 9: return QVariant::fromValue<QPoint>(((QPointEdit*)w)->value().toPoint()); break; case 9: return QVariant::fromValue<QPoint>(((QPointEdit *)w)->value().toPoint()); break;
case 10: return QVariant::fromValue<QPointF>(((QPointEdit*)w)->value()); break; case 10: return QVariant::fromValue<QPointF>(((QPointEdit *)w)->value()); break;
case 11: return QVariant::fromValue<QRect>(((QRectEdit*)w)->value().toRect()); break; case 11: return QVariant::fromValue<QRect>(((QRectEdit *)w)->value().toRect()); break;
case 12: return QVariant::fromValue<QRectF>(((QRectEdit*)w)->value()); break; case 12: return QVariant::fromValue<QRectF>(((QRectEdit *)w)->value()); break;
case 13: return QVariant::fromValue<PropertyValuePair>(PropertyValuePair(w->property("__prop").value<QMetaProperty>(), ((QComboBox*)w)->itemData(((QComboBox*)w)->currentIndex()))); break; case 13:
return QVariant::fromValue<PropertyValuePair>(
PropertyValuePair(w->property("__prop").value<QMetaProperty>(), ((QComboBox *)w)->itemData(((QComboBox *)w)->currentIndex())));
break;
default: return QVariant(); break; default: return QVariant(); break;
} }
return QVariant(); return QVariant();
@@ -183,35 +251,44 @@ const QVariant Delegate::widgetProperty(QWidget * w) const {
void Delegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const { void Delegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
if (index.data(Qt::UserRole + 1).toString() != "__flag") if (index.data(Qt::UserRole + 1).toString() != "__flag") model->setData(index, widgetProperty(editor), Qt::UserRole);
model->setData(index, widgetProperty(editor), Qt::UserRole);
} }
void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
QStyledItemDelegate::paint(painter, option, index); QStyledItemDelegate::paint(painter, option, index);
QVariant value = index.data(Qt::UserRole); QVariant value = index.data(Qt::UserRole);
QStyle * style = QApplication::style(); QStyle * style = QApplication::style();
QStyleOption * so = 0; QStyleOption * so = 0;
QStyleOptionComplex * soc = 0; QStyleOptionComplex * soc = 0;
QString text; QString text;
QRect rect; QRect rect;
QPalette::ColorRole role = (option.state.testFlag(QStyle::State_Selected) && option.state.testFlag(QStyle::State_Active) ? QPalette::HighlightedText : QPalette::WindowText); QPalette::ColorRole role =
(option.state.testFlag(QStyle::State_Selected) && option.state.testFlag(QStyle::State_Active) ? QPalette::HighlightedText
: QPalette::WindowText);
if (index.data(Qt::UserRole + 2).toString() == "__flags") { if (index.data(Qt::UserRole + 2).toString() == "__flags") {
text = "0x" + QString::number(value.toInt(), 16).toUpper(); text = "0x" + QString::number(value.toInt(), 16).toUpper();
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
return; return;
} }
if (index.data(Qt::UserRole + 1) == "__flag") { if (index.data(Qt::UserRole + 1) == "__flag") {
qulonglong key = index.data(Qt::UserRole).toULongLong(); qulonglong key = index.data(Qt::UserRole).toULongLong();
value = index.parent().data(Qt::UserRole); value = index.parent().data(Qt::UserRole);
so = new QStyleOptionButton(); so = new QStyleOptionButton();
so->rect = option.rect; so->rect = option.rect;
so->palette = option.palette; so->palette = option.palette;
so->fontMetrics = option.fontMetrics; so->fontMetrics = option.fontMetrics;
((QStyleOptionButton*)so)->state = (((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0) ? QStyle::State_On : QStyle::State_Off) | option.state; ((QStyleOptionButton *)so)->state =
((QStyleOptionButton*)so)->text = "0x" + QString::number(key, 16).toUpper(); (((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0) ? QStyle::State_On
: QStyle::State_Off) |
option.state;
((QStyleOptionButton *)so)->text = "0x" + QString::number(key, 16).toUpper();
if (option.state.testFlag(QStyle::State_Selected)) if (option.state.testFlag(QStyle::State_Selected))
so->palette.setColor(QPalette::WindowText, so->palette.color(QPalette::HighlightedText)); so->palette.setColor(QPalette::WindowText, so->palette.color(QPalette::HighlightedText));
style->drawControl(QStyle::CE_CheckBox, so, painter); style->drawControl(QStyle::CE_CheckBox, so, painter);
@@ -226,8 +303,13 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
break; break;
} }
} }
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
} }
} else { } else {
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
@@ -241,8 +323,13 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::Int: case QMetaType::Int:
#endif #endif
text.setNum(value.toInt()); text.setNum(value.toInt());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::UInt: case QVariant::UInt:
@@ -250,8 +337,13 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::UInt: case QMetaType::UInt:
#endif #endif
text.setNum(value.toUInt()); text.setNum(value.toUInt());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::LongLong: case QVariant::LongLong:
@@ -259,8 +351,13 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::LongLong: case QMetaType::LongLong:
#endif #endif
text.setNum(value.toLongLong()); text.setNum(value.toLongLong());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::ULongLong: case QVariant::ULongLong:
@@ -268,8 +365,13 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::ULongLong: case QMetaType::ULongLong:
#endif #endif
text.setNum(value.toULongLong()); text.setNum(value.toULongLong());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::Double: case QVariant::Double:
@@ -277,20 +379,25 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::Double: case QMetaType::Double:
#endif #endif
text.setNum(value.toDouble(), 'f', 3); text.setNum(value.toDouble(), 'f', 3);
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::Bool: case QVariant::Bool:
#else #else
case QMetaType::Bool: case QMetaType::Bool:
#endif #endif
so = new QStyleOptionButton(); so = new QStyleOptionButton();
so->rect = option.rect; so->rect = option.rect;
so->state = option.state; so->state = option.state;
so->palette = option.palette; so->palette = option.palette;
so->fontMetrics = option.fontMetrics; so->fontMetrics = option.fontMetrics;
((QStyleOptionButton*)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off) | option.state; ((QStyleOptionButton *)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off) | option.state;
style->drawControl(QStyle::CE_CheckBox, so, painter); style->drawControl(QStyle::CE_CheckBox, so, painter);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
@@ -298,7 +405,7 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
#else #else
case QMetaType::QColor: case QMetaType::QColor:
#endif #endif
rect = option.rect;//style->subElementRect(QStyle::QStyle::SE_FrameContents, so); rect = option.rect; // style->subElementRect(QStyle::QStyle::SE_FrameContents, so);
rect.setRect(rect.x() + 3, rect.y() + 3, rect.width() - 6, rect.height() - 6); rect.setRect(rect.x() + 3, rect.y() + 3, rect.width() - 6, rect.height() - 6);
painter->fillRect(rect, ab); painter->fillRect(rect, ab);
painter->fillRect(rect, value.value<QColor>()); painter->fillRect(rect, value.value<QColor>());
@@ -309,8 +416,13 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::QPoint: case QMetaType::QPoint:
#endif #endif
text = pointString(value.toPoint()); text = pointString(value.toPoint());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::PointF: case QVariant::PointF:
@@ -318,8 +430,13 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::QPointF: case QMetaType::QPointF:
#endif #endif
text = pointString(value.toPointF()); text = pointString(value.toPointF());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::Rect: case QVariant::Rect:
@@ -327,8 +444,13 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::QRect: case QMetaType::QRect:
#endif #endif
text = rectString(value.toRect()); text = rectString(value.toRect());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::RectF: case QVariant::RectF:
@@ -336,40 +458,52 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
case QMetaType::QRectF: case QMetaType::QRectF:
#endif #endif
text = rectString(value.toRectF()); text = rectString(value.toRectF());
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text), style->drawItemText(painter,
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role); style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
text,
role);
break; break;
#if QT_VERSION_MAJOR <= 5 #if QT_VERSION_MAJOR <= 5
case QVariant::String: default: case QVariant::String:
default:
#else #else
case QMetaType::QString: default: case QMetaType::QString:
default:
#endif #endif
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, value.toString()), style->drawItemText(
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, value.toString(), role); painter,
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, value.toString()),
Qt::AlignLeft | Qt::AlignVCenter,
option.palette,
true,
value.toString(),
role);
break; break;
} }
} }
} }
/*so = new QStyleOptionFrame(); /*so = new QStyleOptionFrame();
so->rect = option.rect; so->rect = option.rect;
so->state = option.state; so->state = option.state;
so->palette = option.palette; so->palette = option.palette;
so->fontMetrics = option.fontMetrics; so->fontMetrics = option.fontMetrics;
((QStyleOptionFrame*)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off); ((QStyleOptionFrame*)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off);
style->drawPrimitive(QStyle::PE_PanelLineEdit, so, painter); style->drawPrimitive(QStyle::PE_PanelLineEdit, so, painter);
style->drawPrimitive(QStyle::PE_FrameLineEdit, so, painter); style->drawPrimitive(QStyle::PE_FrameLineEdit, so, painter);
break;*/ break;*/
if (so != 0) delete so; if (so != 0) delete so;
if (soc != 0) delete soc; if (soc != 0) delete soc;
} }
void Delegate::changedFlag() { void Delegate::changedFlag() {
QAbstractItemModel * model = const_cast<QAbstractItemModel * >(cmi.model()); QAbstractItemModel * model = const_cast<QAbstractItemModel *>(cmi.model());
model->setData(cmi, qobject_cast<QCheckBox * >(sender())->isChecked(), Qt::UserRole + 3); model->setData(cmi, qobject_cast<QCheckBox *>(sender())->isChecked(), Qt::UserRole + 3);
QModelIndex p = cmi.parent(), mi; QModelIndex p = cmi.parent(), mi;
int row = 0; int row = 0;
qulonglong val = 0; qulonglong val = 0;
QList<QModelIndex> chldr; QList<QModelIndex> chldr;
mi = model->index(row, 1, p); mi = model->index(row, 1, p);
@@ -378,26 +512,24 @@ void Delegate::changedFlag() {
model->setData(mi, !mi.data(Qt::UserRole + 4).toBool(), Qt::UserRole + 4); model->setData(mi, !mi.data(Qt::UserRole + 4).toBool(), Qt::UserRole + 4);
mi = model->index(++row, 1, p); mi = model->index(++row, 1, p);
} }
bool cc = cmi.data(Qt::UserRole + 3).toBool(); bool cc = cmi.data(Qt::UserRole + 3).toBool();
qulonglong cv = cmi.data(Qt::UserRole).toULongLong(); qulonglong cv = cmi.data(Qt::UserRole).toULongLong();
//qDebug() << "*****"; // qDebug() << "*****";
if (cc && cv == 0) { if (cc && cv == 0) {
val = 0; val = 0;
//qDebug() << "null" << cv; // qDebug() << "null" << cv;
} else { } else {
if (!cc && cv != 0) { if (!cc && cv != 0) {
//qDebug() << "uncheck" << cv; // qDebug() << "uncheck" << cv;
for (int i = 0; i < chldr.size(); ++i) { for (int i = 0; i < chldr.size(); ++i) {
if (chldr[i] == cmi) continue; if (chldr[i] == cmi) continue;
//qDebug() << (chldr[i].data(Qt::UserRole).toULongLong() & cv); // qDebug() << (chldr[i].data(Qt::UserRole).toULongLong() & cv);
if (chldr[i].data(Qt::UserRole).toULongLong() & cv) if (chldr[i].data(Qt::UserRole).toULongLong() & cv) model->setData(chldr[i], false, Qt::UserRole + 3);
model->setData(chldr[i], false, Qt::UserRole + 3);
} }
} }
for (int i = 0; i < chldr.size(); ++i) { for (int i = 0; i < chldr.size(); ++i) {
//qDebug() << chldr[i].data(Qt::UserRole + 3).toBool(); // qDebug() << chldr[i].data(Qt::UserRole + 3).toBool();
if (chldr[i].data(Qt::UserRole + 3).toBool()) if (chldr[i].data(Qt::UserRole + 3).toBool()) val |= chldr[i].data(Qt::UserRole).toULongLong();
val |= chldr[i].data(Qt::UserRole).toULongLong();
} }
} }
for (int i = 0; i < chldr.size(); ++i) { for (int i = 0; i < chldr.size(); ++i) {
@@ -405,25 +537,22 @@ void Delegate::changedFlag() {
cv = chldr[i].data(Qt::UserRole).toULongLong(); cv = chldr[i].data(Qt::UserRole).toULongLong();
model->setData(chldr[i], ((val & cv) == cv && cv != 0) || (val == 0 && cv == 0), Qt::UserRole + 3); model->setData(chldr[i], ((val & cv) == cv && cv != 0) || (val == 0 && cv == 0), Qt::UserRole + 3);
} }
//qDebug() << val; // qDebug() << val;
model->setData(p, val, Qt::UserRole); model->setData(p, val, Qt::UserRole);
model->setData(p.sibling(p.row(), 1), val, Qt::UserRole); model->setData(p.sibling(p.row(), 1), val, Qt::UserRole);
} }
PropertyEditor::PropertyEditor(QWidget * parent): QTreeWidget(parent) { PropertyEditor::PropertyEditor(QWidget * parent): QTreeWidget(parent) {
object = 0; object = 0;
active_ = false; active_ = false;
configTree(); configTree();
connect(this, SIGNAL(itemClicked(QTreeWidgetItem * , int)), this, SLOT(itemClicked(QTreeWidgetItem * , int))); connect(this, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *, int)));
connect(this, SIGNAL(itemChanged(QTreeWidgetItem * , int)), this, SLOT(itemChanged(QTreeWidgetItem * , int))); connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(itemChanged(QTreeWidgetItem *, int)));
} }
PropertyEditor::~PropertyEditor() { PropertyEditor::~PropertyEditor() {}
}
void PropertyEditor::changeEvent(QEvent * e) { void PropertyEditor::changeEvent(QEvent * e) {
@@ -446,7 +575,6 @@ void PropertyEditor::configTree() {
setHeaderLabels(lbls); setHeaderLabels(lbls);
setAlternatingRowColors(true); setAlternatingRowColors(true);
setItemDelegateForColumn(1, new Delegate()); setItemDelegateForColumn(1, new Delegate());
} }
@@ -475,25 +603,25 @@ void PropertyEditor::rebuild() {
clear(); clear();
configTree(); configTree();
if (object == 0) return; if (object == 0) return;
active_ = false; active_ = false;
const QMetaObject * mo = object->metaObject(); const QMetaObject * mo = object->metaObject();
QList<const QMetaObject * > mol; QList<const QMetaObject *> mol;
while (mo != 0) { while (mo != 0) {
mol.push_front(mo); mol.push_front(mo);
mo = mo->superClass(); mo = mo->superClass();
} }
int ps, pe; int ps, pe;
QTreeWidgetItem * ti, * tli, * tfi; QTreeWidgetItem *ti, *tli, *tfi;
QVariant value; QVariant value;
// QWidget * pw = 0; // QWidget * pw = 0;
int chue = 0; int chue = 0;
QColor bc; QColor bc;
font_b = font(); font_b = font();
font_b.setBold(true); font_b.setBold(true);
foreach (const QMetaObject * o, mol) { foreach(const QMetaObject * o, mol) {
ps = o->propertyOffset(); ps = o->propertyOffset();
pe = o->propertyCount();// - ps; pe = o->propertyCount(); // - ps;
//qDebug() << i->className() << ps << pe; // qDebug() << i->className() << ps << pe;
tli = new QTreeWidgetItem(); tli = new QTreeWidgetItem();
tli->setText(0, o->className()); tli->setText(0, o->className());
tli->setFont(0, font_b); tli->setFont(0, font_b);
@@ -505,7 +633,7 @@ void PropertyEditor::rebuild() {
for (int i = ps; i < pe; ++i) { for (int i = ps; i < pe; ++i) {
props << o->property(i); props << o->property(i);
value = o->property(i).read(object); value = o->property(i).read(object);
ti = new QTreeWidgetItem(); ti = new QTreeWidgetItem();
ti->setSizeHint(1, QSize(20, 20)); ti->setSizeHint(1, QSize(20, 20));
bc.setHsv(chue, 60, 245 + (i % 2) * 20 - 10); bc.setHsv(chue, 60, 245 + (i % 2) * 20 - 10);
setItemBackColor(ti, bc); setItemBackColor(ti, bc);
@@ -528,14 +656,13 @@ void PropertyEditor::rebuild() {
ti->setData(1, Qt::UserRole, value); ti->setData(1, Qt::UserRole, value);
ti->setData(1, Qt::UserRole + 2, "__flags"); ti->setData(1, Qt::UserRole + 2, "__flags");
ti->setData(0, Qt::UserRole + 1, QVariant::fromValue<QMetaProperty>(props.back())); ti->setData(0, Qt::UserRole + 1, QVariant::fromValue<QMetaProperty>(props.back()));
} } else if (props.back().isEnumType())
else if (props.back().isEnumType())
value.setValue<PropertyValuePair>(PropertyValuePair(props.back(), value)); value.setValue<PropertyValuePair>(PropertyValuePair(props.back(), value));
//ti->setText(1, value.toString()); // ti->setText(1, value.toString());
ti->setData(1, Qt::UserRole, value); ti->setData(1, Qt::UserRole, value);
tli->addChild(ti); tli->addChild(ti);
//const_cast<QModelIndex & >(indexFromItem(ti, 1)).; // const_cast<QModelIndex & >(indexFromItem(ti, 1)).;
//if (pw != 0) setItemWidget(ti, 1, pw); // if (pw != 0) setItemWidget(ti, 1, pw);
} }
chue += 60; chue += 60;
chue %= 360; chue %= 360;
@@ -544,6 +671,4 @@ void PropertyEditor::rebuild() {
} }
void PropertyEditor::refresh() { void PropertyEditor::refresh() {}
}

View File

@@ -1,85 +1,104 @@
/* /*
QGL PropertyEditor QGL PropertyEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PROPERTYEDITOR_H #ifndef PROPERTYEDITOR_H
#define PROPERTYEDITOR_H #define PROPERTYEDITOR_H
#include <QTreeWidget> #include <QDebug>
#include <QEvent>
#include <QHeaderView> #include <QHeaderView>
#include <QMetaProperty> #include <QMetaProperty>
#include <QEvent>
#include <QDebug>
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QTreeWidget>
#include <qpiconfigwidget.h> #include <qpiconfigwidget.h>
class Delegate: public QStyledItemDelegate { class Delegate: public QStyledItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
Delegate(QObject * parent = 0): QStyledItemDelegate() {ab = QBrush(QImage(":/icons/alpha.png"));} Delegate(QObject * parent = 0): QStyledItemDelegate() { ab = QBrush(QImage(":/icons/alpha.png")); }
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {cmi = const_cast<QModelIndex & >(index); return widgetForProperty(parent, index);} QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
void setEditorData(QWidget * editor, const QModelIndex & index) const {setWidgetProperty(editor, index.data(Qt::UserRole));} cmi = const_cast<QModelIndex &>(index);
return widgetForProperty(parent, index);
}
void setEditorData(QWidget * editor, const QModelIndex & index) const { setWidgetProperty(editor, index.data(Qt::UserRole)); }
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const; void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const {editor->setGeometry(option.rect);} void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const {
editor->setGeometry(option.rect);
}
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
private: private:
QWidget * widgetForProperty(QWidget * parent, const QModelIndex & index) const; QWidget * widgetForProperty(QWidget * parent, const QModelIndex & index) const;
void setWidgetProperty(QWidget * w, const QVariant & value) const; void setWidgetProperty(QWidget * w, const QVariant & value) const;
const QVariant widgetProperty(QWidget * w) const; const QVariant widgetProperty(QWidget * w) const;
QString pointString(const QPoint & p) const {return QString::number(p.x()) + " x " + QString::number(p.y());} QString pointString(const QPoint & p) const { return QString::number(p.x()) + " x " + QString::number(p.y()); }
QString pointString(const QPointF & p) const {return QString::number(p.x()) + " x " + QString::number(p.y());} QString pointString(const QPointF & p) const { return QString::number(p.x()) + " x " + QString::number(p.y()); }
QString rectString(const QRect & r) const {return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " + QString rectString(const QRect & r) const {
QString::number(r.width()) + " x " + QString::number(r.height());} return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " + QString::number(r.width()) + " x " +
QString rectString(const QRectF & r) const {return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " + QString::number(r.height());
QString::number(r.width()) + " x " + QString::number(r.height());} }
QString rectString(const QRectF & r) const {
return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " + QString::number(r.width()) + " x " +
QString::number(r.height());
}
QBrush ab; QBrush ab;
mutable QModelIndex cmi; mutable QModelIndex cmi;
private slots: private slots:
void changed() {setModelData((QWidget * )sender(), const_cast<QAbstractItemModel * >(cmi.model()), cmi);} void changed() { setModelData((QWidget *)sender(), const_cast<QAbstractItemModel *>(cmi.model()), cmi); }
void changedFlag(); void changedFlag();
}; };
typedef QPair<QMetaProperty, QVariant> PropertyValuePair; typedef QPair<QMetaProperty, QVariant> PropertyValuePair;
Q_DECLARE_METATYPE (PropertyValuePair) Q_DECLARE_METATYPE(PropertyValuePair)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECLARE_METATYPE (QMetaProperty) Q_DECLARE_METATYPE(QMetaProperty)
#endif #endif
class PropertyEditor: public QTreeWidget { class PropertyEditor: public QTreeWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit PropertyEditor(QWidget * parent = 0); explicit PropertyEditor(QWidget * parent = 0);
virtual ~PropertyEditor(); virtual ~PropertyEditor();
void assignObject(QObject * o) {object = o; rebuild();} void assignObject(QObject * o) {
object = o;
rebuild();
}
protected: protected:
void changeEvent(QEvent * e); void changeEvent(QEvent * e);
private: private:
void configTree(); void configTree();
void setItemBackColor(QTreeWidgetItem * i, const QColor & c) {i->setBackground(0, c); i->setBackground(1, c);} void setItemBackColor(QTreeWidgetItem * i, const QColor & c) {
void setItemForeColor(QTreeWidgetItem * i, const QColor & c) {i->setForeground(0, c); i->setForeground(1, c);} i->setBackground(0, c);
i->setBackground(1, c);
}
void setItemForeColor(QTreeWidgetItem * i, const QColor & c) {
i->setForeground(0, c);
i->setForeground(1, c);
}
void rebuild(); void rebuild();
void refresh(); void refresh();
@@ -91,7 +110,6 @@ private:
private slots: private slots:
void itemClicked(QTreeWidgetItem * item, int column); void itemClicked(QTreeWidgetItem * item, int column);
void itemChanged(QTreeWidgetItem * item, int column); void itemChanged(QTreeWidgetItem * item, int column);
}; };
#endif // PROPERTYEDITOR_H #endif // PROPERTYEDITOR_H

View File

@@ -1,29 +1,31 @@
/* /*
QGL SceneTree QGL SceneTree
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "scene_tree.h" #include "scene_tree.h"
#include "ui_scene_tree.h"
#include "glcamera.h" #include "glcamera.h"
#include "qglview.h" #include "qglview.h"
#include <QTreeWidget> #include "ui_scene_tree.h"
#include <QScrollBar>
#include <QAction> #include <QAction>
#include <QEvent> #include <QEvent>
#include <QScrollBar>
#include <QTreeWidget>
enum Column { enum Column {
cName, cName,
@@ -65,13 +67,17 @@ SceneTree::SceneTree(QWidget * parent): QWidget(parent) {
icon_vis[0] = QIcon(":/icons/layer-visible-off.png"); icon_vis[0] = QIcon(":/icons/layer-visible-off.png");
icon_vis[1] = QIcon(":/icons/layer-visible-on.png"); icon_vis[1] = QIcon(":/icons/layer-visible-on.png");
ui->treeObjects->addActions(actionsSelection()); ui->treeObjects->addActions(actionsSelection());
ui->treeObjects->addAction (newSeparator()); ui->treeObjects->addAction(newSeparator());
ui->treeObjects->addActions(actionsAdd()); ui->treeObjects->addActions(actionsAdd());
ui->buttonFilter->addActions(QList<QAction*>() << ui->actionFilter_node << ui->actionFilter_mesh << ui->actionFilter_light << ui->actionFilter_camera); ui->buttonFilter->addActions(QList<QAction *>()
view = 0; << ui->actionFilter_node << ui->actionFilter_mesh << ui->actionFilter_light << ui->actionFilter_camera);
view = 0;
hidden_by_filter = obj_count = 0; hidden_by_filter = obj_count = 0;
block_tree = false; block_tree = false;
connect(ui->treeObjects->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(treeObjects_selectionCnahged())); connect(ui->treeObjects->selectionModel(),
SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
this,
SLOT(treeObjects_selectionCnahged()));
} }
@@ -87,7 +93,7 @@ void SceneTree::assignQGLView(QGLView * v) {
connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
connect(view, SIGNAL(materialsChanged()), this, SLOT(materialsChanged())); connect(view, SIGNAL(materialsChanged()), this, SLOT(materialsChanged()));
connect(view->scene(), SIGNAL(treeChanged()), this, SLOT(objectsTreeChanged())); connect(view->scene(), SIGNAL(treeChanged()), this, SLOT(objectsTreeChanged()));
connect(view->scene(), SIGNAL(__objectDeleted(ObjectBase*)), this, SLOT(__objectDeleted(ObjectBase*))); connect(view->scene(), SIGNAL(__objectDeleted(ObjectBase *)), this, SLOT(__objectDeleted(ObjectBase *)));
view->setContextActions(actionsSelection()); view->setContextActions(actionsSelection());
checkActions(); checkActions();
} }
@@ -102,12 +108,9 @@ QList<QAction *> SceneTree::actionsAdd() {
QList<QAction *> SceneTree::actionsSelection() { QList<QAction *> SceneTree::actionsSelection() {
QList<QAction *> ret; QList<QAction *> ret;
ret << ui->actionFocus << newSeparator() ret << ui->actionFocus << newSeparator() << ui->actionGroup << ui->actionClone << newSeparator() << ui->actionSelect_parent
<< ui->actionGroup << ui->actionClone << newSeparator() << ui->actionSelect_by_mesh << ui->actionSelect_by_material << newSeparator() << ui->actionTransfer_transform_to_children
<< ui->actionSelect_parent << ui->actionSelect_by_mesh << ui->actionSelect_by_material << newSeparator() << newSeparator() << ui->actionActive_camera << ui->actionDefault_camera << newSeparator() << ui->actionRemove;
<< ui->actionTransfer_transform_to_children << newSeparator()
<< ui->actionActive_camera << ui->actionDefault_camera << newSeparator()
<< ui->actionRemove;
return ret; return ret;
} }
@@ -129,8 +132,7 @@ void SceneTree::changeEvent(QEvent * e) {
void SceneTree::rememberExpanded(QTreeWidgetItem * ti) { void SceneTree::rememberExpanded(QTreeWidgetItem * ti) {
for (int i = 0; i < ti->childCount(); ++i) { for (int i = 0; i < ti->childCount(); ++i) {
QTreeWidgetItem * ci = ti->child(i); QTreeWidgetItem * ci = ti->child(i);
if (ci->isExpanded()) if (ci->isExpanded()) expanded_ << itemObject(ci);
expanded_ << itemObject(ci);
rememberExpanded(ci); rememberExpanded(ci);
} }
} }
@@ -148,13 +150,12 @@ void SceneTree::restoreExpanded(QTreeWidgetItem * ti) {
void SceneTree::makeObjetTree(ObjectBase * o, QTreeWidgetItem * ti) { void SceneTree::makeObjetTree(ObjectBase * o, QTreeWidgetItem * ti) {
++obj_count; ++obj_count;
for (int i = 0; i < o->childCount(); ++i) { for (int i = 0; i < o->childCount(); ++i) {
ObjectBase * co = o->child(i); ObjectBase * co = o->child(i);
QTreeWidgetItem * ci = new QTreeWidgetItem(ti); QTreeWidgetItem * ci = new QTreeWidgetItem(ti);
ci->setText(cName, co->name()); ci->setText(cName, co->name());
ci->setCheckState(cVis, co->isVisible() ? Qt::Checked : Qt::Unchecked); ci->setCheckState(cVis, co->isVisible() ? Qt::Checked : Qt::Unchecked);
ci->setIcon(cVis, icon_vis[co->isVisible(true)]); ci->setIcon(cVis, icon_vis[co->isVisible(true)]);
if (co->material()) if (co->material()) ci->setText(cMaterial, co->material()->name);
ci->setText(cMaterial, co->material()->name);
ci->setFlags(ci->flags() | Qt::ItemIsEditable); ci->setFlags(ci->flags() | Qt::ItemIsEditable);
ObjectType t = otNode; ObjectType t = otNode;
switch (co->type()) { switch (co->type()) {
@@ -189,7 +190,7 @@ void SceneTree::makeObjetTree(ObjectBase * o, QTreeWidgetItem * ti) {
ObjectBase * SceneTree::itemObject(QTreeWidgetItem * item) const { ObjectBase * SceneTree::itemObject(QTreeWidgetItem * item) const {
if (!item) return 0; if (!item) return 0;
return (ObjectBase*)(item->data(cName, irObject).toULongLong()); return (ObjectBase *)(item->data(cName, irObject).toULongLong());
} }
@@ -201,12 +202,11 @@ int SceneTree::itemType(QTreeWidgetItem * item) const {
void SceneTree::selectionChanged() { void SceneTree::selectionChanged() {
if (block_tree) return; if (block_tree) return;
block_tree = true; block_tree = true;
QList<QTreeWidgetItem*> il = ui->treeObjects->findItems("", Qt::MatchContains | Qt::MatchRecursive); QList<QTreeWidgetItem *> il = ui->treeObjects->findItems("", Qt::MatchContains | Qt::MatchRecursive);
const ObjectBase * fo = 0; const ObjectBase * fo = 0;
if (view->selectedObjects().size() == 1) if (view->selectedObjects().size() == 1) fo = view->selectedObject();
fo = view->selectedObject(); foreach(QTreeWidgetItem * i, il) {
foreach (QTreeWidgetItem * i, il) {
ObjectBase * o = itemObject(i); ObjectBase * o = itemObject(i);
i->setSelected(o->isSelected()); i->setSelected(o->isSelected());
if (fo && (fo == o)) { if (fo && (fo == o)) {
@@ -219,18 +219,17 @@ void SceneTree::selectionChanged() {
void SceneTree::materialsChanged() { void SceneTree::materialsChanged() {
foreach (QTreeWidgetItem * i, geo_items) { foreach(QTreeWidgetItem * i, geo_items) {
ObjectBase * o = itemObject(i); ObjectBase * o = itemObject(i);
if (!o) continue; if (!o) continue;
if (o->material()) if (o->material()) i->setText(cMaterial, o->material()->name);
i->setText(cMaterial, o->material()->name);
} }
} }
void SceneTree::cameraChanged() { void SceneTree::cameraChanged() {
if (!view) return; if (!view) return;
foreach (QTreeWidgetItem * i, cam_items) { foreach(QTreeWidgetItem * i, cam_items) {
ObjectBase * o = itemObject(i); ObjectBase * o = itemObject(i);
if (!o) continue; if (!o) continue;
i->setText(cVis, (o == view->camera()) ? "*" : ""); i->setText(cVis, (o == view->camera()) ? "*" : "");
@@ -242,8 +241,8 @@ bool SceneTree::filterTree(QTreeWidgetItem * ti, const QString & filter, int typ
bool ret = false; bool ret = false;
for (int i = 0; i < ti->childCount(); ++i) { for (int i = 0; i < ti->childCount(); ++i) {
QTreeWidgetItem * ci = ti->child(i); QTreeWidgetItem * ci = ti->child(i);
QString cit = ci->text(cName); QString cit = ci->text(cName);
int t = itemType(ci); int t = itemType(ci);
if (ci->childCount() > 0) { if (ci->childCount() > 0) {
if (!filterTree(ci, filter, types)) { if (!filterTree(ci, filter, types)) {
ci->setHidden(true); ci->setHidden(true);
@@ -259,11 +258,12 @@ bool SceneTree::filterTree(QTreeWidgetItem * ti, const QString & filter, int typ
} else { } else {
f = f || cit.contains(filter, Qt::CaseInsensitive); f = f || cit.contains(filter, Qt::CaseInsensitive);
} }
if ((types & t) != t) if ((types & t) != t) f = false;
f = false;
ci->setHidden(!f); ci->setHidden(!f);
if (f) ret = true; if (f)
else ++hidden_by_filter; ret = true;
else
++hidden_by_filter;
} }
} }
return ret; return ret;
@@ -272,23 +272,23 @@ bool SceneTree::filterTree(QTreeWidgetItem * ti, const QString & filter, int typ
void SceneTree::checkActions() { void SceneTree::checkActions() {
bool has_1 = false, has_m = false; bool has_1 = false, has_m = false;
bool has_cam = false; bool has_cam = false;
bool has_mesh = false; bool has_mesh = false;
bool is_def_cam = false; bool is_def_cam = false;
if (view) { if (view) {
is_def_cam = view->isDefaultCamera(); is_def_cam = view->isDefaultCamera();
ObjectBaseList slo = view->selectedObjects(); ObjectBaseList slo = view->selectedObjects();
has_1 = !slo.isEmpty(); has_1 = !slo.isEmpty();
has_m = slo.size() > 1; has_m = slo.size() > 1;
for (ObjectBase * o : slo) { for (ObjectBase * o: slo) {
if (o->type() == ObjectBase::glCamera) has_cam = (slo.size() == 1); if (o->type() == ObjectBase::glCamera) has_cam = (slo.size() == 1);
if (o->type() == ObjectBase::glMesh) has_mesh = true; if (o->type() == ObjectBase::glMesh) has_mesh = true;
} }
} }
ui->actionFocus ->setEnabled(has_mesh); ui->actionFocus->setEnabled(has_mesh);
ui->actionRemove->setEnabled(has_1); ui->actionRemove->setEnabled(has_1);
ui->actionClone ->setEnabled(has_1); ui->actionClone->setEnabled(has_1);
ui->actionGroup->setEnabled(has_m); ui->actionGroup->setEnabled(has_m);
ui->actionTransfer_transform_to_children->setEnabled(has_1); ui->actionTransfer_transform_to_children->setEnabled(has_1);
ui->actionSelect_parent->setEnabled(has_1); ui->actionSelect_parent->setEnabled(has_1);
@@ -304,8 +304,8 @@ void SceneTree::treeObjects_selectionCnahged() {
block_tree = true; block_tree = true;
view->scene()->clearSelection(); view->scene()->clearSelection();
ObjectBaseList sol; ObjectBaseList sol;
QList<QTreeWidgetItem*> til = ui->treeObjects->selectedItems(); QList<QTreeWidgetItem *> til = ui->treeObjects->selectedItems();
foreach (QTreeWidgetItem * i, til) foreach(QTreeWidgetItem * i, til)
sol << itemObject(i); sol << itemObject(i);
view->scene()->selectObjects(sol); view->scene()->selectObjects(sol);
block_tree = false; block_tree = false;
@@ -315,9 +315,9 @@ void SceneTree::treeObjects_selectionCnahged() {
void SceneTree::filter() { void SceneTree::filter() {
int types = 0; int types = 0;
if (ui->actionFilter_node ->isChecked()) types |= otNode ; if (ui->actionFilter_node->isChecked()) types |= otNode;
if (ui->actionFilter_mesh ->isChecked()) types |= otMesh ; if (ui->actionFilter_mesh->isChecked()) types |= otMesh;
if (ui->actionFilter_light ->isChecked()) types |= otLight ; if (ui->actionFilter_light->isChecked()) types |= otLight;
if (ui->actionFilter_camera->isChecked()) types |= otCamera; if (ui->actionFilter_camera->isChecked()) types |= otCamera;
if (types == 0) types = 0xFF; if (types == 0) types = 0xFF;
hidden_by_filter = 0; hidden_by_filter = 0;
@@ -348,14 +348,14 @@ void SceneTree::on_treeObjects_itemChanged(QTreeWidgetItem * item, int column) {
if (o) o->setName(item->text(cName)); if (o) o->setName(item->text(cName));
} }
if (column == cVis) { if (column == cVis) {
bool vis = item->checkState(cVis) == Qt::Checked; bool vis = item->checkState(cVis) == Qt::Checked;
QList<QTreeWidgetItem*> til = ui->treeObjects->selectedItems(); QList<QTreeWidgetItem *> til = ui->treeObjects->selectedItems();
if (!til.contains(item)) { if (!til.contains(item)) {
til.clear(); til.clear();
til << item; til << item;
} }
foreach (QTreeWidgetItem * ti, til) { foreach(QTreeWidgetItem * ti, til) {
//itemObject(ti)->setVisible(vis); // itemObject(ti)->setVisible(vis);
itemObject(ti)->setVisible(vis); itemObject(ti)->setVisible(vis);
} }
} }
@@ -365,13 +365,12 @@ void SceneTree::on_treeObjects_itemChanged(QTreeWidgetItem * item, int column) {
void SceneTree::on_treeObjects_itemMoved(QTreeWidgetItem * item, QTreeWidgetItem * new_parent) { void SceneTree::on_treeObjects_itemMoved(QTreeWidgetItem * item, QTreeWidgetItem * new_parent) {
ObjectBase * co = itemObject(item); ObjectBase * co = itemObject(item);
if (!co->hasParent()) return; if (!co->hasParent()) return;
//co->parent()->removeChild(co); // co->parent()->removeChild(co);
if (new_parent == ui->treeObjects->invisibleRootItem()) { if (new_parent == ui->treeObjects->invisibleRootItem()) {
view->scene()->rootObject()->addChild(co); view->scene()->rootObject()->addChild(co);
} else { } else {
ObjectBase * po = itemObject(new_parent); ObjectBase * po = itemObject(new_parent);
if (po) if (po) po->addChild(co);
po->addChild(co);
} }
} }
@@ -402,9 +401,9 @@ void SceneTree::on_actionAdd_camera_triggered() {
void SceneTree::on_actionClone_triggered() { void SceneTree::on_actionClone_triggered() {
if (!view) return; if (!view) return;
QList<QTreeWidgetItem*> sil = ui->treeObjects->selectedItems(); QList<QTreeWidgetItem *> sil = ui->treeObjects->selectedItems();
ObjectBaseList col; ObjectBaseList col;
foreach (QTreeWidgetItem * i, sil) { foreach(QTreeWidgetItem * i, sil) {
ObjectBase * o = itemObject(i); ObjectBase * o = itemObject(i);
if (!o) continue; if (!o) continue;
ObjectBase * no = o->clone(); ObjectBase * no = o->clone();
@@ -418,10 +417,10 @@ void SceneTree::on_actionClone_triggered() {
void SceneTree::on_actionGroup_triggered() { void SceneTree::on_actionGroup_triggered() {
if (!view) return; if (!view) return;
ObjectBaseList sol = view->scene()->selectedObjects(true); ObjectBaseList sol = view->scene()->selectedObjects(true);
ObjectBase * cp = sol[0]->parent(); ObjectBase * cp = sol[0]->parent();
ObjectBase * nr = new ObjectBase(); ObjectBase * nr = new ObjectBase();
cp->addChild(nr); cp->addChild(nr);
foreach (ObjectBase * o, sol) foreach(ObjectBase * o, sol)
nr->addChild(o); nr->addChild(o);
view->scene()->selectObject(nr); view->scene()->selectObject(nr);
} }
@@ -430,7 +429,7 @@ void SceneTree::on_actionGroup_triggered() {
void SceneTree::on_actionTransfer_transform_to_children_triggered() { void SceneTree::on_actionTransfer_transform_to_children_triggered() {
if (!view) return; if (!view) return;
ObjectBaseList sol = view->scene()->selectedObjects(true); ObjectBaseList sol = view->scene()->selectedObjects(true);
foreach (ObjectBase * o, sol) foreach(ObjectBase * o, sol)
o->transferTransformToChildren(); o->transferTransformToChildren();
} }
@@ -455,11 +454,10 @@ void SceneTree::on_actionDefault_camera_triggered() {
void SceneTree::on_actionSelect_parent_triggered() { void SceneTree::on_actionSelect_parent_triggered() {
if (!view) return; if (!view) return;
ObjectBaseList sol = view->scene()->selectedObjects(true); ObjectBaseList sol = view->scene()->selectedObjects(true);
QSet<ObjectBase*> nsl; QSet<ObjectBase *> nsl;
foreach (ObjectBase * o, sol) { foreach(ObjectBase * o, sol) {
ObjectBase * po = o->parent(); ObjectBase * po = o->parent();
if (po != view->scene()->rootObject()) if (po != view->scene()->rootObject()) o = po;
o = po;
nsl << o; nsl << o;
} }
view->scene()->selectObjects(nsl.values()); view->scene()->selectObjects(nsl.values());
@@ -478,8 +476,8 @@ void SceneTree::on_actionSelect_by_material_triggered() {
void SceneTree::removeObjects() { void SceneTree::removeObjects() {
if (!view) return; if (!view) return;
QList<QTreeWidgetItem*> sil = ui->treeObjects->selectedItems(); QList<QTreeWidgetItem *> sil = ui->treeObjects->selectedItems();
foreach (QTreeWidgetItem * i, sil) { foreach(QTreeWidgetItem * i, sil) {
ObjectBase * o = itemObject(i); ObjectBase * o = itemObject(i);
if (o->isSelected(true)) view->scene()->clearSelection(); if (o->isSelected(true)) view->scene()->clearSelection();
if (o) delete o; if (o) delete o;
@@ -493,7 +491,7 @@ void SceneTree::focusObjects() {
if (!view->camera()) return; if (!view->camera()) return;
Box3D bb; Box3D bb;
ObjectBaseList ol = view->selectedObjects(); ObjectBaseList ol = view->selectedObjects();
foreach (ObjectBase * o, ol) { foreach(ObjectBase * o, ol) {
o->calculateBoundingBox(); o->calculateBoundingBox();
bb |= o->boundingBox(); bb |= o->boundingBox();
} }
@@ -512,7 +510,7 @@ void SceneTree::objectsTreeChanged() {
block_tree = false; block_tree = false;
if (!view) return; if (!view) return;
block_tree = true; block_tree = true;
obj_count = 0; obj_count = 0;
makeObjetTree(view->scene()->rootObject(), ui->treeObjects->invisibleRootItem()); makeObjetTree(view->scene()->rootObject(), ui->treeObjects->invisibleRootItem());
--obj_count; --obj_count;
restoreExpanded(ui->treeObjects->invisibleRootItem()); restoreExpanded(ui->treeObjects->invisibleRootItem());

View File

@@ -1,44 +1,45 @@
/* /*
QGL SceneTree QGL SceneTree
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SCENE_TREE_H #ifndef SCENE_TREE_H
#define SCENE_TREE_H #define SCENE_TREE_H
#include <QWidget>
#include <QIcon>
#include "glscene.h" #include "glscene.h"
#include <QIcon>
#include <QWidget>
class QTreeWidgetItem; class QTreeWidgetItem;
namespace Ui { namespace Ui {
class SceneTree; class SceneTree;
} }
class SceneTree: public QWidget class SceneTree: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
SceneTree(QWidget * parent = 0); SceneTree(QWidget * parent = 0);
~SceneTree(); ~SceneTree();
void assignQGLView(QGLView * v); void assignQGLView(QGLView * v);
QList<QAction*> actionsAdd(); QList<QAction *> actionsAdd();
QList<QAction*> actionsSelection(); QList<QAction *> actionsSelection();
void expandItems(); void expandItems();
private: private:
@@ -55,21 +56,21 @@ private:
bool block_tree; bool block_tree;
int hidden_by_filter, obj_count; int hidden_by_filter, obj_count;
QIcon icon_empty, icon_geo, icon_camera, icon_light, icon_vis[2]; QIcon icon_empty, icon_geo, icon_camera, icon_light, icon_vis[2];
QSet<ObjectBase*> expanded_; QSet<ObjectBase *> expanded_;
QList<QTreeWidgetItem*> geo_items, cam_items; QList<QTreeWidgetItem *> geo_items, cam_items;
QGLView * view; QGLView * view;
private slots: private slots:
void treeObjects_selectionCnahged(); void treeObjects_selectionCnahged();
void on_treeObjects_itemChanged(QTreeWidgetItem * item, int column); void on_treeObjects_itemChanged(QTreeWidgetItem * item, int column);
void on_treeObjects_itemMoved (QTreeWidgetItem * item, QTreeWidgetItem * new_parent); void on_treeObjects_itemMoved(QTreeWidgetItem * item, QTreeWidgetItem * new_parent);
void on_actionAdd_node_triggered(); void on_actionAdd_node_triggered();
void on_actionAdd_light_triggered(); void on_actionAdd_light_triggered();
void on_actionAdd_camera_triggered(); void on_actionAdd_camera_triggered();
void on_actionFocus_triggered() {focusObjects();} void on_actionFocus_triggered() { focusObjects(); }
void on_actionRemove_triggered() {removeObjects();} void on_actionRemove_triggered() { removeObjects(); }
void on_actionClone_triggered(); void on_actionClone_triggered();
void on_actionGroup_triggered(); void on_actionGroup_triggered();
void on_actionTransfer_transform_to_children_triggered(); void on_actionTransfer_transform_to_children_triggered();
@@ -95,7 +96,6 @@ public slots:
signals: signals:
private: private:
}; };
#endif // SCENE_TREE_H #endif // SCENE_TREE_H

View File

@@ -1,59 +1,58 @@
/* /*
QGL SceneTree QGL SceneTree
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef TREEWIDGET_H #ifndef TREEWIDGET_H
#define TREEWIDGET_H #define TREEWIDGET_H
#include <QTreeWidget>
#include <QDropEvent>
#include <QDebug> #include <QDebug>
#include <QTimer> #include <QDropEvent>
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QTimer>
#include <QTreeWidget>
class InternalMoveTreeWidget: public QTreeWidget class InternalMoveTreeWidget: public QTreeWidget {
{
Q_OBJECT Q_OBJECT
public: public:
InternalMoveTreeWidget(QWidget * parent = 0): QTreeWidget(parent) {} InternalMoveTreeWidget(QWidget * parent = 0): QTreeWidget(parent) {}
protected: protected:
virtual void dropEvent(QDropEvent * e) { virtual void dropEvent(QDropEvent * e) {
QList<QTreeWidgetItem*> sil = selectedItems(); QList<QTreeWidgetItem *> sil = selectedItems();
if (sil.isEmpty()) return; if (sil.isEmpty()) return;
QTreeWidget::dropEvent(e); QTreeWidget::dropEvent(e);
foreach (QTreeWidgetItem * ti, sil) { foreach(QTreeWidgetItem * ti, sil) {
QTreeWidgetItem * ti_p = ti->parent(); QTreeWidgetItem * ti_p = ti->parent();
if (!ti_p) ti_p = invisibleRootItem(); if (!ti_p) ti_p = invisibleRootItem();
int ti_ppos = ti_p->indexOfChild(ti); int ti_ppos = ti_p->indexOfChild(ti);
emit itemMoved(ti, ti_p, ti_ppos); emit itemMoved(ti, ti_p, ti_ppos);
} }
} }
signals: signals:
void itemMoved(QTreeWidgetItem * item, QTreeWidgetItem * new_parent, int new_index); void itemMoved(QTreeWidgetItem * item, QTreeWidgetItem * new_parent, int new_index);
}; };
class NoEditDelegate: public QStyledItemDelegate { class NoEditDelegate: public QStyledItemDelegate {
public: public:
NoEditDelegate(QObject* parent=0): QStyledItemDelegate(parent) {} NoEditDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { virtual QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
return nullptr; return nullptr;
} }
}; };

View File

@@ -1,23 +1,25 @@
/* /*
QGL ViewEditor QGL ViewEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "view_editor.h" #include "view_editor.h"
#include "ui_view_editor.h" #include "ui_view_editor.h"
#include <QFileDialog> #include <QFileDialog>
#include <colorbutton.h> #include <colorbutton.h>
#include <spinslider.h> #include <spinslider.h>
@@ -26,10 +28,10 @@
ViewEditor::ViewEditor(QWidget * parent): QWidget(parent) { ViewEditor::ViewEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::ViewEditor(); ui = new Ui::ViewEditor();
ui->setupUi(this); ui->setupUi(this);
view = nullptr; view = nullptr;
active = true; active = true;
ui->checkCameraLight->setCheckState(Qt::PartiallyChecked); ui->checkCameraLight->setCheckState(Qt::PartiallyChecked);
#if QT_VERSION >= QT_VERSION_CHECK(5,12,0) #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
ui->spinDepthStart->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType); ui->spinDepthStart->setStepType(QAbstractSpinBox::AdaptiveDecimalStepType);
#endif #endif
} }
@@ -64,11 +66,8 @@ void ViewEditor::assignQGLView(QGLView * v) {
void ViewEditor::changeEvent(QEvent * e) { void ViewEditor::changeEvent(QEvent * e) {
QWidget::changeEvent(e); QWidget::changeEvent(e);
switch (e->type()) { switch (e->type()) {
case QEvent::LanguageChange: case QEvent::LanguageChange: ui->retranslateUi(this); break;
ui->retranslateUi(this); default: break;
break;
default:
break;
} }
} }
@@ -161,7 +160,6 @@ void ViewEditor::on_checkService_clicked(bool val) {
void ViewEditor::on_checkCameraLight_stateChanged(int s) { void ViewEditor::on_checkCameraLight_stateChanged(int s) {
if (!view || !active) return; if (!view || !active) return;
view->setCameraLightMode((QGLView::CameraLightMode)s); view->setCameraLightMode((QGLView::CameraLightMode)s);
} }
@@ -205,4 +203,3 @@ void ViewEditor::on_checkVSync_clicked(bool val) {
if (!view || !active) return; if (!view || !active) return;
view->setVSync(val); view->setVSync(val);
} }

View File

@@ -1,34 +1,35 @@
/* /*
QGL ViewEditor QGL ViewEditor
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef VIEW_EDITOR_H #ifndef VIEW_EDITOR_H
#define VIEW_EDITOR_H #define VIEW_EDITOR_H
#include <QWidget>
#include "qglview.h" #include "qglview.h"
#include <QWidget>
namespace Ui { namespace Ui {
class ViewEditor; class ViewEditor;
} }
class ViewEditor: public QWidget class ViewEditor: public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit ViewEditor(QWidget * parent = 0); explicit ViewEditor(QWidget * parent = 0);
@@ -60,7 +61,7 @@ private slots:
void on_checkVSync_clicked(bool val); void on_checkVSync_clicked(bool val);
void on_buttonHDRClear_clicked(); void on_buttonHDRClear_clicked();
void on_buttonHDRSelect_clicked(); void on_buttonHDRSelect_clicked();
void on_colorFogBack_colorChanged(const QColor &color); void on_colorFogBack_colorChanged(const QColor & color);
void on_spinFogDensity_valueChanged(double arg1); void on_spinFogDensity_valueChanged(double arg1);
void on_spinFogDecay_valueChanged(double arg1); void on_spinFogDecay_valueChanged(double arg1);
}; };