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;
for (int i = 0; i < colors.size(); ++i)
buffers << GL_COLOR_ATTACHMENT0 + i;
glDrawBuffers(colors.size(), buffers.constData());
glDrawBuffers(buffers.size(), buffers.constData());
glReadBuffer(GL_COLOR_ATTACHMENT0);
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
glViewport(0, 0, wid, hei);
@@ -105,9 +105,10 @@ void GLFramebuffer::release() {
void GLFramebuffer::setWriteBuffers(int indeces[]) {
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];
glDrawBuffers(colors.size(), buffers.constData());
}
glDrawBuffers(buffers.size(), buffers.constData());
}
@@ -115,7 +116,7 @@ void GLFramebuffer::setWriteBuffers(int * indeces, int count) {
QVector<GLenum> buffers;
for (int i = 0; i < count; ++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);
}
}
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 bindColorTextures();
void bindDepthTexture(int channel);
private:
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;
}
void GLObjectBase::draw(bool simplest) {
vbo.draw(geom_prim, simplest);
void GLObjectBase::draw(QGLShaderProgram * prog, bool simplest) {
vbo.draw(geom_prim, prog, simplest);
/*if (!d_vertices.isEmpty()) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
@@ -147,7 +147,7 @@ void GLObjectBase::buildTransform() {
itransform_.setToIdentity();
GLObjectBase * p = parent_;
if (p != 0)
itransform_ *= p->itransform_;
itransform_ = p->itransform_;
if (raw_matrix) {
itransform_.translate(pos_);
itransform_ *= mat_;
@@ -159,6 +159,7 @@ void GLObjectBase::buildTransform() {
itransform_.rotate(angles_.x(), 1., 0., 0.);
itransform_.scale(scale_);
}
//qDebug() << name_ << itransform_;
foreach (GLObjectBase * i, children_)
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) {
if (!visible_) return;
glPushMatrix();
if (pos_.x() != 0. || pos_.y() != 0. || pos_.z() != 0.) glTranslated(pos_.x(), pos_.y(), pos_.z());
if (raw_matrix) {
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();
//glPushMatrix();
///qglMultMatrix TODO
material_.apply(0);
if (id != 0) {
++(*id);
ids->insert(*id, this);
//glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
//qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
}
draw();
draw(0);
foreach (GLObjectBase * i, children_)
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);
glDisable(GL_LIGHTING);
glPointSize(8.);

View File

@@ -21,6 +21,7 @@
#include "glvbo.h"
#include "glframebuffer.h"
#include "glmaterial.h"
class GLObjectBase
{
@@ -41,7 +42,7 @@ public:
void setName(const QString & name) {name_ = name;}
//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 draw(bool simplest = false);
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
virtual void update() {}
bool isInit() const {return is_init;}
bool isTexturesLoaded() const {return is_tex_loaded;}
@@ -180,6 +181,7 @@ protected:
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 checkPass();
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
int pass_; // Pass
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.);}
virtual GLObjectBase * clone(bool withChildren = 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;
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 (view_ == 0) return;
pass_ = GLObjectBase::Transparent;

View File

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

View File

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

View File

@@ -26,7 +26,7 @@ class GLPrimitivePoint: public GLObjectBase
{
public:
GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) {sz = 8.;}
virtual void draw(bool simplest = false);
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
private:
double sz;
};
@@ -38,7 +38,7 @@ class GLPrimitiveLine: public GLObjectBase
{
public:
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 point1() const {return p1;}
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
#define GLTEXTUREMANAGER_H
#include "gltypes.h"
#include "glmaterial.h"
#include <QDir>
#include <QFileInfo>

View File

@@ -20,11 +20,9 @@
#include "qglview.h"
QGLWidget * currentQGLView;
GLTextureManager * currentGLTextureManager;
Camera * currentCamera;
QMatrix4x4 globCameraMatrix;
QMutex globMutex;
QStringList GLTextureManagerBase::search_pathes(".");
QString readCharsUntilNull(QDataStream & s) {
@@ -74,7 +72,17 @@ QMatrix4x4 getGLMatrix(GLenum matrix) {
qreal qm[16];
for (int i = 0; i < 16; ++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) {
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();
prog->addShaderFromSourceFile(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();
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;
QMatrix4x4 glMatrixPerspective(double angle, double aspect, double near_, double far_) {
QMatrix4x4 ret;
double t = 1. / (tan(angle * deg2rad / 2.));
ret(0, 0) = t / aspect;
ret(1, 1) = t;
ret(2, 2) = far_ / (far_ - near_) - 1.;
ret(2, 3) = 2. * far_ * near_ / (far_ - near_);
ret(3, 2) = -1;
ret(3, 3) = 0.;
return ret;
}
@@ -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() {
QVector3D dv = aim_ - pos_, tv;
@@ -346,7 +185,10 @@ void Camera::apply(const GLdouble & aspect) {
glLoadIdentity();
if (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);
glLoadIdentity();
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) {
QString s = str.trimmed();
@@ -632,199 +427,25 @@ Vector3i::Vector3i(const QString & str) {
}
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 glEnableDepth() {
glEnable(GL_DEPTH_TEST);
//glDepthFunc(GL_GREATER);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
}
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 glDisableDepth() {
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
}
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);
}*/
}
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();
void glClearFramebuffer(const QColor & color, bool depth) {
glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
glClearDepth(1.);
if (depth)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
else
glClear(GL_COLOR_BUFFER_BIT);
}

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());}
void qglMultMatrix(const QMatrix4x4 & m);
void glEnableDepth();
void glDisableDepth();
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 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 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 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);}}
@@ -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);}
void glDrawQuad(GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f);
QMatrix4x4 getGLMatrix(GLenum matrix);
void setGLMatrix(QMatrix4x4 matrix);
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 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 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, 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 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 rotateQImageRight(const QImage & im);
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);}
@@ -174,76 +178,6 @@ extern QGLWidget * currentQGLView;
extern QMatrix4x4 globCameraMatrix;
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
{
friend class QGLView;
@@ -328,44 +262,6 @@ private:
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 {
GLfloat x;
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 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 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, 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, const Vector3i & v) {s << v.p0 << v.p1 << v.p2; return s;}
inline QDataStream & operator >>(QDataStream & s, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; return s;}
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);
inline double cosABV(const QVector3D & v0, const QVector3D & v1) {
@@ -519,45 +411,4 @@ protected:
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

View File

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

View File

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

View File

@@ -327,8 +327,8 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
name = readCharsUntilNull(stream);
//qDebug() << " mat map" << QString::number(cur_map, 16) << name;
switch (cur_map) {
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.diffuse.bitmap_path = name; break;
case LOADER_3DS_CHUNK_BUMP_MAP: mat.bump.bitmap_path = name; break;
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.map_diffuse.bitmap_path = name; break;
case LOADER_3DS_CHUNK_BUMP_MAP: mat.map_bump.bitmap_path = name; break;
}
break;
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());
//qDebug() << materials.size() << "materials";
for (int i = 0; i < materials.size(); ++i) {
materials[i].diffuse.bitmap_id = 0;
materials[i].map_diffuse.bitmap_id = 0;
mst = -1;
while (mst < 0 && !stream.atEnd()) {
line = stream.readLine();
@@ -120,15 +120,15 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
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(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(15) == "*MATERIAL_SHINE") {materials[i].shine = line.right(line.length() - 16).toFloat() * 100.; 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].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(12) == "*MAP_DIFFUSE") {
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();
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()) {
materials[i].diffuse.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].diffuse.bitmap_path));
parent->textures << materials[i].diffuse.bitmap_id;
@@ -141,10 +141,10 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
if (line.left(9) == "*MAP_BUMP") {
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();
//qDebug() << "bump amount" << materials[i].bump.bitmap_amount;
materials[i].map_bump.color_amount = line.right(line.length() - 12).toFloat();
//qDebug() << "bump amount" << materials[i].bump.color_amount;
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()) {
materials[i].bump.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].bump.bitmap_path));
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;
col = readXMLColor(pn.firstChildElement("specular"));
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"));
if (!fbx) mat.transparency = 1. - mat.transparency;
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);
if (!text.isEmpty()) mat.diffuse.bitmap_path = text;
if (!text.isEmpty()) mat.map_diffuse.bitmap_path = text;
pn = prof.firstChildElement("technique").firstChildElement("extra").firstChild();
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;
/*

View File

@@ -156,7 +156,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
}
if (line.startsWith("Ks")) {
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));
if (mc > 0.) v /= mc;
mat.color_specular = QColor::fromRgbF(v.x, v.y, v.z);
@@ -164,7 +164,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
continue;
}
if (line.startsWith("Ns")) {
mat.shine = line.mid(2).trimmed().toDouble();
mat.roughness = 2. / exp(line.mid(2).trimmed().toDouble());
continue;
}
if (line.startsWith("d")) {
@@ -172,7 +172,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
continue;
}
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;
}
if (line.startsWith("map_bump")) {
@@ -181,9 +181,9 @@ QVector<Material> readMTL(QString obj_path, QString path) {
line = line.mid(3).trimmed();
QString sv = line.left(line.indexOf(" "));
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;
continue;
}

View File

@@ -34,8 +34,8 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
//spinSliderShine->setDecimals(2);
view->setFrameShape(QFrame::NoFrame);
//view->setRenderer(new RendererDeferredShading(view));
view->setRenderer(new RendererSimple(view));
view->setMouseSelectionEnabled(true);
view->setRenderer(new RendererDeferredShading(view));
view->setMouseSelectionEnabled(false);
view->setMouseRotateEnabled(true);
view->setBackColor(Qt::lightGray);
//view->setLightingMode(QGLView::PerPixel);
@@ -62,13 +62,11 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
//obj->child("teapot")->setLineWidth(2.);
//obj->child("cone")->setRenderMode(GLObjectBase::Line);
//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/images");
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();
view->addObject(obj);
@@ -95,7 +93,8 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
view->setHoverHaloEnabled(false);
Light * l = new Light(view->camera().pos());
l->intensity = 0.8;
view->addObject(l);
l->setName("camera");
//view->addObject(l);
view->start(-1);
//view->light(0)->light_type = Light::Omni;
//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()));
//show();
//comboBox->setCurrentIndex(2);
}

View File

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

View File

@@ -23,6 +23,7 @@
MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) {
ui = new Ui::MaterialEditor();
ui->setupUi(this);
ui->frameReflection->hide();
active = true;
}
@@ -46,24 +47,24 @@ void MaterialEditor::setMaterial(const Material & m) {
ui->colorSpecular->setColor(m.color_specular);
ui->colorSelfIllum->setColor(m.color_self_illumination);
ui->checkGlass->setChecked(m.glass);
ui->comboModel->setCurrentIndex((int)m.light_model);
ui->spinShine->setValue(m.shine);
ui->spinShineStrength->setValue(m.shine_strength);
ui->spinRoughness->setValue(m.roughness);
ui->spinSpecular->setValue(m.specular);
ui->spinTransparent->setValue(m.transparency);
ui->spinReflect->setValue(m.reflectivity);
ui->spinBump->setValue(m.bump_scale);
ui->spinRelief->setValue(m.relief_scale);
ui->spinIOF->setValue(m.iof);
ui->spinDispersion->setValue(m.dispersion);
ui->lineDiffuse->setProperty("GLpath", m.diffuse.bitmap_path); ui->lineDiffuse->setText(QFileInfo(m.diffuse.bitmap_path).fileName());
ui->lineBump->setProperty("GLpath", m.bump.bitmap_path); ui->lineBump->setText(QFileInfo(m.bump.bitmap_path).fileName());
ui->lineRelief->setProperty("GLpath", m.relief.bitmap_path); ui->lineRelief->setText(QFileInfo(m.relief.bitmap_path).fileName());
ui->lineReflFront->setProperty("GLpath", m.reflection.path(0)); ui->lineReflFront->setText(QFileInfo(m.reflection.path(0)).fileName());
ui->lineReflBack->setProperty("GLpath", m.reflection.path(1)); ui->lineReflBack->setText(QFileInfo(m.reflection.path(1)).fileName());
ui->lineReflLeft->setProperty("GLpath", m.reflection.path(2)); ui->lineReflLeft->setText(QFileInfo(m.reflection.path(2)).fileName());
ui->lineReflRight->setProperty("GLpath", m.reflection.path(3)); ui->lineReflRight->setText(QFileInfo(m.reflection.path(3)).fileName());
ui->lineReflTop->setProperty("GLpath", m.reflection.path(4)); ui->lineReflTop->setText(QFileInfo(m.reflection.path(4)).fileName());
ui->lineReflBottom->setProperty("GLpath", m.reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(m.reflection.path(5)).fileName());
ui->mapDiffuse->setMap(m.map_diffuse);
ui->mapSpecular->setMap(m.map_specular);
ui->mapSelfIllum->setMap(m.map_self_illumination);
ui->mapRoughness->setMap(m.map_roughness);
ui->mapBump->setMap(m.map_bump);
ui->mapRelief->setMap(m.map_relief);
ui->lineReflFront->setProperty("GLpath", m.map_reflection.path(0)); ui->lineReflFront->setText(QFileInfo(m.map_reflection.path(0)).fileName());
ui->lineReflBack->setProperty("GLpath", m.map_reflection.path(1)); ui->lineReflBack->setText(QFileInfo(m.map_reflection.path(1)).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;
}
@@ -74,55 +75,28 @@ Material MaterialEditor::material() {
m.color_specular = ui->colorSpecular->color();
m.color_self_illumination = ui->colorSelfIllum->color();
m.glass = ui->checkGlass->isChecked();
m.light_model = (Material::LightModel)ui->comboModel->currentIndex();
m.shine = ui->spinShine->value();
m.shine_strength = ui->spinShineStrength->value();
m.roughness = ui->spinRoughness->value();
m.specular = ui->spinSpecular->value();
m.transparency = ui->spinTransparent->value();
m.reflectivity = ui->spinReflect->value();
m.bump_scale = ui->spinBump->value();
m.relief_scale = ui->spinRelief->value();
m.iof = ui->spinIOF->value();
m.dispersion = ui->spinDispersion->value();
m.diffuse.bitmap_path = ui->lineDiffuse->property("GLpath").toString();
m.bump.bitmap_path = ui->lineBump->property("GLpath").toString();
m.relief.bitmap_path = ui->lineRelief->property("GLpath").toString();
m.reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
m.reflection.setPath(1, ui->lineReflBack->property("GLpath").toString());
m.reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString());
m.reflection.setPath(3, ui->lineReflRight->property("GLpath").toString());
m.reflection.setPath(4, ui->lineReflTop->property("GLpath").toString());
m.reflection.setPath(5, ui->lineReflBottom->property("GLpath").toString());
m.map_diffuse = ui->mapDiffuse->map();
m.map_specular = ui->mapSpecular->map();
m.map_self_illumination = ui->mapSelfIllum->map();
m.map_roughness = ui->mapRoughness->map();
m.map_bump = ui->mapBump->map();
m.map_relief = ui->mapRelief->map();
m.map_reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
m.map_reflection.setPath(1, ui->lineReflBack->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;
}
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() {
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;
@@ -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() {
ui->lineReflFront->setText("");
ui->lineReflFront->setProperty("GLpath", "");

View File

@@ -20,7 +20,7 @@
#define MATERIAL_EDITOR_H
#include <QFileDialog>
#include "gltypes.h"
#include "glmaterial.h"
namespace Ui {
class MaterialEditor;
@@ -43,12 +43,6 @@ protected:
private slots:
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_buttonReflFrontClear_clicked();
void on_buttonReflBackSelect_clicked();

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>327</width>
<height>593</height>
<width>470</width>
<height>692</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@@ -23,10 +23,16 @@
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Diffuse</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Diffuse</string>
<string>Color:</string>
</property>
</widget>
</item>
@@ -37,65 +43,104 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapDiffuse" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Specular</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Specular</string>
<string>Color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="0" column="1">
<widget class="ColorButton" name="colorSpecular">
<property name="useAlphaChannel">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapSpecular" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Self illumination</string>
</property>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Light model</string>
<string>Color:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboModel">
<item>
<property name="text">
<string>Phong</string>
<item row="0" column="1">
<widget class="ColorButton" name="colorSelfIllum">
<property name="useAlphaChannel">
<bool>true</bool>
</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">
<item row="1" column="0" colspan="2">
<widget class="MaterialMapEditor" name="mapSelfIllum" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="4" column="0" colspan="2">
<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">
<string>Glass</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Shininess</string>
<string>Roughness</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="SpinSlider" name="spinShine">
<item row="7" column="1">
<widget class="SpinSlider" name="spinRoughness">
<property name="maximum">
<double>1.000000000000000</double>
</property>
@@ -110,15 +155,15 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="8" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Shine strength</string>
<string>Specular</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="SpinSlider" name="spinShineStrength">
<item row="8" column="1">
<widget class="SpinSlider" name="spinSpecular">
<property name="maximum">
<double>64.000000000000000</double>
</property>
@@ -139,14 +184,14 @@
</property>
</widget>
</item>
<item row="7" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Transparency</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="9" column="1">
<widget class="SpinSlider" name="spinTransparent">
<property name="maximum">
<double>1.000000000000000</double>
@@ -162,14 +207,14 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="10" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Reflectivity</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="10" column="1">
<widget class="SpinSlider" name="spinReflect">
<property name="maximum">
<double>1.000000000000000</double>
@@ -185,101 +230,6 @@
</property>
</widget>
</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">
<widget class="QLabel" name="label_11">
<property name="text">
@@ -306,29 +256,41 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<item row="12" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Self-illumination</string>
<string>Dispersion</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="ColorButton" name="colorSelfIllum">
<property name="useAlphaChannel">
<bool>true</bool>
<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="16" column="0">
<item row="13" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Reflection map</string>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QFrame" name="frame">
<item row="13" column="1">
<widget class="QFrame" name="frameReflection">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@@ -532,87 +494,16 @@
</layout>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Dispersion</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>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Roughness</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<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>
<widget class="MaterialMapEditor" name="mapRoughness" native="true"/>
</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>
</widget>
</item>
</layout>
@@ -628,6 +519,15 @@
<extends>QPushButton</extends>
<header>colorbutton.h</header>
</customwidget>
<customwidget>
<class>MaterialMapEditor</class>
<extends>QWidget</extends>
<header>material_map_editor.h</header>
<container>1</container>
<slots>
<signal>changed()</signal>
</slots>
</customwidget>
</customwidgets>
<resources/>
<connections>
@@ -638,8 +538,8 @@
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>272</x>
<y>17</y>
<x>326</x>
<y>49</y>
</hint>
<hint type="destinationlabel">
<x>282</x>
@@ -654,8 +554,8 @@
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>271</x>
<y>39</y>
<x>325</x>
<y>128</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
@@ -664,30 +564,14 @@
</hints>
</connection>
<connection>
<sender>comboModel</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>
<sender>spinRoughness</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>127</y>
<x>443</x>
<y>404</y>
</hint>
<hint type="destinationlabel">
<x>280</x>
@@ -696,14 +580,14 @@
</hints>
</connection>
<connection>
<sender>spinShineStrength</sender>
<sender>spinSpecular</sender>
<signal>valueChanged(double)</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>153</y>
<x>443</x>
<y>426</y>
</hint>
<hint type="destinationlabel">
<x>283</x>
@@ -718,8 +602,8 @@
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>179</y>
<x>443</x>
<y>448</y>
</hint>
<hint type="destinationlabel">
<x>283</x>
@@ -734,8 +618,8 @@
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>204</y>
<x>443</x>
<y>470</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
@@ -743,54 +627,6 @@
</hint>
</hints>
</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>
<sender>spinIOF</sender>
<signal>valueChanged(double)</signal>
@@ -798,8 +634,8 @@
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>291</y>
<x>443</x>
<y>492</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
@@ -814,8 +650,8 @@
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>279</x>
<y>121</y>
<x>443</x>
<y>382</y>
</hint>
<hint type="destinationlabel">
<x>284</x>
@@ -830,8 +666,8 @@
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>322</x>
<y>63</y>
<x>376</x>
<y>202</y>
</hint>
<hint type="destinationlabel">
<x>326</x>
@@ -846,8 +682,8 @@
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>313</x>
<y>313</y>
<x>460</x>
<y>514</y>
</hint>
<hint type="destinationlabel">
<x>326</x>
@@ -856,34 +692,98 @@
</hints>
</connection>
<connection>
<sender>lineRelief</sender>
<signal>textChanged(QString)</signal>
<sender>mapDiffuse</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>123</x>
<y>391</y>
<x>445</x>
<y>63</y>
</hint>
<hint type="destinationlabel">
<x>17</x>
<y>364</y>
<x>469</x>
<y>63</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinRelief</sender>
<signal>valueChanged(double)</signal>
<sender>mapSpecular</sender>
<signal>changed()</signal>
<receiver>MaterialEditor</receiver>
<slot>materialChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>317</x>
<y>260</y>
<x>443</x>
<y>143</y>
</hint>
<hint type="destinationlabel">
<x>327</x>
<y>261</y>
<x>467</x>
<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>
</hints>
</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);
setViewportUpdateMode(FullViewportUpdate);
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);
setFocusPolicy(Qt::WheelFocus);
setScene(new QGraphicsScene());
@@ -51,7 +53,7 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
selectionHaloFill_ = 0.5;
shadow_map_size = dynamic_cubemap_size = 512;
//lmode = Simple;
shader_select = shader_halo = shader_rope = 0;
shader_select = shader_halo = 0;
cur_luminance = 1.;
accom_time = 32.;
accom_max_speed = 0.1;
@@ -74,7 +76,7 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
QGLView::~QGLView() {
if (shader_select != 0) delete shader_select;
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;
paintGL();
painter_->endNativePainting();
glDisable(GL_DEPTH_TEST);
glDisableDepth();
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
glReleaseTextures();
@@ -131,7 +133,7 @@ void QGLView::initializeGL() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//glEnable(GL_TEXTURE_2D);
//glEnable(GL_TEXTURE_CUBE_MAP);
glEnable(GL_DEPTH_TEST);
glEnableDepth();
glEnable(GL_CULL_FACE);
glEnableClientState(GL_VERTEX_ARRAY);
@@ -168,7 +170,7 @@ void QGLView::initializeGL() {
shader_select = new QGLShaderProgram(context());
shader_halo = new QGLShaderProgram(context());
shader_rope = new QGLShaderProgram(context());
//shader_rope = new QGLShaderProgram(context());
reloadThisShaders();
is_init = true;
@@ -192,16 +194,17 @@ void QGLView::initializeGL() {
void QGLView::paintGL() {
//QMutexLocker ml_v(&v_mutex);
glEnable(GL_CULL_FACE);
//glDisble(GL_CULL_FACE);
//glDisable(GL_CULL_FACE);
camera_.apply(aspect);
start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
//objects_.buildTransform();
/// Selection detect
//glClearFramebuffer(QColor(100, 0, 0, 0));
if (mouseSelect_) {
glReleaseTextures();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glEnableDepth();
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_CUBE_MAP);
@@ -248,8 +251,7 @@ void QGLView::paintGL() {
renderHalo(sel_obj, ids.key(sel_obj), selectionHaloColor_, selectionHaloFill_);
}
fbo_selection.release();
glEnable(GL_DEPTH_TEST);
glEnable(GL_RESCALE_NORMAL);
glEnableDepth();
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
@@ -277,7 +279,7 @@ void QGLView::paintGL() {
glEnable(GL_BLEND);
glDisable(GL_TEXTURE_CUBE_MAP);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glDisableDepth();
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
if (selectionHalo_) {
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2));
@@ -372,7 +374,17 @@ void QGLView::renderSelection() {
ids.clear();
if (shaders_supported) sh_id_loc = shader_select->uniformLocation("id");
//qDebug() << sh_id_loc;
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
glPushMatrix();
renderSingleSelection(objects_);
glPopMatrix();
}
void QGLView::renderShadow() {
glPushMatrix();
renderSingleShadow(objects_);
glPopMatrix();
}
@@ -382,32 +394,27 @@ void QGLView::renderSingleSelection(GLObjectBase & o) {
o.loadTextures();
}
if (!o.visible_ || !o.select_) return;
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_);
}
QMatrix4x4 curview = start_rp.view_matrix * o.itransform_;
ids.insert(cid, &o);
if (shaders_supported) shader_select->setUniformValue(sh_id_loc, QVector4D(float((cid >> 24) & 0xFF) / 255.f,
if (shaders_supported){
setUniformMatrices(shader_select, start_rp.proj_matrix, curview);
shader_select->setUniformValue(sh_id_loc, QVector4D(float((cid >> 24) & 0xFF) / 255.f,
float((cid >> 16) & 0xFF) / 255.f,
float((cid >> 8) & 0xFF) / 255.f,
float(cid & 0xFF) / 255.f));
else glColor4f(float((cid >> 24) & 0xFF) / 255.f,
} else {
setGLMatrix(curview);
glColor4f(float((cid >> 24) & 0xFF) / 255.f,
float((cid >> 16) & 0xFF) / 255.f,
float((cid >> 8) & 0xFF) / 255.f,
float(cid & 0xFF) / 255.f);
}
//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);
++cid;
o.draw(true);
o.draw(0, true);
foreach (GLObjectBase * i, o.children_)
renderSingleSelection(*i);
glPopMatrix();
}
@@ -417,19 +424,13 @@ void QGLView::renderSingleShadow(GLObjectBase & o) {
o.loadTextures();
}
if (!o.visible_) return;
glPushMatrix();
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_);
setGLMatrix(start_rp.view_matrix * o.itransform_);
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_);
glPointSize(o.line_width > 0. ? o.line_width : lineWidth_);
o.draw(true);
o.draw(0, true);
foreach (GLObjectBase * i, o.children_)
renderSingleSelection(*i);
glPopMatrix();
}

View File

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

View File

@@ -19,67 +19,86 @@
#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;
}
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;
QMatrix4x4 pm = getGLMatrix(GL_PROJECTION_MATRIX);//, mvm = getGLMatrix(GL_MODELVIEW_MATRIX), pmvm = pm * mvm, lpm, lmvm, lpmvm;
if (passes < 1) passes = 1;
fbo.bind();
int buffs[] = {0, 1, 2};
int buffs[] = {0, 1, 2, 3};
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));
//glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glEnableDepth();
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("t1", 1);
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()));
renderObjects(GLObjectBase::Solid, 0, 0, true, false, false);
renderObjects(GLObjectBase::Solid, 0, shader_ds_0, true, false, false);
//glReleaseShaders();
//fbo.release();
glResetAllTransforms();
prepareUniform();
glSetLightEnabled(false);
glDisable(GL_BLEND);
//glBlendFunc(GL_ONE, GL_ONE);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisableDepth();
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("t1", 1);
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("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()));
fbo.setWriteBuffer(3);
fbo.setWriteBuffer(4);
fbo.bindColorTextures();
fbo.bindDepthTexture(4);
glClearFramebuffer(Qt::black, false);
QVector<QVector4D> lpos;
GLfloat glmvm[16];
glGetFloatv(GL_MODELVIEW_MATRIX, glmvm);
//glResetAllTransforms();
//QVector<QVector4D> lpos;
//qDebug() << view_matrix;
for (int l = 0; l < passes; ++l) {
fbo.setWriteBuffer(4 - l % 2);
shader_ds_1->setUniformValue("tb", 3 + l % 2);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(glmvm);
setupLights(l, 8);
shader_ds_1->setUniformValue("lightsCount", cplc);
glDrawQuad();
fbo.setWriteBuffer(5 - l % 2);
shader_ds_1->setUniformValue("tb", 4 + l % 2);
setupDSLights(l, 16, view_matrix);
//shader_ds_1->setUniformValue("lightsCount", cplc);
drawFB(shader_ds_1);
//renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled());
//renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled());
glFinish();
glFlush();
}
fbo.release();
glReleaseShaders();
glActiveTextureChannel(0);
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(3 + passes % 2));
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(4 + passes % 2));
if (view.isFXAAEnabled()) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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) {
shader_ds_0->setUniformValue("has_diffuse", object.material().diffuse.bitmap_id != 0);
shader_ds_0->setUniformValue("has_bump", object.material().bump.bitmap_id != 0);
shader_ds_0->setUniformValue("has_height", object.material().relief.bitmap_id != 0);
shader_ds_0->setUniformValue("bump_scale", object.material().bump_scale);
shader_ds_0->setUniformValue("height_scale", object.material().relief_scale);
shader_ds_0->setUniformValue("has_diffuse", object.material().map_diffuse.bitmap_id != 0);
shader_ds_0->setUniformValue("has_bump", object.material().map_bump.bitmap_id != 0);
shader_ds_0->setUniformValue("has_height", object.material().map_relief.bitmap_id != 0);
shader_ds_0->setUniformValue("bump_scale", object.material().map_bump.color_amount);
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();
protected:
virtual void init(int width, int height) {fbo.resize(width, height);}
virtual void resize(int width, int height) {fbo.resize(width, height);}
virtual void reloadShaders();
virtual void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp);
virtual void setupShadersLights(int lights_count) {cplc = lights_count;}
void init(int width, int height) {fbo.resize(width, height);}
void resize(int width, int height) {fbo.resize(width, height);}
void reloadShaders();
void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp);
void setupShadersLights(int lights_count) {cplc = lights_count;}
void setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix);
void setupAmbientLight(const QColor & a, bool first_pass);
void prepareUniform();
void setUniform(QGLShaderProgram * prog);
void drawFB(QGLShaderProgram * prog);
private:
int cplc;
GLFramebuffer fbo;
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

View File

@@ -62,9 +62,7 @@ void RendererSimple::renderScene() {
if (passes > 1) fbo.setWriteBuffer(1);
if (l == 0) {
glClearFramebuffer(view.backColor());
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glEnableDepth();
} else {
glClearFramebuffer(Qt::black, false);
glEnable(GL_DEPTH_TEST);
@@ -98,8 +96,7 @@ void RendererSimple::renderScene() {
glBlendFunc(GL_ONE, GL_ONE);
glReleaseTextures();
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(1));
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisableDepth();
fbo.setWriteBuffer(0);
glDrawQuad();
}
@@ -111,7 +108,7 @@ void RendererSimple::renderScene() {
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture());
glSetLightEnabled(false);
glSetCapEnabled(GL_BLEND, false);
glDisable(GL_DEPTH_TEST);
glDisableDepth();
if (view.isFXAAEnabled()) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
glBindTexture(GL_TEXTURE_1D, tex[0]);
glGetTexImage(GL_TEXTURE_1D, 0, GL_RGBA, GL_FLOAT, pos.data());

View File

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

View File

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

View File

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

View File

@@ -1,69 +1,77 @@
#version 130
#version 150
//#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 float z_near, z_far;
uniform bool firstPass;
uniform vec2 dt;
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_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;
vec3 li, si, ldir, halfV;
float sh_pow, sh_mul, dist, NdotL, spot, ldist, diff;
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);
ldist = length(ldir);
ldir = normalize(ldir);
NdotL = max(dot(n, ldir), 0.);
spot = step(0., NdotL);
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 *= step(gl_LightSource[index].spotCosCutoff, spot);
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);
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);
//si += spot * gl_LightSource[index].specular.rgb * sh_mul * light_specular(0, ldir, n, halfV, v, sh_pow);
///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);
float NdotLs = NdotL*NdotL;
float ndlc = (1. - NdotLs) / NdotLs;
float der = NdotLs * (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);
si += spot * gl_LightSource[index].specular.rgb * (sh_mul / (der*der) / 3.1416);
li += spot * qgl_Light[index].color.rgb * diff;// * light_diffuse(0, ldir, n);
si += spot * qgl_Light[index].color.rgb * (sh_mul / (der*der) / 3.1416);
}
}
void main(void) {
//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.) {
gl_FragColor = back_color;
qgl_FragData[0] = back_color;
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);
vec3 dc = v0.rgb, n = v1.xyz * 2. - vec3(1.);
float height = v2.w;
li = gl_LightModel.ambient.rgb;
li = qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity;
//li = vec3(0.);
si = vec3(0.);
pos = vec4(sp, 0, 1.) * mat;
pos *= v0.w;
pos.rgb += n * height;
pos = vec4(sp, 0, 1)*mat_proji;
pos.xyz *= v0.w;
//pos.xy *= 10.;
//pos.z = v0.w;
vec3 v = normalize(-pos.xyz);
sh_pow = 1. / max((1. - v1.w), 0.0001);
sh_mul = max(1. - v1.w, 0.0001);
if (lightsCount > 0) {
//calcLight(0, n, v, v2);
/*if (lightsCount > 0) {
calcLight(0, n, v, v2);
if (lightsCount > 1) {
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;
//gl_FragColor.rgb = vec3(v2.rgb);
}*/
//qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb;// + texture2D(tb, tc).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) {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
view_dir = view_corner;
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;
void main(void) {
gl_FragColor = id;
qgl_FragData[0] = id;
}

View File

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

View File

@@ -1,4 +1,4 @@
#version 130
#version 150
uniform vec2 dt;
uniform vec4 selected, color;
@@ -6,13 +6,14 @@ uniform sampler2D t0;
uniform float fill;
void main(void) {
vec4 ds0 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(-1, 0)) - selected);
vec4 ds1 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2( 1, 0)) - selected);
vec4 ds2 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(0, -1)) - selected);
vec4 ds3 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(0, 1)) - selected);
vec2 tc = qgl_FragTexture.xy;
vec4 ds0 = abs(textureLodOffset(t0, tc, 0., ivec2(-1, 0)) - selected);
vec4 ds1 = abs(textureLodOffset(t0, tc, 0., ivec2( 1, 0)) - 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 vs = step(1e-6, d0 + d1 + d2 + d3);
float vm = step(1e-3, (d0 * 255.) * (d1 * 255.) * (d2 * 255.) * (d3 * 255.));
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) {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
qgl_FragTexture = qgl_Texture;
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;
pass_ = GLObjectBase::Transparent;
//qDebug() << "save states" << cv.size();

View File

@@ -31,9 +31,9 @@ public:
WaterSystem();
~WaterSystem();
virtual void draw(bool simplest = false);
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
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:
class Chunk;