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;
|
QVector<GLenum> buffers;
|
||||||
for (int i = 0; i < colors.size(); ++i)
|
for (int i = 0; i < colors.size(); ++i)
|
||||||
buffers << GL_COLOR_ATTACHMENT0 + i;
|
buffers << GL_COLOR_ATTACHMENT0 + i;
|
||||||
glDrawBuffers(colors.size(), buffers.constData());
|
glDrawBuffers(buffers.size(), buffers.constData());
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
glViewport(0, 0, wid, hei);
|
glViewport(0, 0, wid, hei);
|
||||||
@@ -105,9 +105,10 @@ void GLFramebuffer::release() {
|
|||||||
|
|
||||||
void GLFramebuffer::setWriteBuffers(int indeces[]) {
|
void GLFramebuffer::setWriteBuffers(int indeces[]) {
|
||||||
QVector<GLenum> buffers;
|
QVector<GLenum> buffers;
|
||||||
for (uint i = 0; i < sizeof(indeces); ++i)
|
for (uint i = 0; i < sizeof(indeces); ++i) {
|
||||||
buffers << GL_COLOR_ATTACHMENT0 + indeces[i];
|
buffers << GL_COLOR_ATTACHMENT0 + indeces[i];
|
||||||
glDrawBuffers(colors.size(), buffers.constData());
|
}
|
||||||
|
glDrawBuffers(buffers.size(), buffers.constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,7 +116,7 @@ void GLFramebuffer::setWriteBuffers(int * indeces, int count) {
|
|||||||
QVector<GLenum> buffers;
|
QVector<GLenum> buffers;
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
buffers << GL_COLOR_ATTACHMENT0 + indeces[i];
|
buffers << GL_COLOR_ATTACHMENT0 + indeces[i];
|
||||||
glDrawBuffers(colors.size(), buffers.constData());
|
glDrawBuffers(buffers.size(), buffers.constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -127,3 +128,9 @@ void GLFramebuffer::bindColorTextures() {
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLFramebuffer::bindDepthTexture(int channel) {
|
||||||
|
glActiveTextureChannel(channel);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex_d);
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public:
|
|||||||
|
|
||||||
void copyDepthFrom(GLuint tex) {;}
|
void copyDepthFrom(GLuint tex) {;}
|
||||||
void bindColorTextures();
|
void bindColorTextures();
|
||||||
|
void bindDepthTexture(int channel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_depth, is_changed;
|
bool is_depth, is_changed;
|
||||||
|
|||||||
231
qglview/glmaterial.cpp
Normal file
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;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLObjectBase::draw(bool simplest) {
|
void GLObjectBase::draw(QGLShaderProgram * prog, bool simplest) {
|
||||||
vbo.draw(geom_prim, simplest);
|
vbo.draw(geom_prim, prog, simplest);
|
||||||
/*if (!d_vertices.isEmpty()) {
|
/*if (!d_vertices.isEmpty()) {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
|
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
|
||||||
@@ -147,7 +147,7 @@ void GLObjectBase::buildTransform() {
|
|||||||
itransform_.setToIdentity();
|
itransform_.setToIdentity();
|
||||||
GLObjectBase * p = parent_;
|
GLObjectBase * p = parent_;
|
||||||
if (p != 0)
|
if (p != 0)
|
||||||
itransform_ *= p->itransform_;
|
itransform_ = p->itransform_;
|
||||||
if (raw_matrix) {
|
if (raw_matrix) {
|
||||||
itransform_.translate(pos_);
|
itransform_.translate(pos_);
|
||||||
itransform_ *= mat_;
|
itransform_ *= mat_;
|
||||||
@@ -159,6 +159,7 @@ void GLObjectBase::buildTransform() {
|
|||||||
itransform_.rotate(angles_.x(), 1., 0., 0.);
|
itransform_.rotate(angles_.x(), 1., 0., 0.);
|
||||||
itransform_.scale(scale_);
|
itransform_.scale(scale_);
|
||||||
}
|
}
|
||||||
|
//qDebug() << name_ << itransform_;
|
||||||
foreach (GLObjectBase * i, children_)
|
foreach (GLObjectBase * i, children_)
|
||||||
i->buildTransform();
|
i->buildTransform();
|
||||||
}
|
}
|
||||||
@@ -170,29 +171,36 @@ void GLObjectBase::checkPass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QMatrix4x4 GLObjectBase::worldMatrix(QMatrix4x4 parent) const {
|
||||||
|
QMatrix4x4 mat;
|
||||||
|
mat.translate(pos_);
|
||||||
|
if (raw_matrix) {
|
||||||
|
mat *= mat_;
|
||||||
|
} else {
|
||||||
|
if (angles_.z() != 0.) mat.rotate(angles_.z(), 0., 0., 1.);
|
||||||
|
if (angles_.y() != 0.) mat.rotate(angles_.y(), 0., 1., 0.);
|
||||||
|
if (angles_.x() != 0.) mat.rotate(angles_.x(), 1., 0., 0.);
|
||||||
|
mat.scale(scale_);
|
||||||
|
}
|
||||||
|
return parent * mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLObjectBase::render(int * id, QMap<int, GLObjectBase * > * ids, int sh_id_loc) {
|
void GLObjectBase::render(int * id, QMap<int, GLObjectBase * > * ids, int sh_id_loc) {
|
||||||
if (!visible_) return;
|
if (!visible_) return;
|
||||||
glPushMatrix();
|
//glPushMatrix();
|
||||||
if (pos_.x() != 0. || pos_.y() != 0. || pos_.z() != 0.) glTranslated(pos_.x(), pos_.y(), pos_.z());
|
///qglMultMatrix TODO
|
||||||
if (raw_matrix) {
|
material_.apply(0);
|
||||||
qglMultMatrix(mat_);
|
|
||||||
} else {
|
|
||||||
if (angles_.z() != 0.) glRotated(angles_.z(), 0., 0., 1.);
|
|
||||||
if (angles_.y() != 0.) glRotated(angles_.y(), 0., 1., 0.);
|
|
||||||
if (angles_.x() != 0.) glRotated(angles_.x(), 1., 0., 0.);
|
|
||||||
if (scale_.x() != 1. || scale_.y() != 1. || scale_.z() != 1.) glScaled(scale_.x(), scale_.y(), scale_.z());
|
|
||||||
}
|
|
||||||
material_.apply();
|
|
||||||
if (id != 0) {
|
if (id != 0) {
|
||||||
++(*id);
|
++(*id);
|
||||||
ids->insert(*id, this);
|
ids->insert(*id, this);
|
||||||
//glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
|
//glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
|
||||||
//qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
|
//qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
|
||||||
}
|
}
|
||||||
draw();
|
draw(0);
|
||||||
foreach (GLObjectBase * i, children_)
|
foreach (GLObjectBase * i, children_)
|
||||||
i->render(id, ids, sh_id_loc);
|
i->render(id, ids, sh_id_loc);
|
||||||
glPopMatrix();
|
//glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,7 +225,7 @@ GLObjectBase * Light::clone(bool withChildren) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Light::draw(bool simplest) {
|
void Light::draw(QGLShaderProgram * prog, bool simplest) {
|
||||||
bool l = glIsEnabled(GL_LIGHTING);
|
bool l = glIsEnabled(GL_LIGHTING);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glPointSize(8.);
|
glPointSize(8.);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "glvbo.h"
|
#include "glvbo.h"
|
||||||
#include "glframebuffer.h"
|
#include "glframebuffer.h"
|
||||||
|
#include "glmaterial.h"
|
||||||
|
|
||||||
class GLObjectBase
|
class GLObjectBase
|
||||||
{
|
{
|
||||||
@@ -41,7 +42,7 @@ public:
|
|||||||
void setName(const QString & name) {name_ = name;}
|
void setName(const QString & name) {name_ = name;}
|
||||||
//virtual GLuint hList() {return list;}
|
//virtual GLuint hList() {return list;}
|
||||||
virtual void init() {calculateBoundingBox(); vbo.init(); vbo.rebuffer(); /*material_.reflection.create();*/ /*qDebug() << "init" << vbo.buffer_;*/ is_init = true;}
|
virtual void init() {calculateBoundingBox(); vbo.init(); vbo.rebuffer(); /*material_.reflection.create();*/ /*qDebug() << "init" << vbo.buffer_;*/ is_init = true;}
|
||||||
virtual void draw(bool simplest = false);
|
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
|
||||||
virtual void update() {}
|
virtual void update() {}
|
||||||
bool isInit() const {return is_init;}
|
bool isInit() const {return is_init;}
|
||||||
bool isTexturesLoaded() const {return is_tex_loaded;}
|
bool isTexturesLoaded() const {return is_tex_loaded;}
|
||||||
@@ -180,6 +181,7 @@ protected:
|
|||||||
void initInternal() {init(); loadTextures(); foreach (GLObjectBase * i, children_) i->initInternal();}
|
void initInternal() {init(); loadTextures(); foreach (GLObjectBase * i, children_) i->initInternal();}
|
||||||
void render(int * id = 0, QMap<int, GLObjectBase * > * ids = 0, int sh_id_loc = 0);
|
void render(int * id = 0, QMap<int, GLObjectBase * > * ids = 0, int sh_id_loc = 0);
|
||||||
void checkPass();
|
void checkPass();
|
||||||
|
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
|
||||||
|
|
||||||
int pass_; // Pass
|
int pass_; // Pass
|
||||||
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix;
|
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix;
|
||||||
@@ -214,7 +216,7 @@ public:
|
|||||||
Light(const QVector3D & p, const QColor & c = Qt::white, GLdouble i = 1.): GLObjectBase(), shadow_map(true, 1, GL_R16F) {type_ = GLObjectBase::Light; light_type = Omni; pos_ = p; intensity = i; /*color_ = c;*/ decay_linear = decay_quadratic = angle_spread = angle_decay_exp = decay_start = 0.; decay_const = decay_end = 1.; direction.setZ(1.);}
|
Light(const QVector3D & p, const QColor & c = Qt::white, GLdouble i = 1.): GLObjectBase(), shadow_map(true, 1, GL_R16F) {type_ = GLObjectBase::Light; light_type = Omni; pos_ = p; intensity = i; /*color_ = c;*/ decay_linear = decay_quadratic = angle_spread = angle_decay_exp = decay_start = 0.; decay_const = decay_end = 1.; direction.setZ(1.);}
|
||||||
virtual GLObjectBase * clone(bool withChildren = true);
|
virtual GLObjectBase * clone(bool withChildren = true);
|
||||||
virtual void init() {shadow_map.resize(512, 512); is_init = true;}
|
virtual void init() {shadow_map.resize(512, 512); is_init = true;}
|
||||||
virtual void draw(bool simplest = false);
|
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
|
||||||
|
|
||||||
QVector3D direction;
|
QVector3D direction;
|
||||||
GLdouble angle_spread;
|
GLdouble angle_spread;
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ void GLParticlesSystem::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLParticlesSystem::draw(bool) {
|
void GLParticlesSystem::draw(QGLShaderProgram * prog, bool) {
|
||||||
if (particles.isEmpty()) return;
|
if (particles.isEmpty()) return;
|
||||||
if (view_ == 0) return;
|
if (view_ == 0) return;
|
||||||
pass_ = GLObjectBase::Transparent;
|
pass_ = GLObjectBase::Transparent;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
void draw(bool);
|
void draw(QGLShaderProgram * prog, bool);
|
||||||
|
|
||||||
float birthRate() const {return birthRate_;}
|
float birthRate() const {return birthRate_;}
|
||||||
float lifeDuration() const {return lifeDuration_;}
|
float lifeDuration() const {return lifeDuration_;}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "glprimitives.h"
|
#include "glprimitives.h"
|
||||||
|
|
||||||
|
|
||||||
void GLPrimitivePoint::draw(bool simplest) {
|
void GLPrimitivePoint::draw(QGLShaderProgram * prog, bool simplest) {
|
||||||
glPointSize(sz);
|
glPointSize(sz);
|
||||||
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
|
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
|
||||||
glBegin(GL_POINTS);
|
glBegin(GL_POINTS);
|
||||||
@@ -29,7 +29,7 @@ void GLPrimitivePoint::draw(bool simplest) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GLPrimitiveLine::draw(bool simplest) {
|
void GLPrimitiveLine::draw(QGLShaderProgram * prog, bool simplest) {
|
||||||
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
|
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glVertex3d(p0.x(), p0.y(), p0.z());
|
glVertex3d(p0.x(), p0.y(), p0.z());
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class GLPrimitivePoint: public GLObjectBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) {sz = 8.;}
|
GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) {sz = 8.;}
|
||||||
virtual void draw(bool simplest = false);
|
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
|
||||||
private:
|
private:
|
||||||
double sz;
|
double sz;
|
||||||
};
|
};
|
||||||
@@ -38,7 +38,7 @@ class GLPrimitiveLine: public GLObjectBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GLPrimitiveLine(QVector3D p0_ = QVector3D(), QVector3D p1_ = QVector3D()) {p0 = p0_; p1 = p1_;}
|
GLPrimitiveLine(QVector3D p0_ = QVector3D(), QVector3D p1_ = QVector3D()) {p0 = p0_; p1 = p1_;}
|
||||||
virtual void draw(bool simplest = false);
|
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
|
||||||
QVector3D point0() const {return p0;}
|
QVector3D point0() const {return p0;}
|
||||||
QVector3D point1() const {return p1;}
|
QVector3D point1() const {return p1;}
|
||||||
void setPoint0(const QVector3D & p) {p0 = p;}
|
void setPoint0(const QVector3D & p) {p0 = p;}
|
||||||
|
|||||||
224
qglview/glrendererbase.cpp
Normal file
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
|
#ifndef GLTEXTUREMANAGER_H
|
||||||
#define GLTEXTUREMANAGER_H
|
#define GLTEXTUREMANAGER_H
|
||||||
|
|
||||||
#include "gltypes.h"
|
#include "glmaterial.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,9 @@
|
|||||||
#include "qglview.h"
|
#include "qglview.h"
|
||||||
|
|
||||||
QGLWidget * currentQGLView;
|
QGLWidget * currentQGLView;
|
||||||
GLTextureManager * currentGLTextureManager;
|
|
||||||
Camera * currentCamera;
|
Camera * currentCamera;
|
||||||
QMatrix4x4 globCameraMatrix;
|
QMatrix4x4 globCameraMatrix;
|
||||||
QMutex globMutex;
|
QMutex globMutex;
|
||||||
QStringList GLTextureManagerBase::search_pathes(".");
|
|
||||||
|
|
||||||
|
|
||||||
QString readCharsUntilNull(QDataStream & s) {
|
QString readCharsUntilNull(QDataStream & s) {
|
||||||
@@ -74,7 +72,17 @@ QMatrix4x4 getGLMatrix(GLenum matrix) {
|
|||||||
qreal qm[16];
|
qreal qm[16];
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i)
|
||||||
qm[i] = gm[i];
|
qm[i] = gm[i];
|
||||||
return QMatrix4x4(qm, 4, 4).transposed();
|
return QMatrix4x4(qm).transposed();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setGLMatrix(QMatrix4x4 matrix) {
|
||||||
|
GLfloat gm[16];
|
||||||
|
qreal qm[16];
|
||||||
|
matrix.transposed().copyDataTo(qm);
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
gm[i] = qm[i];
|
||||||
|
glLoadMatrixf(gm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -129,33 +137,16 @@ void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & dir) {
|
QMatrix4x4 glMatrixPerspective(double angle, double aspect, double near_, double far_) {
|
||||||
prog->removeAllShaders();
|
QMatrix4x4 ret;
|
||||||
QDir d(dir);
|
double t = 1. / (tan(angle * deg2rad / 2.));
|
||||||
QFileInfoList sl;
|
ret(0, 0) = t / aspect;
|
||||||
//qDebug() << "[QGLView] Shader \"" + name + "\" load shaders from" << d.absolutePath();
|
ret(1, 1) = t;
|
||||||
#if QT_VERSION >= 0x040700
|
ret(2, 2) = far_ / (far_ - near_) - 1.;
|
||||||
sl = d.entryInfoList(QStringList(name + ".geom"), QDir::Files | QDir::NoDotAndDotDot);
|
ret(2, 3) = 2. * far_ * near_ / (far_ - near_);
|
||||||
foreach (const QFileInfo & i, sl) {
|
ret(3, 2) = -1;
|
||||||
qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName();
|
ret(3, 3) = 0.;
|
||||||
prog->addShaderFromSourceFile(QGLShader::Geometry, i.absoluteFilePath());
|
return ret;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
sl = d.entryInfoList(QStringList(name + ".vert"), QDir::Files | QDir::NoDotAndDotDot);
|
|
||||||
foreach (const QFileInfo & i, sl) {
|
|
||||||
//qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
|
|
||||||
prog->addShaderFromSourceFile(QGLShader::Vertex, i.absoluteFilePath());
|
|
||||||
}
|
|
||||||
sl = d.entryInfoList(QStringList(name + ".frag"), QDir::Files | QDir::NoDotAndDotDot);
|
|
||||||
foreach (const QFileInfo & i, sl) {
|
|
||||||
//qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName();
|
|
||||||
prog->addShaderFromSourceFile(QGLShader::Fragment, i.absoluteFilePath());
|
|
||||||
}
|
|
||||||
if (!prog->link()) {
|
|
||||||
//qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -180,158 +171,6 @@ QImage rotateQImageRight(const QImage & im) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool GLCubeTexture::create() {
|
|
||||||
//qDebug("create");
|
|
||||||
destroy();
|
|
||||||
glGenTextures(1, &id_);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, id_);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
|
||||||
//glClearError();
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
||||||
//qDebug() << glGetError();
|
|
||||||
changed_ = false;
|
|
||||||
return id_ > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLCubeTexture::load() {
|
|
||||||
if (isEmpty()) return;
|
|
||||||
create();
|
|
||||||
if (!path(0).isEmpty()) loadFront(path(0));
|
|
||||||
if (!path(1).isEmpty()) loadBack(path(1));
|
|
||||||
if (!path(2).isEmpty()) loadLeft(path(2));
|
|
||||||
if (!path(3).isEmpty()) loadRight(path(3));
|
|
||||||
if (!path(4).isEmpty()) loadTop(path(4));
|
|
||||||
if (!path(5).isEmpty()) loadBottom(path(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLCubeTexture::loadFromDirectory(const QString & dir) {
|
|
||||||
QDir d(dir); QFileInfoList sl;
|
|
||||||
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath());
|
|
||||||
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBack(sl[0].absoluteFilePath());
|
|
||||||
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadLeft(sl[0].absoluteFilePath());
|
|
||||||
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadRight(sl[0].absoluteFilePath());
|
|
||||||
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadTop(sl[0].absoluteFilePath());
|
|
||||||
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBottom(sl[0].absoluteFilePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLCubeTexture::loadPathesFromDirectory(const QString & dir) {
|
|
||||||
QDir d(dir); QFileInfoList sl;
|
|
||||||
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[0] = sl[0].absoluteFilePath();
|
|
||||||
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[1] = sl[0].absoluteFilePath();
|
|
||||||
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[2] = sl[0].absoluteFilePath();
|
|
||||||
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[3] = sl[0].absoluteFilePath();
|
|
||||||
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[4] = sl[0].absoluteFilePath();
|
|
||||||
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) pathes[5] = sl[0].absoluteFilePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLuint GLTextureManagerBase::loadTexture(const QString & path, bool ownership, bool bump) {
|
|
||||||
QString p = findFile(path, search_pathes);
|
|
||||||
if (p.isEmpty()) return 0;
|
|
||||||
int tid = ((GLTextureManagerBase*)currentGLTextureManager)->textureID(p, bump);
|
|
||||||
if (tid > 0) {
|
|
||||||
//qDebug() << "[TextureManager] Found" << path << "as" << tid;
|
|
||||||
return tid;
|
|
||||||
}
|
|
||||||
QImage image(p);
|
|
||||||
if (bump) convertToNormal(image);
|
|
||||||
//qDebug() << p << image.width() << image.height() << image.format() << bump;
|
|
||||||
tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, QGLContext::MipmapBindOption*/);
|
|
||||||
if (tid == 0) {
|
|
||||||
qDebug() << "[TextureManager] Can`t load" << p;
|
|
||||||
return tid;
|
|
||||||
}
|
|
||||||
qDebug() << "[TextureManager] Loaded" << p << "as" << tid;
|
|
||||||
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids[bump ? 1 : 0].insert(p, tid);
|
|
||||||
return tid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLuint GLTextureManagerBase::loadTexture(const QImage & im, bool ownership, bool bump) {
|
|
||||||
if (im.isNull()) return 0;
|
|
||||||
QImage image(im);
|
|
||||||
if (bump) convertToNormal(image);
|
|
||||||
GLuint tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
|
||||||
if (tid == 0) {
|
|
||||||
qDebug() << "[TextureManager] Can`t load image";
|
|
||||||
return tid;
|
|
||||||
}
|
|
||||||
//qDebug() << "[TextureManager] Loaded image as" << tid;
|
|
||||||
if (ownership) ((GLTextureManagerBase*)currentGLTextureManager)->tex_ids[bump ? 1 : 0].insert(QString(), tid);
|
|
||||||
return tid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3d colorVector(QRgb c) {return Vector3d(((uchar*)(&c))[0] / 255., ((uchar*)(&c))[1] / 255., ((uchar*)(&c))[2] / 255.);}
|
|
||||||
|
|
||||||
void GLTextureManagerBase::convertToNormal(QImage & im) {
|
|
||||||
if (im.isNull()) return;
|
|
||||||
QImage sim = im.convertToFormat(QImage::Format_ARGB32);
|
|
||||||
double sum[3] = {0., 0., 0.};
|
|
||||||
llong a = 0;
|
|
||||||
const uchar * sd = sim.constBits();
|
|
||||||
for (int i = 0; i < sim.height(); i++) {
|
|
||||||
for (int j = 0; j < sim.width(); j++) {
|
|
||||||
sum[2] += double(sd[a]) / 255. - 0.5; ++a;
|
|
||||||
sum[1] += double(sd[a]) / 255. - 0.5; ++a;
|
|
||||||
sum[0] += double(sd[a]) / 255. - 0.5; ++a;
|
|
||||||
++a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double wh = sim.width() * sim.height();
|
|
||||||
sum[0] /= wh;
|
|
||||||
sum[1] /= wh;
|
|
||||||
sum[2] /= wh;
|
|
||||||
qDebug() << sum[0] << sum[1] << sum[2];
|
|
||||||
if ((qAbs(sum[0]) <= 0.05) && (qAbs(sum[1]) <= 0.05) && (sum[2] >= 0.4)) /// already normal
|
|
||||||
return;
|
|
||||||
qDebug() << "convert to bump";
|
|
||||||
QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32);
|
|
||||||
int tx, ty, w = sim.width(), h = sim.height();
|
|
||||||
a = 0;
|
|
||||||
uchar * dd = dim.bits();
|
|
||||||
for (int i = 0; i < sim.height(); i++) {
|
|
||||||
for (int j = 0; j < sim.width(); j++) {
|
|
||||||
tx = j - 1;
|
|
||||||
tx = tx < 0 ? w + tx : tx % w;
|
|
||||||
ty = i - 1;
|
|
||||||
ty = ty < 0 ? h + ty : ty % h;
|
|
||||||
Vector3d p[3], res;
|
|
||||||
p[0] = colorVector(sim.pixel(j, i));
|
|
||||||
p[1] = colorVector(sim.pixel(j, ty));
|
|
||||||
p[2] = colorVector(sim.pixel(tx, i));
|
|
||||||
res.y = piClamp(0.5 + (p[0].length() - p[1].length()) / 2., 0., 1.);
|
|
||||||
res.x = piClamp(0.5 + (p[0].length() - p[2].length()) / 2., 0., 1.);
|
|
||||||
tx = (j + 1) % w;
|
|
||||||
ty = (i + 1) % h;
|
|
||||||
p[1] = colorVector(sim.pixel(j, ty));
|
|
||||||
p[2] = colorVector(sim.pixel(tx, i));
|
|
||||||
res.y = piClamp(0.5 + (p[0].length() - p[1].length()) / 2., 0., 1.);
|
|
||||||
res.x = piClamp(0.5 + (p[0].length() - p[2].length()) / 2., 0., 1.);
|
|
||||||
res.z = 1.;
|
|
||||||
dd[a] = res.z * 255; ++a;
|
|
||||||
dd[a] = res.x * 255; ++a;
|
|
||||||
dd[a] = res.y * 255; ++a;
|
|
||||||
dd[a] = 255; ++a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
im = dim;
|
|
||||||
//im.save("_bump.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Camera::anglesFromPoints() {
|
void Camera::anglesFromPoints() {
|
||||||
QVector3D dv = aim_ - pos_, tv;
|
QVector3D dv = aim_ - pos_, tv;
|
||||||
@@ -346,7 +185,10 @@ void Camera::apply(const GLdouble & aspect) {
|
|||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
if (aspect <= 1.)
|
if (aspect <= 1.)
|
||||||
glScaled(aspect, aspect, 1.);
|
glScaled(aspect, aspect, 1.);
|
||||||
gluPerspective(fov_, aspect, depth_start, depth_end);
|
QMatrix4x4 pm;// = glMatrixPerspective(fov_, aspect, depth_start, depth_end);
|
||||||
|
pm.perspective(fov_, aspect, depth_start, depth_end);
|
||||||
|
//qDebug() << pm << glMatrixPerspective(fov_, aspect, depth_start, depth_end);;
|
||||||
|
setGLMatrix(pm);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glTranslated(0., 0., -distance());
|
glTranslated(0., 0., -distance());
|
||||||
@@ -518,53 +360,6 @@ QVector3D Camera::pointFromViewport(int x_, int y_, double z_) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Material::Material(): reflection(512) {
|
|
||||||
color_diffuse = color_specular = Qt::white;
|
|
||||||
color_self_illumination = Qt::black;
|
|
||||||
glass = false;
|
|
||||||
transparency = reflectivity = 0.f;
|
|
||||||
bump_scale = relief_scale = iof = 1.f;
|
|
||||||
dispersion = 0.05f;
|
|
||||||
shine = 0.5;
|
|
||||||
shine_strength = 1.f;
|
|
||||||
light_model = Phong;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Material::apply() {
|
|
||||||
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
|
||||||
GLfloat mat_specular[4] = {0.9f, 0.9f, 0.9f, 1.0f};
|
|
||||||
GLfloat mat_emission[4] = {0.f, 0.f, 0.f, 1.0f};
|
|
||||||
mat_diffuse[0] = color_diffuse.redF();
|
|
||||||
mat_diffuse[1] = color_diffuse.greenF();
|
|
||||||
mat_diffuse[2] = color_diffuse.blueF();
|
|
||||||
mat_diffuse[3] = color_diffuse.alphaF() * (1.f - transparency);
|
|
||||||
mat_specular[0] = shine_strength * color_specular.redF();
|
|
||||||
mat_specular[1] = shine_strength * color_specular.greenF();
|
|
||||||
mat_specular[2] = shine_strength * color_specular.blueF();
|
|
||||||
mat_emission[0] = color_self_illumination.redF();
|
|
||||||
mat_emission[1] = color_self_illumination.greenF();
|
|
||||||
mat_emission[2] = color_self_illumination.blueF();
|
|
||||||
glColor4f(mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
|
|
||||||
//qDebug() << color_diffuse.alphaF() * (1.f - transparency);
|
|
||||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
|
|
||||||
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
|
|
||||||
glMaterialf(GL_FRONT, GL_SHININESS, shine);
|
|
||||||
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
|
|
||||||
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Material::loadTextures(GLTextureManagerBase * tm) {
|
|
||||||
//qDebug() << "load textures";
|
|
||||||
if (tm == 0) tm = (GLTextureManagerBase*)currentGLTextureManager;
|
|
||||||
if (!diffuse.bitmap_path.isEmpty()) diffuse.bitmap_id = tm->loadTexture(diffuse.bitmap_path);
|
|
||||||
if (!bump.bitmap_path.isEmpty()) bump.bitmap_id = tm->loadTexture(bump.bitmap_path, true, true);
|
|
||||||
if (!relief.bitmap_path.isEmpty()) relief.bitmap_id = tm->loadTexture(relief.bitmap_path);
|
|
||||||
if (!diffuse_2.bitmap_path.isEmpty()) diffuse_2.bitmap_id = tm->loadTexture(diffuse_2.bitmap_path);
|
|
||||||
reflection.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QColor colorFromString(const QString & str) {
|
QColor colorFromString(const QString & str) {
|
||||||
QString s = str.trimmed();
|
QString s = str.trimmed();
|
||||||
@@ -632,199 +427,25 @@ Vector3i::Vector3i(const QString & str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void glEnableDepth() {
|
||||||
void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index) {
|
glEnable(GL_DEPTH_TEST);
|
||||||
QVector3D lp = l.worldPos(), ld = (l.itransform_ * QVector4D(l.direction, 0.)).toVector3D().normalized();
|
//glDepthFunc(GL_GREATER);
|
||||||
GLfloat pos[] = {0.f, 0.f, 0.f, 0.f};
|
glDepthFunc(GL_LESS);
|
||||||
GLfloat dir[] = {0.f, 0.f, 0.f};
|
glDepthMask(GL_TRUE);
|
||||||
GLfloat col[] = {0.f, 0.f, 0.f};
|
|
||||||
pos[0] = l.light_type == Light::Directional ? -l.direction.x() : lp.x();
|
|
||||||
pos[1] = l.light_type == Light::Directional ? -l.direction.y() : lp.y();
|
|
||||||
pos[2] = l.light_type == Light::Directional ? -l.direction.z() : lp.z();
|
|
||||||
pos[3] = l.light_type == Light::Directional ? 0. : 1.;
|
|
||||||
dir[0] = ld.x();
|
|
||||||
dir[1] = ld.y();
|
|
||||||
dir[2] = ld.z();
|
|
||||||
col[0] = l.visible_ ? l.color().redF() * l.intensity : 0.;
|
|
||||||
col[1] = l.visible_ ? l.color().greenF() * l.intensity : 0.;
|
|
||||||
col[2] = l.visible_ ? l.color().blueF() * l.intensity : 0.;
|
|
||||||
glEnable(gl_index);
|
|
||||||
//glLightfv(gl_index, GL_AMBIENT, ambient);
|
|
||||||
glLightfv(gl_index, GL_DIFFUSE, col);
|
|
||||||
glLightfv(gl_index, GL_SPECULAR, col);
|
|
||||||
glLightfv(gl_index, GL_POSITION, pos);
|
|
||||||
glLightf(gl_index, GL_CONSTANT_ATTENUATION, l.decay_const);
|
|
||||||
glLightf(gl_index, GL_LINEAR_ATTENUATION, l.decay_linear);
|
|
||||||
glLightf(gl_index, GL_QUADRATIC_ATTENUATION, l.decay_quadratic);
|
|
||||||
if (l.light_type == Light::Cone) {
|
|
||||||
glLightfv(gl_index, GL_SPOT_DIRECTION, dir);
|
|
||||||
glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_spread);
|
|
||||||
glLightf(gl_index, GL_SPOT_EXPONENT, l.angle_decay_exp);
|
|
||||||
} else {
|
|
||||||
glLightf(gl_index, GL_SPOT_CUTOFF, 180.);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLRendererBase::setupAmbientLight(const QColor & a, bool first_pass) {
|
void glDisableDepth() {
|
||||||
GLfloat ambient[] = {0.0f, 0.0f, 0.0f, 1.f};
|
glDisable(GL_DEPTH_TEST);
|
||||||
if (first_pass) {
|
glDepthMask(GL_FALSE);
|
||||||
ambient[0] = view.ambientColor_.redF();
|
|
||||||
ambient[1] = view.ambientColor_.greenF();
|
|
||||||
ambient[2] = view.ambientColor_.blueF();
|
|
||||||
}
|
|
||||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLRendererBase::setupShadersLights(int lights_count) {
|
void glClearFramebuffer(const QColor & color, bool depth) {
|
||||||
/*foreach (QGLShaderProgram * i, view.shaders_ppl) {
|
glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
||||||
i->bind();
|
glClearDepth(1.);
|
||||||
i->setUniformValue("lightsCount", lights_count);
|
if (depth)
|
||||||
i->setUniformValue("acc_light", lights_count > 0);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
//i->setUniformValue("mat", mvm);
|
else
|
||||||
}*/
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingParameters & rp, bool first_object) {
|
|
||||||
if (first_object) {
|
|
||||||
glReleaseTextures();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setupShadersTextures(o, rp);
|
|
||||||
Material & mat(o.material_);
|
|
||||||
if (rp.light) {
|
|
||||||
if (o.accept_light) {if (!rp.prev_light) {glSetLightEnabled(true); rp.prev_light = true;}}
|
|
||||||
else {if (rp.prev_light) {glSetLightEnabled(false); rp.prev_light = false;}}
|
|
||||||
}
|
|
||||||
if (rp.fog) {
|
|
||||||
if (o.accept_fog) {if (!rp.prev_fog) {glSetFogEnabled(true); rp.prev_fog = true;}}
|
|
||||||
else {if (rp.prev_fog) {glSetFogEnabled(false); rp.prev_fog = false;}}
|
|
||||||
}
|
|
||||||
if (rp.textures) {
|
|
||||||
if (rp.prev_tex[0] != mat.diffuse.bitmap_id) {
|
|
||||||
rp.prev_tex[0] = mat.diffuse.bitmap_id;
|
|
||||||
glActiveTextureChannel(0); glBindTexture(GL_TEXTURE_2D, mat.diffuse.bitmap_id);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
|
|
||||||
}
|
|
||||||
if (rp.prev_tex[1] != mat.bump.bitmap_id) {
|
|
||||||
rp.prev_tex[1] = mat.bump.bitmap_id;
|
|
||||||
glActiveTextureChannel(1); glBindTexture(GL_TEXTURE_2D, mat.bump.bitmap_id);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
|
|
||||||
}
|
|
||||||
if (rp.prev_tex[2] != mat.relief.bitmap_id) {
|
|
||||||
rp.prev_tex[2] = mat.relief.bitmap_id;
|
|
||||||
glActiveTextureChannel(2); glBindTexture(GL_TEXTURE_2D, mat.relief.bitmap_id);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
|
|
||||||
}
|
|
||||||
glActiveTextureChannel(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLRendererBase::setupLights(int pass, int lights_per_pass) {
|
|
||||||
int light_start, light_end, lmax;
|
|
||||||
light_start = pass * lights_per_pass;
|
|
||||||
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights_.size());
|
|
||||||
setupAmbientLight(view.ambientColor_, pass == 0);
|
|
||||||
if (!view.lights_.isEmpty()) {
|
|
||||||
setupShadersLights(light_end - light_start);
|
|
||||||
for (int i = light_start; i < light_end; ++i)
|
|
||||||
setupLight(*view.lights_[i], i - light_start, GL_LIGHT0 + i - light_start);
|
|
||||||
lmax = light_start + 8;
|
|
||||||
for (int i = light_end; i < lmax; ++i)
|
|
||||||
glDisable(GL_LIGHT0 + i - light_start);
|
|
||||||
} else {
|
|
||||||
setupShadersLights(0);
|
|
||||||
for (int i = 0; i < 8; ++i)
|
|
||||||
glDisable(GL_LIGHT0 + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLRendererBase::applyFilteringParameters() {
|
|
||||||
if (view.linearFiltering_) {
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
||||||
} else {
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
|
||||||
}
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.anisotropicLevel_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, bool textures, bool light, bool fog) {
|
|
||||||
RenderingParameters rp;
|
|
||||||
rp.pass = pass;
|
|
||||||
rp.light_pass = light_pass;
|
|
||||||
rp.shaders = shaders;
|
|
||||||
rp.textures = textures;
|
|
||||||
rp.light = rp.prev_light = light;
|
|
||||||
rp.fog = rp.prev_fog = fog;
|
|
||||||
for (int i = 0; i < 32; ++i) rp.prev_tex[i] = 0;
|
|
||||||
rp.prev_light_model = Material::Phong;
|
|
||||||
setupTextures(view.objects_, rp, true);
|
|
||||||
glSetLightEnabled(rp.prev_light);
|
|
||||||
glSetFogEnabled(rp.prev_fog);
|
|
||||||
glSetCapEnabled(GL_TEXTURE_2D, rp.textures);
|
|
||||||
glSetCapEnabled(GL_BLEND, pass == GLObjectBase::Transparent);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
|
||||||
renderSingleObject(view.objects_, rp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rp) {
|
|
||||||
if (!o.isInit())
|
|
||||||
o.init();
|
|
||||||
if (!o.isTexturesLoaded())
|
|
||||||
o.loadTextures();
|
|
||||||
if (!o.visible_) return;
|
|
||||||
Material & mat(o.material_);
|
|
||||||
glPushMatrix();
|
|
||||||
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
|
|
||||||
if (o.raw_matrix) {
|
|
||||||
qglMultMatrix(o.mat_);
|
|
||||||
} else {
|
|
||||||
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
|
|
||||||
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
|
|
||||||
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
|
|
||||||
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
|
|
||||||
}
|
|
||||||
if (rp.pass == o.pass_) {
|
|
||||||
setupTextures(o, rp, false);
|
|
||||||
mat.apply();
|
|
||||||
glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
|
|
||||||
glLineWidth(o.line_width > 0. ? o.line_width : view.lineWidth_);
|
|
||||||
glPointSize(o.line_width > 0. ? o.line_width : view.lineWidth_);
|
|
||||||
o.update();
|
|
||||||
if (o.pass_ == GLObjectBase::Transparent) {
|
|
||||||
glActiveTextureChannel(3);
|
|
||||||
if (mat.reflectivity > 0.) {
|
|
||||||
glEnable(GL_TEXTURE_CUBE_MAP);
|
|
||||||
if (!mat.reflection.isEmpty()) mat.reflection.bind();
|
|
||||||
else glDisable(GL_TEXTURE_CUBE_MAP);
|
|
||||||
} else glDisable(GL_TEXTURE_CUBE_MAP);
|
|
||||||
if (rp.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP);
|
|
||||||
GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity};
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
|
|
||||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, bc);
|
|
||||||
glGetFloatv(GL_MODELVIEW_MATRIX, gm);
|
|
||||||
glMatrixMode(GL_TEXTURE);
|
|
||||||
glLoadTransposeMatrixf(gm);
|
|
||||||
glScalef(-1., -1., -1.);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glActiveTextureChannel(0);
|
|
||||||
}
|
|
||||||
o.draw();
|
|
||||||
}
|
|
||||||
foreach (GLObjectBase * i, o.children_)
|
|
||||||
renderSingleObject(*i, rp);
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,11 +140,13 @@ inline QColor operator /(const QColor & c, double v) {return QColor(c.red() / v,
|
|||||||
|
|
||||||
inline void qglColor(const QColor & c) {glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());}
|
inline void qglColor(const QColor & c) {glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());}
|
||||||
void qglMultMatrix(const QMatrix4x4 & m);
|
void qglMultMatrix(const QMatrix4x4 & m);
|
||||||
|
void glEnableDepth();
|
||||||
|
void glDisableDepth();
|
||||||
inline void glActiveTextureChannel(int channel) {glActiveTexture(GL_TEXTURE0 + channel); glClientActiveTexture(GL_TEXTURE0 + channel);}
|
inline void glActiveTextureChannel(int channel) {glActiveTexture(GL_TEXTURE0 + channel); glClientActiveTexture(GL_TEXTURE0 + channel);}
|
||||||
inline void glResetAllTransforms() {glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}
|
inline void glResetAllTransforms() {glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}
|
||||||
inline void glClearError() {int c = 100; while (glGetError() != GL_NO_ERROR && --c > 0) glGetError();}
|
inline void glClearError() {int c = 100; while (glGetError() != GL_NO_ERROR && --c > 0) glGetError();}
|
||||||
inline void glClearAccumulation(const QColor & color = Qt::black) {glClearAccum(color.redF(), color.greenF(), color.blueF(), color.alphaF()); glClear(GL_ACCUM_BUFFER_BIT);}
|
inline void glClearAccumulation(const QColor & color = Qt::black) {glClearAccum(color.redF(), color.greenF(), color.blueF(), color.alphaF()); glClear(GL_ACCUM_BUFFER_BIT);}
|
||||||
inline void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true) {glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); if (depth) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else glClear(GL_COLOR_BUFFER_BIT);}
|
void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true);
|
||||||
inline void glReleaseTextures(int channels = 8) {for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}}
|
inline void glReleaseTextures(int channels = 8) {for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}}
|
||||||
inline void glReleaseFramebuffer() {glBindFramebuffer(GL_FRAMEBUFFER, 0);}
|
inline void glReleaseFramebuffer() {glBindFramebuffer(GL_FRAMEBUFFER, 0);}
|
||||||
inline void glDisableTextures(int channels = 8) {for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP);}}
|
inline void glDisableTextures(int channels = 8) {for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP);}}
|
||||||
@@ -155,15 +157,17 @@ inline void glSetFogEnabled(bool on) {if (on) glEnable(GL_FOG); else glDisable(G
|
|||||||
inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);}
|
inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);}
|
||||||
void glDrawQuad(GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f);
|
void glDrawQuad(GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f);
|
||||||
QMatrix4x4 getGLMatrix(GLenum matrix);
|
QMatrix4x4 getGLMatrix(GLenum matrix);
|
||||||
|
void setGLMatrix(QMatrix4x4 matrix);
|
||||||
inline void deleteGLTexture(GLuint & tex) {if (tex != 0) glDeleteTextures(1, &tex); tex = 0;}
|
inline void deleteGLTexture(GLuint & tex) {if (tex != 0) glDeleteTextures(1, &tex); tex = 0;}
|
||||||
inline void deleteGLFramebuffer(GLuint & fbo) {if (fbo != 0) glDeleteFramebuffers(1, &fbo); fbo = 0;}
|
inline void deleteGLFramebuffer(GLuint & fbo) {if (fbo != 0) glDeleteFramebuffers(1, &fbo); fbo = 0;}
|
||||||
inline void deleteGLRenderbuffer(GLuint & drbo) {if (drbo != 0) glDeleteRenderbuffers(1, &drbo); drbo = 0;}
|
inline void deleteGLRenderbuffer(GLuint & drbo) {if (drbo != 0) glDeleteRenderbuffers(1, &drbo); drbo = 0;}
|
||||||
inline void deleteGLBuffer(GLuint & bo) {if (bo != 0) glDeleteBuffers(1, &bo); bo = 0;}
|
inline void deleteGLBuffer(GLuint & bo) {if (bo != 0) glDeleteBuffers(1, &bo); bo = 0;}
|
||||||
|
inline void deleteGLVertexArray(GLuint & va) {if (va != 0) glDeleteVertexArrays(1, &va); va = 0;}
|
||||||
void createGLTexture(GLuint & tex, int width, int height, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
|
void createGLTexture(GLuint & tex, int width, int height, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
|
||||||
void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
|
void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
|
||||||
inline void qglTranslate(const QVector3D & v) {glTranslated(v.x(), v.y(), v.z());}
|
inline void qglTranslate(const QVector3D & v) {glTranslated(v.x(), v.y(), v.z());}
|
||||||
inline void qglScale(const QVector3D & v) {glScaled(v.x(), v.y(), v.z());}
|
inline void qglScale(const QVector3D & v) {glScaled(v.x(), v.y(), v.z());}
|
||||||
bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString & dir = QString());
|
QMatrix4x4 glMatrixPerspective(double angle, double aspect, double near_, double far_);
|
||||||
QImage rotateQImageLeft(const QImage & im);
|
QImage rotateQImageLeft(const QImage & im);
|
||||||
QImage rotateQImageRight(const QImage & im);
|
QImage rotateQImageRight(const QImage & im);
|
||||||
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);}
|
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);}
|
||||||
@@ -174,76 +178,6 @@ extern QGLWidget * currentQGLView;
|
|||||||
extern QMatrix4x4 globCameraMatrix;
|
extern QMatrix4x4 globCameraMatrix;
|
||||||
extern QMutex globMutex;
|
extern QMutex globMutex;
|
||||||
|
|
||||||
|
|
||||||
class GLTexture {
|
|
||||||
public:
|
|
||||||
GLTexture(int _width, int _height, const GLenum & _format = GL_RGBA8, const GLenum & _target = GL_TEXTURE_2D) {wid = _width; hei = _height; format_ = _format; target_ = _target; id_ = 0;}
|
|
||||||
bool create() {destroy(); createGLTexture(id_, wid, hei, format_, target_); return id_ > 0;}
|
|
||||||
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;}
|
|
||||||
void bind() {if (id_ > 0) glBindTexture(target_, id_);}
|
|
||||||
void release() {glBindTexture(target_, 0);}
|
|
||||||
int width() const {return wid;}
|
|
||||||
int height() const {return hei;}
|
|
||||||
GLenum format() const {return format_;}
|
|
||||||
GLenum target() const {return target_;}
|
|
||||||
GLuint id() const {return id_;}
|
|
||||||
private:
|
|
||||||
int wid, hei;
|
|
||||||
GLenum format_, target_;
|
|
||||||
GLuint id_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class GLCubeTexture {
|
|
||||||
public:
|
|
||||||
GLCubeTexture(int _size, const GLenum & _format = GL_RGBA8) {size = _size; format_ = _format; id_ = 0; changed_ = false; pathes.resize(6);}
|
|
||||||
bool create();
|
|
||||||
void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;}
|
|
||||||
void bind() {if (changed_) {changed_ = false; create();} if (id_ > 0) glBindTexture(GL_TEXTURE_CUBE_MAP, id_);}
|
|
||||||
void release() {glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}
|
|
||||||
void resize(int _size) {size = _size; changed_ = true;}
|
|
||||||
void loadFromDirectory(const QString & dir);
|
|
||||||
void loadFront(const QString & path) {bind(); pathes[0] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_X);}
|
|
||||||
void loadBack(const QString & path) {bind(); pathes[1] = path; createGLTexture(id_, rotateQImageRight(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_X);}
|
|
||||||
void loadLeft(const QString & path) {bind(); pathes[2] = path; createGLTexture(id_, QImage(path).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);}
|
|
||||||
void loadRight(const QString & path) {bind(); pathes[3] = path; createGLTexture(id_, rotateQImage180(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Y);}
|
|
||||||
void loadTop(const QString & path) {bind(); pathes[4] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);}
|
|
||||||
void loadBottom(const QString & path) {bind(); pathes[5] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Z);}
|
|
||||||
void load();
|
|
||||||
bool isEmpty() const {foreach (const QString & i, pathes) if (!i.isEmpty()) return false; return true;}
|
|
||||||
GLenum format() const {return format_;}
|
|
||||||
void setFormat(GLenum f) {format_ = f; changed_ = true;}
|
|
||||||
GLuint id() const {return id_;}
|
|
||||||
const QString & path(int side) const {return pathes[side];}
|
|
||||||
void setPath(int side, const QString & p) {pathes[side] = p;}
|
|
||||||
void loadPathesFromDirectory(const QString & dir);
|
|
||||||
private:
|
|
||||||
bool changed_;
|
|
||||||
int size;
|
|
||||||
GLenum format_;
|
|
||||||
GLuint id_;
|
|
||||||
QVector<QString> pathes;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GLTextureManager;
|
|
||||||
|
|
||||||
class GLTextureManagerBase {
|
|
||||||
public:
|
|
||||||
static void addSearchPath(const QString & path) {search_pathes << path;}
|
|
||||||
static QStringList searchPathes() {return search_pathes;}
|
|
||||||
static GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false);
|
|
||||||
static GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false);
|
|
||||||
int textureID(const QString & path, bool bump = false) {return tex_ids[bump ? 1 : 0][path];}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void convertToNormal(QImage & im);
|
|
||||||
static QStringList search_pathes;
|
|
||||||
QMap<QString, GLuint> tex_ids[2];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
extern GLTextureManager * currentGLTextureManager;
|
|
||||||
|
|
||||||
class Camera
|
class Camera
|
||||||
{
|
{
|
||||||
friend class QGLView;
|
friend class QGLView;
|
||||||
@@ -328,44 +262,6 @@ private:
|
|||||||
|
|
||||||
extern Camera * currentCamera;
|
extern Camera * currentCamera;
|
||||||
|
|
||||||
struct Map {
|
|
||||||
Map() {bitmap_id = 0; bitmap_amount = 1.f; animation_frame_rate = -1.f;}
|
|
||||||
QString bitmap_path;
|
|
||||||
GLuint bitmap_id;
|
|
||||||
QPointF bitmap_offset;
|
|
||||||
float bitmap_amount;
|
|
||||||
QString animation;
|
|
||||||
float animation_frame_rate;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Material {
|
|
||||||
enum LightModel {Phong = 0, CookTorrance = 1, Minnaert = 2, Strauss = 3, OrenNayar = 4};
|
|
||||||
Material();
|
|
||||||
QString name;
|
|
||||||
void apply();
|
|
||||||
void loadTextures(GLTextureManagerBase * tm = 0);
|
|
||||||
QColor color_diffuse;
|
|
||||||
QColor color_specular;
|
|
||||||
QColor color_self_illumination;
|
|
||||||
LightModel light_model;
|
|
||||||
bool glass;
|
|
||||||
float shine;
|
|
||||||
float shine_strength;
|
|
||||||
float transparency;
|
|
||||||
float reflectivity;
|
|
||||||
float iof;
|
|
||||||
float dispersion;
|
|
||||||
float bump_scale;
|
|
||||||
float relief_scale;
|
|
||||||
Map diffuse;
|
|
||||||
Map bump;
|
|
||||||
Map relief;
|
|
||||||
Map diffuse_2;
|
|
||||||
Map diffuse_3;
|
|
||||||
Map diffuse_4;
|
|
||||||
GLCubeTexture reflection;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Box3D {
|
struct Box3D {
|
||||||
GLfloat x;
|
GLfloat x;
|
||||||
GLfloat y;
|
GLfloat y;
|
||||||
@@ -479,14 +375,10 @@ inline uint qHash(const Vector3i & v) {return v.p0 + v.p1 * 1024 + v.p2 * 1024 *
|
|||||||
inline QDebug operator <<(QDebug d, const Vector3d& v) {d.nospace() << "{" << v.x << ", " << v.y << ", " << v.z << "}"; return d.space();}
|
inline QDebug operator <<(QDebug d, const Vector3d& v) {d.nospace() << "{" << v.x << ", " << v.y << ", " << v.z << "}"; return d.space();}
|
||||||
inline QDebug operator <<(QDebug d, const Vector3i & v) {d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}"; return d.space();}
|
inline QDebug operator <<(QDebug d, const Vector3i & v) {d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}"; return d.space();}
|
||||||
|
|
||||||
inline QDataStream & operator <<(QDataStream & s, const Map & m) {s << m.bitmap_path << m.bitmap_amount << m.animation << m.animation_frame_rate; return s;}
|
|
||||||
inline QDataStream & operator <<(QDataStream & s, const Vector3d & v) {s << v.x << v.y << v.z; return s;}
|
inline QDataStream & operator <<(QDataStream & s, const Vector3d & v) {s << v.x << v.y << v.z; return s;}
|
||||||
|
inline QDataStream & operator >>(QDataStream & s, Vector3d & v) {s >> v.x >> v.y >> v.z; return s;}
|
||||||
inline QDataStream & operator <<(QDataStream & s, const Vector3i & v) {s << v.p0 << v.p1 << v.p2; return s;}
|
inline QDataStream & operator <<(QDataStream & s, const Vector3i & v) {s << v.p0 << v.p1 << v.p2; return s;}
|
||||||
inline QDataStream & operator <<(QDataStream & s, const Material & m) {s << m.color_diffuse << m.shine << m.shine_strength << m.color_specular << m.transparency << m.diffuse << m.bump; return s;}
|
inline QDataStream & operator >>(QDataStream & s, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; return s;}
|
||||||
inline QDataStream & operator >>(QDataStream & s, Map & m) {s >> m.bitmap_path >> m.bitmap_amount >> m.animation >> m.animation_frame_rate; return s;}
|
|
||||||
inline QDataStream & operator >>(QDataStream & s, Vector3d & v) {s >> v.x >> v.y >> v.z; return s;}
|
|
||||||
inline QDataStream & operator >>(QDataStream & s, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; return s;}
|
|
||||||
inline QDataStream & operator >>(QDataStream & s, Material & m) {s >> m.color_diffuse >> m.shine >> m.shine_strength >> m.color_specular >> m.transparency >> m.diffuse >> m.bump; return s;}
|
|
||||||
|
|
||||||
QColor colorFromString(const QString & str);
|
QColor colorFromString(const QString & str);
|
||||||
inline double cosABV(const QVector3D & v0, const QVector3D & v1) {
|
inline double cosABV(const QVector3D & v0, const QVector3D & v1) {
|
||||||
@@ -519,45 +411,4 @@ protected:
|
|||||||
Camera camera_;
|
Camera camera_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class GLRendererBase: public QObject
|
|
||||||
{
|
|
||||||
friend class QGLView;
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
GLRendererBase(QGLView * view_): view(*view_) {}
|
|
||||||
virtual void renderScene() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
struct RenderingParameters {
|
|
||||||
int pass;
|
|
||||||
int light_pass;
|
|
||||||
bool light;
|
|
||||||
bool fog;
|
|
||||||
bool textures;
|
|
||||||
bool prev_light;
|
|
||||||
bool prev_fog;
|
|
||||||
Material::LightModel prev_light_model;
|
|
||||||
GLuint prev_tex[32];
|
|
||||||
void * shaders;
|
|
||||||
QGLShaderProgram * cur_shader;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual void setupLight(const Light & l, int inpass_index, int gl_index);
|
|
||||||
virtual void setupAmbientLight(const QColor & a, bool first_pass);
|
|
||||||
virtual void setupShadersLights(int lights_count);
|
|
||||||
virtual void setupTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp, bool first_object = false);
|
|
||||||
virtual void setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) {}
|
|
||||||
virtual void reloadShaders() {}
|
|
||||||
virtual void init(int width, int height) {}
|
|
||||||
virtual void resize(int width, int height) {}
|
|
||||||
|
|
||||||
void setupLights(int pass, int lights_per_pass);
|
|
||||||
inline void applyFilteringParameters();
|
|
||||||
void renderObjects(int pass, int light_pass, void * shaders = 0, bool textures = true, bool light = true, bool fog = true);
|
|
||||||
void renderSingleObject(GLObjectBase & o, RenderingParameters & rp);
|
|
||||||
|
|
||||||
QGLView & view;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // GLTYPES_H
|
#endif // GLTYPES_H
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
GLVBO::GLVBO(GLenum usage_) {
|
GLVBO::GLVBO(GLenum usage_) {
|
||||||
buffer_ = 0;
|
buffer_ = 0;
|
||||||
|
va_ = 0;
|
||||||
usage = usage_;
|
usage = usage_;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
@@ -32,12 +33,20 @@ GLVBO::~GLVBO() {
|
|||||||
|
|
||||||
|
|
||||||
void GLVBO::init() {
|
void GLVBO::init() {
|
||||||
if (!isIinit())
|
if (!isIinit()) {
|
||||||
|
//glGenVertexArrays(1, &va_);
|
||||||
glGenBuffers(1, &buffer_);
|
glGenBuffers(1, &buffer_);
|
||||||
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLVBO::destroy() {
|
||||||
|
deleteGLBuffer(buffer_);
|
||||||
|
//deleteGLVertexArray(va_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GLVBO::rebuffer(bool clear_) {
|
bool GLVBO::rebuffer(bool clear_) {
|
||||||
QVector<GLfloat> data;
|
QVector<GLfloat> data;
|
||||||
//data.clear();
|
//data.clear();
|
||||||
@@ -54,9 +63,12 @@ bool GLVBO::rebuffer(bool clear_) {
|
|||||||
data << colors_;
|
data << colors_;
|
||||||
has_colors = true;
|
has_colors = true;
|
||||||
} else has_colors = false;
|
} else has_colors = false;
|
||||||
|
//glBindVertexArray(va_);
|
||||||
|
//qDebug() << "load buffer" << data.size() << buffer_;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, buffer_);
|
glBindBuffer(GL_ARRAY_BUFFER, buffer_);
|
||||||
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.constData(), usage);
|
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.constData(), usage);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
//glBindVertexArray(0);
|
||||||
vert_count = vertices_.size() / 3;
|
vert_count = vertices_.size() / 3;
|
||||||
changed = false;
|
changed = false;
|
||||||
//qDebug() << "rebuff" << buffer_ << vert_count;
|
//qDebug() << "rebuff" << buffer_ << vert_count;
|
||||||
@@ -65,35 +77,76 @@ bool GLVBO::rebuffer(bool clear_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLVBO::draw(GLenum type, bool simplest) {
|
void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
|
||||||
if (buffer_ == 0 || vert_count == 0) return;
|
if (buffer_ == 0 || vert_count == 0) return;
|
||||||
if (changed) rebuffer();
|
if (changed) rebuffer();
|
||||||
//qDebug() << "draw" << vert_count;
|
//qDebug() << "draw" << vert_count;
|
||||||
void * offset = (void*)(vert_count * 3 * sizeof(GLfloat));
|
void * offset = (void*)(vert_count * 3 * sizeof(GLfloat));
|
||||||
|
//glBindVertexArray(va_);
|
||||||
|
|
||||||
|
void * offsets[3] = {0, 0, 0};
|
||||||
|
if (has_normals) {
|
||||||
|
offsets[0] = offset;
|
||||||
|
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
||||||
|
}
|
||||||
|
if (has_texcoords) {
|
||||||
|
offsets[1] = offset;
|
||||||
|
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
|
||||||
|
}
|
||||||
|
if (has_colors) {
|
||||||
|
offsets[2] = offset;
|
||||||
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, buffer_);
|
glBindBuffer(GL_ARRAY_BUFFER, buffer_);
|
||||||
glMultiTexCoord3f(GL_TEXTURE2, 0.f, 1.f, 0.f);
|
if (prog) {
|
||||||
glVertexPointer(3, GL_FLOAT, 0, 0);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
if (!simplest) {
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
int loc = prog->attributeLocation("_qgl_Vertex");
|
||||||
|
glEnableVertexAttribArray(loc);
|
||||||
|
glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, 0);
|
||||||
|
loc = prog->attributeLocation("qgl_Normal");
|
||||||
if (has_normals) {
|
if (has_normals) {
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableVertexAttribArray(loc);
|
||||||
glNormalPointer(GL_FLOAT, 0, offset);
|
glVertexAttribPointer(loc, 3, GL_FLOAT, 0, 0, offsets[0]);
|
||||||
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
} else
|
||||||
} else glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableVertexAttribArray(loc);
|
||||||
|
loc = prog->attributeLocation("qgl_Texture");
|
||||||
if (has_texcoords) {
|
if (has_texcoords) {
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableVertexAttribArray(loc);
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, offset);
|
glVertexAttribPointer(loc, 2, GL_FLOAT, 0, 0, offsets[1]);
|
||||||
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
|
} else
|
||||||
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableVertexAttribArray(loc);
|
||||||
|
loc = prog->attributeLocation("qgl_Color");
|
||||||
if (has_colors) {
|
if (has_colors) {
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glEnableVertexAttribArray(loc);
|
||||||
glColorPointer(4, GL_FLOAT, 0, offset);
|
glVertexAttribPointer(loc, 4, GL_FLOAT, 0, 0, offsets[2]);
|
||||||
} else glDisableClientState(GL_COLOR_ARRAY);
|
} else
|
||||||
}/* else {
|
glDisableVertexAttribArray(loc);
|
||||||
glDisable(GL_NORMAL_ARRAY);
|
} else {
|
||||||
glDisable(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glDisable(GL_COLOR_ARRAY);
|
glVertexPointer(3, GL_FLOAT, 0, 0);
|
||||||
}*/
|
if (!simplest) {
|
||||||
|
if (has_normals) {
|
||||||
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
glNormalPointer(GL_FLOAT, 0, offset);
|
||||||
|
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
||||||
|
} else glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
if (has_texcoords) {
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 0, offset);
|
||||||
|
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
|
||||||
|
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
if (has_colors) {
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glColorPointer(4, GL_FLOAT, 0, offset);
|
||||||
|
} else glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//qDebug() << "draw" << vert_count << buffer_ << offsets[0] << offsets[1] << offsets[3];
|
||||||
glDrawArrays(type, 0, vert_count);
|
glDrawArrays(type, 0, vert_count);
|
||||||
|
//qDebug() << "draw" << vert_count << buffer_ << "done";
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ public:
|
|||||||
//GLVBO & operator =(const GLVBO & o) {return *this;}
|
//GLVBO & operator =(const GLVBO & o) {return *this;}
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void destroy() {deleteGLBuffer(buffer_);}
|
void destroy();
|
||||||
bool rebuffer(bool clear_ = false);
|
bool rebuffer(bool clear_ = false);
|
||||||
void draw(GLenum type, bool simplest = false);
|
void draw(GLenum type, QGLShaderProgram * prog, bool simplest = false);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
GLuint buffer() const {return buffer_;}
|
GLuint buffer() const {return buffer_;}
|
||||||
@@ -52,7 +52,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
QVector<GLfloat> vertices_, normals_, texcoords_, colors_;
|
QVector<GLfloat> vertices_, normals_, texcoords_, colors_;
|
||||||
GLenum usage;
|
GLenum usage;
|
||||||
GLuint buffer_;
|
GLuint buffer_, va_;
|
||||||
int vert_count;
|
int vert_count;
|
||||||
bool changed, has_normals, has_texcoords, has_colors;
|
bool changed, has_normals, has_texcoords, has_colors;
|
||||||
|
|
||||||
|
|||||||
@@ -327,8 +327,8 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, double scale) {
|
|||||||
name = readCharsUntilNull(stream);
|
name = readCharsUntilNull(stream);
|
||||||
//qDebug() << " mat map" << QString::number(cur_map, 16) << name;
|
//qDebug() << " mat map" << QString::number(cur_map, 16) << name;
|
||||||
switch (cur_map) {
|
switch (cur_map) {
|
||||||
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.diffuse.bitmap_path = name; break;
|
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.map_diffuse.bitmap_path = name; break;
|
||||||
case LOADER_3DS_CHUNK_BUMP_MAP: mat.bump.bitmap_path = name; break;
|
case LOADER_3DS_CHUNK_BUMP_MAP: mat.map_bump.bitmap_path = name; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6);
|
default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6);
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
|
|||||||
materials.resize(line.right(line.length() - mst - 14).toInt());
|
materials.resize(line.right(line.length() - mst - 14).toInt());
|
||||||
//qDebug() << materials.size() << "materials";
|
//qDebug() << materials.size() << "materials";
|
||||||
for (int i = 0; i < materials.size(); ++i) {
|
for (int i = 0; i < materials.size(); ++i) {
|
||||||
materials[i].diffuse.bitmap_id = 0;
|
materials[i].map_diffuse.bitmap_id = 0;
|
||||||
mst = -1;
|
mst = -1;
|
||||||
while (mst < 0 && !stream.atEnd()) {
|
while (mst < 0 && !stream.atEnd()) {
|
||||||
line = stream.readLine();
|
line = stream.readLine();
|
||||||
@@ -120,15 +120,15 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
|
|||||||
line = stream.readLine().trimmed();
|
line = stream.readLine().trimmed();
|
||||||
if (line.left(17) == "*MATERIAL_DIFFUSE") {materials[i].color_diffuse = colorFromString(line.right(line.length() - 18)); continue;} //qDebug() << "diffuse " << i << " = " << colorFromString(line.right(line.length() - 18));
|
if (line.left(17) == "*MATERIAL_DIFFUSE") {materials[i].color_diffuse = colorFromString(line.right(line.length() - 18)); continue;} //qDebug() << "diffuse " << i << " = " << colorFromString(line.right(line.length() - 18));
|
||||||
if (line.left(18) == "*MATERIAL_SPECULAR") {materials[i].color_specular = colorFromString(line.right(line.length() - 19)); continue;} //qDebug() << "specular " << i << " = " << colorFromString(line.right(line.length() - 19));
|
if (line.left(18) == "*MATERIAL_SPECULAR") {materials[i].color_specular = colorFromString(line.right(line.length() - 19)); continue;} //qDebug() << "specular " << i << " = " << colorFromString(line.right(line.length() - 19));
|
||||||
if (line.left(23) == "*MATERIAL_SHINESTRENGTH") {materials[i].shine_strength = line.right(line.length() - 24).toFloat(); continue;}
|
if (line.left(23) == "*MATERIAL_SHINESTRENGTH") {materials[i].specular = line.right(line.length() - 24).toFloat(); continue;}
|
||||||
if (line.left(15) == "*MATERIAL_SHINE") {materials[i].shine = line.right(line.length() - 16).toFloat() * 100.; continue;}
|
if (line.left(15) == "*MATERIAL_SHINE") {materials[i].roughness = 2. / exp(line.right(line.length() - 16).toFloat()); continue;}
|
||||||
if (line.left(22) == "*MATERIAL_TRANSPARENCY") {materials[i].transparency = line.right(line.length() - 23).toFloat(); continue;}
|
if (line.left(22) == "*MATERIAL_TRANSPARENCY") {materials[i].transparency = line.right(line.length() - 23).toFloat(); continue;}
|
||||||
if (line.left(12) == "*MAP_DIFFUSE") {
|
if (line.left(12) == "*MAP_DIFFUSE") {
|
||||||
line = stream.readLine().trimmed();
|
line = stream.readLine().trimmed();
|
||||||
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
|
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
|
||||||
materials[i].bump.bitmap_amount = line.right(line.length() - 12).toFloat();
|
materials[i].map_bump.color_amount = line.right(line.length() - 12).toFloat();
|
||||||
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
|
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
|
||||||
materials[i].diffuse.bitmap_path = line.mid(9, line.length() - 10);
|
materials[i].map_diffuse.bitmap_path = line.mid(9, line.length() - 10);
|
||||||
/*if (!materials[i].diffuse.bitmap_path.isEmpty()) {
|
/*if (!materials[i].diffuse.bitmap_path.isEmpty()) {
|
||||||
materials[i].diffuse.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].diffuse.bitmap_path));
|
materials[i].diffuse.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].diffuse.bitmap_path));
|
||||||
parent->textures << materials[i].diffuse.bitmap_id;
|
parent->textures << materials[i].diffuse.bitmap_id;
|
||||||
@@ -141,10 +141,10 @@ GLObjectBase * loadFromASEFile(const QString & filepath, double scale) {
|
|||||||
if (line.left(9) == "*MAP_BUMP") {
|
if (line.left(9) == "*MAP_BUMP") {
|
||||||
line = stream.readLine().trimmed();
|
line = stream.readLine().trimmed();
|
||||||
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
|
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
|
||||||
materials[i].bump.bitmap_amount = line.right(line.length() - 12).toFloat();
|
materials[i].map_bump.color_amount = line.right(line.length() - 12).toFloat();
|
||||||
//qDebug() << "bump amount" << materials[i].bump.bitmap_amount;
|
//qDebug() << "bump amount" << materials[i].bump.color_amount;
|
||||||
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
|
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
|
||||||
materials[i].bump.bitmap_path = line.mid(9, line.length() - 10);
|
materials[i].map_bump.bitmap_path = line.mid(9, line.length() - 10);
|
||||||
/*if (!materials[i].bump.bitmap_path.isEmpty()) {
|
/*if (!materials[i].bump.bitmap_path.isEmpty()) {
|
||||||
materials[i].bump.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].bump.bitmap_path));
|
materials[i].bump.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].bump.bitmap_path));
|
||||||
parent->textures << materials[i].bump.bitmap_id;
|
parent->textures << materials[i].bump.bitmap_id;
|
||||||
|
|||||||
@@ -140,17 +140,17 @@ QVector<Material> LoaderDAE::readMaterials(QDomElement le, QDomElement li, bool
|
|||||||
if (col.isValid()) mat.color_diffuse = col;
|
if (col.isValid()) mat.color_diffuse = col;
|
||||||
col = readXMLColor(pn.firstChildElement("specular"));
|
col = readXMLColor(pn.firstChildElement("specular"));
|
||||||
if (col.isValid()) mat.color_specular = col;
|
if (col.isValid()) mat.color_specular = col;
|
||||||
mat.shine = 2. / exp(readXMLFloat(pn.firstChildElement("shininess")));
|
mat.roughness = 2. / exp(readXMLFloat(pn.firstChildElement("shininess")));
|
||||||
mat.transparency = readXMLFloat(pn.firstChildElement("transparency"));
|
mat.transparency = readXMLFloat(pn.firstChildElement("transparency"));
|
||||||
if (!fbx) mat.transparency = 1. - mat.transparency;
|
if (!fbx) mat.transparency = 1. - mat.transparency;
|
||||||
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
|
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
|
||||||
if (!text.isEmpty()) mat.diffuse.bitmap_path = text;
|
if (!text.isEmpty()) mat.map_diffuse.bitmap_path = text;
|
||||||
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
|
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
|
||||||
if (!text.isEmpty()) mat.diffuse.bitmap_path = text;
|
if (!text.isEmpty()) mat.map_diffuse.bitmap_path = text;
|
||||||
|
|
||||||
pn = prof.firstChildElement("technique").firstChildElement("extra").firstChild();
|
pn = prof.firstChildElement("technique").firstChildElement("extra").firstChild();
|
||||||
text = readXMLTexture(pn.firstChildElement("bump"), prof, li);
|
text = readXMLTexture(pn.firstChildElement("bump"), prof, li);
|
||||||
if (!text.isEmpty()) mat.bump.bitmap_path = text;
|
if (!text.isEmpty()) mat.map_bump.bitmap_path = text;
|
||||||
|
|
||||||
ret << mat;
|
ret << mat;
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
|
|||||||
}
|
}
|
||||||
if (line.startsWith("Ks")) {
|
if (line.startsWith("Ks")) {
|
||||||
Vector3d v = readVector3d(line.mid(2).trimmed());
|
Vector3d v = readVector3d(line.mid(2).trimmed());
|
||||||
mat.shine_strength = v.length();
|
mat.specular = v.length();
|
||||||
double mc = qMax(v.x, qMax(v.y, v.z));
|
double mc = qMax(v.x, qMax(v.y, v.z));
|
||||||
if (mc > 0.) v /= mc;
|
if (mc > 0.) v /= mc;
|
||||||
mat.color_specular = QColor::fromRgbF(v.x, v.y, v.z);
|
mat.color_specular = QColor::fromRgbF(v.x, v.y, v.z);
|
||||||
@@ -164,7 +164,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.startsWith("Ns")) {
|
if (line.startsWith("Ns")) {
|
||||||
mat.shine = line.mid(2).trimmed().toDouble();
|
mat.roughness = 2. / exp(line.mid(2).trimmed().toDouble());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.startsWith("d")) {
|
if (line.startsWith("d")) {
|
||||||
@@ -172,7 +172,7 @@ QVector<Material> readMTL(QString obj_path, QString path) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.startsWith("map_Kd")) {
|
if (line.startsWith("map_Kd")) {
|
||||||
mat.diffuse.bitmap_path = findFile(line.mid(6).trimmed(), sp);
|
mat.map_diffuse.bitmap_path = findFile(line.mid(6).trimmed(), sp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.startsWith("map_bump")) {
|
if (line.startsWith("map_bump")) {
|
||||||
@@ -181,9 +181,9 @@ QVector<Material> readMTL(QString obj_path, QString path) {
|
|||||||
line = line.mid(3).trimmed();
|
line = line.mid(3).trimmed();
|
||||||
QString sv = line.left(line.indexOf(" "));
|
QString sv = line.left(line.indexOf(" "));
|
||||||
line = line.mid(sv.size()).trimmed();
|
line = line.mid(sv.size()).trimmed();
|
||||||
mat.bump_scale = sv.toDouble();
|
mat.map_bump.color_amount = sv.toDouble();
|
||||||
}
|
}
|
||||||
mat.bump.bitmap_path = findFile(line, sp);
|
mat.map_bump.bitmap_path = findFile(line, sp);
|
||||||
//qDebug() << "BUMP" << mat.name << mat.bump_scale << mat.bump.bitmap_path;
|
//qDebug() << "BUMP" << mat.name << mat.bump_scale << mat.bump.bitmap_path;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
|
|||||||
//spinSliderShine->setDecimals(2);
|
//spinSliderShine->setDecimals(2);
|
||||||
view->setFrameShape(QFrame::NoFrame);
|
view->setFrameShape(QFrame::NoFrame);
|
||||||
//view->setRenderer(new RendererDeferredShading(view));
|
//view->setRenderer(new RendererDeferredShading(view));
|
||||||
view->setRenderer(new RendererSimple(view));
|
view->setRenderer(new RendererDeferredShading(view));
|
||||||
view->setMouseSelectionEnabled(true);
|
view->setMouseSelectionEnabled(false);
|
||||||
view->setMouseRotateEnabled(true);
|
view->setMouseRotateEnabled(true);
|
||||||
view->setBackColor(Qt::lightGray);
|
view->setBackColor(Qt::lightGray);
|
||||||
//view->setLightingMode(QGLView::PerPixel);
|
//view->setLightingMode(QGLView::PerPixel);
|
||||||
@@ -62,13 +62,11 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
|
|||||||
//obj->child("teapot")->setLineWidth(2.);
|
//obj->child("teapot")->setLineWidth(2.);
|
||||||
//obj->child("cone")->setRenderMode(GLObjectBase::Line);
|
//obj->child("cone")->setRenderMode(GLObjectBase::Line);
|
||||||
//view->camera().setAim(obj->child("sphere001")->pos());
|
//view->camera().setAim(obj->child("sphere001")->pos());
|
||||||
QImageReader im("D:/orders/libs/qglview/data/SU-33_maps/Map__14_Mix.tga");
|
|
||||||
QImage i = im.read();
|
|
||||||
qDebug() << i.size() << im.errorString();
|
|
||||||
GLTextureManager::addSearchPath("data");
|
GLTextureManager::addSearchPath("data");
|
||||||
GLTextureManager::addSearchPath("data/images");
|
GLTextureManager::addSearchPath("data/images");
|
||||||
GLTextureManager::addSearchPath("data/SU-33_maps");
|
GLTextureManager::addSearchPath("data/SU-33_maps");
|
||||||
obj = loadFromDAEFile("data/su33t.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
|
obj = loadFromDAEFile("data/test.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
|
||||||
|
obj->setScale(0.1);
|
||||||
//obj = new GLPrimitiveEllipsoid(100, 100, 100, 100, 100);//GLPrimitiveCube();
|
//obj = new GLPrimitiveEllipsoid(100, 100, 100, 100, 100);//GLPrimitiveCube();
|
||||||
view->addObject(obj);
|
view->addObject(obj);
|
||||||
|
|
||||||
@@ -95,7 +93,8 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
|
|||||||
view->setHoverHaloEnabled(false);
|
view->setHoverHaloEnabled(false);
|
||||||
Light * l = new Light(view->camera().pos());
|
Light * l = new Light(view->camera().pos());
|
||||||
l->intensity = 0.8;
|
l->intensity = 0.8;
|
||||||
view->addObject(l);
|
l->setName("camera");
|
||||||
|
//view->addObject(l);
|
||||||
view->start(-1);
|
view->start(-1);
|
||||||
//view->light(0)->light_type = Light::Omni;
|
//view->light(0)->light_type = Light::Omni;
|
||||||
//obj = loadFrom3DSFile("34.3DS", 0.03);
|
//obj = loadFrom3DSFile("34.3DS", 0.03);
|
||||||
@@ -148,6 +147,7 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
|
|||||||
//view->addObject(new Light(view->camera().pos()));
|
//view->addObject(new Light(view->camera().pos()));
|
||||||
|
|
||||||
//show();
|
//show();
|
||||||
|
//comboBox->setCurrentIndex(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1246</width>
|
<width>1246</width>
|
||||||
<height>844</height>
|
<height>856</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>3</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab">
|
<widget class="QWidget" name="tab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) {
|
MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) {
|
||||||
ui = new Ui::MaterialEditor();
|
ui = new Ui::MaterialEditor();
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
ui->frameReflection->hide();
|
||||||
active = true;
|
active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,24 +47,24 @@ void MaterialEditor::setMaterial(const Material & m) {
|
|||||||
ui->colorSpecular->setColor(m.color_specular);
|
ui->colorSpecular->setColor(m.color_specular);
|
||||||
ui->colorSelfIllum->setColor(m.color_self_illumination);
|
ui->colorSelfIllum->setColor(m.color_self_illumination);
|
||||||
ui->checkGlass->setChecked(m.glass);
|
ui->checkGlass->setChecked(m.glass);
|
||||||
ui->comboModel->setCurrentIndex((int)m.light_model);
|
ui->spinRoughness->setValue(m.roughness);
|
||||||
ui->spinShine->setValue(m.shine);
|
ui->spinSpecular->setValue(m.specular);
|
||||||
ui->spinShineStrength->setValue(m.shine_strength);
|
|
||||||
ui->spinTransparent->setValue(m.transparency);
|
ui->spinTransparent->setValue(m.transparency);
|
||||||
ui->spinReflect->setValue(m.reflectivity);
|
ui->spinReflect->setValue(m.reflectivity);
|
||||||
ui->spinBump->setValue(m.bump_scale);
|
|
||||||
ui->spinRelief->setValue(m.relief_scale);
|
|
||||||
ui->spinIOF->setValue(m.iof);
|
ui->spinIOF->setValue(m.iof);
|
||||||
ui->spinDispersion->setValue(m.dispersion);
|
ui->spinDispersion->setValue(m.dispersion);
|
||||||
ui->lineDiffuse->setProperty("GLpath", m.diffuse.bitmap_path); ui->lineDiffuse->setText(QFileInfo(m.diffuse.bitmap_path).fileName());
|
ui->mapDiffuse->setMap(m.map_diffuse);
|
||||||
ui->lineBump->setProperty("GLpath", m.bump.bitmap_path); ui->lineBump->setText(QFileInfo(m.bump.bitmap_path).fileName());
|
ui->mapSpecular->setMap(m.map_specular);
|
||||||
ui->lineRelief->setProperty("GLpath", m.relief.bitmap_path); ui->lineRelief->setText(QFileInfo(m.relief.bitmap_path).fileName());
|
ui->mapSelfIllum->setMap(m.map_self_illumination);
|
||||||
ui->lineReflFront->setProperty("GLpath", m.reflection.path(0)); ui->lineReflFront->setText(QFileInfo(m.reflection.path(0)).fileName());
|
ui->mapRoughness->setMap(m.map_roughness);
|
||||||
ui->lineReflBack->setProperty("GLpath", m.reflection.path(1)); ui->lineReflBack->setText(QFileInfo(m.reflection.path(1)).fileName());
|
ui->mapBump->setMap(m.map_bump);
|
||||||
ui->lineReflLeft->setProperty("GLpath", m.reflection.path(2)); ui->lineReflLeft->setText(QFileInfo(m.reflection.path(2)).fileName());
|
ui->mapRelief->setMap(m.map_relief);
|
||||||
ui->lineReflRight->setProperty("GLpath", m.reflection.path(3)); ui->lineReflRight->setText(QFileInfo(m.reflection.path(3)).fileName());
|
ui->lineReflFront->setProperty("GLpath", m.map_reflection.path(0)); ui->lineReflFront->setText(QFileInfo(m.map_reflection.path(0)).fileName());
|
||||||
ui->lineReflTop->setProperty("GLpath", m.reflection.path(4)); ui->lineReflTop->setText(QFileInfo(m.reflection.path(4)).fileName());
|
ui->lineReflBack->setProperty("GLpath", m.map_reflection.path(1)); ui->lineReflBack->setText(QFileInfo(m.map_reflection.path(1)).fileName());
|
||||||
ui->lineReflBottom->setProperty("GLpath", m.reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(m.reflection.path(5)).fileName());
|
ui->lineReflLeft->setProperty("GLpath", m.map_reflection.path(2)); ui->lineReflLeft->setText(QFileInfo(m.map_reflection.path(2)).fileName());
|
||||||
|
ui->lineReflRight->setProperty("GLpath", m.map_reflection.path(3)); ui->lineReflRight->setText(QFileInfo(m.map_reflection.path(3)).fileName());
|
||||||
|
ui->lineReflTop->setProperty("GLpath", m.map_reflection.path(4)); ui->lineReflTop->setText(QFileInfo(m.map_reflection.path(4)).fileName());
|
||||||
|
ui->lineReflBottom->setProperty("GLpath", m.map_reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(m.map_reflection.path(5)).fileName());
|
||||||
active = true;
|
active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,55 +75,28 @@ Material MaterialEditor::material() {
|
|||||||
m.color_specular = ui->colorSpecular->color();
|
m.color_specular = ui->colorSpecular->color();
|
||||||
m.color_self_illumination = ui->colorSelfIllum->color();
|
m.color_self_illumination = ui->colorSelfIllum->color();
|
||||||
m.glass = ui->checkGlass->isChecked();
|
m.glass = ui->checkGlass->isChecked();
|
||||||
m.light_model = (Material::LightModel)ui->comboModel->currentIndex();
|
m.roughness = ui->spinRoughness->value();
|
||||||
m.shine = ui->spinShine->value();
|
m.specular = ui->spinSpecular->value();
|
||||||
m.shine_strength = ui->spinShineStrength->value();
|
|
||||||
m.transparency = ui->spinTransparent->value();
|
m.transparency = ui->spinTransparent->value();
|
||||||
m.reflectivity = ui->spinReflect->value();
|
m.reflectivity = ui->spinReflect->value();
|
||||||
m.bump_scale = ui->spinBump->value();
|
|
||||||
m.relief_scale = ui->spinRelief->value();
|
|
||||||
m.iof = ui->spinIOF->value();
|
m.iof = ui->spinIOF->value();
|
||||||
m.dispersion = ui->spinDispersion->value();
|
m.dispersion = ui->spinDispersion->value();
|
||||||
m.diffuse.bitmap_path = ui->lineDiffuse->property("GLpath").toString();
|
m.map_diffuse = ui->mapDiffuse->map();
|
||||||
m.bump.bitmap_path = ui->lineBump->property("GLpath").toString();
|
m.map_specular = ui->mapSpecular->map();
|
||||||
m.relief.bitmap_path = ui->lineRelief->property("GLpath").toString();
|
m.map_self_illumination = ui->mapSelfIllum->map();
|
||||||
m.reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
|
m.map_roughness = ui->mapRoughness->map();
|
||||||
m.reflection.setPath(1, ui->lineReflBack->property("GLpath").toString());
|
m.map_bump = ui->mapBump->map();
|
||||||
m.reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString());
|
m.map_relief = ui->mapRelief->map();
|
||||||
m.reflection.setPath(3, ui->lineReflRight->property("GLpath").toString());
|
m.map_reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
|
||||||
m.reflection.setPath(4, ui->lineReflTop->property("GLpath").toString());
|
m.map_reflection.setPath(1, ui->lineReflBack->property("GLpath").toString());
|
||||||
m.reflection.setPath(5, ui->lineReflBottom->property("GLpath").toString());
|
m.map_reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString());
|
||||||
|
m.map_reflection.setPath(3, ui->lineReflRight->property("GLpath").toString());
|
||||||
|
m.map_reflection.setPath(4, ui->lineReflTop->property("GLpath").toString());
|
||||||
|
m.map_reflection.setPath(5, ui->lineReflBottom->property("GLpath").toString());
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MaterialEditor::on_buttonDiffuseSelect_clicked() {
|
|
||||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineDiffuse->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
|
||||||
if (str.isEmpty()) return;
|
|
||||||
ui->lineDiffuse->setProperty("GLpath", str);
|
|
||||||
ui->lineDiffuse->setText(QFileInfo(str).fileName());
|
|
||||||
materialChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MaterialEditor::on_buttonBumpSelect_clicked() {
|
|
||||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineBump->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
|
||||||
if (str.isEmpty()) return;
|
|
||||||
ui->lineBump->setProperty("GLpath", str);
|
|
||||||
ui->lineBump->setText(QFileInfo(str).fileName());
|
|
||||||
materialChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MaterialEditor::on_buttonReliefSelect_clicked() {
|
|
||||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineRelief->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
|
||||||
if (str.isEmpty()) return;
|
|
||||||
ui->lineRelief->setProperty("GLpath", str);
|
|
||||||
ui->lineRelief->setText(QFileInfo(str).fileName());
|
|
||||||
materialChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MaterialEditor::on_buttonReflFrontSelect_clicked() {
|
void MaterialEditor::on_buttonReflFrontSelect_clicked() {
|
||||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflFront->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflFront->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||||
if (str.isEmpty()) return;
|
if (str.isEmpty()) return;
|
||||||
@@ -177,27 +151,6 @@ void MaterialEditor::on_buttonReflBottomSelect_clicked() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MaterialEditor::on_buttonDiffuseClear_clicked() {
|
|
||||||
ui->lineDiffuse->setText("");
|
|
||||||
ui->lineDiffuse->setProperty("GLpath", "");
|
|
||||||
materialChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MaterialEditor::on_buttonBumpClear_clicked() {
|
|
||||||
ui->lineBump->setText("");
|
|
||||||
ui->lineBump->setProperty("GLpath", "");
|
|
||||||
materialChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MaterialEditor::on_buttonReliefClear_clicked() {
|
|
||||||
ui->lineRelief->setText("");
|
|
||||||
ui->lineRelief->setProperty("GLpath", "");
|
|
||||||
materialChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MaterialEditor::on_buttonReflFrontClear_clicked() {
|
void MaterialEditor::on_buttonReflFrontClear_clicked() {
|
||||||
ui->lineReflFront->setText("");
|
ui->lineReflFront->setText("");
|
||||||
ui->lineReflFront->setProperty("GLpath", "");
|
ui->lineReflFront->setProperty("GLpath", "");
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#define MATERIAL_EDITOR_H
|
#define MATERIAL_EDITOR_H
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include "gltypes.h"
|
#include "glmaterial.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MaterialEditor;
|
class MaterialEditor;
|
||||||
@@ -43,12 +43,6 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void materialChanged() {if (active) emit changed();}
|
void materialChanged() {if (active) emit changed();}
|
||||||
void on_buttonDiffuseSelect_clicked();
|
|
||||||
void on_buttonDiffuseClear_clicked();
|
|
||||||
void on_buttonBumpSelect_clicked();
|
|
||||||
void on_buttonBumpClear_clicked();
|
|
||||||
void on_buttonReliefSelect_clicked();
|
|
||||||
void on_buttonReliefClear_clicked();
|
|
||||||
void on_buttonReflFrontSelect_clicked();
|
void on_buttonReflFrontSelect_clicked();
|
||||||
void on_buttonReflFrontClear_clicked();
|
void on_buttonReflFrontClear_clicked();
|
||||||
void on_buttonReflBackSelect_clicked();
|
void on_buttonReflBackSelect_clicked();
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>327</width>
|
<width>470</width>
|
||||||
<height>593</height>
|
<height>692</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
@@ -23,79 +23,124 @@
|
|||||||
<property name="verticalSpacing">
|
<property name="verticalSpacing">
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="text">
|
<property name="title">
|
||||||
<string>Diffuse</string>
|
<string>Diffuse</string>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_3">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Color:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="ColorButton" name="colorDiffuse">
|
||||||
|
<property name="useAlphaChannel">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="MaterialMapEditor" name="mapDiffuse" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="1" column="0" colspan="2">
|
||||||
<widget class="ColorButton" name="colorDiffuse">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="useAlphaChannel">
|
<property name="title">
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Specular</string>
|
<string>Specular</string>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_4">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Color:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="ColorButton" name="colorSpecular">
|
||||||
|
<property name="useAlphaChannel">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="MaterialMapEditor" name="mapSpecular" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="2" column="0" colspan="2">
|
||||||
<widget class="ColorButton" name="colorSpecular">
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
<property name="useAlphaChannel">
|
<property name="title">
|
||||||
<bool>true</bool>
|
<string>Self illumination</string>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_5">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_12">
|
||||||
|
<property name="text">
|
||||||
|
<string>Color:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="ColorButton" name="colorSelfIllum">
|
||||||
|
<property name="useAlphaChannel">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="MaterialMapEditor" name="mapSelfIllum" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QGroupBox" name="groupBox_5">
|
||||||
|
<property name="title">
|
||||||
|
<string>Bump</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="MaterialMapEditor" name="mapBump" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0" colspan="2">
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="title">
|
||||||
|
<string>Relief</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="MaterialMapEditor" name="mapRelief" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QCheckBox" name="checkGlass">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Light model</string>
|
<string>Glass</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="7" column="0">
|
||||||
<widget class="QComboBox" name="comboModel">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Phong</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Cook-Torrance</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Minnaert</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Strauss</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Oren-Nayar</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Shininess</string>
|
<string>Roughness</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="7" column="1">
|
||||||
<widget class="SpinSlider" name="spinShine">
|
<widget class="SpinSlider" name="spinRoughness">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>1.000000000000000</double>
|
<double>1.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
@@ -110,15 +155,15 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="8" column="0">
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Shine strength</string>
|
<string>Specular</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="SpinSlider" name="spinShineStrength">
|
<widget class="SpinSlider" name="spinSpecular">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>64.000000000000000</double>
|
<double>64.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
@@ -139,14 +184,14 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
<item row="9" column="0">
|
||||||
<widget class="QLabel" name="label_6">
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Transparency</string>
|
<string>Transparency</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="9" column="1">
|
||||||
<widget class="SpinSlider" name="spinTransparent">
|
<widget class="SpinSlider" name="spinTransparent">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>1.000000000000000</double>
|
<double>1.000000000000000</double>
|
||||||
@@ -162,14 +207,14 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0">
|
<item row="10" column="0">
|
||||||
<widget class="QLabel" name="label_7">
|
<widget class="QLabel" name="label_7">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Reflectivity</string>
|
<string>Reflectivity</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="1">
|
<item row="10" column="1">
|
||||||
<widget class="SpinSlider" name="spinReflect">
|
<widget class="SpinSlider" name="spinReflect">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>1.000000000000000</double>
|
<double>1.000000000000000</double>
|
||||||
@@ -185,101 +230,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
|
||||||
<widget class="QLabel" name="label_8">
|
|
||||||
<property name="text">
|
|
||||||
<string>Bump scale</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
|
||||||
<widget class="SpinSlider" name="spinBump">
|
|
||||||
<property name="maximum">
|
|
||||||
<double>4.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.010000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="pageStep">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="13" column="0">
|
|
||||||
<widget class="QLabel" name="label_9">
|
|
||||||
<property name="text">
|
|
||||||
<string>Diffuse map</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="13" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="lineDiffuse"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="buttonDiffuseClear">
|
|
||||||
<property name="text">
|
|
||||||
<string>X</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="buttonDiffuseSelect">
|
|
||||||
<property name="text">
|
|
||||||
<string>^</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="14" column="0">
|
|
||||||
<widget class="QLabel" name="label_10">
|
|
||||||
<property name="text">
|
|
||||||
<string>Bump map</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="14" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="lineBump"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="buttonBumpClear">
|
|
||||||
<property name="text">
|
|
||||||
<string>X</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="buttonBumpSelect">
|
|
||||||
<property name="text">
|
|
||||||
<string>^</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QCheckBox" name="checkGlass">
|
|
||||||
<property name="text">
|
|
||||||
<string>Glass</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="11" column="0">
|
<item row="11" column="0">
|
||||||
<widget class="QLabel" name="label_11">
|
<widget class="QLabel" name="label_11">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -306,29 +256,41 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="12" column="0">
|
||||||
<widget class="QLabel" name="label_12">
|
<widget class="QLabel" name="label_15">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Self-illumination</string>
|
<string>Dispersion</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="12" column="1">
|
||||||
<widget class="ColorButton" name="colorSelfIllum">
|
<widget class="SpinSlider" name="spinDispersion">
|
||||||
<property name="useAlphaChannel">
|
<property name="maximum">
|
||||||
<bool>true</bool>
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="16" column="0">
|
<item row="13" column="0">
|
||||||
<widget class="QLabel" name="label_13">
|
<widget class="QLabel" name="label_13">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Reflection map</string>
|
<string>Reflection map</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="16" column="1">
|
<item row="13" column="1">
|
||||||
<widget class="QFrame" name="frame">
|
<widget class="QFrame" name="frameReflection">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::StyledPanel</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
</property>
|
</property>
|
||||||
@@ -532,87 +494,16 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="0">
|
<item row="3" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_15">
|
<widget class="QGroupBox" name="groupBox_6">
|
||||||
<property name="text">
|
<property name="title">
|
||||||
<string>Dispersion</string>
|
<string>Roughness</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="12" column="1">
|
|
||||||
<widget class="SpinSlider" name="spinDispersion">
|
|
||||||
<property name="maximum">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.010000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="pageStep">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="15" column="0">
|
|
||||||
<widget class="QLabel" name="label_16">
|
|
||||||
<property name="text">
|
|
||||||
<string>Relief map</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="15" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="lineRelief"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="buttonReliefClear">
|
|
||||||
<property name="text">
|
|
||||||
<string>X</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="buttonReliefSelect">
|
|
||||||
<property name="text">
|
|
||||||
<string>^</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="10" column="0">
|
|
||||||
<widget class="QLabel" name="label_17">
|
|
||||||
<property name="text">
|
|
||||||
<string>Relief scale</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="10" column="1">
|
|
||||||
<widget class="SpinSlider" name="spinRelief">
|
|
||||||
<property name="maximum">
|
|
||||||
<double>4.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.010000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="pageStep">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="MaterialMapEditor" name="mapRoughness" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -628,6 +519,15 @@
|
|||||||
<extends>QPushButton</extends>
|
<extends>QPushButton</extends>
|
||||||
<header>colorbutton.h</header>
|
<header>colorbutton.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>MaterialMapEditor</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>material_map_editor.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
<slots>
|
||||||
|
<signal>changed()</signal>
|
||||||
|
</slots>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -638,8 +538,8 @@
|
|||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>272</x>
|
<x>326</x>
|
||||||
<y>17</y>
|
<y>49</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>282</x>
|
<x>282</x>
|
||||||
@@ -654,8 +554,8 @@
|
|||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>271</x>
|
<x>325</x>
|
||||||
<y>39</y>
|
<y>128</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>284</x>
|
<x>284</x>
|
||||||
@@ -664,30 +564,14 @@
|
|||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>comboModel</sender>
|
<sender>spinRoughness</sender>
|
||||||
<signal>currentIndexChanged(int)</signal>
|
|
||||||
<receiver>MaterialEditor</receiver>
|
|
||||||
<slot>materialChanged()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>279</x>
|
|
||||||
<y>98</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>284</x>
|
|
||||||
<y>70</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>spinShine</sender>
|
|
||||||
<signal>valueChanged(double)</signal>
|
<signal>valueChanged(double)</signal>
|
||||||
<receiver>MaterialEditor</receiver>
|
<receiver>MaterialEditor</receiver>
|
||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>279</x>
|
<x>443</x>
|
||||||
<y>127</y>
|
<y>404</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>280</x>
|
<x>280</x>
|
||||||
@@ -696,14 +580,14 @@
|
|||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>spinShineStrength</sender>
|
<sender>spinSpecular</sender>
|
||||||
<signal>valueChanged(double)</signal>
|
<signal>valueChanged(double)</signal>
|
||||||
<receiver>MaterialEditor</receiver>
|
<receiver>MaterialEditor</receiver>
|
||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>279</x>
|
<x>443</x>
|
||||||
<y>153</y>
|
<y>426</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>283</x>
|
<x>283</x>
|
||||||
@@ -718,8 +602,8 @@
|
|||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>279</x>
|
<x>443</x>
|
||||||
<y>179</y>
|
<y>448</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>283</x>
|
<x>283</x>
|
||||||
@@ -734,8 +618,8 @@
|
|||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>279</x>
|
<x>443</x>
|
||||||
<y>204</y>
|
<y>470</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>284</x>
|
<x>284</x>
|
||||||
@@ -743,54 +627,6 @@
|
|||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
|
||||||
<sender>spinBump</sender>
|
|
||||||
<signal>valueChanged(double)</signal>
|
|
||||||
<receiver>MaterialEditor</receiver>
|
|
||||||
<slot>materialChanged()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>279</x>
|
|
||||||
<y>230</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>284</x>
|
|
||||||
<y>202</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>lineDiffuse</sender>
|
|
||||||
<signal>textChanged(QString)</signal>
|
|
||||||
<receiver>MaterialEditor</receiver>
|
|
||||||
<slot>materialChanged()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>264</x>
|
|
||||||
<y>349</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>99</x>
|
|
||||||
<y>211</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>lineBump</sender>
|
|
||||||
<signal>textChanged(QString)</signal>
|
|
||||||
<receiver>MaterialEditor</receiver>
|
|
||||||
<slot>materialChanged()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>264</x>
|
|
||||||
<y>376</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>98</x>
|
|
||||||
<y>245</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
<connection>
|
||||||
<sender>spinIOF</sender>
|
<sender>spinIOF</sender>
|
||||||
<signal>valueChanged(double)</signal>
|
<signal>valueChanged(double)</signal>
|
||||||
@@ -798,8 +634,8 @@
|
|||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>279</x>
|
<x>443</x>
|
||||||
<y>291</y>
|
<y>492</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>284</x>
|
<x>284</x>
|
||||||
@@ -814,8 +650,8 @@
|
|||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>279</x>
|
<x>443</x>
|
||||||
<y>121</y>
|
<y>382</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>284</x>
|
<x>284</x>
|
||||||
@@ -830,8 +666,8 @@
|
|||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>322</x>
|
<x>376</x>
|
||||||
<y>63</y>
|
<y>202</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>326</x>
|
<x>326</x>
|
||||||
@@ -846,8 +682,8 @@
|
|||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>313</x>
|
<x>460</x>
|
||||||
<y>313</y>
|
<y>514</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>326</x>
|
<x>326</x>
|
||||||
@@ -856,34 +692,98 @@
|
|||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>lineRelief</sender>
|
<sender>mapDiffuse</sender>
|
||||||
<signal>textChanged(QString)</signal>
|
<signal>changed()</signal>
|
||||||
<receiver>MaterialEditor</receiver>
|
<receiver>MaterialEditor</receiver>
|
||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>123</x>
|
<x>445</x>
|
||||||
<y>391</y>
|
<y>63</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>17</x>
|
<x>469</x>
|
||||||
<y>364</y>
|
<y>63</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>spinRelief</sender>
|
<sender>mapSpecular</sender>
|
||||||
<signal>valueChanged(double)</signal>
|
<signal>changed()</signal>
|
||||||
<receiver>MaterialEditor</receiver>
|
<receiver>MaterialEditor</receiver>
|
||||||
<slot>materialChanged()</slot>
|
<slot>materialChanged()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>317</x>
|
<x>443</x>
|
||||||
<y>260</y>
|
<y>143</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>327</x>
|
<x>467</x>
|
||||||
<y>261</y>
|
<y>143</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>mapSelfIllum</sender>
|
||||||
|
<signal>changed()</signal>
|
||||||
|
<receiver>MaterialEditor</receiver>
|
||||||
|
<slot>materialChanged()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>447</x>
|
||||||
|
<y>216</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>468</x>
|
||||||
|
<y>216</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>mapBump</sender>
|
||||||
|
<signal>changed()</signal>
|
||||||
|
<receiver>MaterialEditor</receiver>
|
||||||
|
<slot>materialChanged()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>450</x>
|
||||||
|
<y>308</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>469</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>mapRelief</sender>
|
||||||
|
<signal>changed()</signal>
|
||||||
|
<receiver>MaterialEditor</receiver>
|
||||||
|
<slot>materialChanged()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>450</x>
|
||||||
|
<y>353</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>469</x>
|
||||||
|
<y>304</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>mapRoughness</sender>
|
||||||
|
<signal>changed()</signal>
|
||||||
|
<receiver>MaterialEditor</receiver>
|
||||||
|
<slot>materialChanged()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>442</x>
|
||||||
|
<y>257</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>474</x>
|
||||||
|
<y>250</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
|||||||
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);
|
setFrameShape(QFrame::NoFrame);
|
||||||
setViewportUpdateMode(FullViewportUpdate);
|
setViewportUpdateMode(FullViewportUpdate);
|
||||||
setCacheMode(CacheNone);
|
setCacheMode(CacheNone);
|
||||||
setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers)));
|
QGLFormat f(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers);
|
||||||
|
f.setSwapInterval(0);
|
||||||
|
setViewport(new QGLWidget(f));
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setFocusPolicy(Qt::WheelFocus);
|
setFocusPolicy(Qt::WheelFocus);
|
||||||
setScene(new QGraphicsScene());
|
setScene(new QGraphicsScene());
|
||||||
@@ -51,7 +53,7 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
|
|||||||
selectionHaloFill_ = 0.5;
|
selectionHaloFill_ = 0.5;
|
||||||
shadow_map_size = dynamic_cubemap_size = 512;
|
shadow_map_size = dynamic_cubemap_size = 512;
|
||||||
//lmode = Simple;
|
//lmode = Simple;
|
||||||
shader_select = shader_halo = shader_rope = 0;
|
shader_select = shader_halo = 0;
|
||||||
cur_luminance = 1.;
|
cur_luminance = 1.;
|
||||||
accom_time = 32.;
|
accom_time = 32.;
|
||||||
accom_max_speed = 0.1;
|
accom_max_speed = 0.1;
|
||||||
@@ -74,7 +76,7 @@ QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
|
|||||||
QGLView::~QGLView() {
|
QGLView::~QGLView() {
|
||||||
if (shader_select != 0) delete shader_select;
|
if (shader_select != 0) delete shader_select;
|
||||||
if (shader_halo != 0) delete shader_halo;
|
if (shader_halo != 0) delete shader_halo;
|
||||||
if (shader_rope != 0) delete shader_rope;
|
//if (shader_rope != 0) delete shader_rope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,7 +114,7 @@ void QGLView::drawBackground(QPainter * painter, const QRectF & rect) {
|
|||||||
f = false;
|
f = false;
|
||||||
paintGL();
|
paintGL();
|
||||||
painter_->endNativePainting();
|
painter_->endNativePainting();
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisableDepth();
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glReleaseTextures();
|
glReleaseTextures();
|
||||||
@@ -131,7 +133,7 @@ void QGLView::initializeGL() {
|
|||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
//glEnable(GL_TEXTURE_2D);
|
//glEnable(GL_TEXTURE_2D);
|
||||||
//glEnable(GL_TEXTURE_CUBE_MAP);
|
//glEnable(GL_TEXTURE_CUBE_MAP);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnableDepth();
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
@@ -168,7 +170,7 @@ void QGLView::initializeGL() {
|
|||||||
|
|
||||||
shader_select = new QGLShaderProgram(context());
|
shader_select = new QGLShaderProgram(context());
|
||||||
shader_halo = new QGLShaderProgram(context());
|
shader_halo = new QGLShaderProgram(context());
|
||||||
shader_rope = new QGLShaderProgram(context());
|
//shader_rope = new QGLShaderProgram(context());
|
||||||
reloadThisShaders();
|
reloadThisShaders();
|
||||||
is_init = true;
|
is_init = true;
|
||||||
|
|
||||||
@@ -192,16 +194,17 @@ void QGLView::initializeGL() {
|
|||||||
void QGLView::paintGL() {
|
void QGLView::paintGL() {
|
||||||
//QMutexLocker ml_v(&v_mutex);
|
//QMutexLocker ml_v(&v_mutex);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
//glDisble(GL_CULL_FACE);
|
//glDisable(GL_CULL_FACE);
|
||||||
camera_.apply(aspect);
|
camera_.apply(aspect);
|
||||||
|
start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||||
|
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||||
|
//objects_.buildTransform();
|
||||||
|
|
||||||
/// Selection detect
|
/// Selection detect
|
||||||
//glClearFramebuffer(QColor(100, 0, 0, 0));
|
//glClearFramebuffer(QColor(100, 0, 0, 0));
|
||||||
if (mouseSelect_) {
|
if (mouseSelect_) {
|
||||||
glReleaseTextures();
|
glReleaseTextures();
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnableDepth();
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
glDepthMask(GL_TRUE);
|
|
||||||
glDisable(GL_TEXTURE_1D);
|
glDisable(GL_TEXTURE_1D);
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||||
@@ -248,8 +251,7 @@ void QGLView::paintGL() {
|
|||||||
renderHalo(sel_obj, ids.key(sel_obj), selectionHaloColor_, selectionHaloFill_);
|
renderHalo(sel_obj, ids.key(sel_obj), selectionHaloColor_, selectionHaloFill_);
|
||||||
}
|
}
|
||||||
fbo_selection.release();
|
fbo_selection.release();
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnableDepth();
|
||||||
glEnable(GL_RESCALE_NORMAL);
|
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
@@ -277,7 +279,7 @@ void QGLView::paintGL() {
|
|||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisableDepth();
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
if (selectionHalo_) {
|
if (selectionHalo_) {
|
||||||
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2));
|
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2));
|
||||||
@@ -372,7 +374,17 @@ void QGLView::renderSelection() {
|
|||||||
ids.clear();
|
ids.clear();
|
||||||
if (shaders_supported) sh_id_loc = shader_select->uniformLocation("id");
|
if (shaders_supported) sh_id_loc = shader_select->uniformLocation("id");
|
||||||
//qDebug() << sh_id_loc;
|
//qDebug() << sh_id_loc;
|
||||||
|
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||||
|
glPushMatrix();
|
||||||
renderSingleSelection(objects_);
|
renderSingleSelection(objects_);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QGLView::renderShadow() {
|
||||||
|
glPushMatrix();
|
||||||
|
renderSingleShadow(objects_);
|
||||||
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -382,32 +394,27 @@ void QGLView::renderSingleSelection(GLObjectBase & o) {
|
|||||||
o.loadTextures();
|
o.loadTextures();
|
||||||
}
|
}
|
||||||
if (!o.visible_ || !o.select_) return;
|
if (!o.visible_ || !o.select_) return;
|
||||||
glPushMatrix();
|
QMatrix4x4 curview = start_rp.view_matrix * o.itransform_;
|
||||||
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
|
|
||||||
if (o.raw_matrix) {
|
|
||||||
qglMultMatrix(o.mat_);
|
|
||||||
} else {
|
|
||||||
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
|
|
||||||
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
|
|
||||||
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
|
|
||||||
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
|
|
||||||
}
|
|
||||||
ids.insert(cid, &o);
|
ids.insert(cid, &o);
|
||||||
if (shaders_supported) shader_select->setUniformValue(sh_id_loc, QVector4D(float((cid >> 24) & 0xFF) / 255.f,
|
if (shaders_supported){
|
||||||
float((cid >> 16) & 0xFF) / 255.f,
|
setUniformMatrices(shader_select, start_rp.proj_matrix, curview);
|
||||||
float((cid >> 8) & 0xFF) / 255.f,
|
shader_select->setUniformValue(sh_id_loc, QVector4D(float((cid >> 24) & 0xFF) / 255.f,
|
||||||
float(cid & 0xFF) / 255.f));
|
float((cid >> 16) & 0xFF) / 255.f,
|
||||||
else glColor4f(float((cid >> 24) & 0xFF) / 255.f,
|
float((cid >> 8) & 0xFF) / 255.f,
|
||||||
|
float(cid & 0xFF) / 255.f));
|
||||||
|
} else {
|
||||||
|
setGLMatrix(curview);
|
||||||
|
glColor4f(float((cid >> 24) & 0xFF) / 255.f,
|
||||||
float((cid >> 16) & 0xFF) / 255.f,
|
float((cid >> 16) & 0xFF) / 255.f,
|
||||||
float((cid >> 8) & 0xFF) / 255.f,
|
float((cid >> 8) & 0xFF) / 255.f,
|
||||||
float(cid & 0xFF) / 255.f);
|
float(cid & 0xFF) / 255.f);
|
||||||
|
}
|
||||||
//qDebug() << o.name() << "assign to" << sh_id_loc << cid;
|
//qDebug() << o.name() << "assign to" << sh_id_loc << cid;
|
||||||
//glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) / 255.f);
|
//glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) / 255.f);
|
||||||
++cid;
|
++cid;
|
||||||
o.draw(true);
|
o.draw(0, true);
|
||||||
foreach (GLObjectBase * i, o.children_)
|
foreach (GLObjectBase * i, o.children_)
|
||||||
renderSingleSelection(*i);
|
renderSingleSelection(*i);
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -417,19 +424,13 @@ void QGLView::renderSingleShadow(GLObjectBase & o) {
|
|||||||
o.loadTextures();
|
o.loadTextures();
|
||||||
}
|
}
|
||||||
if (!o.visible_) return;
|
if (!o.visible_) return;
|
||||||
glPushMatrix();
|
setGLMatrix(start_rp.view_matrix * o.itransform_);
|
||||||
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
|
|
||||||
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
|
|
||||||
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
|
|
||||||
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
|
|
||||||
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, o.render_mode != GLObjectBase::View ? o.render_mode : (rmode != GLObjectBase::View ? rmode : GL_FILL));
|
glPolygonMode(GL_FRONT_AND_BACK, o.render_mode != GLObjectBase::View ? o.render_mode : (rmode != GLObjectBase::View ? rmode : GL_FILL));
|
||||||
glLineWidth(o.line_width > 0. ? o.line_width : lineWidth_);
|
glLineWidth(o.line_width > 0. ? o.line_width : lineWidth_);
|
||||||
glPointSize(o.line_width > 0. ? o.line_width : lineWidth_);
|
glPointSize(o.line_width > 0. ? o.line_width : lineWidth_);
|
||||||
o.draw(true);
|
o.draw(0, true);
|
||||||
foreach (GLObjectBase * i, o.children_)
|
foreach (GLObjectBase * i, o.children_)
|
||||||
renderSingleSelection(*i);
|
renderSingleSelection(*i);
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include "glprimitives.h"
|
#include "glprimitives.h"
|
||||||
#include "glparticles_system.h"
|
#include "glparticles_system.h"
|
||||||
|
#include "glrendererbase.h"
|
||||||
|
|
||||||
|
|
||||||
class QGLView: public QGraphicsView, public QGLViewBase
|
class QGLView: public QGraphicsView, public QGLViewBase
|
||||||
@@ -190,7 +191,7 @@ public:
|
|||||||
void setSelectionRectBrush(const QBrush & v) {sel_brush = v;}
|
void setSelectionRectBrush(const QBrush & v) {sel_brush = v;}
|
||||||
|
|
||||||
GLdouble aspect, iaspect;
|
GLdouble aspect, iaspect;
|
||||||
QGLShaderProgram * shader_rope;
|
//QGLShaderProgram * shader_rope;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void drawBackground(QPainter * painter, const QRectF & rect);
|
virtual void drawBackground(QPainter * painter, const QRectF & rect);
|
||||||
@@ -210,7 +211,7 @@ protected:
|
|||||||
|
|
||||||
inline void applyFog();
|
inline void applyFog();
|
||||||
void renderSelection();
|
void renderSelection();
|
||||||
void renderShadow() {renderSingleShadow(objects_);}
|
void renderShadow();
|
||||||
|
|
||||||
void checkCaps();
|
void checkCaps();
|
||||||
void collectLights();
|
void collectLights();
|
||||||
@@ -222,7 +223,6 @@ private:
|
|||||||
void renderSingleSelection(GLObjectBase & o);
|
void renderSingleSelection(GLObjectBase & o);
|
||||||
void renderSingleShadow(GLObjectBase & o);
|
void renderSingleShadow(GLObjectBase & o);
|
||||||
void renderHalo(const GLObjectBase * obj, const int iid, const QColor & color, const double & fill);
|
void renderHalo(const GLObjectBase * obj, const int iid, const QColor & color, const double & fill);
|
||||||
void applyLightShader(Material::LightModel type);
|
|
||||||
QList<QGraphicsItem * > collectGraphicItems();
|
QList<QGraphicsItem * > collectGraphicItems();
|
||||||
void collectGraphicItems(QList<QGraphicsItem * > & list, QGraphicsItem * o);
|
void collectGraphicItems(QList<QGraphicsItem * > & list, QGraphicsItem * o);
|
||||||
void reloadThisShaders();
|
void reloadThisShaders();
|
||||||
@@ -253,6 +253,7 @@ private:
|
|||||||
SelectionMode sel_mode;
|
SelectionMode sel_mode;
|
||||||
Qt::MouseButton sel_button;
|
Qt::MouseButton sel_button;
|
||||||
Qt::KeyboardModifier sel_mod;
|
Qt::KeyboardModifier sel_mod;
|
||||||
|
GLRendererBase::RenderingParameters start_rp;
|
||||||
double lineWidth_, linearFiltering_, accom_time, accom_max_speed, cur_luminance;
|
double lineWidth_, linearFiltering_, accom_time, accom_max_speed, cur_luminance;
|
||||||
double fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_;
|
double fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_;
|
||||||
int timer, fps_cnt, sh_id_loc, shadow_map_size, dynamic_cubemap_size;
|
int timer, fps_cnt, sh_id_loc, shadow_map_size, dynamic_cubemap_size;
|
||||||
|
|||||||
@@ -19,67 +19,86 @@
|
|||||||
#include "renderer_deferred_shading.h"
|
#include "renderer_deferred_shading.h"
|
||||||
|
|
||||||
|
|
||||||
RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo(5, true, GL_RGBA16F) {
|
RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo(6, true, GL_RGBA16F) {
|
||||||
shader_fxaa = shader_ds_0 = shader_ds_1 = 0;
|
shader_fxaa = shader_ds_0 = shader_ds_1 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RendererDeferredShading::renderScene() {
|
void RendererDeferredShading::renderScene() {
|
||||||
|
prepareUniform();
|
||||||
|
QMatrix4x4 view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||||
|
QMatrix4x4 proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||||
|
QMatrix4x4 viewprojinv = (proj_matrix * view_matrix).inverted();
|
||||||
|
corner_dirs[0] = (QVector4D(-1, -1, 1, 1) * viewprojinv).normalized();
|
||||||
|
corner_dirs[1] = (QVector4D( 1, -1, 1, 1) * viewprojinv).normalized();
|
||||||
|
corner_dirs[2] = (QVector4D( 1, 1, 1, 1) * viewprojinv).normalized();
|
||||||
|
corner_dirs[3] = (QVector4D(-1, 1, 1, 1) * viewprojinv).normalized();
|
||||||
|
//qDebug() << corner_dirs[0] << corner_dirs[1] << corner_dirs[2] << corner_dirs[3];
|
||||||
int passes = (view.lightsCount() - 1) / 8 + 1;
|
int passes = (view.lightsCount() - 1) / 8 + 1;
|
||||||
QMatrix4x4 pm = getGLMatrix(GL_PROJECTION_MATRIX);//, mvm = getGLMatrix(GL_MODELVIEW_MATRIX), pmvm = pm * mvm, lpm, lmvm, lpmvm;
|
|
||||||
if (passes < 1) passes = 1;
|
if (passes < 1) passes = 1;
|
||||||
fbo.bind();
|
fbo.bind();
|
||||||
int buffs[] = {0, 1, 2};
|
int buffs[] = {0, 1, 2, 3};
|
||||||
fbo.setWriteBuffers(buffs);
|
fbo.setWriteBuffers(buffs);
|
||||||
|
if (white_image_id == 0) {
|
||||||
|
glActiveTextureChannel(6);
|
||||||
|
white_image_id = ((GLTextureManagerBase*)currentGLTextureManager)->loadTexture(white_image, false);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, white_image_id);
|
||||||
|
glActiveTextureChannel(0);
|
||||||
|
}
|
||||||
glClearFramebuffer(QColor(0, 0, 0, 0));
|
glClearFramebuffer(QColor(0, 0, 0, 0));
|
||||||
//glEnable(GL_TEXTURE_2D);
|
//glEnable(GL_TEXTURE_2D);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnableDepth();
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
glDepthMask(GL_TRUE);
|
|
||||||
shader_ds_0->bind();
|
shader_ds_0->bind();
|
||||||
|
setUniform(shader_ds_0);
|
||||||
|
shader_ds_0->setUniformValue("z_far", GLfloat(view.depthEnd()));
|
||||||
|
shader_ds_0->setUniformValue("z_near", GLfloat(view.depthStart()));
|
||||||
shader_ds_0->setUniformValue("t0", 0);
|
shader_ds_0->setUniformValue("t0", 0);
|
||||||
shader_ds_0->setUniformValue("t1", 1);
|
shader_ds_0->setUniformValue("t1", 1);
|
||||||
shader_ds_0->setUniformValue("t2", 2);
|
shader_ds_0->setUniformValue("t2", 2);
|
||||||
|
shader_ds_0->setUniformValue("t3", 3);
|
||||||
shader_ds_0->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height()));
|
shader_ds_0->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height()));
|
||||||
renderObjects(GLObjectBase::Solid, 0, 0, true, false, false);
|
renderObjects(GLObjectBase::Solid, 0, shader_ds_0, true, false, false);
|
||||||
//glReleaseShaders();
|
//glReleaseShaders();
|
||||||
//fbo.release();
|
//fbo.release();
|
||||||
|
|
||||||
|
glResetAllTransforms();
|
||||||
|
prepareUniform();
|
||||||
glSetLightEnabled(false);
|
glSetLightEnabled(false);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
//glBlendFunc(GL_ONE, GL_ONE);
|
//glBlendFunc(GL_ONE, GL_ONE);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisableDepth();
|
||||||
glDepthMask(GL_FALSE);
|
|
||||||
shader_ds_1->bind();
|
shader_ds_1->bind();
|
||||||
|
setUniform(shader_ds_1);
|
||||||
|
shader_ds_1->setUniformValue("z_far", GLfloat(view.depthEnd()));
|
||||||
|
shader_ds_1->setUniformValue("z_near", GLfloat(view.depthStart()));
|
||||||
shader_ds_1->setUniformValue("t0", 0);
|
shader_ds_1->setUniformValue("t0", 0);
|
||||||
shader_ds_1->setUniformValue("t1", 1);
|
shader_ds_1->setUniformValue("t1", 1);
|
||||||
shader_ds_1->setUniformValue("t2", 2);
|
shader_ds_1->setUniformValue("t2", 2);
|
||||||
|
shader_ds_1->setUniformValue("t3", 3);
|
||||||
|
shader_ds_1->setUniformValue("td", 4);
|
||||||
shader_ds_1->setUniformValue("back_color", view.backColor());
|
shader_ds_1->setUniformValue("back_color", view.backColor());
|
||||||
shader_ds_1->setUniformValue("mat", pm.inverted());
|
shader_ds_1->setUniformValue("mat_proji", proj_matrix.inverted());
|
||||||
shader_ds_1->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height()));
|
shader_ds_1->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height()));
|
||||||
fbo.setWriteBuffer(3);
|
fbo.setWriteBuffer(4);
|
||||||
fbo.bindColorTextures();
|
fbo.bindColorTextures();
|
||||||
|
fbo.bindDepthTexture(4);
|
||||||
glClearFramebuffer(Qt::black, false);
|
glClearFramebuffer(Qt::black, false);
|
||||||
QVector<QVector4D> lpos;
|
//QVector<QVector4D> lpos;
|
||||||
GLfloat glmvm[16];
|
//qDebug() << view_matrix;
|
||||||
glGetFloatv(GL_MODELVIEW_MATRIX, glmvm);
|
|
||||||
//glResetAllTransforms();
|
|
||||||
for (int l = 0; l < passes; ++l) {
|
for (int l = 0; l < passes; ++l) {
|
||||||
fbo.setWriteBuffer(4 - l % 2);
|
fbo.setWriteBuffer(5 - l % 2);
|
||||||
shader_ds_1->setUniformValue("tb", 3 + l % 2);
|
shader_ds_1->setUniformValue("tb", 4 + l % 2);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
setupDSLights(l, 16, view_matrix);
|
||||||
glLoadMatrixf(glmvm);
|
//shader_ds_1->setUniformValue("lightsCount", cplc);
|
||||||
setupLights(l, 8);
|
drawFB(shader_ds_1);
|
||||||
shader_ds_1->setUniformValue("lightsCount", cplc);
|
|
||||||
glDrawQuad();
|
|
||||||
//renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled());
|
//renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled());
|
||||||
//renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled());
|
//renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled());
|
||||||
glFinish();
|
glFlush();
|
||||||
}
|
}
|
||||||
fbo.release();
|
fbo.release();
|
||||||
glReleaseShaders();
|
glReleaseShaders();
|
||||||
glActiveTextureChannel(0);
|
glActiveTextureChannel(0);
|
||||||
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(3 + passes % 2));
|
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(4 + passes % 2));
|
||||||
if (view.isFXAAEnabled()) {
|
if (view.isFXAAEnabled()) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
@@ -107,9 +126,82 @@ void RendererDeferredShading::reloadShaders() {
|
|||||||
|
|
||||||
|
|
||||||
void RendererDeferredShading::setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) {
|
void RendererDeferredShading::setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) {
|
||||||
shader_ds_0->setUniformValue("has_diffuse", object.material().diffuse.bitmap_id != 0);
|
shader_ds_0->setUniformValue("has_diffuse", object.material().map_diffuse.bitmap_id != 0);
|
||||||
shader_ds_0->setUniformValue("has_bump", object.material().bump.bitmap_id != 0);
|
shader_ds_0->setUniformValue("has_bump", object.material().map_bump.bitmap_id != 0);
|
||||||
shader_ds_0->setUniformValue("has_height", object.material().relief.bitmap_id != 0);
|
shader_ds_0->setUniformValue("has_height", object.material().map_relief.bitmap_id != 0);
|
||||||
shader_ds_0->setUniformValue("bump_scale", object.material().bump_scale);
|
shader_ds_0->setUniformValue("bump_scale", object.material().map_bump.color_amount);
|
||||||
shader_ds_0->setUniformValue("height_scale", object.material().relief_scale);
|
shader_ds_0->setUniformValue("height_scale", object.material().map_relief.color_amount);
|
||||||
|
glActiveTextureChannel(6);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, white_image_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix) {
|
||||||
|
int light_start, light_end, lmax;
|
||||||
|
light_start = pass * lights_per_pass;
|
||||||
|
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights().size());
|
||||||
|
lmax = light_start + 8;
|
||||||
|
amb_light.intensity = (pass == 0 ? 1. : 0.);
|
||||||
|
amb_light.setColor(pass == 0 ? view.ambientColor() : Qt::black);
|
||||||
|
amb_light.setName("ambient");
|
||||||
|
setUniformLight(shader_ds_1, &amb_light, "qgl_AmbientLight", QMatrix4x4());
|
||||||
|
amb_light.intensity = 0.;
|
||||||
|
QVector<Light*> lv;
|
||||||
|
for (int i = light_start; i < light_end; ++i)
|
||||||
|
lv << view.lights()[i];
|
||||||
|
amb_light.setName("null");
|
||||||
|
for (int i = light_end; i < lmax; ++i)
|
||||||
|
lv << &amb_light;
|
||||||
|
setUniformLights(shader_ds_1, lv, view_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RendererDeferredShading::setupAmbientLight(const QColor & a, bool first_pass) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RendererDeferredShading::prepareUniform() {
|
||||||
|
pm = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||||
|
mvm = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||||
|
mvpm = pm * mvm;
|
||||||
|
pim = pm.inverted();
|
||||||
|
mvim = mvm.inverted();
|
||||||
|
mvpim = mvpm.inverted();
|
||||||
|
nm = mvm.normalMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RendererDeferredShading::setUniform(QGLShaderProgram * prog) {
|
||||||
|
//qDebug() << mvm;
|
||||||
|
prog->setUniformValue("qgl_ModelViewMatrix", mvm);
|
||||||
|
prog->setUniformValue("qgl_ProjectionMatrix", pm);
|
||||||
|
prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm);
|
||||||
|
prog->setUniformValue("qgl_NormalMatrix", nm);
|
||||||
|
prog->setUniformValue("qgl_ModelViewMatrixInverse", mvim);
|
||||||
|
prog->setUniformValue("qgl_ProjectionMatrixInverse", pim);
|
||||||
|
prog->setUniformValue("qgl_ModelViewProjectionMatrixInverse", mvpim);
|
||||||
|
prog->setUniformValue("qgl_ModelViewMatrixTranspose", mvm.transposed());
|
||||||
|
prog->setUniformValue("qgl_ProjectionMatrixTranspose", pm.transposed());
|
||||||
|
prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed());
|
||||||
|
prog->setUniformValue("qgl_ModelViewMatrixInverseTranspose", mvim.transposed());
|
||||||
|
prog->setUniformValue("qgl_ProjectionMatrixInverseTranspose", pim.transposed());
|
||||||
|
prog->setUniformValue("qgl_ModelViewProjectionMatrixInverseTranspose", mvpim.transposed());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RendererDeferredShading::drawFB(QGLShaderProgram * prog) {
|
||||||
|
glSetPolygonMode(GL_FILL);
|
||||||
|
int loc = prog->attributeLocation("qgl_Color");
|
||||||
|
glVertexAttrib3f(loc, 1.f, 1.f, 1.f);
|
||||||
|
int locv = prog->attributeLocation("qgl_Vertex"),
|
||||||
|
loct = prog->attributeLocation("qgl_Texture"),
|
||||||
|
locc = prog->attributeLocation("view_corner");
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glColor3f(1.f, 1.f, 1.f);
|
||||||
|
prog->setAttributeValue(locc, corner_dirs[0]); glVertexAttrib2f(loct, 0.f, 0.f); glTexCoord2f(0.f, 0.f); glVertexAttrib2f(locv, -1.f, -1.f); glVertex2f(-1.f, -1.f);
|
||||||
|
prog->setAttributeValue(locc, corner_dirs[1]); glVertexAttrib2f(loct, 1.f, 0.f); glTexCoord2f(1.f, 0.f); glVertexAttrib2f(locv, 1.f, -1.f); glVertex2f(1.f, -1.f);
|
||||||
|
prog->setAttributeValue(locc, corner_dirs[2]); glVertexAttrib2f(loct, 1.f, 1.f); glTexCoord2f(1.f, 1.f); glVertexAttrib2f(locv, 1.f, 1.f); glVertex2f(1.f, 1.f);
|
||||||
|
prog->setAttributeValue(locc, corner_dirs[3]); glVertexAttrib2f(loct, 0.f, 1.f); glTexCoord2f(0.f, 1.f); glVertexAttrib2f(locv, -1.f, 1.f); glVertex2f(-1.f, 1.f);
|
||||||
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,17 +30,28 @@ public:
|
|||||||
virtual void renderScene();
|
virtual void renderScene();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void init(int width, int height) {fbo.resize(width, height);}
|
void init(int width, int height) {fbo.resize(width, height);}
|
||||||
virtual void resize(int width, int height) {fbo.resize(width, height);}
|
void resize(int width, int height) {fbo.resize(width, height);}
|
||||||
virtual void reloadShaders();
|
void reloadShaders();
|
||||||
virtual void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp);
|
void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp);
|
||||||
virtual void setupShadersLights(int lights_count) {cplc = lights_count;}
|
void setupShadersLights(int lights_count) {cplc = lights_count;}
|
||||||
|
void setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix);
|
||||||
|
void setupAmbientLight(const QColor & a, bool first_pass);
|
||||||
|
|
||||||
|
void prepareUniform();
|
||||||
|
void setUniform(QGLShaderProgram * prog);
|
||||||
|
void drawFB(QGLShaderProgram * prog);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int cplc;
|
int cplc;
|
||||||
GLFramebuffer fbo;
|
GLFramebuffer fbo;
|
||||||
QGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1;
|
QGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1;
|
||||||
|
|
||||||
|
QMatrix4x4 pm, mvm, mvpm, pim, mvim, mvpim;
|
||||||
|
QMatrix3x3 nm;
|
||||||
|
QVector4D corner_dirs[4];
|
||||||
|
Light amb_light;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RENDERER_DEFERRED_SHADING_H
|
#endif // RENDERER_DEFERRED_SHADING_H
|
||||||
|
|||||||
@@ -62,9 +62,7 @@ void RendererSimple::renderScene() {
|
|||||||
if (passes > 1) fbo.setWriteBuffer(1);
|
if (passes > 1) fbo.setWriteBuffer(1);
|
||||||
if (l == 0) {
|
if (l == 0) {
|
||||||
glClearFramebuffer(view.backColor());
|
glClearFramebuffer(view.backColor());
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnableDepth();
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
glDepthMask(GL_TRUE);
|
|
||||||
} else {
|
} else {
|
||||||
glClearFramebuffer(Qt::black, false);
|
glClearFramebuffer(Qt::black, false);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
@@ -98,8 +96,7 @@ void RendererSimple::renderScene() {
|
|||||||
glBlendFunc(GL_ONE, GL_ONE);
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
glReleaseTextures();
|
glReleaseTextures();
|
||||||
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(1));
|
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(1));
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisableDepth();
|
||||||
glDepthMask(GL_FALSE);
|
|
||||||
fbo.setWriteBuffer(0);
|
fbo.setWriteBuffer(0);
|
||||||
glDrawQuad();
|
glDrawQuad();
|
||||||
}
|
}
|
||||||
@@ -111,7 +108,7 @@ void RendererSimple::renderScene() {
|
|||||||
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture());
|
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture());
|
||||||
glSetLightEnabled(false);
|
glSetLightEnabled(false);
|
||||||
glSetCapEnabled(GL_BLEND, false);
|
glSetCapEnabled(GL_BLEND, false);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisableDepth();
|
||||||
if (view.isFXAAEnabled()) {
|
if (view.isFXAAEnabled()) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void RopeSystem::init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RopeSystem::draw(bool simplest) {
|
void RopeSystem::draw(QGLShaderProgram * prog, bool simplest) {
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_1D, tex[0]);
|
glBindTexture(GL_TEXTURE_1D, tex[0]);
|
||||||
glGetTexImage(GL_TEXTURE_1D, 0, GL_RGBA, GL_FLOAT, pos.data());
|
glGetTexImage(GL_TEXTURE_1D, 0, GL_RGBA, GL_FLOAT, pos.data());
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public:
|
|||||||
RopeSystem();
|
RopeSystem();
|
||||||
~RopeSystem();
|
~RopeSystem();
|
||||||
|
|
||||||
virtual void draw(bool simplest = false);
|
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void update() {}
|
virtual void update() {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +1,48 @@
|
|||||||
#version 130
|
#version 150
|
||||||
|
|
||||||
in vec3 src_normal, normal;//, et;
|
in vec3 src_normal, normal;//, et;
|
||||||
in vec4 pos, col;
|
in vec4 pos;
|
||||||
in float fogCoord;
|
in float fogCoord;
|
||||||
|
|
||||||
uniform int light_model;
|
uniform bool acc_fog;
|
||||||
uniform sampler2D t0, t1, t2, t3;
|
|
||||||
uniform float bump_scale, height_scale;
|
|
||||||
uniform bool acc_fog, has_diffuse, has_bump, has_height;
|
|
||||||
uniform vec2 dt;
|
uniform vec2 dt;
|
||||||
|
uniform float z_far, z_near;
|
||||||
|
|
||||||
const vec3 luma = vec3(0.299, 0.587, 0.114);
|
const vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 dc = col;
|
float z = pos.w;//((z_near / (z_near-z_far)) * z_far) / (pos.w - (z_far / (z_far-z_near)));
|
||||||
vec2 tc = gl_TexCoord[0].xy;
|
vec4 dc = qgl_FragColor;
|
||||||
float hei = 0.;
|
vec2 tc = qgl_FragTexture.xy;
|
||||||
if (has_height) hei = dot(texture2D(t2, gl_TexCoord[0].xy).rgb, luma) * height_scale;
|
float hei = dot(texture2D(qgl_Material.map_relief.map, tc).rgb, luma) * qgl_Material.map_relief.amount + qgl_Material.map_relief.offset;
|
||||||
if (acc_fog) dc.xyz = mix(dc.rgb, gl_Fog.color.rgb, fogCoord);
|
//if (acc_fog) dc.xyz = mix(dc.rgb, gl_Fog.color.rgb, fogCoord);
|
||||||
|
|
||||||
vec3 n, dn;
|
vec3 n, dn;
|
||||||
if (has_bump) {
|
dn = (texture2D(qgl_Material.map_bump.map, tc).rgb - vec3(0.5, 0.5, 1.)) * qgl_Material.map_bump.amount + qgl_Material.map_bump.offset;
|
||||||
dn = (texture2D(t1, gl_TexCoord[0].xy).rgb - vec3(0.5, 0.5, 1.)) * bump_scale;
|
dn.x = -dn.x;
|
||||||
dn.x = -dn.x;
|
dn = dn * mat3(qgl_ModelViewMatrixInverse);
|
||||||
dn = dn * mat3(gl_ModelViewMatrixInverse);
|
n = normalize(normal - dn);
|
||||||
n = normalize(normal - dn);
|
|
||||||
} else n = normalize(normal);
|
|
||||||
|
|
||||||
if (has_diffuse) {
|
/*vec2 dpm = normalize(gl_FragCoord.xy * dt * 2. - vec2(1., 1.)), ntc;
|
||||||
|
ntc = gl_FragCoord.xy * dt * 2. - vec2(1., 1.) + dpm * hei;
|
||||||
|
dpm = gl_ModelViewProjectionMatrixInverse
|
||||||
|
dpm = dpm * gl_ModelViewProjectionMatrixInverse;
|
||||||
|
dpm += */
|
||||||
|
//tc += 1+et.xy * hei/10;// / et.z;
|
||||||
|
dc *= texture2D(qgl_Material.map_diffuse.map, tc) * qgl_Material.map_diffuse.amount + qgl_Material.map_diffuse.offset;
|
||||||
|
|
||||||
/*vec2 dpm = normalize(gl_FragCoord.xy * dt * 2. - vec2(1., 1.)), ntc;
|
vec4 spec = texture2D(qgl_Material.map_specular.map, tc) * qgl_Material.map_specular.amount + qgl_Material.map_specular.offset;
|
||||||
ntc = gl_FragCoord.xy * dt * 2. - vec2(1., 1.) + dpm * hei;
|
spec *= qgl_Material.color_specular * qgl_Material.specular;
|
||||||
dpm = gl_ModelViewProjectionMatrixInverse
|
vec4 rough = texture2D(qgl_Material.map_roughness.map, tc) * qgl_Material.map_roughness.amount + qgl_Material.map_roughness.offset;
|
||||||
dpm = dpm * gl_ModelViewProjectionMatrixInverse;
|
rough *= qgl_Material.roughness;
|
||||||
dpm += */
|
vec4 self = texture2D(qgl_Material.map_self_illumination.map, tc) * qgl_Material.map_self_illumination.amount + qgl_Material.map_self_illumination.offset;
|
||||||
//tc += 1+et.xy * hei/10;// / et.z;
|
self *= qgl_Material.color_self_illumination;
|
||||||
dc *= texture2D(t0, tc);
|
|
||||||
}
|
qgl_FragData[0] = vec4(dc.rgb, z);
|
||||||
|
qgl_FragData[1] = vec4(n.xyz / 2. + vec3(0.5), rough);
|
||||||
|
qgl_FragData[2] = vec4(spec.rgb, hei);
|
||||||
|
qgl_FragData[3] = vec4(pos.xyz, pos.z);
|
||||||
|
|
||||||
gl_FragData[0] = vec4(dc.rgb, pos.w);
|
|
||||||
gl_FragData[1] = vec4(n.xyz / 2. + vec3(0.5), gl_FrontMaterial.shininess);
|
|
||||||
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, hei);
|
|
||||||
//gl_FragData[0] = vec4(et.xyz, pos.w);
|
//gl_FragData[0] = vec4(et.xyz, pos.w);
|
||||||
//gl_FragDepth = gl_FragCoord.z - clamp(hei / pos.z / pos.z / (abs(n.z) + 1), -0.01, 0.01);
|
//gl_FragDepth = gl_FragCoord.z - clamp(hei / pos.z / pos.z / (abs(n.z) + 1), -0.01, 0.01);
|
||||||
/*vec4 dp = pos;
|
/*vec4 dp = pos;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#version 130
|
#version 150
|
||||||
|
|
||||||
out vec3 src_normal, normal;//, et;
|
out vec3 src_normal, normal;//, et;
|
||||||
out vec4 pos, col;
|
out vec4 pos;
|
||||||
out float fogCoord, fs_gid;
|
out float fogCoord, fs_gid;
|
||||||
|
|
||||||
uniform bool acc_fog;
|
uniform bool acc_fog;
|
||||||
@@ -9,34 +9,19 @@ uniform vec2 dt;
|
|||||||
uniform vec3 eye;
|
uniform vec3 eye;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
normal = (gl_NormalMatrix * gl_Normal);
|
normal = (qgl_NormalMatrix * qgl_Normal);
|
||||||
|
pos.xyz = vec3(qgl_ModelViewMatrix * qgl_Vertex);
|
||||||
pos.xyz = vec3(gl_ModelViewMatrix * gl_Vertex);
|
/*if (acc_fog) {
|
||||||
col = gl_Color;
|
|
||||||
if (acc_fog) {
|
|
||||||
fogCoord = (gl_Fog.end - length(pos.xyz) * 0.85) / (gl_Fog.end - gl_Fog.start);
|
fogCoord = (gl_Fog.end - length(pos.xyz) * 0.85) / (gl_Fog.end - gl_Fog.start);
|
||||||
fogCoord = 1. - clamp(fogCoord, 0., 1.);
|
fogCoord = 1. - clamp(fogCoord, 0., 1.);
|
||||||
}
|
}*/
|
||||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
//gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
gl_TexCoord[1] = gl_MultiTexCoord1;
|
//gl_TexCoord[1] = gl_MultiTexCoord1;
|
||||||
gl_Position = ftransform();
|
qgl_FragTexture = qgl_Texture;
|
||||||
src_normal = normalize(/*gl_NormalMatrix * */vec3(pos.xy * dt * 2., 0));
|
qgl_FragColor = qgl_Color;
|
||||||
//pos = gl_Position;
|
vec4 tp = qgl_ftransform();
|
||||||
|
//tp /= tp.w;
|
||||||
//vec3 v = normalize(-pos.xyz); // vector to the eye
|
src_normal = normalize(vec3(pos.xy * dt * 2., 0));
|
||||||
|
pos.w = tp.w;
|
||||||
/*vec3 t = gl_NormalMatrix * vec3(1., 0., 0.);
|
gl_Position = tp;//ftransform();
|
||||||
vec3 b = gl_NormalMatrix * vec3(0., 1., 0.);
|
|
||||||
et = vec3(dot(v, t), dot(v, b), dot(v, normal));*/
|
|
||||||
|
|
||||||
//vec3 t = normalize(gl_NormalMatrix * vec3(gl_MultiTexCoord0.yx, 1));
|
|
||||||
//vec3 b = cross(normal, t);
|
|
||||||
|
|
||||||
/*mat3 tbnMatrix = mat3(t.x, b.x, normal.x,
|
|
||||||
t.y, b.y, normal.y,
|
|
||||||
t.z, b.z, normal.z);
|
|
||||||
et = tbnMatrix * v;*/
|
|
||||||
|
|
||||||
|
|
||||||
pos.w = gl_Position.w;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,69 +1,77 @@
|
|||||||
#version 130
|
#version 150
|
||||||
//#extension GL_EXT_gpu_shader4 : enable
|
//#extension GL_EXT_gpu_shader4 : enable
|
||||||
|
|
||||||
uniform vec3 ambient;
|
in vec4 view_dir;
|
||||||
|
in vec3 view_pos;
|
||||||
|
|
||||||
uniform sampler2D t0, t1, t2, tb;
|
uniform vec3 ambient;
|
||||||
|
uniform sampler2D t0, t1, t2, t3, tb;
|
||||||
|
uniform sampler2D td;
|
||||||
uniform int gid, lightsCount;
|
uniform int gid, lightsCount;
|
||||||
|
uniform float z_near, z_far;
|
||||||
uniform bool firstPass;
|
uniform bool firstPass;
|
||||||
uniform vec2 dt;
|
uniform vec2 dt;
|
||||||
uniform vec4 back_color;
|
uniform vec4 back_color;
|
||||||
uniform mat4 mat;
|
uniform mat4 mat_proji;
|
||||||
|
|
||||||
float light_diffuse(int model, vec3 l, vec3 n) {return max(0., dot(l, n));}
|
float light_diffuse(int model, vec3 l, vec3 n) {return max(0., dot(l, n));}
|
||||||
float light_specular(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) {return max(0., pow(dot(n, h), shininess));}
|
//float light_specular(int model, vec3 l, vec3 n, vec3 h, vec3 v, float shininess) {return max(0., pow(dot(n, h), shininess));}
|
||||||
|
|
||||||
vec4 pos, lpos;
|
vec4 pos, lpos;
|
||||||
vec3 li, si, ldir, halfV;
|
vec3 li, si, ldir, halfV;
|
||||||
float sh_pow, sh_mul, dist, NdotL, spot, ldist, diff;
|
float sh_pow, sh_mul, dist, NdotL, spot, ldist, diff;
|
||||||
|
|
||||||
void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) {
|
void calcLight(in int index, in vec3 n, in vec3 v, in vec4 v2) {
|
||||||
lpos = gl_LightSource[index].position;
|
lpos = qgl_Light[index].position;
|
||||||
ldir = lpos.xyz - (pos.xyz * lpos.w);
|
ldir = lpos.xyz - (pos.xyz * lpos.w);
|
||||||
ldist = length(ldir);
|
ldist = length(ldir);
|
||||||
ldir = normalize(ldir);
|
ldir = normalize(ldir);
|
||||||
NdotL = max(dot(n, ldir), 0.);
|
NdotL = max(dot(n, ldir), 0.);
|
||||||
spot = step(0., NdotL);
|
spot = step(0., NdotL);
|
||||||
if (NdotL > 0.) {
|
if (NdotL > 0.) {
|
||||||
if (gl_LightSource[index].spotCutoff < 180.) {
|
/*if (gl_LightSource[index].spotCutoff < 180.) {
|
||||||
spot = max(dot(-ldir, gl_LightSource[index].spotDirection.xyz), 0.);
|
spot = max(dot(-ldir, gl_LightSource[index].spotDirection.xyz), 0.);
|
||||||
spot *= step(gl_LightSource[index].spotCosCutoff, spot);
|
spot *= step(gl_LightSource[index].spotCosCutoff, spot);
|
||||||
spot = pow(spot, (gl_LightSource[index].spotExponent + 0.001));
|
spot = pow(spot, (gl_LightSource[index].spotExponent + 0.001));
|
||||||
}
|
}*/
|
||||||
|
spot /= (qgl_Light[index].constantAttenuation + ldist * (qgl_Light[index].linearAttenuation + ldist * qgl_Light[index].quadraticAttenuation));
|
||||||
halfV = normalize(ldir + v);
|
halfV = normalize(ldir + v);
|
||||||
spot /= (gl_LightSource[index].constantAttenuation + ldist * (gl_LightSource[index].linearAttenuation + ldist * gl_LightSource[index].quadraticAttenuation));
|
///li += spot * gl_LightSource[index].diffuse.rgb * light_diffuse(0, ldir, n);
|
||||||
//li += spot * gl_LightSource[index].diffuse.rgb * light_diffuse(0, ldir, n);
|
///si += spot * gl_LightSource[index].specular.rgb * sh_mul * light_specular(0, ldir, n, halfV, v, sh_pow);
|
||||||
//si += spot * gl_LightSource[index].specular.rgb * sh_mul * light_specular(0, ldir, n, halfV, v, sh_pow);
|
|
||||||
float NdotLs = NdotL*NdotL;
|
float NdotLs = NdotL*NdotL;
|
||||||
float ndlc = (1. - NdotLs) / NdotLs;
|
float ndlc = (1. - NdotLs) / NdotLs;
|
||||||
float der = NdotLs * (sh_mul + ndlc);
|
float der = NdotLs * (sh_mul + ndlc);
|
||||||
diff = 2. / (1. + sqrt(1. + (1. - sh_mul) * ndlc));
|
diff = 2. / (1. + sqrt(1. + (1. - sh_mul) * ndlc));
|
||||||
li += spot * gl_LightSource[index].diffuse.rgb * diff * light_diffuse(0, ldir, n);
|
li += spot * qgl_Light[index].color.rgb * diff;// * light_diffuse(0, ldir, n);
|
||||||
si += spot * gl_LightSource[index].specular.rgb * (sh_mul / (der*der) / 3.1416);
|
si += spot * qgl_Light[index].color.rgb * (sh_mul / (der*der) / 3.1416);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
//if (d == 1.) discard;
|
//if (d == 1.) discard;
|
||||||
vec4 v0 = texture2D(t0, gl_TexCoord[0].xy);
|
vec2 tc = qgl_FragTexture.xy;
|
||||||
|
vec4 v0 = texture2D(t0, tc);
|
||||||
if (v0.w == 0.) {
|
if (v0.w == 0.) {
|
||||||
gl_FragColor = back_color;
|
qgl_FragData[0] = back_color;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vec4 v1 = texture2D(t1, gl_TexCoord[0].xy), v2 = texture2D(t2, gl_TexCoord[0].xy);//, v3 = texture2D(t2, gl_TexCoord[0].xy);
|
vec4 v1 = texture2D(t1, tc), v2 = texture2D(t2, tc), v3 = texture2D(t3, tc);
|
||||||
vec2 sp = gl_FragCoord.xy * dt * 2 - vec2(1, 1);
|
vec2 sp = gl_FragCoord.xy * dt * 2 - vec2(1, 1);
|
||||||
vec3 dc = v0.rgb, n = v1.xyz * 2. - vec3(1.);
|
vec3 dc = v0.rgb, n = v1.xyz * 2. - vec3(1.);
|
||||||
float height = v2.w;
|
float height = v2.w;
|
||||||
li = gl_LightModel.ambient.rgb;
|
li = qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity;
|
||||||
|
//li = vec3(0.);
|
||||||
si = vec3(0.);
|
si = vec3(0.);
|
||||||
|
|
||||||
pos = vec4(sp, 0, 1.) * mat;
|
pos = vec4(sp, 0, 1)*mat_proji;
|
||||||
pos *= v0.w;
|
pos.xyz *= v0.w;
|
||||||
pos.rgb += n * height;
|
//pos.xy *= 10.;
|
||||||
|
//pos.z = v0.w;
|
||||||
vec3 v = normalize(-pos.xyz);
|
vec3 v = normalize(-pos.xyz);
|
||||||
sh_pow = 1. / max((1. - v1.w), 0.0001);
|
sh_pow = 1. / max((1. - v1.w), 0.0001);
|
||||||
sh_mul = max(1. - v1.w, 0.0001);
|
sh_mul = max(1. - v1.w, 0.0001);
|
||||||
if (lightsCount > 0) {
|
//calcLight(0, n, v, v2);
|
||||||
|
/*if (lightsCount > 0) {
|
||||||
calcLight(0, n, v, v2);
|
calcLight(0, n, v, v2);
|
||||||
if (lightsCount > 1) {
|
if (lightsCount > 1) {
|
||||||
calcLight(1, n, v, v2);
|
calcLight(1, n, v, v2);
|
||||||
@@ -86,7 +94,15 @@ void main(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
gl_FragColor.rgb = li * dc + si * v2.rgb + texture2D(tb, gl_TexCoord[0].xy).rgb;
|
//qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb;// + texture2D(tb, tc).rgb;
|
||||||
//gl_FragColor.rgb = vec3(v2.rgb);
|
//vec4 lp = mat*qgl_Light[0].position;
|
||||||
|
lpos = qgl_Light[0].position;
|
||||||
|
ldir = lpos.xyz - pos.xyz;
|
||||||
|
ldist = length(ldir);
|
||||||
|
float d = texture2D(td, tc).r;
|
||||||
|
//float z = ((z_near / (z_near-z_far)) * z_far) / (d - (z_far / (z_far-z_near)));
|
||||||
|
float z = z_near * z_far / (d * (z_far - z_near) - z_far);
|
||||||
|
//qgl_FragData[0].rgb = vec3(abs((v0.w)+(v3.z))-0.5);
|
||||||
|
qgl_FragData[0].rgb = vec3((-z*view_pos));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
#version 130
|
#version 150
|
||||||
|
|
||||||
|
in vec4 view_corner;
|
||||||
|
out vec4 view_dir;
|
||||||
|
out vec3 view_pos;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
view_dir = view_corner;
|
||||||
gl_Position = ftransform();
|
view_pos = vec3(qgl_ModelViewMatrix * vec4(qgl_Vertex.xy, 1, 1));
|
||||||
|
qgl_FragTexture = qgl_Texture;
|
||||||
|
qgl_FragColor = qgl_Color;
|
||||||
|
gl_Position = qgl_ftransform();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#version 120
|
#version 150
|
||||||
|
|
||||||
uniform vec4 id;
|
uniform vec4 id;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_FragColor = id;
|
qgl_FragData[0] = id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#version 120
|
#version 150
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_Position = ftransform();
|
gl_Position = qgl_ftransform();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 130
|
#version 150
|
||||||
|
|
||||||
uniform vec2 dt;
|
uniform vec2 dt;
|
||||||
uniform vec4 selected, color;
|
uniform vec4 selected, color;
|
||||||
@@ -6,13 +6,14 @@ uniform sampler2D t0;
|
|||||||
uniform float fill;
|
uniform float fill;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 ds0 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(-1, 0)) - selected);
|
vec2 tc = qgl_FragTexture.xy;
|
||||||
vec4 ds1 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2( 1, 0)) - selected);
|
vec4 ds0 = abs(textureLodOffset(t0, tc, 0., ivec2(-1, 0)) - selected);
|
||||||
vec4 ds2 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(0, -1)) - selected);
|
vec4 ds1 = abs(textureLodOffset(t0, tc, 0., ivec2( 1, 0)) - selected);
|
||||||
vec4 ds3 = abs(textureLodOffset(t0, gl_TexCoord[0].xy, 0., ivec2(0, 1)) - selected);
|
vec4 ds2 = abs(textureLodOffset(t0, tc, 0., ivec2(0, -1)) - selected);
|
||||||
|
vec4 ds3 = abs(textureLodOffset(t0, tc, 0., ivec2(0, 1)) - selected);
|
||||||
float d0 = dot(ds0, vec4(1., 1., 1., 1.)), d1 = dot(ds1, vec4(1., 1., 1., 1.)), d2 = dot(ds2, vec4(1., 1., 1., 1.)), d3 = dot(ds3, vec4(1., 1., 1., 1.));
|
float d0 = dot(ds0, vec4(1., 1., 1., 1.)), d1 = dot(ds1, vec4(1., 1., 1., 1.)), d2 = dot(ds2, vec4(1., 1., 1., 1.)), d3 = dot(ds3, vec4(1., 1., 1., 1.));
|
||||||
float vs = step(1e-6, d0 + d1 + d2 + d3);
|
float vs = step(1e-6, d0 + d1 + d2 + d3);
|
||||||
float vm = step(1e-3, (d0 * 255.) * (d1 * 255.) * (d2 * 255.) * (d3 * 255.));
|
float vm = step(1e-3, (d0 * 255.) * (d1 * 255.) * (d2 * 255.) * (d3 * 255.));
|
||||||
float v = mix(vs - vm, vs - vm - vm + 1, fill);
|
float v = mix(vs - vm, vs - vm - vm + 1, fill);
|
||||||
gl_FragColor = vec4(color.rgb, v * color.a);
|
qgl_FragData[0] = vec4(color.rgb, v * color.a);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#version 130
|
#version 150
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
qgl_FragTexture = qgl_Texture;
|
||||||
gl_Position = ftransform();
|
gl_Position = qgl_ftransform();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ void WaterSystem::Particle::process(const QList<QVector<Particle> * > & near_par
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WaterSystem::draw(bool simplest) {
|
void WaterSystem::draw(QGLShaderProgram * prog, bool simplest) {
|
||||||
//return;
|
//return;
|
||||||
pass_ = GLObjectBase::Transparent;
|
pass_ = GLObjectBase::Transparent;
|
||||||
//qDebug() << "save states" << cv.size();
|
//qDebug() << "save states" << cv.size();
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ public:
|
|||||||
WaterSystem();
|
WaterSystem();
|
||||||
~WaterSystem();
|
~WaterSystem();
|
||||||
|
|
||||||
virtual void draw(bool simplest = false);
|
virtual void draw(QGLShaderProgram * prog, bool simplest = false);
|
||||||
virtual void update();
|
virtual void update();
|
||||||
virtual void init() {createGLTexture(texture, QImage("./media-record.png")); material_.diffuse.bitmap_id = texture; is_init = true;}
|
virtual void init() {createGLTexture(texture, QImage("./media-record.png")); material_.map_diffuse.bitmap_id = texture; is_init = true;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class Chunk;
|
class Chunk;
|
||||||
|
|||||||
Reference in New Issue
Block a user