git-svn-id: svn://db.shs.com.ru/libs@44 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
231
qglview/glmaterial.cpp
Normal 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
136
qglview/glmaterial.h
Normal 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
|
||||
@@ -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.);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
224
qglview/glrendererbase.cpp
Normal 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
68
qglview/glrendererbase.h
Normal 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
211
qglview/glshaders.cpp
Normal 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
36
qglview/glshaders.h
Normal 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
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifndef GLTEXTUREMANAGER_H
|
||||
#define GLTEXTUREMANAGER_H
|
||||
|
||||
#include "gltypes.h"
|
||||
#include "glmaterial.h"
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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, 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, 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;}
|
||||
inline QDataStream & operator >>(QDataStream & s, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; 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
|
||||
|
||||
@@ -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,35 +77,76 @@ bool GLVBO::rebuffer(bool clear_) {
|
||||
}
|
||||
|
||||
|
||||
void GLVBO::draw(GLenum type, bool simplest) {
|
||||
void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
|
||||
if (buffer_ == 0 || vert_count == 0) return;
|
||||
if (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);
|
||||
glVertexPointer(3, GL_FLOAT, 0, 0);
|
||||
if (!simplest) {
|
||||
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) {
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, 0, offset);
|
||||
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
||||
} else glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableVertexAttribArray(loc);
|
||||
glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, offsets[0]);
|
||||
} else
|
||||
glDisableVertexAttribArray(loc);
|
||||
loc = prog->attributeLocation("qgl_Texture");
|
||||
if (has_texcoords) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, offset);
|
||||
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
|
||||
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableVertexAttribArray(loc);
|
||||
glVertexAttribPointer(loc, 2, GL_FLOAT, 0, 0, offsets[1]);
|
||||
} else
|
||||
glDisableVertexAttribArray(loc);
|
||||
loc = prog->attributeLocation("qgl_Color");
|
||||
if (has_colors) {
|
||||
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);
|
||||
}*/
|
||||
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) {
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, 0, offset);
|
||||
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
||||
} else glDisableClientState(GL_NORMAL_ARRAY);
|
||||
if (has_texcoords) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, offset);
|
||||
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
|
||||
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
if (has_colors) {
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glColorPointer(4, GL_FLOAT, 0, offset);
|
||||
} else glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
//qDebug() << "draw" << vert_count << buffer_ << offsets[0] << offsets[1] << offsets[3];
|
||||
glDrawArrays(type, 0, vert_count);
|
||||
//qDebug() << "draw" << vert_count << buffer_ << "done";
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
@@ -138,4 +191,4 @@ bool GLVBO::loadFromFile(const QString & filename) {
|
||||
return !isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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", "");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,79 +23,124 @@
|
||||
<property name="verticalSpacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<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>Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="ColorButton" name="colorDiffuse">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="MaterialMapEditor" name="mapDiffuse" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="ColorButton" name="colorDiffuse">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<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>Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="ColorButton" name="colorSpecular">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="MaterialMapEditor" name="mapSpecular" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="ColorButton" name="colorSpecular">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
<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>Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="ColorButton" name="colorSelfIllum">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="MaterialMapEditor" name="mapSelfIllum" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<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>Light model</string>
|
||||
<string>Glass</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="comboModel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Phong</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Cook-Torrance</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Minnaert</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Strauss</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Oren-Nayar</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<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>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineRelief"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonReliefClear">
|
||||
<property name="text">
|
||||
<string>X</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonReliefSelect">
|
||||
<property name="text">
|
||||
<string>^</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>Relief scale</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="SpinSlider" name="spinRelief">
|
||||
<property name="maximum">
|
||||
<double>4.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<double>0.100000000000000</double>
|
||||
<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="MaterialMapEditor" name="mapRoughness" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
|
||||
72
qglview/material_map_editor.cpp
Normal file
72
qglview/material_map_editor.cpp
Normal 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();
|
||||
}
|
||||
54
qglview/material_map_editor.h
Normal file
54
qglview/material_map_editor.h
Normal 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
|
||||
165
qglview/material_map_editor.ui
Normal file
165
qglview/material_map_editor.ui
Normal 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>
|
||||
@@ -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,
|
||||
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,
|
||||
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 {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
|
||||
@@ -1,46 +1,48 @@
|
||||
#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.x = -dn.x;
|
||||
dn = dn * mat3(gl_ModelViewMatrixInverse);
|
||||
n = normalize(normal - dn);
|
||||
} else n = normalize(normal);
|
||||
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(qgl_ModelViewMatrixInverse);
|
||||
n = normalize(normal - dn);
|
||||
|
||||
if (has_diffuse) {
|
||||
/*vec2 dpm = normalize(gl_FragCoord.xy * dt * 2. - vec2(1., 1.)), ntc;
|
||||
ntc = gl_FragCoord.xy * dt * 2. - vec2(1., 1.) + dpm * hei;
|
||||
dpm = gl_ModelViewProjectionMatrixInverse
|
||||
dpm = dpm * gl_ModelViewProjectionMatrixInverse;
|
||||
dpm += */
|
||||
//tc += 1+et.xy * hei/10;// / et.z;
|
||||
dc *= texture2D(qgl_Material.map_diffuse.map, tc) * qgl_Material.map_diffuse.amount + qgl_Material.map_diffuse.offset;
|
||||
|
||||
/*vec2 dpm = normalize(gl_FragCoord.xy * dt * 2. - vec2(1., 1.)), ntc;
|
||||
ntc = gl_FragCoord.xy * dt * 2. - vec2(1., 1.) + dpm * hei;
|
||||
dpm = gl_ModelViewProjectionMatrixInverse
|
||||
dpm = dpm * gl_ModelViewProjectionMatrixInverse;
|
||||
dpm += */
|
||||
//tc += 1+et.xy * hei/10;// / et.z;
|
||||
dc *= texture2D(t0, tc);
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#version 120
|
||||
#version 150
|
||||
|
||||
uniform vec4 id;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = id;
|
||||
qgl_FragData[0] = id;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#version 120
|
||||
#version 150
|
||||
|
||||
void main(void) {
|
||||
gl_Position = ftransform();
|
||||
gl_Position = qgl_ftransform();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user