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

This commit is contained in:
2015-11-20 21:19:36 +00:00
parent cabaead1c6
commit 104a7f99ad
48 changed files with 1973 additions and 1273 deletions

View File

@@ -87,7 +87,7 @@ void GLFramebuffer::bind() {
QVector<GLenum> buffers; QVector<GLenum> buffers;
for (int i = 0; i < colors.size(); ++i) for (int i = 0; i < colors.size(); ++i)
buffers << GL_COLOR_ATTACHMENT0 + i; buffers << GL_COLOR_ATTACHMENT0 + i;
glDrawBuffers(colors.size(), buffers.constData()); glDrawBuffers(buffers.size(), buffers.constData());
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
//glDrawBuffer(GL_COLOR_ATTACHMENT0); //glDrawBuffer(GL_COLOR_ATTACHMENT0);
glViewport(0, 0, wid, hei); glViewport(0, 0, wid, hei);
@@ -105,9 +105,10 @@ void GLFramebuffer::release() {
void GLFramebuffer::setWriteBuffers(int indeces[]) { void GLFramebuffer::setWriteBuffers(int indeces[]) {
QVector<GLenum> buffers; QVector<GLenum> buffers;
for (uint i = 0; i < sizeof(indeces); ++i) for (uint i = 0; i < sizeof(indeces); ++i) {
buffers << GL_COLOR_ATTACHMENT0 + indeces[i]; buffers << GL_COLOR_ATTACHMENT0 + indeces[i];
glDrawBuffers(colors.size(), buffers.constData()); }
glDrawBuffers(buffers.size(), buffers.constData());
} }
@@ -115,7 +116,7 @@ void GLFramebuffer::setWriteBuffers(int * indeces, int count) {
QVector<GLenum> buffers; QVector<GLenum> buffers;
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
buffers << GL_COLOR_ATTACHMENT0 + indeces[i]; buffers << GL_COLOR_ATTACHMENT0 + indeces[i];
glDrawBuffers(colors.size(), buffers.constData()); glDrawBuffers(buffers.size(), buffers.constData());
} }
@@ -127,3 +128,9 @@ void GLFramebuffer::bindColorTextures() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
} }
} }
void GLFramebuffer::bindDepthTexture(int channel) {
glActiveTextureChannel(channel);
glBindTexture(GL_TEXTURE_2D, tex_d);
}

View File

@@ -47,6 +47,7 @@ public:
void copyDepthFrom(GLuint tex) {;} void copyDepthFrom(GLuint tex) {;}
void bindColorTextures(); void bindColorTextures();
void bindDepthTexture(int channel);
private: private:
bool is_depth, is_changed; bool is_depth, is_changed;

231
qglview/glmaterial.cpp Normal file
View File

@@ -0,0 +1,231 @@
/*
QGLView
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gltypes.h"
#include "qglview.h"
GLTextureManager * currentGLTextureManager;
QStringList GLTextureManagerBase::search_pathes(".");
bool GLCubeTexture::create() {
//qDebug("create");
destroy();
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_CUBE_MAP, id_);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
//glClearError();
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//qDebug() << glGetError();
changed_ = false;
return id_ > 0;
}
void GLCubeTexture::load() {
if (isEmpty()) return;
create();
if (!path(0).isEmpty()) loadFront(path(0));
if (!path(1).isEmpty()) loadBack(path(1));
if (!path(2).isEmpty()) loadLeft(path(2));
if (!path(3).isEmpty()) loadRight(path(3));
if (!path(4).isEmpty()) loadTop(path(4));
if (!path(5).isEmpty()) loadBottom(path(5));
}
void GLCubeTexture::loadFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl;
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBack(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadLeft(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadRight(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadTop(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBottom(sl[0].absoluteFilePath());
}
void GLCubeTexture::loadPathesFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl;
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[1] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[2] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[3] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[4] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[5] = sl[0].absoluteFilePath();
}
GLuint GLTextureManagerBase::loadTexture(const QString & path, bool ownership, bool bump) {
QString p = findFile(path, search_pathes);
if (p.isEmpty()) return 0;
int tid = ((GLTextureManagerBase*)currentGLTextureManager)->textureID(p, bump);
if (tid > 0) {
//qDebug() << "[TextureManager] Found" << path << "as" << tid;
return tid;
}
QImage image(p);
if (bump) convertToNormal(image);
//qDebug() << p << image.width() << image.height() << image.format() << bump;
tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, QGLContext::MipmapBindOption*/);
if (tid == 0) {
qDebug() << "[TextureManager] Can`t load" << p;
return tid;
}
qDebug() << "[TextureManager] Loaded" << p << "as" << tid;
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids[bump ? 1 : 0].insert(p, tid);
return tid;
}
GLuint GLTextureManagerBase::loadTexture(const QImage & im, bool ownership, bool bump) {
if (im.isNull()) return 0;
QImage image(im);
if (bump) convertToNormal(image);
GLuint tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D);
if (tid == 0) {
qDebug() << "[TextureManager] Can`t load image";
return tid;
}
//qDebug() << "[TextureManager] Loaded image as" << tid;
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids[bump ? 1 : 0].insert(QString(), tid);
return tid;
}
Vector3d colorVector(QRgb c) {return Vector3d(((uchar*)(&c))[0] / 255., ((uchar*)(&c))[1] / 255., ((uchar*)(&c))[2] / 255.);}
void GLTextureManagerBase::convertToNormal(QImage & im) {
if (im.isNull()) return;
QImage sim = im.convertToFormat(QImage::Format_ARGB32);
double sum[3] = {0., 0., 0.};
llong a = 0;
const uchar * sd = sim.constBits();
for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) {
sum[2] += double(sd[a]) / 255. - 0.5; ++a;
sum[1] += double(sd[a]) / 255. - 0.5; ++a;
sum[0] += double(sd[a]) / 255. - 0.5; ++a;
++a;
}
}
double wh = sim.width() * sim.height();
sum[0] /= wh;
sum[1] /= wh;
sum[2] /= wh;
qDebug() << sum[0] << sum[1] << sum[2];
if ((qAbs(sum[0]) <= 0.05) && (qAbs(sum[1]) <= 0.05) && (sum[2] >= 0.4)) /// already normal
return;
qDebug() << "convert to bump";
QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32);
int tx, ty, w = sim.width(), h = sim.height();
a = 0;
uchar * dd = dim.bits();
for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) {
tx = j - 1;
tx = tx < 0 ? w + tx : tx % w;
ty = i - 1;
ty = ty < 0 ? h + ty : ty % h;
Vector3d p[3], res;
p[0] = colorVector(sim.pixel(j, i));
p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i));
res.y = piClamp(0.5 + (p[0].length() - p[1].length()) / 2., 0., 1.);
res.x = piClamp(0.5 + (p[0].length() - p[2].length()) / 2., 0., 1.);
tx = (j + 1) % w;
ty = (i + 1) % h;
p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i));
res.y = piClamp(0.5 + (p[0].length() - p[1].length()) / 2., 0., 1.);
res.x = piClamp(0.5 + (p[0].length() - p[2].length()) / 2., 0., 1.);
res.z = 1.;
dd[a] = res.z * 255; ++a;
dd[a] = res.x * 255; ++a;
dd[a] = res.y * 255; ++a;
dd[a] = 255; ++a;
}
}
im = dim;
//im.save("_bump.png");
}
Material::Material(): map_reflection(512) {
color_diffuse = color_specular = Qt::white;
color_self_illumination = Qt::black;
glass = false;
transparency = reflectivity = 0.f;
roughness = 0.5f;
iof = 1.f;
dispersion = 0.05f;
specular = 1.f;
}
void Material::apply(QGLShaderProgram * prog) {
if (prog) {
setUniformMaterial(prog, *this);
} else {
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat mat_specular[4] = {0.9f, 0.9f, 0.9f, 1.0f};
GLfloat mat_emission[4] = {0.f, 0.f, 0.f, 1.0f};
mat_diffuse[0] = color_diffuse.redF();
mat_diffuse[1] = color_diffuse.greenF();
mat_diffuse[2] = color_diffuse.blueF();
mat_diffuse[3] = color_diffuse.alphaF() * (1.f - transparency);
mat_specular[0] = specular * color_specular.redF();
mat_specular[1] = specular * color_specular.greenF();
mat_specular[2] = specular * color_specular.blueF();
mat_emission[0] = color_self_illumination.redF();
mat_emission[1] = color_self_illumination.greenF();
mat_emission[2] = color_self_illumination.blueF();
glColor4f(mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, (1. - roughness)*100.);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
}
}
void Material::loadTextures(GLTextureManagerBase * tm) {
//qDebug() << "load textures";
if (tm == 0) tm = (GLTextureManagerBase*)currentGLTextureManager;
if (!map_diffuse.bitmap_path.isEmpty()) map_diffuse.bitmap_id = tm->loadTexture(map_diffuse.bitmap_path);
if (!map_bump.bitmap_path.isEmpty()) map_bump.bitmap_id = tm->loadTexture(map_bump.bitmap_path, true, true);
if (!map_relief.bitmap_path.isEmpty()) map_relief.bitmap_id = tm->loadTexture(map_relief.bitmap_path);
if (!map_roughness.bitmap_path.isEmpty()) map_roughness.bitmap_id = tm->loadTexture(map_roughness.bitmap_path);
if (!map_specular.bitmap_path.isEmpty()) map_specular.bitmap_id = tm->loadTexture(map_specular.bitmap_path);
if (!map_self_illumination.bitmap_path.isEmpty()) map_self_illumination.bitmap_id = tm->loadTexture(map_self_illumination.bitmap_path);
//if (!map_diffuse_2.bitmap_path.isEmpty()) map_diffuse_2.bitmap_id = tm->loadTexture(map_diffuse_2.bitmap_path);
map_reflection.load();
}

136
qglview/glmaterial.h Normal file
View File

@@ -0,0 +1,136 @@
/*
QGLView
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GLMATERIAL_H
#define GLMATERIAL_H
#include "gltypes.h"
class GLTexture {
public:
GLTexture(int _width, int _height, const GLenum & _format = GL_RGBA8, const GLenum & _target = GL_TEXTURE_2D) {wid = _width; hei = _height; format_ = _format; target_ = _target; id_ = 0;}
bool create() {destroy(); createGLTexture(id_, wid, hei, format_, target_); return id_ > 0;}
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;}
void bind() {if (id_ > 0) glBindTexture(target_, id_);}
void release() {glBindTexture(target_, 0);}
int width() const {return wid;}
int height() const {return hei;}
GLenum format() const {return format_;}
GLenum target() const {return target_;}
GLuint id() const {return id_;}
private:
int wid, hei;
GLenum format_, target_;
GLuint id_;
};
class GLCubeTexture {
public:
GLCubeTexture(int _size, const GLenum & _format = GL_RGBA8) {size = _size; format_ = _format; id_ = 0; changed_ = false; pathes.resize(6);}
bool create();
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;}
void bind() {if (changed_) {changed_ = false; create();} if (id_ > 0) glBindTexture(GL_TEXTURE_CUBE_MAP, id_);}
void release() {glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}
void resize(int _size) {size = _size; changed_ = true;}
void loadFromDirectory(const QString & dir);
void loadFront(const QString & path) {bind(); pathes[0] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_X);}
void loadBack(const QString & path) {bind(); pathes[1] = path; createGLTexture(id_, rotateQImageRight(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_X);}
void loadLeft(const QString & path) {bind(); pathes[2] = path; createGLTexture(id_, QImage(path).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);}
void loadRight(const QString & path) {bind(); pathes[3] = path; createGLTexture(id_, rotateQImage180(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Y);}
void loadTop(const QString & path) {bind(); pathes[4] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);}
void loadBottom(const QString & path) {bind(); pathes[5] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Z);}
void load();
bool isEmpty() const {foreach (const QString & i, pathes) if (!i.isEmpty()) return false; return true;}
GLenum format() const {return format_;}
void setFormat(GLenum f) {format_ = f; changed_ = true;}
GLuint id() const {return id_;}
const QString & path(int side) const {return pathes[side];}
void setPath(int side, const QString & p) {pathes[side] = p;}
void loadPathesFromDirectory(const QString & dir);
private:
bool changed_;
int size;
GLenum format_;
GLuint id_;
QVector<QString> pathes;
};
class GLTextureManager;
class GLTextureManagerBase {
public:
static void addSearchPath(const QString & path) {search_pathes << path;}
static QStringList searchPathes() {return search_pathes;}
static GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false);
static GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false);
int textureID(const QString & path, bool bump = false) {return tex_ids[bump ? 1 : 0][path];}
protected:
static void convertToNormal(QImage & im);
static QStringList search_pathes;
QMap<QString, GLuint> tex_ids[2];
};
extern GLTextureManager * currentGLTextureManager;
struct Map {
Map() {bitmap_id = 0; color_amount = 1.f; color_offset = 0.f; animation_frame_rate = -1.f;}
QString bitmap_path;
GLuint bitmap_id;
QPointF bitmap_offset;
float color_amount;
float color_offset;
QString animation;
float animation_frame_rate;
};
struct Material {
Material();
void apply(QGLShaderProgram * prog);
void loadTextures(GLTextureManagerBase * tm = 0);
QString name;
QColor color_diffuse;
QColor color_specular;
QColor color_self_illumination;
bool glass;
float roughness;
float specular;
float transparency;
float reflectivity;
float iof;
float dispersion;
Map map_diffuse;
Map map_bump;
Map map_relief;
Map map_self_illumination;
Map map_roughness;
Map map_specular;
/*Map map_diffuse_2;
Map map_diffuse_3;
Map map_diffuse_4;*/
GLCubeTexture map_reflection;
};
inline QDataStream & operator <<(QDataStream & s, const Map & m) {s << m.bitmap_path << m.color_amount << m.color_offset << m.animation << m.animation_frame_rate; return s;}
inline QDataStream & operator >>(QDataStream & s, Map & m) {s >> m.bitmap_path >> m.color_amount >> m.color_offset >> m.animation >> m.animation_frame_rate; return s;}
inline QDataStream & operator <<(QDataStream & s, const Material & m) {s << m.name << m.color_diffuse << m.color_specular << m.color_self_illumination << m.roughness << m.specular << m.transparency << m.reflectivity << m.glass << m.map_diffuse << m.map_bump << m.map_relief << m.map_specular << m.map_roughness; return s;}
inline QDataStream & operator >>(QDataStream & s, Material & m) {s >> m.name >> m.color_diffuse >> m.color_specular >> m.color_self_illumination >> m.roughness >> m.specular >> m.transparency >> m.reflectivity >> m.glass >> m.map_diffuse >> m.map_bump >> m.map_relief >> m.map_specular >> m.map_roughness; return s;}
#endif // GLMATERIAL_H

View File

@@ -77,8 +77,8 @@ GLObjectBase * GLObjectBase::clone(bool withChildren) {
return o; return o;
} }
void GLObjectBase::draw(bool simplest) { void GLObjectBase::draw(QGLShaderProgram * prog, bool simplest) {
vbo.draw(geom_prim, simplest); vbo.draw(geom_prim, prog, simplest);
/*if (!d_vertices.isEmpty()) { /*if (!d_vertices.isEmpty()) {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData()); glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
@@ -147,7 +147,7 @@ void GLObjectBase::buildTransform() {
itransform_.setToIdentity(); itransform_.setToIdentity();
GLObjectBase * p = parent_; GLObjectBase * p = parent_;
if (p != 0) if (p != 0)
itransform_ *= p->itransform_; itransform_ = p->itransform_;
if (raw_matrix) { if (raw_matrix) {
itransform_.translate(pos_); itransform_.translate(pos_);
itransform_ *= mat_; itransform_ *= mat_;
@@ -159,6 +159,7 @@ void GLObjectBase::buildTransform() {
itransform_.rotate(angles_.x(), 1., 0., 0.); itransform_.rotate(angles_.x(), 1., 0., 0.);
itransform_.scale(scale_); itransform_.scale(scale_);
} }
//qDebug() << name_ << itransform_;
foreach (GLObjectBase * i, children_) foreach (GLObjectBase * i, children_)
i->buildTransform(); i->buildTransform();
} }
@@ -170,29 +171,36 @@ void GLObjectBase::checkPass() {
} }
QMatrix4x4 GLObjectBase::worldMatrix(QMatrix4x4 parent) const {
QMatrix4x4 mat;
mat.translate(pos_);
if (raw_matrix) {
mat *= mat_;
} else {
if (angles_.z() != 0.) mat.rotate(angles_.z(), 0., 0., 1.);
if (angles_.y() != 0.) mat.rotate(angles_.y(), 0., 1., 0.);
if (angles_.x() != 0.) mat.rotate(angles_.x(), 1., 0., 0.);
mat.scale(scale_);
}
return parent * mat;
}
void GLObjectBase::render(int * id, QMap<int, GLObjectBase * > * ids, int sh_id_loc) { void GLObjectBase::render(int * id, QMap<int, GLObjectBase * > * ids, int sh_id_loc) {
if (!visible_) return; if (!visible_) return;
glPushMatrix(); //glPushMatrix();
if (pos_.x() != 0. || pos_.y() != 0. || pos_.z() != 0.) glTranslated(pos_.x(), pos_.y(), pos_.z()); ///qglMultMatrix TODO
if (raw_matrix) { material_.apply(0);
qglMultMatrix(mat_);
} else {
if (angles_.z() != 0.) glRotated(angles_.z(), 0., 0., 1.);
if (angles_.y() != 0.) glRotated(angles_.y(), 0., 1., 0.);
if (angles_.x() != 0.) glRotated(angles_.x(), 1., 0., 0.);
if (scale_.x() != 1. || scale_.y() != 1. || scale_.z() != 1.) glScaled(scale_.x(), scale_.y(), scale_.z());
}
material_.apply();
if (id != 0) { if (id != 0) {
++(*id); ++(*id);
ids->insert(*id, this); ids->insert(*id, this);
//glVertexAttrib1f(sh_id_loc, (*id) / 255.f); //glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
//qDebug() << "assign to" << sh_id_loc << (*id) / 255.f; //qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
} }
draw(); draw(0);
foreach (GLObjectBase * i, children_) foreach (GLObjectBase * i, children_)
i->render(id, ids, sh_id_loc); i->render(id, ids, sh_id_loc);
glPopMatrix(); //glPopMatrix();
} }
@@ -217,7 +225,7 @@ GLObjectBase * Light::clone(bool withChildren) {
} }
void Light::draw(bool simplest) { void Light::draw(QGLShaderProgram * prog, bool simplest) {
bool l = glIsEnabled(GL_LIGHTING); bool l = glIsEnabled(GL_LIGHTING);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glPointSize(8.); glPointSize(8.);

View File

@@ -21,6 +21,7 @@
#include "glvbo.h" #include "glvbo.h"
#include "glframebuffer.h" #include "glframebuffer.h"
#include "glmaterial.h"
class GLObjectBase class GLObjectBase
{ {
@@ -41,7 +42,7 @@ public:
void setName(const QString & name) {name_ = name;} void setName(const QString & name) {name_ = name;}
//virtual GLuint hList() {return list;} //virtual GLuint hList() {return list;}
virtual void init() {calculateBoundingBox(); vbo.init(); vbo.rebuffer(); /*material_.reflection.create();*/ /*qDebug() << "init" << vbo.buffer_;*/ is_init = true;} virtual void init() {calculateBoundingBox(); vbo.init(); vbo.rebuffer(); /*material_.reflection.create();*/ /*qDebug() << "init" << vbo.buffer_;*/ is_init = true;}
virtual void draw(bool simplest = false); virtual void draw(QGLShaderProgram * prog, bool simplest = false);
virtual void update() {} virtual void update() {}
bool isInit() const {return is_init;} bool isInit() const {return is_init;}
bool isTexturesLoaded() const {return is_tex_loaded;} bool isTexturesLoaded() const {return is_tex_loaded;}
@@ -180,6 +181,7 @@ protected:
void initInternal() {init(); loadTextures(); foreach (GLObjectBase * i, children_) i->initInternal();} void initInternal() {init(); loadTextures(); foreach (GLObjectBase * i, children_) i->initInternal();}
void render(int * id = 0, QMap<int, GLObjectBase * > * ids = 0, int sh_id_loc = 0); void render(int * id = 0, QMap<int, GLObjectBase * > * ids = 0, int sh_id_loc = 0);
void checkPass(); void checkPass();
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
int pass_; // Pass int pass_; // Pass
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix; bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix;
@@ -214,7 +216,7 @@ public:
Light(const QVector3D & p, const QColor & c = Qt::white, GLdouble i = 1.): GLObjectBase(), shadow_map(true, 1, GL_R16F) {type_ = GLObjectBase::Light; light_type = Omni; pos_ = p; intensity = i; /*color_ = c;*/ decay_linear = decay_quadratic = angle_spread = angle_decay_exp = decay_start = 0.; decay_const = decay_end = 1.; direction.setZ(1.);} Light(const QVector3D & p, const QColor & c = Qt::white, GLdouble i = 1.): GLObjectBase(), shadow_map(true, 1, GL_R16F) {type_ = GLObjectBase::Light; light_type = Omni; pos_ = p; intensity = i; /*color_ = c;*/ decay_linear = decay_quadratic = angle_spread = angle_decay_exp = decay_start = 0.; decay_const = decay_end = 1.; direction.setZ(1.);}
virtual GLObjectBase * clone(bool withChildren = true); virtual GLObjectBase * 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;}
virtual void draw(bool simplest = false); virtual void draw(QGLShaderProgram * prog, bool simplest = false);
QVector3D direction; QVector3D direction;
GLdouble angle_spread; GLdouble angle_spread;

View File

@@ -107,7 +107,7 @@ void GLParticlesSystem::update() {
} }
void GLParticlesSystem::draw(bool) { void GLParticlesSystem::draw(QGLShaderProgram * prog, bool) {
if (particles.isEmpty()) return; if (particles.isEmpty()) return;
if (view_ == 0) return; if (view_ == 0) return;
pass_ = GLObjectBase::Transparent; pass_ = GLObjectBase::Transparent;

View File

@@ -47,7 +47,7 @@ public:
}; };
void update(); void update();
void draw(bool); void draw(QGLShaderProgram * prog, bool);
float birthRate() const {return birthRate_;} float birthRate() const {return birthRate_;}
float lifeDuration() const {return lifeDuration_;} float lifeDuration() const {return lifeDuration_;}

View File

@@ -19,7 +19,7 @@
#include "glprimitives.h" #include "glprimitives.h"
void GLPrimitivePoint::draw(bool simplest) { void GLPrimitivePoint::draw(QGLShaderProgram * prog, bool simplest) {
glPointSize(sz); glPointSize(sz);
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF()); glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
glBegin(GL_POINTS); glBegin(GL_POINTS);
@@ -29,7 +29,7 @@ void GLPrimitivePoint::draw(bool simplest) {
void GLPrimitiveLine::draw(bool simplest) { void GLPrimitiveLine::draw(QGLShaderProgram * prog, bool simplest) {
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF()); glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex3d(p0.x(), p0.y(), p0.z()); glVertex3d(p0.x(), p0.y(), p0.z());

View File

@@ -26,7 +26,7 @@ class GLPrimitivePoint: public GLObjectBase
{ {
public: public:
GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) {sz = 8.;} GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) {sz = 8.;}
virtual void draw(bool simplest = false); virtual void draw(QGLShaderProgram * prog, bool simplest = false);
private: private:
double sz; double sz;
}; };
@@ -38,7 +38,7 @@ class GLPrimitiveLine: public GLObjectBase
{ {
public: public:
GLPrimitiveLine(QVector3D p0_ = QVector3D(), QVector3D p1_ = QVector3D()) {p0 = p0_; p1 = p1_;} GLPrimitiveLine(QVector3D p0_ = QVector3D(), QVector3D p1_ = QVector3D()) {p0 = p0_; p1 = p1_;}
virtual void draw(bool simplest = false); virtual void draw(QGLShaderProgram * prog, bool simplest = false);
QVector3D point0() const {return p0;} QVector3D point0() const {return p0;}
QVector3D point1() const {return p1;} QVector3D point1() const {return p1;}
void setPoint0(const QVector3D & p) {p0 = p;} void setPoint0(const QVector3D & p) {p0 = p;}

224
qglview/glrendererbase.cpp Normal file
View File

@@ -0,0 +1,224 @@
/*
QGLView
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "glrendererbase.h"
#include "globject.h"
#include "qglview.h"
GLRendererBase::GLRendererBase(QGLView * view_): view(*view_) {
white_image = QImage(1, 1, QImage::Format_ARGB32);
white_image.fill(0xFFFFFFFF);
white_image_id = 0;
}
void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index) {
QVector3D lp = l.worldPos(), ld = (l.itransform_ * QVector4D(l.direction, 0.)).toVector3D().normalized();
GLfloat pos[] = {0.f, 0.f, 0.f, 0.f};
GLfloat dir[] = {0.f, 0.f, 0.f};
GLfloat col[] = {0.f, 0.f, 0.f};
pos[0] = l.light_type == Light::Directional ? -l.direction.x() : lp.x();
pos[1] = l.light_type == Light::Directional ? -l.direction.y() : lp.y();
pos[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z();
pos[3] = l.light_type == Light::Directional ? 0. : 1.;
dir[0] = ld.x();
dir[1] = ld.y();
dir[2] = ld.z();
col[0] = l.visible_ ? l.color().redF() * l.intensity : 0.;
col[1] = l.visible_ ? l.color().greenF() * l.intensity : 0.;
col[2] = l.visible_ ? l.color().blueF() * l.intensity : 0.;
glEnable(gl_index);
//glLightfv(gl_index, GL_AMBIENT, ambient);
glLightfv(gl_index, GL_DIFFUSE, col);
glLightfv(gl_index, GL_SPECULAR, col);
glLightfv(gl_index, GL_POSITION, pos);
glLightf(gl_index, GL_CONSTANT_ATTENUATION, l.decay_const);
glLightf(gl_index, GL_LINEAR_ATTENUATION, l.decay_linear);
glLightf(gl_index, GL_QUADRATIC_ATTENUATION, l.decay_quadratic);
if (l.light_type == Light::Cone) {
glLightfv(gl_index, GL_SPOT_DIRECTION, dir);
glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_spread);
glLightf(gl_index, GL_SPOT_EXPONENT, l.angle_decay_exp);
} else {
glLightf(gl_index, GL_SPOT_CUTOFF, 180.);
}
}
void GLRendererBase::setupAmbientLight(const QColor & a, bool first_pass) {
GLfloat ambient[] = {0.0f, 0.0f, 0.0f, 1.f};
if (first_pass) {
ambient[0] = view.ambientColor_.redF();
ambient[1] = view.ambientColor_.greenF();
ambient[2] = view.ambientColor_.blueF();
}
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
}
void GLRendererBase::setupShadersLights(int lights_count) {
/*foreach (QGLShaderProgram * i, view.shaders_ppl) {
i->bind();
i->setUniformValue("lightsCount", lights_count);
i->setUniformValue("acc_light", lights_count > 0);
//i->setUniformValue("mat", mvm);
}*/
}
#define BIND_TEXTURE(ch, map) if (rp.prev_tex[ch] != mat.map.bitmap_id) { \
rp.prev_tex[ch] = mat.map.bitmap_id; \
glActiveTextureChannel(ch); glBindTexture(GL_TEXTURE_2D, mat.map.bitmap_id); \
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);}
void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingParameters & rp, bool first_object) {
if (first_object) {
glReleaseTextures();
return;
}
setupShadersTextures(o, rp);
Material & mat(o.material_);
if (rp.light) {
if (o.accept_light) {if (!rp.prev_light) {glSetLightEnabled(true); rp.prev_light = true;}}
else {if (rp.prev_light) {glSetLightEnabled(false); rp.prev_light = false;}}
}
if (rp.fog) {
if (o.accept_fog) {if (!rp.prev_fog) {glSetFogEnabled(true); rp.prev_fog = true;}}
else {if (rp.prev_fog) {glSetFogEnabled(false); rp.prev_fog = false;}}
}
if (rp.textures) {
BIND_TEXTURE(0, map_diffuse);
BIND_TEXTURE(1, map_bump);
BIND_TEXTURE(2, map_relief);
BIND_TEXTURE(3, map_self_illumination);
BIND_TEXTURE(4, map_roughness);
BIND_TEXTURE(5, map_specular);
glActiveTextureChannel(0);
}
}
#undef BIND_TEXTURE
void GLRendererBase::setupLights(int pass, int lights_per_pass) {
int light_start, light_end, lmax;
light_start = pass * lights_per_pass;
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights_.size());
setupAmbientLight(view.ambientColor_, pass == 0);
if (!view.lights_.isEmpty()) {
setupShadersLights(light_end - light_start);
for (int i = light_start; i < light_end; ++i)
setupLight(*view.lights_[i], i - light_start, GL_LIGHT0 + i - light_start);
lmax = light_start + 8;
for (int i = light_end; i < lmax; ++i)
glDisable(GL_LIGHT0 + i - light_start);
} else {
setupShadersLights(0);
for (int i = 0; i < 8; ++i)
glDisable(GL_LIGHT0 + i);
}
}
void GLRendererBase::applyFilteringParameters() {
if (view.linearFiltering_) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
}
void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, bool textures, bool light, bool fog) {
RenderingParameters rp;
rp.pass = pass;
rp.light_pass = light_pass;
rp.shaders = shaders;
rp.textures = textures;
rp.light = rp.prev_light = light;
rp.fog = rp.prev_fog = fog;
rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
//qDebug() << "view:" << rp.view_matrix;
for (int i = 0; i < 32; ++i) rp.prev_tex[i] = 0;
setupTextures(view.objects_, rp, true);
glSetLightEnabled(rp.prev_light);
glSetFogEnabled(rp.prev_fog);
glSetCapEnabled(GL_TEXTURE_2D, rp.textures);
glSetCapEnabled(GL_BLEND, pass == GLObjectBase::Transparent);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_CUBE_MAP);
glPushMatrix();
renderSingleObject(view.objects_, rp);
glPopMatrix();
}
void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rp) {
if (!o.isInit())
o.init();
if (!o.isTexturesLoaded())
o.loadTextures();
if (!o.visible_) return;
if (rp.pass == o.pass_) {
Material & mat(o.material_);
QMatrix4x4 curview = rp.view_matrix * o.itransform_;
setupTextures(o, rp, false);
mat.apply((QGLShaderProgram*)rp.shaders);
glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
glLineWidth(o.line_width > 0. ? o.line_width : view.lineWidth_);
glPointSize(o.line_width > 0. ? o.line_width : view.lineWidth_);
o.update();
if (o.pass_ == GLObjectBase::Transparent) {
glActiveTextureChannel(3);
if (mat.reflectivity > 0.) {
glEnable(GL_TEXTURE_CUBE_MAP);
if (!mat.map_reflection.isEmpty()) mat.map_reflection.bind();
else glDisable(GL_TEXTURE_CUBE_MAP);
} else glDisable(GL_TEXTURE_CUBE_MAP);
if (rp.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP);
GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity};
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, bc);
glGetFloatv(GL_MODELVIEW_MATRIX, gm);
glMatrixMode(GL_TEXTURE);
glLoadTransposeMatrixf(gm);
glScalef(-1., -1., -1.);
glMatrixMode(GL_MODELVIEW);
glActiveTextureChannel(0);
}
if (rp.shaders) {
//qDebug() << o.name() << curview << curview.determinant();
setUniformMatrices((QGLShaderProgram*)rp.shaders, rp.proj_matrix, curview);
} else {
glMatrixMode(GL_MODELVIEW);
setGLMatrix(curview);
}
o.draw((QGLShaderProgram*)rp.shaders);
}
foreach (GLObjectBase * i, o.children_)
renderSingleObject(*i, rp);
}

68
qglview/glrendererbase.h Normal file
View File

@@ -0,0 +1,68 @@
/*
QGLView
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GLRENDERERBASE_H
#define GLRENDERERBASE_H
#include "glshaders.h"
class GLRendererBase: public QObject
{
friend class QGLView;
Q_OBJECT
public:
GLRendererBase(QGLView * view_);
virtual void renderScene() = 0;
protected:
struct RenderingParameters {
int pass;
int light_pass;
bool light;
bool fog;
bool textures;
bool prev_light;
bool prev_fog;
GLuint prev_tex[32];
void * shaders;
QMatrix4x4 view_matrix;
QMatrix4x4 proj_matrix;
QGLShaderProgram * cur_shader;
};
virtual void setupLight(const Light & l, int inpass_index, int gl_index);
virtual void setupAmbientLight(const QColor & a, bool first_pass);
virtual void setupShadersLights(int lights_count);
virtual void setupTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp, bool first_object = false);
virtual void setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) {}
virtual void reloadShaders() {}
virtual void init(int width, int height) {}
virtual void resize(int width, int height) {}
void setupLights(int pass, int lights_per_pass);
inline void applyFilteringParameters();
void renderObjects(int pass, int light_pass, void * shaders = 0, bool textures = true, bool light = true, bool fog = true);
void renderSingleObject(GLObjectBase & o, RenderingParameters & rp);
QGLView & view;
QImage white_image;
GLuint white_image_id;
};
#endif // GLRENDERERBASE_H

211
qglview/glshaders.cpp Normal file
View File

@@ -0,0 +1,211 @@
/*
QGLView
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gltypes.h"
#include "qglview.h"
const char qgl_vertex_head[] =
"in vec3 _qgl_Vertex;\n"
"in vec3 qgl_Normal;\n"
"in vec2 qgl_Texture;\n"
"in vec4 qgl_Color;\n"
"out vec2 qgl_FragTexture;\n"
"out vec4 qgl_FragColor;\n"
"vec4 qgl_Vertex = vec4(_qgl_Vertex, 1.);\n"
"vec4 qgl_ftransform() {return qgl_ModelViewProjectionMatrix * qgl_Vertex;}\n";
const char qgl_fragment_head[] =
"in vec2 qgl_FragTexture;\n"
"in vec4 qgl_FragColor;\n"
"out vec4 qgl_FragData[gl_MaxDrawBuffers];\n";
const char qgl_uniform[] =
"uniform mat4 qgl_ModelViewMatrix;\n"
"uniform mat4 qgl_ProjectionMatrix;\n"
"uniform mat4 qgl_ModelViewProjectionMatrix;\n"
"uniform mat3 qgl_NormalMatrix;\n"
"uniform mat4 qgl_ModelViewMatrixInverse;\n"
"uniform mat4 qgl_ProjectionMatrixInverse;\n"
"uniform mat4 qgl_ModelViewProjectionMatrixInverse;\n"
"uniform mat4 qgl_ModelViewMatrixTranspose;\n"
"uniform mat4 qgl_ProjectionMatrixTranspose;\n"
"uniform mat4 qgl_ModelViewProjectionMatrixTranspose;\n"
"uniform mat4 qgl_ModelViewMatrixInverseTranspose;\n"
"uniform mat4 qgl_ProjectionMatrixInverseTranspose;\n"
"uniform mat4 qgl_ModelViewProjectionMatrixInverseTranspose;\n";
const char qgl_structs[] =
"const int qgl_MaxLights = 16;\n"
"struct QGLLight {\n"
" vec4 position;\n"
" vec4 color;\n"
" float intensity;\n"
" float constantAttenuation;\n"
" float linearAttenuation;\n"
" float quadraticAttenuation;\n"
"};\n"
"struct QGLMap {\n"
" float offset;\n"
" float amount;\n"
" sampler2D map;\n"
"};\n"
"struct QGLMaterial {\n"
" float roughness;\n"
" float specular;\n"
" float transparency;\n"
" float reflectivity;\n"
" float iof;\n"
" float dispersion;\n"
" vec4 color_diffuse;\n"
" vec4 color_specular;\n"
" vec4 color_self_illumination;\n"
" QGLMap map_diffuse;\n"
" QGLMap map_bump;\n"
" QGLMap map_relief;\n"
" QGLMap map_self_illumination;\n"
" QGLMap map_roughness;\n"
" QGLMap map_specular;\n"
"};\n"
"uniform QGLLight qgl_AmbientLight;\n"
"uniform QGLLight qgl_Light[qgl_MaxLights];\n"
"uniform QGLMaterial qgl_Material;\n";
QString loadShaderFile(QGLShaderProgram * prog, QGLShader::ShaderType type, const QString & file) {
QFile f(file);
if (!f.open(QIODevice::ReadOnly)) return "";
QString all = QString::fromUtf8(f.readAll());
int i = all.indexOf("#version");
QString version = all.mid(i + 8, all.indexOf("\n", i) - i - 8).trimmed();
if (version.toInt() >= 150) {
int ip = all.indexOf("\n", i);
if (ip < 0) return all;
if (type == QGLShader::Vertex) {
all.insert(ip + 1, qgl_vertex_head);
}
if (type == QGLShader::Fragment) {
all.insert(ip + 1, qgl_fragment_head);
}
all.insert(ip + 1, qgl_structs);
all.insert(ip + 1, qgl_uniform);
}
prog->addShaderFromSourceCode(type, all);
//qDebug() << "********" << all;
return all;
}
bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & dir) {
prog->removeAllShaders();
QDir d(dir);
QFileInfoList sl;
//qDebug() << "[QGLView] Shader \"" + name + "\" load shaders from" << d.absolutePath();
#if QT_VERSION >= 0x040700
sl = d.entryInfoList(QStringList(name + ".geom"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) {
qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName();
loadShaderFile(prog, QGLShader::Geometry, i.absoluteFilePath());
}
#endif
sl = d.entryInfoList(QStringList(name + ".vert"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
loadShaderFile(prog, QGLShader::Vertex, i.absoluteFilePath());
}
sl = d.entryInfoList(QStringList(name + ".frag"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName();
loadShaderFile(prog, QGLShader::Fragment, i.absoluteFilePath());
}
if (!prog->link()) {
//qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log();
return false;
}
return true;
}
void setUniformMatrices(QGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view) {
QMatrix4x4 mvpm = proj * view;
QMatrix3x3 nm = view.normalMatrix();
prog->setUniformValue("qgl_ModelViewMatrix", view);
prog->setUniformValue("qgl_ProjectionMatrix", proj);
prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm);
prog->setUniformValue("qgl_NormalMatrix", nm);
prog->setUniformValue("qgl_ModelViewMatrixTranspose", view.transposed());
prog->setUniformValue("qgl_ProjectionMatrixTranspose", proj.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed());
}
void setUniformMap(QGLShaderProgram * prog, QString map_name, const Map & map, int channel) {
prog->setUniformValue(("qgl_Material." + map_name + ".offset").toLatin1().constData(), map.color_offset);
prog->setUniformValue(("qgl_Material." + map_name + ".amount").toLatin1().constData(), map.color_amount);
prog->setUniformValue(("qgl_Material." + map_name + ".map").toLatin1().constData(), map.bitmap_id > 0 ? channel : 6);
}
void setUniformMaterial(QGLShaderProgram * prog, const Material & mat) {
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
mat_diffuse[0] = mat.color_diffuse.redF();
mat_diffuse[1] = mat.color_diffuse.greenF();
mat_diffuse[2] = mat.color_diffuse.blueF();
mat_diffuse[3] = mat.color_diffuse.alphaF() * (1.f - mat.transparency);
glVertexAttrib4f(prog->attributeLocation("qgl_Color"), mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
prog->setUniformValue("qgl_Material.roughness", mat.roughness);
prog->setUniformValue("qgl_Material.specular", mat.specular);
prog->setUniformValue("qgl_Material.transparency", mat.transparency);
prog->setUniformValue("qgl_Material.reflectivity", mat.reflectivity);
prog->setUniformValue("qgl_Material.iof", mat.iof);
prog->setUniformValue("qgl_Material.dispersion", mat.dispersion);
prog->setUniformValue("qgl_Material.color_diffuse", mat.color_diffuse);
prog->setUniformValue("qgl_Material.color_self_illumination", mat.color_self_illumination);
prog->setUniformValue("qgl_Material.color_specular", mat.color_specular);
setUniformMap(prog, "map_diffuse", mat.map_diffuse, 0);
setUniformMap(prog, "map_bump", mat.map_bump, 1);
setUniformMap(prog, "map_relief", mat.map_relief, 2);
setUniformMap(prog, "map_self_illumination", mat.map_self_illumination, 3);
setUniformMap(prog, "map_roughness", mat.map_roughness, 4);
setUniformMap(prog, "map_specular", mat.map_specular, 5);
}
void setUniformLights(QGLShaderProgram * prog, const QVector<Light*> & lights, const QMatrix4x4 & mat) {
for (int i = 0; i < lights.size(); ++i)
setUniformLight(prog, lights[i], QString("qgl_Light[%1]").arg(i), mat);
}
/*
" vec3 position;\n"
" vec4 color;\n"
" float intensity;\n"
" float constantAttenuation;\n"
" float linearAttenuation;\n"
" float quadraticAttenuation;\n"
*/
void setUniformLight(QGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat) {
QVector4D pos(light->worldPos(), 1.);
pos = mat * pos;
//qDebug() << "light" << light->name() << ulightn << pos;
prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos);
prog->setUniformValue((ulightn + ".intensity").toLatin1().constData(), GLfloat(light->intensity));
prog->setUniformValue((ulightn + ".color").toLatin1().constData(), light->color());
prog->setUniformValue((ulightn + ".constantAttenuation").toLatin1().constData(), GLfloat(light->decay_const));
prog->setUniformValue((ulightn + ".linearAttenuation").toLatin1().constData(), GLfloat(light->decay_linear));
prog->setUniformValue((ulightn + ".quadraticAttenuation").toLatin1().constData(), GLfloat(light->decay_quadratic));
}

36
qglview/glshaders.h Normal file
View File

@@ -0,0 +1,36 @@
/*
QGLView
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GLSHADERS_H
#define GLSHADERS_H
#include "gltypes.h"
class Map;
class Material;
class Light;
QString loadShaderFile(QGLShaderProgram * prog, QGLShader::ShaderType type, const QString & file);
bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & dir = QString());
void setUniformMatrices(QGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view);
void setUniformMap(QGLShaderProgram * prog, const Map & map, int channel);
void setUniformMaterial(QGLShaderProgram * prog, const Material & mat);
void setUniformLights(QGLShaderProgram * prog, const QVector<Light*> & lights, const QMatrix4x4 & mat);
void setUniformLight(QGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat);
#endif // GLSHADERS_H

View File

@@ -19,7 +19,7 @@
#ifndef GLTEXTUREMANAGER_H #ifndef GLTEXTUREMANAGER_H
#define GLTEXTUREMANAGER_H #define GLTEXTUREMANAGER_H
#include "gltypes.h" #include "glmaterial.h"
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>

View File

@@ -20,11 +20,9 @@
#include "qglview.h" #include "qglview.h"
QGLWidget * currentQGLView; QGLWidget * currentQGLView;
GLTextureManager * currentGLTextureManager;
Camera * currentCamera; Camera * currentCamera;
QMatrix4x4 globCameraMatrix; QMatrix4x4 globCameraMatrix;
QMutex globMutex; QMutex globMutex;
QStringList GLTextureManagerBase::search_pathes(".");
QString readCharsUntilNull(QDataStream & s) { QString readCharsUntilNull(QDataStream & s) {
@@ -74,7 +72,17 @@ QMatrix4x4 getGLMatrix(GLenum matrix) {
qreal qm[16]; qreal qm[16];
for (int i = 0; i < 16; ++i) for (int i = 0; i < 16; ++i)
qm[i] = gm[i]; qm[i] = gm[i];
return QMatrix4x4(qm, 4, 4).transposed(); return QMatrix4x4(qm).transposed();
}
void setGLMatrix(QMatrix4x4 matrix) {
GLfloat gm[16];
qreal qm[16];
matrix.transposed().copyDataTo(qm);
for (int i = 0; i < 16; ++i)
gm[i] = qm[i];
glLoadMatrixf(gm);
} }
@@ -129,33 +137,16 @@ void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format,
} }
bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & dir) { QMatrix4x4 glMatrixPerspective(double angle, double aspect, double near_, double far_) {
prog->removeAllShaders(); QMatrix4x4 ret;
QDir d(dir); double t = 1. / (tan(angle * deg2rad / 2.));
QFileInfoList sl; ret(0, 0) = t / aspect;
//qDebug() << "[QGLView] Shader \"" + name + "\" load shaders from" << d.absolutePath(); ret(1, 1) = t;
#if QT_VERSION >= 0x040700 ret(2, 2) = far_ / (far_ - near_) - 1.;
sl = d.entryInfoList(QStringList(name + ".geom"), QDir::Files | QDir::NoDotAndDotDot); ret(2, 3) = 2. * far_ * near_ / (far_ - near_);
foreach (const QFileInfo & i, sl) { ret(3, 2) = -1;
qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName(); ret(3, 3) = 0.;
prog->addShaderFromSourceFile(QGLShader::Geometry, i.absoluteFilePath()); return ret;
}
#endif
sl = d.entryInfoList(QStringList(name + ".vert"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
prog->addShaderFromSourceFile(QGLShader::Vertex, i.absoluteFilePath());
}
sl = d.entryInfoList(QStringList(name + ".frag"), QDir::Files | QDir::NoDotAndDotDot);
foreach (const QFileInfo & i, sl) {
//qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName();
prog->addShaderFromSourceFile(QGLShader::Fragment, i.absoluteFilePath());
}
if (!prog->link()) {
//qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log();
return false;
}
return true;
} }
@@ -180,158 +171,6 @@ QImage rotateQImageRight(const QImage & im) {
bool GLCubeTexture::create() {
//qDebug("create");
destroy();
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_CUBE_MAP, id_);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
//glClearError();
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//qDebug() << glGetError();
changed_ = false;
return id_ > 0;
}
void GLCubeTexture::load() {
if (isEmpty()) return;
create();
if (!path(0).isEmpty()) loadFront(path(0));
if (!path(1).isEmpty()) loadBack(path(1));
if (!path(2).isEmpty()) loadLeft(path(2));
if (!path(3).isEmpty()) loadRight(path(3));
if (!path(4).isEmpty()) loadTop(path(4));
if (!path(5).isEmpty()) loadBottom(path(5));
}
void GLCubeTexture::loadFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl;
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBack(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadLeft(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadRight(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadTop(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBottom(sl[0].absoluteFilePath());
}
void GLCubeTexture::loadPathesFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl;
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[1] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[2] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[3] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[4] = sl[0].absoluteFilePath();
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[5] = sl[0].absoluteFilePath();
}
GLuint GLTextureManagerBase::loadTexture(const QString & path, bool ownership, bool bump) {
QString p = findFile(path, search_pathes);
if (p.isEmpty()) return 0;
int tid = ((GLTextureManagerBase*)currentGLTextureManager)->textureID(p, bump);
if (tid > 0) {
//qDebug() << "[TextureManager] Found" << path << "as" << tid;
return tid;
}
QImage image(p);
if (bump) convertToNormal(image);
//qDebug() << p << image.width() << image.height() << image.format() << bump;
tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, QGLContext::MipmapBindOption*/);
if (tid == 0) {
qDebug() << "[TextureManager] Can`t load" << p;
return tid;
}
qDebug() << "[TextureManager] Loaded" << p << "as" << tid;
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids[bump ? 1 : 0].insert(p, tid);
return tid;
}
GLuint GLTextureManagerBase::loadTexture(const QImage & im, bool ownership, bool bump) {
if (im.isNull()) return 0;
QImage image(im);
if (bump) convertToNormal(image);
GLuint tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D);
if (tid == 0) {
qDebug() << "[TextureManager] Can`t load image";
return tid;
}
//qDebug() << "[TextureManager] Loaded image as" << tid;
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids[bump ? 1 : 0].insert(QString(), tid);
return tid;
}
Vector3d colorVector(QRgb c) {return Vector3d(((uchar*)(&c))[0] / 255., ((uchar*)(&c))[1] / 255., ((uchar*)(&c))[2] / 255.);}
void GLTextureManagerBase::convertToNormal(QImage & im) {
if (im.isNull()) return;
QImage sim = im.convertToFormat(QImage::Format_ARGB32);
double sum[3] = {0., 0., 0.};
llong a = 0;
const uchar * sd = sim.constBits();
for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) {
sum[2] += double(sd[a]) / 255. - 0.5; ++a;
sum[1] += double(sd[a]) / 255. - 0.5; ++a;
sum[0] += double(sd[a]) / 255. - 0.5; ++a;
++a;
}
}
double wh = sim.width() * sim.height();
sum[0] /= wh;
sum[1] /= wh;
sum[2] /= wh;
qDebug() << sum[0] << sum[1] << sum[2];
if ((qAbs(sum[0]) <= 0.05) && (qAbs(sum[1]) <= 0.05) && (sum[2] >= 0.4)) /// already normal
return;
qDebug() << "convert to bump";
QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32);
int tx, ty, w = sim.width(), h = sim.height();
a = 0;
uchar * dd = dim.bits();
for (int i = 0; i < sim.height(); i++) {
for (int j = 0; j < sim.width(); j++) {
tx = j - 1;
tx = tx < 0 ? w + tx : tx % w;
ty = i - 1;
ty = ty < 0 ? h + ty : ty % h;
Vector3d p[3], res;
p[0] = colorVector(sim.pixel(j, i));
p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i));
res.y = piClamp(0.5 + (p[0].length() - p[1].length()) / 2., 0., 1.);
res.x = piClamp(0.5 + (p[0].length() - p[2].length()) / 2., 0., 1.);
tx = (j + 1) % w;
ty = (i + 1) % h;
p[1] = colorVector(sim.pixel(j, ty));
p[2] = colorVector(sim.pixel(tx, i));
res.y = piClamp(0.5 + (p[0].length() - p[1].length()) / 2., 0., 1.);
res.x = piClamp(0.5 + (p[0].length() - p[2].length()) / 2., 0., 1.);
res.z = 1.;
dd[a] = res.z * 255; ++a;
dd[a] = res.x * 255; ++a;
dd[a] = res.y * 255; ++a;
dd[a] = 255; ++a;
}
}
im = dim;
//im.save("_bump.png");
}
void Camera::anglesFromPoints() { void Camera::anglesFromPoints() {
QVector3D dv = aim_ - pos_, tv; QVector3D dv = aim_ - pos_, tv;
@@ -346,7 +185,10 @@ void Camera::apply(const GLdouble & aspect) {
glLoadIdentity(); glLoadIdentity();
if (aspect <= 1.) if (aspect <= 1.)
glScaled(aspect, aspect, 1.); glScaled(aspect, aspect, 1.);
gluPerspective(fov_, aspect, depth_start, depth_end); QMatrix4x4 pm;// = glMatrixPerspective(fov_, aspect, depth_start, depth_end);
pm.perspective(fov_, aspect, depth_start, depth_end);
//qDebug() << pm << glMatrixPerspective(fov_, aspect, depth_start, depth_end);;
setGLMatrix(pm);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
glTranslated(0., 0., -distance()); glTranslated(0., 0., -distance());
@@ -518,53 +360,6 @@ QVector3D Camera::pointFromViewport(int x_, int y_, double z_) {
Material::Material(): reflection(512) {
color_diffuse = color_specular = Qt::white;
color_self_illumination = Qt::black;
glass = false;
transparency = reflectivity = 0.f;
bump_scale = relief_scale = iof = 1.f;
dispersion = 0.05f;
shine = 0.5;
shine_strength = 1.f;
light_model = Phong;
}
void Material::apply() {
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat mat_specular[4] = {0.9f, 0.9f, 0.9f, 1.0f};
GLfloat mat_emission[4] = {0.f, 0.f, 0.f, 1.0f};
mat_diffuse[0] = color_diffuse.redF();
mat_diffuse[1] = color_diffuse.greenF();
mat_diffuse[2] = color_diffuse.blueF();
mat_diffuse[3] = color_diffuse.alphaF() * (1.f - transparency);
mat_specular[0] = shine_strength * color_specular.redF();
mat_specular[1] = shine_strength * color_specular.greenF();
mat_specular[2] = shine_strength * color_specular.blueF();
mat_emission[0] = color_self_illumination.redF();
mat_emission[1] = color_self_illumination.greenF();
mat_emission[2] = color_self_illumination.blueF();
glColor4f(mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
//qDebug() << color_diffuse.alphaF() * (1.f - transparency);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, shine);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
}
void Material::loadTextures(GLTextureManagerBase * tm) {
//qDebug() << "load textures";
if (tm == 0) tm = (GLTextureManagerBase*)currentGLTextureManager;
if (!diffuse.bitmap_path.isEmpty()) diffuse.bitmap_id = tm->loadTexture(diffuse.bitmap_path);
if (!bump.bitmap_path.isEmpty()) bump.bitmap_id = tm->loadTexture(bump.bitmap_path, true, true);
if (!relief.bitmap_path.isEmpty()) relief.bitmap_id = tm->loadTexture(relief.bitmap_path);
if (!diffuse_2.bitmap_path.isEmpty()) diffuse_2.bitmap_id = tm->loadTexture(diffuse_2.bitmap_path);
reflection.load();
}
QColor colorFromString(const QString & str) { QColor colorFromString(const QString & str) {
QString s = str.trimmed(); QString s = str.trimmed();
@@ -632,199 +427,25 @@ Vector3i::Vector3i(const QString & str) {
} }
void glEnableDepth() {
void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index) { glEnable(GL_DEPTH_TEST);
QVector3D lp = l.worldPos(), ld = (l.itransform_ * QVector4D(l.direction, 0.)).toVector3D().normalized(); //glDepthFunc(GL_GREATER);
GLfloat pos[] = {0.f, 0.f, 0.f, 0.f}; glDepthFunc(GL_LESS);
GLfloat dir[] = {0.f, 0.f, 0.f}; glDepthMask(GL_TRUE);
GLfloat col[] = {0.f, 0.f, 0.f};
pos[0] = l.light_type == Light::Directional ? -l.direction.x() : lp.x();
pos[1] = l.light_type == Light::Directional ? -l.direction.y() : lp.y();
pos[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z();
pos[3] = l.light_type == Light::Directional ? 0. : 1.;
dir[0] = ld.x();
dir[1] = ld.y();
dir[2] = ld.z();
col[0] = l.visible_ ? l.color().redF() * l.intensity : 0.;
col[1] = l.visible_ ? l.color().greenF() * l.intensity : 0.;
col[2] = l.visible_ ? l.color().blueF() * l.intensity : 0.;
glEnable(gl_index);
//glLightfv(gl_index, GL_AMBIENT, ambient);
glLightfv(gl_index, GL_DIFFUSE, col);
glLightfv(gl_index, GL_SPECULAR, col);
glLightfv(gl_index, GL_POSITION, pos);
glLightf(gl_index, GL_CONSTANT_ATTENUATION, l.decay_const);
glLightf(gl_index, GL_LINEAR_ATTENUATION, l.decay_linear);
glLightf(gl_index, GL_QUADRATIC_ATTENUATION, l.decay_quadratic);
if (l.light_type == Light::Cone) {
glLightfv(gl_index, GL_SPOT_DIRECTION, dir);
glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_spread);
glLightf(gl_index, GL_SPOT_EXPONENT, l.angle_decay_exp);
} else {
glLightf(gl_index, GL_SPOT_CUTOFF, 180.);
}
} }
void GLRendererBase::setupAmbientLight(const QColor & a, bool first_pass) { void glDisableDepth() {
GLfloat ambient[] = {0.0f, 0.0f, 0.0f, 1.f}; glDisable(GL_DEPTH_TEST);
if (first_pass) { glDepthMask(GL_FALSE);
ambient[0] = view.ambientColor_.redF();
ambient[1] = view.ambientColor_.greenF();
ambient[2] = view.ambientColor_.blueF();
}
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
} }
void GLRendererBase::setupShadersLights(int lights_count) { void glClearFramebuffer(const QColor & color, bool depth) {
/*foreach (QGLShaderProgram * i, view.shaders_ppl) { glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
i->bind(); glClearDepth(1.);
i->setUniformValue("lightsCount", lights_count); if (depth)
i->setUniformValue("acc_light", lights_count > 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//i->setUniformValue("mat", mvm); else
}*/ glClear(GL_COLOR_BUFFER_BIT);
}
void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingParameters & rp, bool first_object) {
if (first_object) {
glReleaseTextures();
return;
}
setupShadersTextures(o, rp);
Material & mat(o.material_);
if (rp.light) {
if (o.accept_light) {if (!rp.prev_light) {glSetLightEnabled(true); rp.prev_light = true;}}
else {if (rp.prev_light) {glSetLightEnabled(false); rp.prev_light = false;}}
}
if (rp.fog) {
if (o.accept_fog) {if (!rp.prev_fog) {glSetFogEnabled(true); rp.prev_fog = true;}}
else {if (rp.prev_fog) {glSetFogEnabled(false); rp.prev_fog = false;}}
}
if (rp.textures) {
if (rp.prev_tex[0] != mat.diffuse.bitmap_id) {
rp.prev_tex[0] = mat.diffuse.bitmap_id;
glActiveTextureChannel(0); glBindTexture(GL_TEXTURE_2D, mat.diffuse.bitmap_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
}
if (rp.prev_tex[1] != mat.bump.bitmap_id) {
rp.prev_tex[1] = mat.bump.bitmap_id;
glActiveTextureChannel(1); glBindTexture(GL_TEXTURE_2D, mat.bump.bitmap_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
}
if (rp.prev_tex[2] != mat.relief.bitmap_id) {
rp.prev_tex[2] = mat.relief.bitmap_id;
glActiveTextureChannel(2); glBindTexture(GL_TEXTURE_2D, mat.relief.bitmap_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
}
glActiveTextureChannel(0);
}
}
void GLRendererBase::setupLights(int pass, int lights_per_pass) {
int light_start, light_end, lmax;
light_start = pass * lights_per_pass;
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights_.size());
setupAmbientLight(view.ambientColor_, pass == 0);
if (!view.lights_.isEmpty()) {
setupShadersLights(light_end - light_start);
for (int i = light_start; i < light_end; ++i)
setupLight(*view.lights_[i], i - light_start, GL_LIGHT0 + i - light_start);
lmax = light_start + 8;
for (int i = light_end; i < lmax; ++i)
glDisable(GL_LIGHT0 + i - light_start);
} else {
setupShadersLights(0);
for (int i = 0; i < 8; ++i)
glDisable(GL_LIGHT0 + i);
}
}
void GLRendererBase::applyFilteringParameters() {
if (view.linearFiltering_) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
}
void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, bool textures, bool light, bool fog) {
RenderingParameters rp;
rp.pass = pass;
rp.light_pass = light_pass;
rp.shaders = shaders;
rp.textures = textures;
rp.light = rp.prev_light = light;
rp.fog = rp.prev_fog = fog;
for (int i = 0; i < 32; ++i) rp.prev_tex[i] = 0;
rp.prev_light_model = Material::Phong;
setupTextures(view.objects_, rp, true);
glSetLightEnabled(rp.prev_light);
glSetFogEnabled(rp.prev_fog);
glSetCapEnabled(GL_TEXTURE_2D, rp.textures);
glSetCapEnabled(GL_BLEND, pass == GLObjectBase::Transparent);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_CUBE_MAP);
renderSingleObject(view.objects_, rp);
}
void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rp) {
if (!o.isInit())
o.init();
if (!o.isTexturesLoaded())
o.loadTextures();
if (!o.visible_) return;
Material & mat(o.material_);
glPushMatrix();
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
if (o.raw_matrix) {
qglMultMatrix(o.mat_);
} else {
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
}
if (rp.pass == o.pass_) {
setupTextures(o, rp, false);
mat.apply();
glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
glLineWidth(o.line_width > 0. ? o.line_width : view.lineWidth_);
glPointSize(o.line_width > 0. ? o.line_width : view.lineWidth_);
o.update();
if (o.pass_ == GLObjectBase::Transparent) {
glActiveTextureChannel(3);
if (mat.reflectivity > 0.) {
glEnable(GL_TEXTURE_CUBE_MAP);
if (!mat.reflection.isEmpty()) mat.reflection.bind();
else glDisable(GL_TEXTURE_CUBE_MAP);
} else glDisable(GL_TEXTURE_CUBE_MAP);
if (rp.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP);
GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity};
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, bc);
glGetFloatv(GL_MODELVIEW_MATRIX, gm);
glMatrixMode(GL_TEXTURE);
glLoadTransposeMatrixf(gm);
glScalef(-1., -1., -1.);
glMatrixMode(GL_MODELVIEW);
glActiveTextureChannel(0);
}
o.draw();
}
foreach (GLObjectBase * i, o.children_)
renderSingleObject(*i, rp);
glPopMatrix();
} }

View File

@@ -140,11 +140,13 @@ inline QColor operator /(const QColor & c, double v) {return QColor(c.red() / v,
inline void qglColor(const QColor & c) {glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());} inline void qglColor(const QColor & c) {glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());}
void qglMultMatrix(const QMatrix4x4 & m); void qglMultMatrix(const QMatrix4x4 & m);
void glEnableDepth();
void glDisableDepth();
inline void glActiveTextureChannel(int channel) {glActiveTexture(GL_TEXTURE0 + channel); glClientActiveTexture(GL_TEXTURE0 + channel);} inline void glActiveTextureChannel(int channel) {glActiveTexture(GL_TEXTURE0 + channel); glClientActiveTexture(GL_TEXTURE0 + channel);}
inline void glResetAllTransforms() {glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity();} inline void glResetAllTransforms() {glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}
inline void glClearError() {int c = 100; while (glGetError() != GL_NO_ERROR && --c > 0) glGetError();} inline void glClearError() {int c = 100; while (glGetError() != GL_NO_ERROR && --c > 0) glGetError();}
inline void glClearAccumulation(const QColor & color = Qt::black) {glClearAccum(color.redF(), color.greenF(), color.blueF(), color.alphaF()); glClear(GL_ACCUM_BUFFER_BIT);} inline void glClearAccumulation(const QColor & color = Qt::black) {glClearAccum(color.redF(), color.greenF(), color.blueF(), color.alphaF()); glClear(GL_ACCUM_BUFFER_BIT);}
inline void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true) {glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); if (depth) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else glClear(GL_COLOR_BUFFER_BIT);} void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true);
inline void glReleaseTextures(int channels = 8) {for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}} inline void glReleaseTextures(int channels = 8) {for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}}
inline void glReleaseFramebuffer() {glBindFramebuffer(GL_FRAMEBUFFER, 0);} inline void glReleaseFramebuffer() {glBindFramebuffer(GL_FRAMEBUFFER, 0);}
inline void glDisableTextures(int channels = 8) {for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP);}} inline void glDisableTextures(int channels = 8) {for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP);}}
@@ -155,15 +157,17 @@ inline void glSetFogEnabled(bool on) {if (on) glEnable(GL_FOG); else glDisable(G
inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);} inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);}
void glDrawQuad(GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f); void glDrawQuad(GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f);
QMatrix4x4 getGLMatrix(GLenum matrix); QMatrix4x4 getGLMatrix(GLenum matrix);
void setGLMatrix(QMatrix4x4 matrix);
inline void deleteGLTexture(GLuint & tex) {if (tex != 0) glDeleteTextures(1, &tex); tex = 0;} inline void deleteGLTexture(GLuint & tex) {if (tex != 0) glDeleteTextures(1, &tex); tex = 0;}
inline void deleteGLFramebuffer(GLuint & fbo) {if (fbo != 0) glDeleteFramebuffers(1, &fbo); fbo = 0;} inline void deleteGLFramebuffer(GLuint & fbo) {if (fbo != 0) glDeleteFramebuffers(1, &fbo); fbo = 0;}
inline void deleteGLRenderbuffer(GLuint & drbo) {if (drbo != 0) glDeleteRenderbuffers(1, &drbo); drbo = 0;} inline void deleteGLRenderbuffer(GLuint & drbo) {if (drbo != 0) glDeleteRenderbuffers(1, &drbo); drbo = 0;}
inline void deleteGLBuffer(GLuint & bo) {if (bo != 0) glDeleteBuffers(1, &bo); bo = 0;} inline void deleteGLBuffer(GLuint & bo) {if (bo != 0) glDeleteBuffers(1, &bo); bo = 0;}
inline void deleteGLVertexArray(GLuint & va) {if (va != 0) glDeleteVertexArrays(1, &va); va = 0;}
void createGLTexture(GLuint & tex, int width, int height, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D); void createGLTexture(GLuint & tex, int width, int height, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D); void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
inline void qglTranslate(const QVector3D & v) {glTranslated(v.x(), v.y(), v.z());} inline void qglTranslate(const QVector3D & v) {glTranslated(v.x(), v.y(), v.z());}
inline void qglScale(const QVector3D & v) {glScaled(v.x(), v.y(), v.z());} inline void qglScale(const QVector3D & v) {glScaled(v.x(), v.y(), v.z());}
bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & dir = QString()); QMatrix4x4 glMatrixPerspective(double angle, double aspect, double near_, double far_);
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);}
@@ -174,76 +178,6 @@ extern QGLWidget * currentQGLView;
extern QMatrix4x4 globCameraMatrix; extern QMatrix4x4 globCameraMatrix;
extern QMutex globMutex; extern QMutex globMutex;
class GLTexture {
public:
GLTexture(int _width, int _height, const GLenum & _format = GL_RGBA8, const GLenum & _target = GL_TEXTURE_2D) {wid = _width; hei = _height; format_ = _format; target_ = _target; id_ = 0;}
bool create() {destroy(); createGLTexture(id_, wid, hei, format_, target_); return id_ > 0;}
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;}
void bind() {if (id_ > 0) glBindTexture(target_, id_);}
void release() {glBindTexture(target_, 0);}
int width() const {return wid;}
int height() const {return hei;}
GLenum format() const {return format_;}
GLenum target() const {return target_;}
GLuint id() const {return id_;}
private:
int wid, hei;
GLenum format_, target_;
GLuint id_;
};
class GLCubeTexture {
public:
GLCubeTexture(int _size, const GLenum & _format = GL_RGBA8) {size = _size; format_ = _format; id_ = 0; changed_ = false; pathes.resize(6);}
bool create();
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;}
void bind() {if (changed_) {changed_ = false; create();} if (id_ > 0) glBindTexture(GL_TEXTURE_CUBE_MAP, id_);}
void release() {glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}
void resize(int _size) {size = _size; changed_ = true;}
void loadFromDirectory(const QString & dir);
void loadFront(const QString & path) {bind(); pathes[0] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_X);}
void loadBack(const QString & path) {bind(); pathes[1] = path; createGLTexture(id_, rotateQImageRight(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_X);}
void loadLeft(const QString & path) {bind(); pathes[2] = path; createGLTexture(id_, QImage(path).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);}
void loadRight(const QString & path) {bind(); pathes[3] = path; createGLTexture(id_, rotateQImage180(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Y);}
void loadTop(const QString & path) {bind(); pathes[4] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);}
void loadBottom(const QString & path) {bind(); pathes[5] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Z);}
void load();
bool isEmpty() const {foreach (const QString & i, pathes) if (!i.isEmpty()) return false; return true;}
GLenum format() const {return format_;}
void setFormat(GLenum f) {format_ = f; changed_ = true;}
GLuint id() const {return id_;}
const QString & path(int side) const {return pathes[side];}
void setPath(int side, const QString & p) {pathes[side] = p;}
void loadPathesFromDirectory(const QString & dir);
private:
bool changed_;
int size;
GLenum format_;
GLuint id_;
QVector<QString> pathes;
};
class GLTextureManager;
class GLTextureManagerBase {
public:
static void addSearchPath(const QString & path) {search_pathes << path;}
static QStringList searchPathes() {return search_pathes;}
static GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false);
static GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false);
int textureID(const QString & path, bool bump = false) {return tex_ids[bump ? 1 : 0][path];}
protected:
static void convertToNormal(QImage & im);
static QStringList search_pathes;
QMap<QString, GLuint> tex_ids[2];
};
extern GLTextureManager * currentGLTextureManager;
class Camera class Camera
{ {
friend class QGLView; friend class QGLView;
@@ -328,44 +262,6 @@ private:
extern Camera * currentCamera; extern Camera * currentCamera;
struct Map {
Map() {bitmap_id = 0; bitmap_amount = 1.f; animation_frame_rate = -1.f;}
QString bitmap_path;
GLuint bitmap_id;
QPointF bitmap_offset;
float bitmap_amount;
QString animation;
float animation_frame_rate;
};
struct Material {
enum LightModel {Phong = 0, CookTorrance = 1, Minnaert = 2, Strauss = 3, OrenNayar = 4};
Material();
QString name;
void apply();
void loadTextures(GLTextureManagerBase * tm = 0);
QColor color_diffuse;
QColor color_specular;
QColor color_self_illumination;
LightModel light_model;
bool glass;
float shine;
float shine_strength;
float transparency;
float reflectivity;
float iof;
float dispersion;
float bump_scale;
float relief_scale;
Map diffuse;
Map bump;
Map relief;
Map diffuse_2;
Map diffuse_3;
Map diffuse_4;
GLCubeTexture reflection;
};
struct Box3D { struct Box3D {
GLfloat x; GLfloat x;
GLfloat y; GLfloat y;
@@ -479,14 +375,10 @@ inline uint qHash(const Vector3i & v) {return v.p0 + v.p1 * 1024 + v.p2 * 1024 *
inline QDebug operator <<(QDebug d, const Vector3d& v) {d.nospace() << "{" << v.x << ", " << v.y << ", " << v.z << "}"; return d.space();} inline QDebug operator <<(QDebug d, const Vector3d& v) {d.nospace() << "{" << v.x << ", " << v.y << ", " << v.z << "}"; return d.space();}
inline QDebug operator <<(QDebug d, const Vector3i & v) {d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}"; return d.space();} 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 Map & m) {s << m.bitmap_path << m.bitmap_amount << m.animation << m.animation_frame_rate; return s;}
inline QDataStream & operator <<(QDataStream & s, const Vector3d & v) {s << v.x << v.y << v.z; return s;} inline QDataStream & operator <<(QDataStream & s, const Vector3d & v) {s << v.x << v.y << v.z; return s;}
inline QDataStream & operator >>(QDataStream & s, Vector3d & v) {s >> v.x >> v.y >> v.z; return s;}
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) {s << v.p0 << v.p1 << v.p2; return s;}
inline QDataStream & operator <<(QDataStream & s, const Material & m) {s << m.color_diffuse << m.shine << m.shine_strength << m.color_specular << m.transparency << m.diffuse << m.bump; return s;} inline QDataStream & operator >>(QDataStream & s, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; return s;}
inline QDataStream & operator >>(QDataStream & s, Map & m) {s >> m.bitmap_path >> m.bitmap_amount >> m.animation >> m.animation_frame_rate; return s;}
inline QDataStream & operator >>(QDataStream & s, Vector3d & v) {s >> v.x >> v.y >> v.z; return s;}
inline QDataStream & operator >>(QDataStream & s, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; return s;}
inline QDataStream & operator >>(QDataStream & s, Material & m) {s >> m.color_diffuse >> m.shine >> m.shine_strength >> m.color_specular >> m.transparency >> m.diffuse >> m.bump; return s;}
QColor colorFromString(const QString & str); QColor colorFromString(const QString & str);
inline double cosABV(const QVector3D & v0, const QVector3D & v1) { inline double cosABV(const QVector3D & v0, const QVector3D & v1) {
@@ -519,45 +411,4 @@ protected:
Camera camera_; Camera camera_;
}; };
class GLRendererBase: public QObject
{
friend class QGLView;
Q_OBJECT
public:
GLRendererBase(QGLView * view_): view(*view_) {}
virtual void renderScene() = 0;
protected:
struct RenderingParameters {
int pass;
int light_pass;
bool light;
bool fog;
bool textures;
bool prev_light;
bool prev_fog;
Material::LightModel prev_light_model;
GLuint prev_tex[32];
void * shaders;
QGLShaderProgram * cur_shader;
};
virtual void setupLight(const Light & l, int inpass_index, int gl_index);
virtual void setupAmbientLight(const QColor & a, bool first_pass);
virtual void setupShadersLights(int lights_count);
virtual void setupTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp, bool first_object = false);
virtual void setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) {}
virtual void reloadShaders() {}
virtual void init(int width, int height) {}
virtual void resize(int width, int height) {}
void setupLights(int pass, int lights_per_pass);
inline void applyFilteringParameters();
void renderObjects(int pass, int light_pass, void * shaders = 0, bool textures = true, bool light = true, bool fog = true);
void renderSingleObject(GLObjectBase & o, RenderingParameters & rp);
QGLView & view;
};
#endif // GLTYPES_H #endif // GLTYPES_H

View File

@@ -21,6 +21,7 @@
GLVBO::GLVBO(GLenum usage_) { GLVBO::GLVBO(GLenum usage_) {
buffer_ = 0; buffer_ = 0;
va_ = 0;
usage = usage_; usage = usage_;
changed = true; changed = true;
} }
@@ -32,12 +33,20 @@ GLVBO::~GLVBO() {
void GLVBO::init() { void GLVBO::init() {
if (!isIinit()) if (!isIinit()) {
//glGenVertexArrays(1, &va_);
glGenBuffers(1, &buffer_); glGenBuffers(1, &buffer_);
}
changed = true; changed = true;
} }
void GLVBO::destroy() {
deleteGLBuffer(buffer_);
//deleteGLVertexArray(va_);
}
bool GLVBO::rebuffer(bool clear_) { bool GLVBO::rebuffer(bool clear_) {
QVector<GLfloat> data; QVector<GLfloat> data;
//data.clear(); //data.clear();
@@ -54,9 +63,12 @@ bool GLVBO::rebuffer(bool clear_) {
data << colors_; data << colors_;
has_colors = true; has_colors = true;
} else has_colors = false; } else has_colors = false;
//glBindVertexArray(va_);
//qDebug() << "load buffer" << data.size() << buffer_;
glBindBuffer(GL_ARRAY_BUFFER, buffer_); glBindBuffer(GL_ARRAY_BUFFER, buffer_);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.constData(), usage); glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.constData(), usage);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
//glBindVertexArray(0);
vert_count = vertices_.size() / 3; vert_count = vertices_.size() / 3;
changed = false; changed = false;
//qDebug() << "rebuff" << buffer_ << vert_count; //qDebug() << "rebuff" << buffer_ << vert_count;
@@ -65,35 +77,76 @@ bool GLVBO::rebuffer(bool clear_) {
} }
void GLVBO::draw(GLenum type, bool simplest) { void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
if (buffer_ == 0 || vert_count == 0) return; if (buffer_ == 0 || vert_count == 0) return;
if (changed) rebuffer(); if (changed) rebuffer();
//qDebug() << "draw" << vert_count; //qDebug() << "draw" << vert_count;
void * offset = (void*)(vert_count * 3 * sizeof(GLfloat)); void * offset = (void*)(vert_count * 3 * sizeof(GLfloat));
//glBindVertexArray(va_);
void * offsets[3] = {0, 0, 0};
if (has_normals) {
offsets[0] = offset;
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
}
if (has_texcoords) {
offsets[1] = offset;
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
}
if (has_colors) {
offsets[2] = offset;
}
glBindBuffer(GL_ARRAY_BUFFER, buffer_); glBindBuffer(GL_ARRAY_BUFFER, buffer_);
glMultiTexCoord3f(GL_TEXTURE2, 0.f, 1.f, 0.f); if (prog) {
glVertexPointer(3, GL_FLOAT, 0, 0); glDisableClientState(GL_VERTEX_ARRAY);
if (!simplest) { glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
int loc = prog->attributeLocation("_qgl_Vertex");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, 0);
loc = prog->attributeLocation("qgl_Normal");
if (has_normals) { if (has_normals) {
glEnableClientState(GL_NORMAL_ARRAY); glEnableVertexAttribArray(loc);
glNormalPointer(GL_FLOAT, 0, offset); glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, offsets[0]);
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat)); } else
} else glDisableClientState(GL_NORMAL_ARRAY); glDisableVertexAttribArray(loc);
loc = prog->attributeLocation("qgl_Texture");
if (has_texcoords) { if (has_texcoords) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableVertexAttribArray(loc);
glTexCoordPointer(2, GL_FLOAT, 0, offset); glVertexAttribPointer(loc, 2, GL_FLOAT, 0, 0, offsets[1]);
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat)); } else
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(loc);
loc = prog->attributeLocation("qgl_Color");
if (has_colors) { if (has_colors) {
glEnableClientState(GL_COLOR_ARRAY); glEnableVertexAttribArray(loc);
glColorPointer(4, GL_FLOAT, 0, offset); glVertexAttribPointer(loc, 4, GL_FLOAT, 0, 0, offsets[2]);
} else glDisableClientState(GL_COLOR_ARRAY); } else
}/* else { glDisableVertexAttribArray(loc);
glDisable(GL_NORMAL_ARRAY); } else {
glDisable(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glDisable(GL_COLOR_ARRAY); glVertexPointer(3, GL_FLOAT, 0, 0);
}*/ if (!simplest) {
if (has_normals) {
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, offset);
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
} else glDisableClientState(GL_NORMAL_ARRAY);
if (has_texcoords) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, offset);
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (has_colors) {
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 0, offset);
} else glDisableClientState(GL_COLOR_ARRAY);
}
}
//qDebug() << "draw" << vert_count << buffer_ << offsets[0] << offsets[1] << offsets[3];
glDrawArrays(type, 0, vert_count); glDrawArrays(type, 0, vert_count);
//qDebug() << "draw" << vert_count << buffer_ << "done";
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }

View File

@@ -31,9 +31,9 @@ public:
//GLVBO & operator =(const GLVBO & o) {return *this;} //GLVBO & operator =(const GLVBO & o) {return *this;}
void init(); void init();
void destroy() {deleteGLBuffer(buffer_);} void destroy();
bool rebuffer(bool clear_ = false); bool rebuffer(bool clear_ = false);
void draw(GLenum type, bool simplest = false); void draw(GLenum type, QGLShaderProgram * prog, bool simplest = false);
void clear(); void clear();
GLuint buffer() const {return buffer_;} GLuint buffer() const {return buffer_;}
@@ -52,7 +52,7 @@ public:
private: private:
QVector<GLfloat> vertices_, normals_, texcoords_, colors_; QVector<GLfloat> vertices_, normals_, texcoords_, colors_;
GLenum usage; GLenum usage;
GLuint buffer_; GLuint buffer_, va_;
int vert_count; int vert_count;
bool changed, has_normals, has_texcoords, has_colors; bool changed, has_normals, has_texcoords, has_colors;

View File

@@ -327,8 +327,8 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
name = readCharsUntilNull(stream); name = readCharsUntilNull(stream);
//qDebug() << " mat map" << QString::number(cur_map, 16) << name; //qDebug() << " mat map" << QString::number(cur_map, 16) << name;
switch (cur_map) { switch (cur_map) {
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.diffuse.bitmap_path = name; break; case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.map_diffuse.bitmap_path = name; break;
case LOADER_3DS_CHUNK_BUMP_MAP: mat.bump.bitmap_path = name; break; case LOADER_3DS_CHUNK_BUMP_MAP: mat.map_bump.bitmap_path = name; break;
} }
break; break;
default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6); default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6);

View File

@@ -109,7 +109,7 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
materials.resize(line.right(line.length() - mst - 14).toInt()); materials.resize(line.right(line.length() - mst - 14).toInt());
//qDebug() << materials.size() << "materials"; //qDebug() << materials.size() << "materials";
for (int i = 0; i < materials.size(); ++i) { for (int i = 0; i < materials.size(); ++i) {
materials[i].diffuse.bitmap_id = 0; materials[i].map_diffuse.bitmap_id = 0;
mst = -1; mst = -1;
while (mst < 0 && !stream.atEnd()) { while (mst < 0 && !stream.atEnd()) {
line = stream.readLine(); line = stream.readLine();
@@ -120,15 +120,15 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
line = stream.readLine().trimmed(); line = stream.readLine().trimmed();
if (line.left(17) == "*MATERIAL_DIFFUSE") {materials[i].color_diffuse = colorFromString(line.right(line.length() - 18)); continue;} //qDebug() << "diffuse " << i << " = " << colorFromString(line.right(line.length() - 18)); if (line.left(17) == "*MATERIAL_DIFFUSE") {materials[i].color_diffuse = colorFromString(line.right(line.length() - 18)); continue;} //qDebug() << "diffuse " << i << " = " << colorFromString(line.right(line.length() - 18));
if (line.left(18) == "*MATERIAL_SPECULAR") {materials[i].color_specular = colorFromString(line.right(line.length() - 19)); continue;} //qDebug() << "specular " << i << " = " << colorFromString(line.right(line.length() - 19)); if (line.left(18) == "*MATERIAL_SPECULAR") {materials[i].color_specular = colorFromString(line.right(line.length() - 19)); continue;} //qDebug() << "specular " << i << " = " << colorFromString(line.right(line.length() - 19));
if (line.left(23) == "*MATERIAL_SHINESTRENGTH") {materials[i].shine_strength = line.right(line.length() - 24).toFloat(); continue;} if (line.left(23) == "*MATERIAL_SHINESTRENGTH") {materials[i].specular = line.right(line.length() - 24).toFloat(); continue;}
if (line.left(15) == "*MATERIAL_SHINE") {materials[i].shine = line.right(line.length() - 16).toFloat() * 100.; continue;} if (line.left(15) == "*MATERIAL_SHINE") {materials[i].roughness = 2. / exp(line.right(line.length() - 16).toFloat()); continue;}
if (line.left(22) == "*MATERIAL_TRANSPARENCY") {materials[i].transparency = line.right(line.length() - 23).toFloat(); continue;} if (line.left(22) == "*MATERIAL_TRANSPARENCY") {materials[i].transparency = line.right(line.length() - 23).toFloat(); continue;}
if (line.left(12) == "*MAP_DIFFUSE") { if (line.left(12) == "*MAP_DIFFUSE") {
line = stream.readLine().trimmed(); line = stream.readLine().trimmed();
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed(); while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
materials[i].bump.bitmap_amount = line.right(line.length() - 12).toFloat(); materials[i].map_bump.color_amount = line.right(line.length() - 12).toFloat();
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed(); while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
materials[i].diffuse.bitmap_path = line.mid(9, line.length() - 10); materials[i].map_diffuse.bitmap_path = line.mid(9, line.length() - 10);
/*if (!materials[i].diffuse.bitmap_path.isEmpty()) { /*if (!materials[i].diffuse.bitmap_path.isEmpty()) {
materials[i].diffuse.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].diffuse.bitmap_path)); materials[i].diffuse.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].diffuse.bitmap_path));
parent->textures << materials[i].diffuse.bitmap_id; parent->textures << materials[i].diffuse.bitmap_id;
@@ -141,10 +141,10 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
if (line.left(9) == "*MAP_BUMP") { if (line.left(9) == "*MAP_BUMP") {
line = stream.readLine().trimmed(); line = stream.readLine().trimmed();
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed(); while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
materials[i].bump.bitmap_amount = line.right(line.length() - 12).toFloat(); materials[i].map_bump.color_amount = line.right(line.length() - 12).toFloat();
//qDebug() << "bump amount" << materials[i].bump.bitmap_amount; //qDebug() << "bump amount" << materials[i].bump.color_amount;
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed(); while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
materials[i].bump.bitmap_path = line.mid(9, line.length() - 10); materials[i].map_bump.bitmap_path = line.mid(9, line.length() - 10);
/*if (!materials[i].bump.bitmap_path.isEmpty()) { /*if (!materials[i].bump.bitmap_path.isEmpty()) {
materials[i].bump.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].bump.bitmap_path)); materials[i].bump.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].bump.bitmap_path));
parent->textures << materials[i].bump.bitmap_id; parent->textures << materials[i].bump.bitmap_id;

View File

@@ -140,17 +140,17 @@ QVector<Material> LoaderDAE::readMaterials(QDomElement le, QDomElement li, bool
if (col.isValid()) mat.color_diffuse = col; if (col.isValid()) mat.color_diffuse = col;
col = readXMLColor(pn.firstChildElement("specular")); col = readXMLColor(pn.firstChildElement("specular"));
if (col.isValid()) mat.color_specular = col; if (col.isValid()) mat.color_specular = col;
mat.shine = 2. / exp(readXMLFloat(pn.firstChildElement("shininess"))); mat.roughness = 2. / exp(readXMLFloat(pn.firstChildElement("shininess")));
mat.transparency = readXMLFloat(pn.firstChildElement("transparency")); mat.transparency = readXMLFloat(pn.firstChildElement("transparency"));
if (!fbx) mat.transparency = 1. - mat.transparency; if (!fbx) mat.transparency = 1. - mat.transparency;
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li); text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
if (!text.isEmpty()) mat.diffuse.bitmap_path = text; if (!text.isEmpty()) mat.map_diffuse.bitmap_path = text;
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li); text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
if (!text.isEmpty()) mat.diffuse.bitmap_path = text; if (!text.isEmpty()) mat.map_diffuse.bitmap_path = text;
pn = prof.firstChildElement("technique").firstChildElement("extra").firstChild(); pn = prof.firstChildElement("technique").firstChildElement("extra").firstChild();
text = readXMLTexture(pn.firstChildElement("bump"), prof, li); text = readXMLTexture(pn.firstChildElement("bump"), prof, li);
if (!text.isEmpty()) mat.bump.bitmap_path = text; if (!text.isEmpty()) mat.map_bump.bitmap_path = text;
ret << mat; ret << mat;
/* /*

View File

@@ -156,7 +156,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
} }
if (line.startsWith("Ks")) { if (line.startsWith("Ks")) {
Vector3d v = readVector3d(line.mid(2).trimmed()); Vector3d v = readVector3d(line.mid(2).trimmed());
mat.shine_strength = v.length(); mat.specular = v.length();
double mc = qMax(v.x, qMax(v.y, v.z)); double mc = qMax(v.x, qMax(v.y, v.z));
if (mc > 0.) v /= mc; if (mc > 0.) v /= mc;
mat.color_specular = QColor::fromRgbF(v.x, v.y, v.z); mat.color_specular = QColor::fromRgbF(v.x, v.y, v.z);
@@ -164,7 +164,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
continue; continue;
} }
if (line.startsWith("Ns")) { if (line.startsWith("Ns")) {
mat.shine = line.mid(2).trimmed().toDouble(); mat.roughness = 2. / exp(line.mid(2).trimmed().toDouble());
continue; continue;
} }
if (line.startsWith("d")) { if (line.startsWith("d")) {
@@ -172,7 +172,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
continue; continue;
} }
if (line.startsWith("map_Kd")) { if (line.startsWith("map_Kd")) {
mat.diffuse.bitmap_path = findFile(line.mid(6).trimmed(), sp); mat.map_diffuse.bitmap_path = findFile(line.mid(6).trimmed(), sp);
continue; continue;
} }
if (line.startsWith("map_bump")) { if (line.startsWith("map_bump")) {
@@ -181,9 +181,9 @@ QVector<Material> readMTL(QString obj_path, QString path) {
line = line.mid(3).trimmed(); line = line.mid(3).trimmed();
QString sv = line.left(line.indexOf(" ")); QString sv = line.left(line.indexOf(" "));
line = line.mid(sv.size()).trimmed(); line = line.mid(sv.size()).trimmed();
mat.bump_scale = sv.toDouble(); mat.map_bump.color_amount = sv.toDouble();
} }
mat.bump.bitmap_path = findFile(line, sp); mat.map_bump.bitmap_path = findFile(line, sp);
//qDebug() << "BUMP" << mat.name << mat.bump_scale << mat.bump.bitmap_path; //qDebug() << "BUMP" << mat.name << mat.bump_scale << mat.bump.bitmap_path;
continue; continue;
} }

View File

@@ -34,8 +34,8 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
//spinSliderShine->setDecimals(2); //spinSliderShine->setDecimals(2);
view->setFrameShape(QFrame::NoFrame); view->setFrameShape(QFrame::NoFrame);
//view->setRenderer(new RendererDeferredShading(view)); //view->setRenderer(new RendererDeferredShading(view));
view->setRenderer(new RendererSimple(view)); view->setRenderer(new RendererDeferredShading(view));
view->setMouseSelectionEnabled(true); view->setMouseSelectionEnabled(false);
view->setMouseRotateEnabled(true); view->setMouseRotateEnabled(true);
view->setBackColor(Qt::lightGray); view->setBackColor(Qt::lightGray);
//view->setLightingMode(QGLView::PerPixel); //view->setLightingMode(QGLView::PerPixel);
@@ -62,13 +62,11 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
//obj->child("teapot")->setLineWidth(2.); //obj->child("teapot")->setLineWidth(2.);
//obj->child("cone")->setRenderMode(GLObjectBase::Line); //obj->child("cone")->setRenderMode(GLObjectBase::Line);
//view->camera().setAim(obj->child("sphere001")->pos()); //view->camera().setAim(obj->child("sphere001")->pos());
QImageReader im("D:/orders/libs/qglview/data/SU-33_maps/Map__14_Mix.tga");
QImage i = im.read();
qDebug() << i.size() << im.errorString();
GLTextureManager::addSearchPath("data"); GLTextureManager::addSearchPath("data");
GLTextureManager::addSearchPath("data/images"); GLTextureManager::addSearchPath("data/images");
GLTextureManager::addSearchPath("data/SU-33_maps"); GLTextureManager::addSearchPath("data/SU-33_maps");
obj = loadFromDAEFile("data/su33t.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube(); obj = loadFromDAEFile("data/test.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
obj->setScale(0.1);
//obj = new GLPrimitiveEllipsoid(100, 100, 100, 100, 100);//GLPrimitiveCube(); //obj = new GLPrimitiveEllipsoid(100, 100, 100, 100, 100);//GLPrimitiveCube();
view->addObject(obj); view->addObject(obj);
@@ -95,7 +93,8 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
view->setHoverHaloEnabled(false); view->setHoverHaloEnabled(false);
Light * l = new Light(view->camera().pos()); Light * l = new Light(view->camera().pos());
l->intensity = 0.8; l->intensity = 0.8;
view->addObject(l); l->setName("camera");
//view->addObject(l);
view->start(-1); view->start(-1);
//view->light(0)->light_type = Light::Omni; //view->light(0)->light_type = Light::Omni;
//obj = loadFrom3DSFile("34.3DS", 0.03); //obj = loadFrom3DSFile("34.3DS", 0.03);
@@ -148,6 +147,7 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
//view->addObject(new Light(view->camera().pos())); //view->addObject(new Light(view->camera().pos()));
//show(); //show();
//comboBox->setCurrentIndex(2);
} }

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1246</width> <width>1246</width>
<height>844</height> <height>856</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -45,7 +45,7 @@
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>3</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
<attribute name="title"> <attribute name="title">

View File

@@ -23,6 +23,7 @@
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->frameReflection->hide();
active = true; active = true;
} }
@@ -46,24 +47,24 @@ void MaterialEditor::setMaterial(const Material & m) {
ui->colorSpecular->setColor(m.color_specular); ui->colorSpecular->setColor(m.color_specular);
ui->colorSelfIllum->setColor(m.color_self_illumination); ui->colorSelfIllum->setColor(m.color_self_illumination);
ui->checkGlass->setChecked(m.glass); ui->checkGlass->setChecked(m.glass);
ui->comboModel->setCurrentIndex((int)m.light_model); ui->spinRoughness->setValue(m.roughness);
ui->spinShine->setValue(m.shine); ui->spinSpecular->setValue(m.specular);
ui->spinShineStrength->setValue(m.shine_strength);
ui->spinTransparent->setValue(m.transparency); ui->spinTransparent->setValue(m.transparency);
ui->spinReflect->setValue(m.reflectivity); ui->spinReflect->setValue(m.reflectivity);
ui->spinBump->setValue(m.bump_scale);
ui->spinRelief->setValue(m.relief_scale);
ui->spinIOF->setValue(m.iof); ui->spinIOF->setValue(m.iof);
ui->spinDispersion->setValue(m.dispersion); ui->spinDispersion->setValue(m.dispersion);
ui->lineDiffuse->setProperty("GLpath", m.diffuse.bitmap_path); ui->lineDiffuse->setText(QFileInfo(m.diffuse.bitmap_path).fileName()); ui->mapDiffuse->setMap(m.map_diffuse);
ui->lineBump->setProperty("GLpath", m.bump.bitmap_path); ui->lineBump->setText(QFileInfo(m.bump.bitmap_path).fileName()); ui->mapSpecular->setMap(m.map_specular);
ui->lineRelief->setProperty("GLpath", m.relief.bitmap_path); ui->lineRelief->setText(QFileInfo(m.relief.bitmap_path).fileName()); ui->mapSelfIllum->setMap(m.map_self_illumination);
ui->lineReflFront->setProperty("GLpath", m.reflection.path(0)); ui->lineReflFront->setText(QFileInfo(m.reflection.path(0)).fileName()); ui->mapRoughness->setMap(m.map_roughness);
ui->lineReflBack->setProperty("GLpath", m.reflection.path(1)); ui->lineReflBack->setText(QFileInfo(m.reflection.path(1)).fileName()); ui->mapBump->setMap(m.map_bump);
ui->lineReflLeft->setProperty("GLpath", m.reflection.path(2)); ui->lineReflLeft->setText(QFileInfo(m.reflection.path(2)).fileName()); ui->mapRelief->setMap(m.map_relief);
ui->lineReflRight->setProperty("GLpath", m.reflection.path(3)); ui->lineReflRight->setText(QFileInfo(m.reflection.path(3)).fileName()); ui->lineReflFront->setProperty("GLpath", m.map_reflection.path(0)); ui->lineReflFront->setText(QFileInfo(m.map_reflection.path(0)).fileName());
ui->lineReflTop->setProperty("GLpath", m.reflection.path(4)); ui->lineReflTop->setText(QFileInfo(m.reflection.path(4)).fileName()); ui->lineReflBack->setProperty("GLpath", m.map_reflection.path(1)); ui->lineReflBack->setText(QFileInfo(m.map_reflection.path(1)).fileName());
ui->lineReflBottom->setProperty("GLpath", m.reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(m.reflection.path(5)).fileName()); ui->lineReflLeft->setProperty("GLpath", m.map_reflection.path(2)); ui->lineReflLeft->setText(QFileInfo(m.map_reflection.path(2)).fileName());
ui->lineReflRight->setProperty("GLpath", m.map_reflection.path(3)); ui->lineReflRight->setText(QFileInfo(m.map_reflection.path(3)).fileName());
ui->lineReflTop->setProperty("GLpath", m.map_reflection.path(4)); ui->lineReflTop->setText(QFileInfo(m.map_reflection.path(4)).fileName());
ui->lineReflBottom->setProperty("GLpath", m.map_reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(m.map_reflection.path(5)).fileName());
active = true; active = true;
} }
@@ -74,55 +75,28 @@ Material MaterialEditor::material() {
m.color_specular = ui->colorSpecular->color(); m.color_specular = ui->colorSpecular->color();
m.color_self_illumination = ui->colorSelfIllum->color(); m.color_self_illumination = ui->colorSelfIllum->color();
m.glass = ui->checkGlass->isChecked(); m.glass = ui->checkGlass->isChecked();
m.light_model = (Material::LightModel)ui->comboModel->currentIndex(); m.roughness = ui->spinRoughness->value();
m.shine = ui->spinShine->value(); m.specular = ui->spinSpecular->value();
m.shine_strength = ui->spinShineStrength->value();
m.transparency = ui->spinTransparent->value(); m.transparency = ui->spinTransparent->value();
m.reflectivity = ui->spinReflect->value(); m.reflectivity = ui->spinReflect->value();
m.bump_scale = ui->spinBump->value();
m.relief_scale = ui->spinRelief->value();
m.iof = ui->spinIOF->value(); m.iof = ui->spinIOF->value();
m.dispersion = ui->spinDispersion->value(); m.dispersion = ui->spinDispersion->value();
m.diffuse.bitmap_path = ui->lineDiffuse->property("GLpath").toString(); m.map_diffuse = ui->mapDiffuse->map();
m.bump.bitmap_path = ui->lineBump->property("GLpath").toString(); m.map_specular = ui->mapSpecular->map();
m.relief.bitmap_path = ui->lineRelief->property("GLpath").toString(); m.map_self_illumination = ui->mapSelfIllum->map();
m.reflection.setPath(0, ui->lineReflFront->property("GLpath").toString()); m.map_roughness = ui->mapRoughness->map();
m.reflection.setPath(1, ui->lineReflBack->property("GLpath").toString()); m.map_bump = ui->mapBump->map();
m.reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString()); m.map_relief = ui->mapRelief->map();
m.reflection.setPath(3, ui->lineReflRight->property("GLpath").toString()); m.map_reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
m.reflection.setPath(4, ui->lineReflTop->property("GLpath").toString()); m.map_reflection.setPath(1, ui->lineReflBack->property("GLpath").toString());
m.reflection.setPath(5, ui->lineReflBottom->property("GLpath").toString()); m.map_reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString());
m.map_reflection.setPath(3, ui->lineReflRight->property("GLpath").toString());
m.map_reflection.setPath(4, ui->lineReflTop->property("GLpath").toString());
m.map_reflection.setPath(5, ui->lineReflBottom->property("GLpath").toString());
return m; return m;
} }
void MaterialEditor::on_buttonDiffuseSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineDiffuse->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineDiffuse->setProperty("GLpath", str);
ui->lineDiffuse->setText(QFileInfo(str).fileName());
materialChanged();
}
void MaterialEditor::on_buttonBumpSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineBump->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineBump->setProperty("GLpath", str);
ui->lineBump->setText(QFileInfo(str).fileName());
materialChanged();
}
void MaterialEditor::on_buttonReliefSelect_clicked() {
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineRelief->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
if (str.isEmpty()) return;
ui->lineRelief->setProperty("GLpath", str);
ui->lineRelief->setText(QFileInfo(str).fileName());
materialChanged();
}
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;
@@ -177,27 +151,6 @@ void MaterialEditor::on_buttonReflBottomSelect_clicked() {
} }
void MaterialEditor::on_buttonDiffuseClear_clicked() {
ui->lineDiffuse->setText("");
ui->lineDiffuse->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonBumpClear_clicked() {
ui->lineBump->setText("");
ui->lineBump->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonReliefClear_clicked() {
ui->lineRelief->setText("");
ui->lineRelief->setProperty("GLpath", "");
materialChanged();
}
void MaterialEditor::on_buttonReflFrontClear_clicked() { void MaterialEditor::on_buttonReflFrontClear_clicked() {
ui->lineReflFront->setText(""); ui->lineReflFront->setText("");
ui->lineReflFront->setProperty("GLpath", ""); ui->lineReflFront->setProperty("GLpath", "");

View File

@@ -20,7 +20,7 @@
#define MATERIAL_EDITOR_H #define MATERIAL_EDITOR_H
#include <QFileDialog> #include <QFileDialog>
#include "gltypes.h" #include "glmaterial.h"
namespace Ui { namespace Ui {
class MaterialEditor; class MaterialEditor;
@@ -43,12 +43,6 @@ protected:
private slots: private slots:
void materialChanged() {if (active) emit changed();} void materialChanged() {if (active) emit changed();}
void on_buttonDiffuseSelect_clicked();
void on_buttonDiffuseClear_clicked();
void on_buttonBumpSelect_clicked();
void on_buttonBumpClear_clicked();
void on_buttonReliefSelect_clicked();
void on_buttonReliefClear_clicked();
void on_buttonReflFrontSelect_clicked(); void on_buttonReflFrontSelect_clicked();
void on_buttonReflFrontClear_clicked(); void on_buttonReflFrontClear_clicked();
void on_buttonReflBackSelect_clicked(); void on_buttonReflBackSelect_clicked();

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>327</width> <width>470</width>
<height>593</height> <height>692</height>
</rect> </rect>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
@@ -23,79 +23,124 @@
<property name="verticalSpacing"> <property name="verticalSpacing">
<number>2</number> <number>2</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0" colspan="2">
<widget class="QLabel" name="label"> <widget class="QGroupBox" name="groupBox">
<property name="text"> <property name="title">
<string>Diffuse</string> <string>Diffuse</string>
</property> </property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorDiffuse">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapDiffuse" native="true"/>
</item>
</layout>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="0" colspan="2">
<widget class="ColorButton" name="colorDiffuse"> <widget class="QGroupBox" name="groupBox_2">
<property name="useAlphaChannel"> <property name="title">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Specular</string> <string>Specular</string>
</property> </property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorSpecular">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapSpecular" native="true"/>
</item>
</layout>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="0" colspan="2">
<widget class="ColorButton" name="colorSpecular"> <widget class="QGroupBox" name="groupBox_3">
<property name="useAlphaChannel"> <property name="title">
<bool>true</bool> <string>Self illumination</string>
</property> </property>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ColorButton" name="colorSelfIllum">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapSelfIllum" native="true"/>
</item>
</layout>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_3"> <widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Bump</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="MaterialMapEditor" name="mapBump" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Relief</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="MaterialMapEditor" name="mapRelief" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="checkGlass">
<property name="text"> <property name="text">
<string>Light model</string> <string>Glass</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="7" column="0">
<widget class="QComboBox" name="comboModel">
<item>
<property name="text">
<string>Phong</string>
</property>
</item>
<item>
<property name="text">
<string>Cook-Torrance</string>
</property>
</item>
<item>
<property name="text">
<string>Minnaert</string>
</property>
</item>
<item>
<property name="text">
<string>Strauss</string>
</property>
</item>
<item>
<property name="text">
<string>Oren-Nayar</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Shininess</string> <string>Roughness</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1"> <item row="7" column="1">
<widget class="SpinSlider" name="spinShine"> <widget class="SpinSlider" name="spinRoughness">
<property name="maximum"> <property name="maximum">
<double>1.000000000000000</double> <double>1.000000000000000</double>
</property> </property>
@@ -110,15 +155,15 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="8" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Shine strength</string> <string>Specular</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="8" column="1">
<widget class="SpinSlider" name="spinShineStrength"> <widget class="SpinSlider" name="spinSpecular">
<property name="maximum"> <property name="maximum">
<double>64.000000000000000</double> <double>64.000000000000000</double>
</property> </property>
@@ -139,14 +184,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0"> <item row="9" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>Transparency</string> <string>Transparency</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="9" column="1">
<widget class="SpinSlider" name="spinTransparent"> <widget class="SpinSlider" name="spinTransparent">
<property name="maximum"> <property name="maximum">
<double>1.000000000000000</double> <double>1.000000000000000</double>
@@ -162,14 +207,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0"> <item row="10" column="0">
<widget class="QLabel" name="label_7"> <widget class="QLabel" name="label_7">
<property name="text"> <property name="text">
<string>Reflectivity</string> <string>Reflectivity</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="10" column="1">
<widget class="SpinSlider" name="spinReflect"> <widget class="SpinSlider" name="spinReflect">
<property name="maximum"> <property name="maximum">
<double>1.000000000000000</double> <double>1.000000000000000</double>
@@ -185,101 +230,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Bump scale</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="SpinSlider" name="spinBump">
<property name="maximum">
<double>4.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="pageStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Diffuse map</string>
</property>
</widget>
</item>
<item row="13" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineDiffuse"/>
</item>
<item>
<widget class="QToolButton" name="buttonDiffuseClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonDiffuseSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="14" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Bump map</string>
</property>
</widget>
</item>
<item row="14" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineBump"/>
</item>
<item>
<widget class="QToolButton" name="buttonBumpClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonBumpSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkGlass">
<property name="text">
<string>Glass</string>
</property>
</widget>
</item>
<item row="11" column="0"> <item row="11" column="0">
<widget class="QLabel" name="label_11"> <widget class="QLabel" name="label_11">
<property name="text"> <property name="text">
@@ -306,29 +256,41 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="12" column="0">
<widget class="QLabel" name="label_12"> <widget class="QLabel" name="label_15">
<property name="text"> <property name="text">
<string>Self-illumination</string> <string>Dispersion</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="12" column="1">
<widget class="ColorButton" name="colorSelfIllum"> <widget class="SpinSlider" name="spinDispersion">
<property name="useAlphaChannel"> <property name="maximum">
<bool>true</bool> <double>1.000000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="pageStep">
<double>0.100000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="16" column="0"> <item row="13" column="0">
<widget class="QLabel" name="label_13"> <widget class="QLabel" name="label_13">
<property name="text"> <property name="text">
<string>Reflection map</string> <string>Reflection map</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="16" column="1"> <item row="13" column="1">
<widget class="QFrame" name="frame"> <widget class="QFrame" name="frameReflection">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
@@ -532,87 +494,16 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="12" column="0"> <item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_15"> <widget class="QGroupBox" name="groupBox_6">
<property name="text"> <property name="title">
<string>Dispersion</string> <string>Roughness</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="SpinSlider" name="spinDispersion">
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="pageStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Relief map</string>
</property>
</widget>
</item>
<item row="15" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="lineRelief"/>
</item>
<item>
<widget class="QToolButton" name="buttonReliefClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonReliefSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Relief scale</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="SpinSlider" name="spinRelief">
<property name="maximum">
<double>4.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="pageStep">
<double>0.100000000000000</double>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="MaterialMapEditor" name="mapRoughness" native="true"/>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>
@@ -628,6 +519,15 @@
<extends>QPushButton</extends> <extends>QPushButton</extends>
<header>colorbutton.h</header> <header>colorbutton.h</header>
</customwidget> </customwidget>
<customwidget>
<class>MaterialMapEditor</class>
<extends>QWidget</extends>
<header>material_map_editor.h</header>
<container>1</container>
<slots>
<signal>changed()</signal>
</slots>
</customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections> <connections>
@@ -638,8 +538,8 @@
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>272</x> <x>326</x>
<y>17</y> <y>49</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>282</x> <x>282</x>
@@ -654,8 +554,8 @@
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>271</x> <x>325</x>
<y>39</y> <y>128</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>284</x> <x>284</x>
@@ -664,30 +564,14 @@
</hints> </hints>
</connection> </connection>
<connection> <connection>
<sender>comboModel</sender> <sender>spinRoughness</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>98</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
<y>70</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinShine</sender>
<signal>valueChanged(double)</signal> <signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver> <receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>279</x> <x>443</x>
<y>127</y> <y>404</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>280</x> <x>280</x>
@@ -696,14 +580,14 @@
</hints> </hints>
</connection> </connection>
<connection> <connection>
<sender>spinShineStrength</sender> <sender>spinSpecular</sender>
<signal>valueChanged(double)</signal> <signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver> <receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>279</x> <x>443</x>
<y>153</y> <y>426</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>283</x> <x>283</x>
@@ -718,8 +602,8 @@
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>279</x> <x>443</x>
<y>179</y> <y>448</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>283</x> <x>283</x>
@@ -734,8 +618,8 @@
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>279</x> <x>443</x>
<y>204</y> <y>470</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>284</x> <x>284</x>
@@ -743,54 +627,6 @@
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>spinBump</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>230</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
<y>202</y>
</hint>
</hints>
</connection>
<connection>
<sender>lineDiffuse</sender>
<signal>textChanged(QString)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>264</x>
<y>349</y>
</hint>
<hint type="destinationlabel">
<x>99</x>
<y>211</y>
</hint>
</hints>
</connection>
<connection>
<sender>lineBump</sender>
<signal>textChanged(QString)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>264</x>
<y>376</y>
</hint>
<hint type="destinationlabel">
<x>98</x>
<y>245</y>
</hint>
</hints>
</connection>
<connection> <connection>
<sender>spinIOF</sender> <sender>spinIOF</sender>
<signal>valueChanged(double)</signal> <signal>valueChanged(double)</signal>
@@ -798,8 +634,8 @@
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>279</x> <x>443</x>
<y>291</y> <y>492</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>284</x> <x>284</x>
@@ -814,8 +650,8 @@
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>279</x> <x>443</x>
<y>121</y> <y>382</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>284</x> <x>284</x>
@@ -830,8 +666,8 @@
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>322</x> <x>376</x>
<y>63</y> <y>202</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>326</x> <x>326</x>
@@ -846,8 +682,8 @@
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>313</x> <x>460</x>
<y>313</y> <y>514</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>326</x> <x>326</x>
@@ -856,34 +692,98 @@
</hints> </hints>
</connection> </connection>
<connection> <connection>
<sender>lineRelief</sender> <sender>mapDiffuse</sender>
<signal>textChanged(QString)</signal> <signal>changed()</signal>
<receiver>MaterialEditor</receiver> <receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>123</x> <x>445</x>
<y>391</y> <y>63</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>17</x> <x>469</x>
<y>364</y> <y>63</y>
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection> <connection>
<sender>spinRelief</sender> <sender>mapSpecular</sender>
<signal>valueChanged(double)</signal> <signal>changed()</signal>
<receiver>MaterialEditor</receiver> <receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot> <slot>materialChanged()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>317</x> <x>443</x>
<y>260</y> <y>143</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>327</x> <x>467</x>
<y>261</y> <y>143</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapSelfIllum</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>447</x>
<y>216</y>
</hint>
<hint type="destinationlabel">
<x>468</x>
<y>216</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapBump</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>450</x>
<y>308</y>
</hint>
<hint type="destinationlabel">
<x>469</x>
<y>260</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapRelief</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>450</x>
<y>353</y>
</hint>
<hint type="destinationlabel">
<x>469</x>
<y>304</y>
</hint>
</hints>
</connection>
<connection>
<sender>mapRoughness</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>442</x>
<y>257</y>
</hint>
<hint type="destinationlabel">
<x>474</x>
<y>250</y>
</hint> </hint>
</hints> </hints>
</connection> </connection>

View File

@@ -0,0 +1,72 @@
/*
QGLView
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "material_map_editor.h"
#include "ui_material_map_editor.h"
MaterialMapEditor::MaterialMapEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::MaterialMapEditor();
ui->setupUi(this);
active = true;
}
void MaterialMapEditor::changeEvent(QEvent * e) {
return;
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void MaterialMapEditor::setMap(const Map & m) {
active = false;
ui->linePath->setProperty("GLpath", m.bitmap_path); ui->linePath->setText(QFileInfo(m.bitmap_path).fileName());
active = true;
}
Map MaterialMapEditor::map() {
Map m;
m.color_amount = ui->sliderAmount->value();
m.color_offset = ui->sliderOffset->value();
m.bitmap_path = ui->linePath->property("GLpath").toString();
return m;
}
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(*)");
if (str.isEmpty()) return;
ui->linePath->setProperty("GLpath", str);
ui->linePath->setText(QFileInfo(str).fileName());
mapChanged();
}
void MaterialMapEditor::on_buttonClear_clicked() {
ui->linePath->setText("");
ui->linePath->setProperty("GLpath", "");
mapChanged();
}

View File

@@ -0,0 +1,54 @@
/*
QGLView
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MATERIAL_MAP_EDITOR_H
#define MATERIAL_MAP_EDITOR_H
#include <QFileDialog>
#include "glmaterial.h"
namespace Ui {
class MaterialMapEditor;
};
class MaterialMapEditor: public QWidget
{
Q_OBJECT
public:
explicit MaterialMapEditor(QWidget * parent = 0);
void setMap(const Map & m);
Map map();
protected:
void changeEvent(QEvent * e);
bool active;
Ui::MaterialMapEditor * ui;
private slots:
void mapChanged() {if (active) emit changed();}
void on_buttonSelect_clicked();
void on_buttonClear_clicked();
signals:
void changed();
};
#endif // MATERIAL_MAP_EDITOR_H

View File

@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaterialMapEditor</class>
<widget class="QWidget" name="MaterialMapEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>509</width>
<height>74</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLineEdit" name="linePath"/>
</item>
<item>
<widget class="QToolButton" name="buttonClear">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonSelect">
<property name="text">
<string>^</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Amount:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SpinSlider" name="sliderAmount">
<property name="minimum">
<double>-10.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="pageStep">
<double>0.200000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Offset:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SpinSlider" name="sliderOffset">
<property name="minimum">
<double>-10.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="pageStep">
<double>0.200000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SpinSlider</class>
<extends>QWidget</extends>
<header>spinslider.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>linePath</sender>
<signal>textChanged(QString)</signal>
<receiver>MaterialMapEditor</receiver>
<slot>mapChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>175</x>
<y>19</y>
</hint>
<hint type="destinationlabel">
<x>99</x>
<y>73</y>
</hint>
</hints>
</connection>
<connection>
<sender>sliderAmount</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialMapEditor</receiver>
<slot>mapChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>440</x>
<y>38</y>
</hint>
<hint type="destinationlabel">
<x>512</x>
<y>37</y>
</hint>
</hints>
</connection>
<connection>
<sender>sliderOffset</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialMapEditor</receiver>
<slot>mapChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>497</x>
<y>66</y>
</hint>
<hint type="destinationlabel">
<x>511</x>
<y>65</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>mapChanged()</slot>
</slots>
</ui>

View File

@@ -23,7 +23,9 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
setFrameShape(QFrame::NoFrame); setFrameShape(QFrame::NoFrame);
setViewportUpdateMode(FullViewportUpdate); setViewportUpdateMode(FullViewportUpdate);
setCacheMode(CacheNone); setCacheMode(CacheNone);
setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers))); QGLFormat f(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers);
f.setSwapInterval(0);
setViewport(new QGLWidget(f));
setMouseTracking(true); setMouseTracking(true);
setFocusPolicy(Qt::WheelFocus); setFocusPolicy(Qt::WheelFocus);
setScene(new QGraphicsScene()); setScene(new QGraphicsScene());
@@ -51,7 +53,7 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
selectionHaloFill_ = 0.5; selectionHaloFill_ = 0.5;
shadow_map_size = dynamic_cubemap_size = 512; shadow_map_size = dynamic_cubemap_size = 512;
//lmode = Simple; //lmode = Simple;
shader_select = shader_halo = shader_rope = 0; shader_select = shader_halo = 0;
cur_luminance = 1.; cur_luminance = 1.;
accom_time = 32.; accom_time = 32.;
accom_max_speed = 0.1; accom_max_speed = 0.1;
@@ -74,7 +76,7 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
QGLView::~QGLView() { QGLView::~QGLView() {
if (shader_select != 0) delete shader_select; if (shader_select != 0) delete shader_select;
if (shader_halo != 0) delete shader_halo; if (shader_halo != 0) delete shader_halo;
if (shader_rope != 0) delete shader_rope; //if (shader_rope != 0) delete shader_rope;
} }
@@ -112,7 +114,7 @@ void QGLView::drawBackground(QPainter * painter, const QRectF & rect) {
f = false; f = false;
paintGL(); paintGL();
painter_->endNativePainting(); painter_->endNativePainting();
glDisable(GL_DEPTH_TEST); glDisableDepth();
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glReleaseTextures(); glReleaseTextures();
@@ -131,7 +133,7 @@ void QGLView::initializeGL() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//glEnable(GL_TEXTURE_2D); //glEnable(GL_TEXTURE_2D);
//glEnable(GL_TEXTURE_CUBE_MAP); //glEnable(GL_TEXTURE_CUBE_MAP);
glEnable(GL_DEPTH_TEST); glEnableDepth();
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
@@ -168,7 +170,7 @@ void QGLView::initializeGL() {
shader_select = new QGLShaderProgram(context()); shader_select = new QGLShaderProgram(context());
shader_halo = new QGLShaderProgram(context()); shader_halo = new QGLShaderProgram(context());
shader_rope = new QGLShaderProgram(context()); //shader_rope = new QGLShaderProgram(context());
reloadThisShaders(); reloadThisShaders();
is_init = true; is_init = true;
@@ -192,16 +194,17 @@ void QGLView::initializeGL() {
void QGLView::paintGL() { void QGLView::paintGL() {
//QMutexLocker ml_v(&v_mutex); //QMutexLocker ml_v(&v_mutex);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
//glDisble(GL_CULL_FACE); //glDisable(GL_CULL_FACE);
camera_.apply(aspect); camera_.apply(aspect);
start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
//objects_.buildTransform();
/// Selection detect /// Selection detect
//glClearFramebuffer(QColor(100, 0, 0, 0)); //glClearFramebuffer(QColor(100, 0, 0, 0));
if (mouseSelect_) { if (mouseSelect_) {
glReleaseTextures(); glReleaseTextures();
glEnable(GL_DEPTH_TEST); glEnableDepth();
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glDisable(GL_TEXTURE_1D); glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_CUBE_MAP); glDisable(GL_TEXTURE_CUBE_MAP);
@@ -248,8 +251,7 @@ void QGLView::paintGL() {
renderHalo(sel_obj, ids.key(sel_obj), selectionHaloColor_, selectionHaloFill_); renderHalo(sel_obj, ids.key(sel_obj), selectionHaloColor_, selectionHaloFill_);
} }
fbo_selection.release(); fbo_selection.release();
glEnable(GL_DEPTH_TEST); glEnableDepth();
glEnable(GL_RESCALE_NORMAL);
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
@@ -277,7 +279,7 @@ void QGLView::paintGL() {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glDisable(GL_TEXTURE_CUBE_MAP); glDisable(GL_TEXTURE_CUBE_MAP);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST); glDisableDepth();
glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendFunc(GL_SRC_ALPHA, GL_ONE);
if (selectionHalo_) { if (selectionHalo_) {
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2)); glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2));
@@ -372,7 +374,17 @@ void QGLView::renderSelection() {
ids.clear(); ids.clear();
if (shaders_supported) sh_id_loc = shader_select->uniformLocation("id"); if (shaders_supported) sh_id_loc = shader_select->uniformLocation("id");
//qDebug() << sh_id_loc; //qDebug() << sh_id_loc;
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
glPushMatrix();
renderSingleSelection(objects_); renderSingleSelection(objects_);
glPopMatrix();
}
void QGLView::renderShadow() {
glPushMatrix();
renderSingleShadow(objects_);
glPopMatrix();
} }
@@ -382,32 +394,27 @@ void QGLView::renderSingleSelection(GLObjectBase & o) {
o.loadTextures(); o.loadTextures();
} }
if (!o.visible_ || !o.select_) return; if (!o.visible_ || !o.select_) return;
glPushMatrix(); QMatrix4x4 curview = start_rp.view_matrix * o.itransform_;
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
if (o.raw_matrix) {
qglMultMatrix(o.mat_);
} else {
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
}
ids.insert(cid, &o); ids.insert(cid, &o);
if (shaders_supported) shader_select->setUniformValue(sh_id_loc, QVector4D(float((cid >> 24) & 0xFF) / 255.f, if (shaders_supported){
float((cid >> 16) & 0xFF) / 255.f, setUniformMatrices(shader_select, start_rp.proj_matrix, curview);
float((cid >> 8) & 0xFF) / 255.f, shader_select->setUniformValue(sh_id_loc, QVector4D(float((cid >> 24) & 0xFF) / 255.f,
float(cid & 0xFF) / 255.f)); float((cid >> 16) & 0xFF) / 255.f,
else glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f,
float(cid & 0xFF) / 255.f));
} else {
setGLMatrix(curview);
glColor4f(float((cid >> 24) & 0xFF) / 255.f,
float((cid >> 16) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f,
float((cid >> 8) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f,
float(cid & 0xFF) / 255.f); float(cid & 0xFF) / 255.f);
}
//qDebug() << o.name() << "assign to" << sh_id_loc << cid; //qDebug() << o.name() << "assign to" << sh_id_loc << cid;
//glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) / 255.f); //glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) / 255.f);
++cid; ++cid;
o.draw(true); o.draw(0, true);
foreach (GLObjectBase * i, o.children_) foreach (GLObjectBase * i, o.children_)
renderSingleSelection(*i); renderSingleSelection(*i);
glPopMatrix();
} }
@@ -417,19 +424,13 @@ void QGLView::renderSingleShadow(GLObjectBase & o) {
o.loadTextures(); o.loadTextures();
} }
if (!o.visible_) return; if (!o.visible_) return;
glPushMatrix(); setGLMatrix(start_rp.view_matrix * o.itransform_);
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
glPolygonMode(GL_FRONT_AND_BACK, o.render_mode != GLObjectBase::View ? o.render_mode : (rmode != GLObjectBase::View ? rmode : GL_FILL)); glPolygonMode(GL_FRONT_AND_BACK, o.render_mode != GLObjectBase::View ? o.render_mode : (rmode != GLObjectBase::View ? rmode : GL_FILL));
glLineWidth(o.line_width > 0. ? o.line_width : lineWidth_); glLineWidth(o.line_width > 0. ? o.line_width : lineWidth_);
glPointSize(o.line_width > 0. ? o.line_width : lineWidth_); glPointSize(o.line_width > 0. ? o.line_width : lineWidth_);
o.draw(true); o.draw(0, true);
foreach (GLObjectBase * i, o.children_) foreach (GLObjectBase * i, o.children_)
renderSingleSelection(*i); renderSingleSelection(*i);
glPopMatrix();
} }

View File

@@ -35,6 +35,7 @@
#include <QApplication> #include <QApplication>
#include "glprimitives.h" #include "glprimitives.h"
#include "glparticles_system.h" #include "glparticles_system.h"
#include "glrendererbase.h"
class QGLView: public QGraphicsView, public QGLViewBase class QGLView: public QGraphicsView, public QGLViewBase
@@ -190,7 +191,7 @@ public:
void setSelectionRectBrush(const QBrush & v) {sel_brush = v;} void setSelectionRectBrush(const QBrush & v) {sel_brush = v;}
GLdouble aspect, iaspect; GLdouble aspect, iaspect;
QGLShaderProgram * shader_rope; //QGLShaderProgram * shader_rope;
protected: protected:
virtual void drawBackground(QPainter * painter, const QRectF & rect); virtual void drawBackground(QPainter * painter, const QRectF & rect);
@@ -210,7 +211,7 @@ protected:
inline void applyFog(); inline void applyFog();
void renderSelection(); void renderSelection();
void renderShadow() {renderSingleShadow(objects_);} void renderShadow();
void checkCaps(); void checkCaps();
void collectLights(); void collectLights();
@@ -222,7 +223,6 @@ private:
void renderSingleSelection(GLObjectBase & o); void renderSingleSelection(GLObjectBase & o);
void renderSingleShadow(GLObjectBase & o); void renderSingleShadow(GLObjectBase & o);
void renderHalo(const GLObjectBase * obj, const int iid, const QColor & color, const double & fill); void renderHalo(const GLObjectBase * obj, const int iid, const QColor & color, const double & fill);
void applyLightShader(Material::LightModel type);
QList<QGraphicsItem * > collectGraphicItems(); QList<QGraphicsItem * > collectGraphicItems();
void collectGraphicItems(QList<QGraphicsItem * > & list, QGraphicsItem * o); void collectGraphicItems(QList<QGraphicsItem * > & list, QGraphicsItem * o);
void reloadThisShaders(); void reloadThisShaders();
@@ -253,6 +253,7 @@ private:
SelectionMode sel_mode; SelectionMode sel_mode;
Qt::MouseButton sel_button; Qt::MouseButton sel_button;
Qt::KeyboardModifier sel_mod; Qt::KeyboardModifier sel_mod;
GLRendererBase::RenderingParameters start_rp;
double lineWidth_, linearFiltering_, accom_time, accom_max_speed, cur_luminance; double lineWidth_, linearFiltering_, accom_time, accom_max_speed, cur_luminance;
double fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_; double fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_;
int timer, fps_cnt, sh_id_loc, shadow_map_size, dynamic_cubemap_size; int timer, fps_cnt, sh_id_loc, shadow_map_size, dynamic_cubemap_size;

View File

@@ -19,67 +19,86 @@
#include "renderer_deferred_shading.h" #include "renderer_deferred_shading.h"
RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo(5, true, GL_RGBA16F) { RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo(6, true, GL_RGBA16F) {
shader_fxaa = shader_ds_0 = shader_ds_1 = 0; shader_fxaa = shader_ds_0 = shader_ds_1 = 0;
} }
void RendererDeferredShading::renderScene() { void RendererDeferredShading::renderScene() {
prepareUniform();
QMatrix4x4 view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
QMatrix4x4 proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
QMatrix4x4 viewprojinv = (proj_matrix * view_matrix).inverted();
corner_dirs[0] = (QVector4D(-1, -1, 1, 1) * viewprojinv).normalized();
corner_dirs[1] = (QVector4D( 1, -1, 1, 1) * viewprojinv).normalized();
corner_dirs[2] = (QVector4D( 1, 1, 1, 1) * viewprojinv).normalized();
corner_dirs[3] = (QVector4D(-1, 1, 1, 1) * viewprojinv).normalized();
//qDebug() << corner_dirs[0] << corner_dirs[1] << corner_dirs[2] << corner_dirs[3];
int passes = (view.lightsCount() - 1) / 8 + 1; int passes = (view.lightsCount() - 1) / 8 + 1;
QMatrix4x4 pm = getGLMatrix(GL_PROJECTION_MATRIX);//, mvm = getGLMatrix(GL_MODELVIEW_MATRIX), pmvm = pm * mvm, lpm, lmvm, lpmvm;
if (passes < 1) passes = 1; if (passes < 1) passes = 1;
fbo.bind(); fbo.bind();
int buffs[] = {0, 1, 2}; int buffs[] = {0, 1, 2, 3};
fbo.setWriteBuffers(buffs); fbo.setWriteBuffers(buffs);
if (white_image_id == 0) {
glActiveTextureChannel(6);
white_image_id = ((GLTextureManagerBase*)currentGLTextureManager)->loadTexture(white_image, false);
glBindTexture(GL_TEXTURE_2D, white_image_id);
glActiveTextureChannel(0);
}
glClearFramebuffer(QColor(0, 0, 0, 0)); glClearFramebuffer(QColor(0, 0, 0, 0));
//glEnable(GL_TEXTURE_2D); //glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST); glEnableDepth();
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
shader_ds_0->bind(); shader_ds_0->bind();
setUniform(shader_ds_0);
shader_ds_0->setUniformValue("z_far", GLfloat(view.depthEnd()));
shader_ds_0->setUniformValue("z_near", GLfloat(view.depthStart()));
shader_ds_0->setUniformValue("t0", 0); shader_ds_0->setUniformValue("t0", 0);
shader_ds_0->setUniformValue("t1", 1); shader_ds_0->setUniformValue("t1", 1);
shader_ds_0->setUniformValue("t2", 2); shader_ds_0->setUniformValue("t2", 2);
shader_ds_0->setUniformValue("t3", 3);
shader_ds_0->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height())); shader_ds_0->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height()));
renderObjects(GLObjectBase::Solid, 0, 0, true, false, false); renderObjects(GLObjectBase::Solid, 0, shader_ds_0, true, false, false);
//glReleaseShaders(); //glReleaseShaders();
//fbo.release(); //fbo.release();
glResetAllTransforms();
prepareUniform();
glSetLightEnabled(false); glSetLightEnabled(false);
glDisable(GL_BLEND); glDisable(GL_BLEND);
//glBlendFunc(GL_ONE, GL_ONE); //glBlendFunc(GL_ONE, GL_ONE);
glDisable(GL_DEPTH_TEST); glDisableDepth();
glDepthMask(GL_FALSE);
shader_ds_1->bind(); shader_ds_1->bind();
setUniform(shader_ds_1);
shader_ds_1->setUniformValue("z_far", GLfloat(view.depthEnd()));
shader_ds_1->setUniformValue("z_near", GLfloat(view.depthStart()));
shader_ds_1->setUniformValue("t0", 0); shader_ds_1->setUniformValue("t0", 0);
shader_ds_1->setUniformValue("t1", 1); shader_ds_1->setUniformValue("t1", 1);
shader_ds_1->setUniformValue("t2", 2); shader_ds_1->setUniformValue("t2", 2);
shader_ds_1->setUniformValue("t3", 3);
shader_ds_1->setUniformValue("td", 4);
shader_ds_1->setUniformValue("back_color", view.backColor()); shader_ds_1->setUniformValue("back_color", view.backColor());
shader_ds_1->setUniformValue("mat", pm.inverted()); shader_ds_1->setUniformValue("mat_proji", proj_matrix.inverted());
shader_ds_1->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height())); shader_ds_1->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height()));
fbo.setWriteBuffer(3); fbo.setWriteBuffer(4);
fbo.bindColorTextures(); fbo.bindColorTextures();
fbo.bindDepthTexture(4);
glClearFramebuffer(Qt::black, false); glClearFramebuffer(Qt::black, false);
QVector<QVector4D> lpos; //QVector<QVector4D> lpos;
GLfloat glmvm[16]; //qDebug() << view_matrix;
glGetFloatv(GL_MODELVIEW_MATRIX, glmvm);
//glResetAllTransforms();
for (int l = 0; l < passes; ++l) { for (int l = 0; l < passes; ++l) {
fbo.setWriteBuffer(4 - l % 2); fbo.setWriteBuffer(5 - l % 2);
shader_ds_1->setUniformValue("tb", 3 + l % 2); shader_ds_1->setUniformValue("tb", 4 + l % 2);
glMatrixMode(GL_MODELVIEW); setupDSLights(l, 16, view_matrix);
glLoadMatrixf(glmvm); //shader_ds_1->setUniformValue("lightsCount", cplc);
setupLights(l, 8); drawFB(shader_ds_1);
shader_ds_1->setUniformValue("lightsCount", cplc);
glDrawQuad();
//renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled()); //renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled());
//renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled()); //renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled());
glFinish(); glFlush();
} }
fbo.release(); fbo.release();
glReleaseShaders(); glReleaseShaders();
glActiveTextureChannel(0); glActiveTextureChannel(0);
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(3 + passes % 2)); glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(4 + passes % 2));
if (view.isFXAAEnabled()) { if (view.isFXAAEnabled()) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -107,9 +126,82 @@ void RendererDeferredShading::reloadShaders() {
void RendererDeferredShading::setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) { void RendererDeferredShading::setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) {
shader_ds_0->setUniformValue("has_diffuse", object.material().diffuse.bitmap_id != 0); shader_ds_0->setUniformValue("has_diffuse", object.material().map_diffuse.bitmap_id != 0);
shader_ds_0->setUniformValue("has_bump", object.material().bump.bitmap_id != 0); shader_ds_0->setUniformValue("has_bump", object.material().map_bump.bitmap_id != 0);
shader_ds_0->setUniformValue("has_height", object.material().relief.bitmap_id != 0); shader_ds_0->setUniformValue("has_height", object.material().map_relief.bitmap_id != 0);
shader_ds_0->setUniformValue("bump_scale", object.material().bump_scale); shader_ds_0->setUniformValue("bump_scale", object.material().map_bump.color_amount);
shader_ds_0->setUniformValue("height_scale", object.material().relief_scale); shader_ds_0->setUniformValue("height_scale", object.material().map_relief.color_amount);
glActiveTextureChannel(6);
glBindTexture(GL_TEXTURE_2D, white_image_id);
}
void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix) {
int light_start, light_end, lmax;
light_start = pass * lights_per_pass;
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights().size());
lmax = light_start + 8;
amb_light.intensity = (pass == 0 ? 1. : 0.);
amb_light.setColor(pass == 0 ? view.ambientColor() : Qt::black);
amb_light.setName("ambient");
setUniformLight(shader_ds_1, &amb_light, "qgl_AmbientLight", QMatrix4x4());
amb_light.intensity = 0.;
QVector<Light*> lv;
for (int i = light_start; i < light_end; ++i)
lv << view.lights()[i];
amb_light.setName("null");
for (int i = light_end; i < lmax; ++i)
lv << &amb_light;
setUniformLights(shader_ds_1, lv, view_matrix);
}
void RendererDeferredShading::setupAmbientLight(const QColor & a, bool first_pass) {
}
void RendererDeferredShading::prepareUniform() {
pm = getGLMatrix(GL_PROJECTION_MATRIX);
mvm = getGLMatrix(GL_MODELVIEW_MATRIX);
mvpm = pm * mvm;
pim = pm.inverted();
mvim = mvm.inverted();
mvpim = mvpm.inverted();
nm = mvm.normalMatrix();
}
void RendererDeferredShading::setUniform(QGLShaderProgram * prog) {
//qDebug() << mvm;
prog->setUniformValue("qgl_ModelViewMatrix", mvm);
prog->setUniformValue("qgl_ProjectionMatrix", pm);
prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm);
prog->setUniformValue("qgl_NormalMatrix", nm);
prog->setUniformValue("qgl_ModelViewMatrixInverse", mvim);
prog->setUniformValue("qgl_ProjectionMatrixInverse", pim);
prog->setUniformValue("qgl_ModelViewProjectionMatrixInverse", mvpim);
prog->setUniformValue("qgl_ModelViewMatrixTranspose", mvm.transposed());
prog->setUniformValue("qgl_ProjectionMatrixTranspose", pm.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed());
prog->setUniformValue("qgl_ModelViewMatrixInverseTranspose", mvim.transposed());
prog->setUniformValue("qgl_ProjectionMatrixInverseTranspose", pim.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixInverseTranspose", mvpim.transposed());
}
void RendererDeferredShading::drawFB(QGLShaderProgram * prog) {
glSetPolygonMode(GL_FILL);
int loc = prog->attributeLocation("qgl_Color");
glVertexAttrib3f(loc, 1.f, 1.f, 1.f);
int locv = prog->attributeLocation("qgl_Vertex"),
loct = prog->attributeLocation("qgl_Texture"),
locc = prog->attributeLocation("view_corner");
glBegin(GL_QUADS);
glColor3f(1.f, 1.f, 1.f);
prog->setAttributeValue(locc, corner_dirs[0]); glVertexAttrib2f(loct, 0.f, 0.f); glTexCoord2f(0.f, 0.f); glVertexAttrib2f(locv, -1.f, -1.f); glVertex2f(-1.f, -1.f);
prog->setAttributeValue(locc, corner_dirs[1]); glVertexAttrib2f(loct, 1.f, 0.f); glTexCoord2f(1.f, 0.f); glVertexAttrib2f(locv, 1.f, -1.f); glVertex2f(1.f, -1.f);
prog->setAttributeValue(locc, corner_dirs[2]); glVertexAttrib2f(loct, 1.f, 1.f); glTexCoord2f(1.f, 1.f); glVertexAttrib2f(locv, 1.f, 1.f); glVertex2f(1.f, 1.f);
prog->setAttributeValue(locc, corner_dirs[3]); glVertexAttrib2f(loct, 0.f, 1.f); glTexCoord2f(0.f, 1.f); glVertexAttrib2f(locv, -1.f, 1.f); glVertex2f(-1.f, 1.f);
glEnd();
} }

View File

@@ -30,17 +30,28 @@ public:
virtual void renderScene(); virtual void renderScene();
protected: protected:
virtual void init(int width, int height) {fbo.resize(width, height);} void init(int width, int height) {fbo.resize(width, height);}
virtual void resize(int width, int height) {fbo.resize(width, height);} void resize(int width, int height) {fbo.resize(width, height);}
virtual void reloadShaders(); void reloadShaders();
virtual void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp); void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp);
virtual void setupShadersLights(int lights_count) {cplc = lights_count;} void setupShadersLights(int lights_count) {cplc = lights_count;}
void setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix);
void setupAmbientLight(const QColor & a, bool first_pass);
void prepareUniform();
void setUniform(QGLShaderProgram * prog);
void drawFB(QGLShaderProgram * prog);
private: private:
int cplc; int cplc;
GLFramebuffer fbo; GLFramebuffer fbo;
QGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1; QGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1;
QMatrix4x4 pm, mvm, mvpm, pim, mvim, mvpim;
QMatrix3x3 nm;
QVector4D corner_dirs[4];
Light amb_light;
}; };
#endif // RENDERER_DEFERRED_SHADING_H #endif // RENDERER_DEFERRED_SHADING_H

View File

@@ -62,9 +62,7 @@ void RendererSimple::renderScene() {
if (passes > 1) fbo.setWriteBuffer(1); if (passes > 1) fbo.setWriteBuffer(1);
if (l == 0) { if (l == 0) {
glClearFramebuffer(view.backColor()); glClearFramebuffer(view.backColor());
glEnable(GL_DEPTH_TEST); glEnableDepth();
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
} else { } else {
glClearFramebuffer(Qt::black, false); glClearFramebuffer(Qt::black, false);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
@@ -98,8 +96,7 @@ void RendererSimple::renderScene() {
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
glReleaseTextures(); glReleaseTextures();
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(1)); glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(1));
glDisable(GL_DEPTH_TEST); glDisableDepth();
glDepthMask(GL_FALSE);
fbo.setWriteBuffer(0); fbo.setWriteBuffer(0);
glDrawQuad(); glDrawQuad();
} }
@@ -111,7 +108,7 @@ void RendererSimple::renderScene() {
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture()); glBindTexture(GL_TEXTURE_2D, fbo.colorTexture());
glSetLightEnabled(false); glSetLightEnabled(false);
glSetCapEnabled(GL_BLEND, false); glSetCapEnabled(GL_BLEND, false);
glDisable(GL_DEPTH_TEST); glDisableDepth();
if (view.isFXAAEnabled()) { if (view.isFXAAEnabled()) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

View File

@@ -47,7 +47,7 @@ void RopeSystem::init() {
} }
void RopeSystem::draw(bool simplest) { void RopeSystem::draw(QGLShaderProgram * prog, bool simplest) {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_1D, tex[0]); glBindTexture(GL_TEXTURE_1D, tex[0]);
glGetTexImage(GL_TEXTURE_1D, 0, GL_RGBA, GL_FLOAT, pos.data()); glGetTexImage(GL_TEXTURE_1D, 0, GL_RGBA, GL_FLOAT, pos.data());

View File

@@ -27,7 +27,7 @@ public:
RopeSystem(); RopeSystem();
~RopeSystem(); ~RopeSystem();
virtual void draw(bool simplest = false); virtual void draw(QGLShaderProgram * prog, bool simplest = false);
virtual void init(); virtual void init();
virtual void update() {} virtual void update() {}

View File

@@ -1,46 +1,48 @@
#version 130 #version 150
in vec3 src_normal, normal;//, et; in vec3 src_normal, normal;//, et;
in vec4 pos, col; in vec4 pos;
in float fogCoord; in float fogCoord;
uniform int light_model; uniform bool acc_fog;
uniform sampler2D t0, t1, t2, t3;
uniform float bump_scale, height_scale;
uniform bool acc_fog, has_diffuse, has_bump, has_height;
uniform vec2 dt; uniform vec2 dt;
uniform float z_far, z_near;
const vec3 luma = vec3(0.299, 0.587, 0.114); const vec3 luma = vec3(0.299, 0.587, 0.114);
void main(void) { void main(void) {
vec4 dc = col; float z = pos.w;//((z_near / (z_near-z_far)) * z_far) / (pos.w - (z_far / (z_far-z_near)));
vec2 tc = gl_TexCoord[0].xy; vec4 dc = qgl_FragColor;
float hei = 0.; vec2 tc = qgl_FragTexture.xy;
if (has_height) hei = dot(texture2D(t2, gl_TexCoord[0].xy).rgb, luma) * height_scale; float hei = dot(texture2D(qgl_Material.map_relief.map, tc).rgb, luma) * qgl_Material.map_relief.amount + qgl_Material.map_relief.offset;
if (acc_fog) dc.xyz = mix(dc.rgb, gl_Fog.color.rgb, fogCoord); //if (acc_fog) dc.xyz = mix(dc.rgb, gl_Fog.color.rgb, fogCoord);
vec3 n, dn; vec3 n, dn;
if (has_bump) { dn = (texture2D(qgl_Material.map_bump.map, tc).rgb - vec3(0.5, 0.5, 1.)) * qgl_Material.map_bump.amount + qgl_Material.map_bump.offset;
dn = (texture2D(t1, gl_TexCoord[0].xy).rgb - vec3(0.5, 0.5, 1.)) * bump_scale; dn.x = -dn.x;
dn.x = -dn.x; dn = dn * mat3(qgl_ModelViewMatrixInverse);
dn = dn * mat3(gl_ModelViewMatrixInverse); n = normalize(normal - dn);
n = normalize(normal - dn);
} else n = normalize(normal);
if (has_diffuse) { /*vec2 dpm = normalize(gl_FragCoord.xy * dt * 2. - vec2(1., 1.)), ntc;
ntc = gl_FragCoord.xy * dt * 2. - vec2(1., 1.) + dpm * hei;
dpm = gl_ModelViewProjectionMatrixInverse
dpm = dpm * gl_ModelViewProjectionMatrixInverse;
dpm += */
//tc += 1+et.xy * hei/10;// / et.z;
dc *= texture2D(qgl_Material.map_diffuse.map, tc) * qgl_Material.map_diffuse.amount + qgl_Material.map_diffuse.offset;
/*vec2 dpm = normalize(gl_FragCoord.xy * dt * 2. - vec2(1., 1.)), ntc; vec4 spec = texture2D(qgl_Material.map_specular.map, tc) * qgl_Material.map_specular.amount + qgl_Material.map_specular.offset;
ntc = gl_FragCoord.xy * dt * 2. - vec2(1., 1.) + dpm * hei; spec *= qgl_Material.color_specular * qgl_Material.specular;
dpm = gl_ModelViewProjectionMatrixInverse vec4 rough = texture2D(qgl_Material.map_roughness.map, tc) * qgl_Material.map_roughness.amount + qgl_Material.map_roughness.offset;
dpm = dpm * gl_ModelViewProjectionMatrixInverse; rough *= qgl_Material.roughness;
dpm += */ vec4 self = texture2D(qgl_Material.map_self_illumination.map, tc) * qgl_Material.map_self_illumination.amount + qgl_Material.map_self_illumination.offset;
//tc += 1+et.xy * hei/10;// / et.z; self *= qgl_Material.color_self_illumination;
dc *= texture2D(t0, tc);
} qgl_FragData[0] = vec4(dc.rgb, z);
qgl_FragData[1] = vec4(n.xyz / 2. + vec3(0.5), rough);
qgl_FragData[2] = vec4(spec.rgb, hei);
qgl_FragData[3] = vec4(pos.xyz, pos.z);
gl_FragData[0] = vec4(dc.rgb, pos.w);
gl_FragData[1] = vec4(n.xyz / 2. + vec3(0.5), gl_FrontMaterial.shininess);
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, hei);
//gl_FragData[0] = vec4(et.xyz, pos.w); //gl_FragData[0] = vec4(et.xyz, pos.w);
//gl_FragDepth = gl_FragCoord.z - clamp(hei / pos.z / pos.z / (abs(n.z) + 1), -0.01, 0.01); //gl_FragDepth = gl_FragCoord.z - clamp(hei / pos.z / pos.z / (abs(n.z) + 1), -0.01, 0.01);
/*vec4 dp = pos; /*vec4 dp = pos;

View File

@@ -1,7 +1,7 @@
#version 130 #version 150
out vec3 src_normal, normal;//, et; out vec3 src_normal, normal;//, et;
out vec4 pos, col; out vec4 pos;
out float fogCoord, fs_gid; out float fogCoord, fs_gid;
uniform bool acc_fog; uniform bool acc_fog;
@@ -9,34 +9,19 @@ uniform vec2 dt;
uniform vec3 eye; uniform vec3 eye;
void main(void) { void main(void) {
normal = (gl_NormalMatrix * gl_Normal); normal = (qgl_NormalMatrix * qgl_Normal);
pos.xyz = vec3(qgl_ModelViewMatrix * qgl_Vertex);
pos.xyz = vec3(gl_ModelViewMatrix * gl_Vertex); /*if (acc_fog) {
col = gl_Color;
if (acc_fog) {
fogCoord = (gl_Fog.end - length(pos.xyz) * 0.85) / (gl_Fog.end - gl_Fog.start); fogCoord = (gl_Fog.end - length(pos.xyz) * 0.85) / (gl_Fog.end - gl_Fog.start);
fogCoord = 1. - clamp(fogCoord, 0., 1.); fogCoord = 1. - clamp(fogCoord, 0., 1.);
} }*/
gl_TexCoord[0] = gl_MultiTexCoord0; //gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1; //gl_TexCoord[1] = gl_MultiTexCoord1;
gl_Position = ftransform(); qgl_FragTexture = qgl_Texture;
src_normal = normalize(/*gl_NormalMatrix * */vec3(pos.xy * dt * 2., 0)); qgl_FragColor = qgl_Color;
//pos = gl_Position; vec4 tp = qgl_ftransform();
//tp /= tp.w;
//vec3 v = normalize(-pos.xyz); // vector to the eye src_normal = normalize(vec3(pos.xy * dt * 2., 0));
pos.w = tp.w;
/*vec3 t = gl_NormalMatrix * vec3(1., 0., 0.); gl_Position = tp;//ftransform();
vec3 b = gl_NormalMatrix * vec3(0., 1., 0.);
et = vec3(dot(v, t), dot(v, b), dot(v, normal));*/
//vec3 t = normalize(gl_NormalMatrix * vec3(gl_MultiTexCoord0.yx, 1));
//vec3 b = cross(normal, t);
/*mat3 tbnMatrix = mat3(t.x, b.x, normal.x,
t.y, b.y, normal.y,
t.z, b.z, normal.z);
et = tbnMatrix * v;*/
pos.w = gl_Position.w;
} }

View File

@@ -1,69 +1,77 @@
#version 130 #version 150
//#extension GL_EXT_gpu_shader4 : enable //#extension GL_EXT_gpu_shader4 : enable
uniform vec3 ambient; in vec4 view_dir;
in vec3 view_pos;
uniform sampler2D t0, t1, t2, tb; uniform vec3 ambient;
uniform sampler2D t0, t1, t2, t3, tb;
uniform sampler2D td;
uniform int gid, lightsCount; uniform int gid, lightsCount;
uniform float z_near, z_far;
uniform bool firstPass; uniform bool firstPass;
uniform vec2 dt; uniform vec2 dt;
uniform vec4 back_color; uniform vec4 back_color;
uniform mat4 mat; uniform mat4 mat_proji;
float light_diffuse(int model, vec3 l, vec3 n) {return max(0., dot(l, n));} float light_diffuse(int model, vec3 l, vec3 n) {return max(0., dot(l, n));}
float light_specular(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) {return max(0., pow(dot(n, h), shininess));} //float light_specular(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) {return max(0., pow(dot(n, h), shininess));}
vec4 pos, lpos; vec4 pos, lpos;
vec3 li, si, ldir, halfV; vec3 li, si, ldir, halfV;
float sh_pow, sh_mul, dist, NdotL, spot, ldist, diff; float sh_pow, sh_mul, dist, NdotL, spot, ldist, diff;
void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) { void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) {
lpos = gl_LightSource[index].position; lpos = qgl_Light[index].position;
ldir = lpos.xyz - (pos.xyz * lpos.w); ldir = lpos.xyz - (pos.xyz * lpos.w);
ldist = length(ldir); ldist = length(ldir);
ldir = normalize(ldir); ldir = normalize(ldir);
NdotL = max(dot(n, ldir), 0.); NdotL = max(dot(n, ldir), 0.);
spot = step(0., NdotL); spot = step(0., NdotL);
if (NdotL > 0.) { if (NdotL > 0.) {
if (gl_LightSource[index].spotCutoff < 180.) { /*if (gl_LightSource[index].spotCutoff < 180.) {
spot = max(dot(-ldir, gl_LightSource[index].spotDirection.xyz), 0.); spot = max(dot(-ldir, gl_LightSource[index].spotDirection.xyz), 0.);
spot *= step(gl_LightSource[index].spotCosCutoff, spot); spot *= step(gl_LightSource[index].spotCosCutoff, spot);
spot = pow(spot, (gl_LightSource[index].spotExponent + 0.001)); spot = pow(spot, (gl_LightSource[index].spotExponent + 0.001));
} }*/
spot /= (qgl_Light[index].constantAttenuation + ldist * (qgl_Light[index].linearAttenuation + ldist * qgl_Light[index].quadraticAttenuation));
halfV = normalize(ldir + v); halfV = normalize(ldir + v);
spot /= (gl_LightSource[index].constantAttenuation + ldist * (gl_LightSource[index].linearAttenuation + ldist * gl_LightSource[index].quadraticAttenuation)); ///li += spot * gl_LightSource[index].diffuse.rgb * light_diffuse(0, ldir, n);
//li += spot * gl_LightSource[index].diffuse.rgb * light_diffuse(0, ldir, n); ///si += spot * gl_LightSource[index].specular.rgb * sh_mul * light_specular(0, ldir, n, halfV, v, sh_pow);
//si += spot * gl_LightSource[index].specular.rgb * sh_mul * light_specular(0, ldir, n, halfV, v, sh_pow);
float NdotLs = NdotL*NdotL; float NdotLs = NdotL*NdotL;
float ndlc = (1. - NdotLs) / NdotLs; float ndlc = (1. - NdotLs) / NdotLs;
float der = NdotLs * (sh_mul + ndlc); float der = NdotLs * (sh_mul + ndlc);
diff = 2. / (1. + sqrt(1. + (1. - sh_mul) * ndlc)); diff = 2. / (1. + sqrt(1. + (1. - sh_mul) * ndlc));
li += spot * gl_LightSource[index].diffuse.rgb * diff * light_diffuse(0, ldir, n); li += spot * qgl_Light[index].color.rgb * diff;// * light_diffuse(0, ldir, n);
si += spot * gl_LightSource[index].specular.rgb * (sh_mul / (der*der) / 3.1416); si += spot * qgl_Light[index].color.rgb * (sh_mul / (der*der) / 3.1416);
} }
} }
void main(void) { void main(void) {
//if (d == 1.) discard; //if (d == 1.) discard;
vec4 v0 = texture2D(t0, gl_TexCoord[0].xy); vec2 tc = qgl_FragTexture.xy;
vec4 v0 = texture2D(t0, tc);
if (v0.w == 0.) { if (v0.w == 0.) {
gl_FragColor = back_color; qgl_FragData[0] = back_color;
return; return;
} }
vec4 v1 = texture2D(t1, gl_TexCoord[0].xy), v2 = texture2D(t2, gl_TexCoord[0].xy);//, v3 = texture2D(t2, gl_TexCoord[0].xy); vec4 v1 = texture2D(t1, tc), v2 = texture2D(t2, tc), v3 = texture2D(t3, tc);
vec2 sp = gl_FragCoord.xy * dt * 2 - vec2(1, 1); vec2 sp = gl_FragCoord.xy * dt * 2 - vec2(1, 1);
vec3 dc = v0.rgb, n = v1.xyz * 2. - vec3(1.); vec3 dc = v0.rgb, n = v1.xyz * 2. - vec3(1.);
float height = v2.w; float height = v2.w;
li = gl_LightModel.ambient.rgb; li = qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity;
//li = vec3(0.);
si = vec3(0.); si = vec3(0.);
pos = vec4(sp, 0, 1.) * mat; pos = vec4(sp, 0, 1)*mat_proji;
pos *= v0.w; pos.xyz *= v0.w;
pos.rgb += n * height; //pos.xy *= 10.;
//pos.z = v0.w;
vec3 v = normalize(-pos.xyz); vec3 v = normalize(-pos.xyz);
sh_pow = 1. / max((1. - v1.w), 0.0001); sh_pow = 1. / max((1. - v1.w), 0.0001);
sh_mul = max(1. - v1.w, 0.0001); sh_mul = max(1. - v1.w, 0.0001);
if (lightsCount > 0) { //calcLight(0, n, v, v2);
/*if (lightsCount > 0) {
calcLight(0, n, v, v2); calcLight(0, n, v, v2);
if (lightsCount > 1) { if (lightsCount > 1) {
calcLight(1, n, v, v2); calcLight(1, n, v, v2);
@@ -86,7 +94,15 @@ void main(void) {
} }
} }
} }
} }*/
gl_FragColor.rgb = li * dc + si * v2.rgb + texture2D(tb, gl_TexCoord[0].xy).rgb; //qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb;// + texture2D(tb, tc).rgb;
//gl_FragColor.rgb = vec3(v2.rgb); //vec4 lp = mat*qgl_Light[0].position;
lpos = qgl_Light[0].position;
ldir = lpos.xyz - pos.xyz;
ldist = length(ldir);
float d = texture2D(td, tc).r;
//float z = ((z_near / (z_near-z_far)) * z_far) / (d - (z_far / (z_far-z_near)));
float z = z_near * z_far / (d * (z_far - z_near) - z_far);
//qgl_FragData[0].rgb = vec3(abs((v0.w)+(v3.z))-0.5);
qgl_FragData[0].rgb = vec3((-z*view_pos));
} }

View File

@@ -1,6 +1,13 @@
#version 130 #version 150
in vec4 view_corner;
out vec4 view_dir;
out vec3 view_pos;
void main(void) { void main(void) {
gl_TexCoord[0] = gl_MultiTexCoord0; view_dir = view_corner;
gl_Position = ftransform(); view_pos = vec3(qgl_ModelViewMatrix * vec4(qgl_Vertex.xy, 1, 1));
qgl_FragTexture = qgl_Texture;
qgl_FragColor = qgl_Color;
gl_Position = qgl_ftransform();
} }

View File

@@ -1,7 +1,7 @@
#version 120 #version 150
uniform vec4 id; uniform vec4 id;
void main(void) { void main(void) {
gl_FragColor = id; qgl_FragData[0] = id;
} }

View File

@@ -1,5 +1,5 @@
#version 120 #version 150
void main(void) { void main(void) {
gl_Position = ftransform(); gl_Position = qgl_ftransform();
} }

View File

@@ -1,4 +1,4 @@
#version 130 #version 150
uniform vec2 dt; uniform vec2 dt;
uniform vec4 selected, color; uniform vec4 selected, color;
@@ -6,13 +6,14 @@ uniform sampler2D t0;
uniform float fill; uniform float fill;
void main(void) { void main(void) {
vec4 ds0 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(-1, 0)) - selected); vec2 tc = qgl_FragTexture.xy;
vec4 ds1 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2( 1, 0)) - selected); vec4 ds0 = abs(textureLodOffset(t0, tc, 0., ivec2(-1, 0)) - selected);
vec4 ds2 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(0, -1)) - selected); vec4 ds1 = abs(textureLodOffset(t0, tc, 0., ivec2( 1, 0)) - selected);
vec4 ds3 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(0, 1)) - selected); vec4 ds2 = abs(textureLodOffset(t0, tc, 0., ivec2(0, -1)) - selected);
vec4 ds3 = abs(textureLodOffset(t0, tc, 0., ivec2(0, 1)) - selected);
float d0 = dot(ds0, vec4(1., 1., 1., 1.)), d1 = dot(ds1, vec4(1., 1., 1., 1.)), d2 = dot(ds2, vec4(1., 1., 1., 1.)), d3 = dot(ds3, vec4(1., 1., 1., 1.)); float d0 = dot(ds0, vec4(1., 1., 1., 1.)), d1 = dot(ds1, vec4(1., 1., 1., 1.)), d2 = dot(ds2, vec4(1., 1., 1., 1.)), d3 = dot(ds3, vec4(1., 1., 1., 1.));
float vs = step(1e-6, d0 + d1 + d2 + d3); float vs = step(1e-6, d0 + d1 + d2 + d3);
float vm = step(1e-3, (d0 * 255.) * (d1 * 255.) * (d2 * 255.) * (d3 * 255.)); float vm = step(1e-3, (d0 * 255.) * (d1 * 255.) * (d2 * 255.) * (d3 * 255.));
float v = mix(vs - vm, vs - vm - vm + 1, fill); float v = mix(vs - vm, vs - vm - vm + 1, fill);
gl_FragColor = vec4(color.rgb, v * color.a); qgl_FragData[0] = vec4(color.rgb, v * color.a);
} }

View File

@@ -1,6 +1,6 @@
#version 130 #version 150
void main(void) { void main(void) {
gl_TexCoord[0] = gl_MultiTexCoord0; qgl_FragTexture = qgl_Texture;
gl_Position = ftransform(); gl_Position = qgl_ftransform();
} }

View File

@@ -172,7 +172,7 @@ void WaterSystem::Particle::process(const QList<QVector<Particle> * > & near_par
} }
void WaterSystem::draw(bool simplest) { void WaterSystem::draw(QGLShaderProgram * prog, bool simplest) {
//return; //return;
pass_ = GLObjectBase::Transparent; pass_ = GLObjectBase::Transparent;
//qDebug() << "save states" << cv.size(); //qDebug() << "save states" << cv.size();

View File

@@ -31,9 +31,9 @@ public:
WaterSystem(); WaterSystem();
~WaterSystem(); ~WaterSystem();
virtual void draw(bool simplest = false); virtual void draw(QGLShaderProgram * prog, bool simplest = false);
virtual void update(); virtual void update();
virtual void init() {createGLTexture(texture, QImage("./media-record.png")); material_.diffuse.bitmap_id = texture; is_init = true;} virtual void init() {createGLTexture(texture, QImage("./media-record.png")); material_.map_diffuse.bitmap_id = texture; is_init = true;}
protected: protected:
class Chunk; class Chunk;