code format
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -21,20 +21,20 @@
|
||||
|
||||
|
||||
Camera::Camera() {
|
||||
type_ = glCamera;
|
||||
fov_ = 60.;
|
||||
type_ = glCamera;
|
||||
fov_ = 60.;
|
||||
angle_limit_lower_xy = 0.f;
|
||||
angle_limit_upper_xy = 360.f;
|
||||
angles_.setY(270.f);
|
||||
depth_start = 0.1f;
|
||||
depth_end = 1000.f;
|
||||
depth_end = 1000.f;
|
||||
mirror_x = mirror_y = false;
|
||||
}
|
||||
|
||||
|
||||
void Camera::anglesFromPoints() {
|
||||
QVector3D dv = aim_ - pos_, tv;
|
||||
tv = QVector3D(dv.x(), dv.y(), 0.);
|
||||
tv = QVector3D(dv.x(), dv.y(), 0.);
|
||||
angles_.setZ(atan2f(tv.x(), tv.y()) * rad2deg);
|
||||
angles_.setY(piClamp<GLfloat>(atan2f(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy) + 180.f);
|
||||
}
|
||||
@@ -42,12 +42,11 @@ void Camera::anglesFromPoints() {
|
||||
|
||||
void Camera::apply(const GLfloat & aspect) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
if (aspect <= 1.f)
|
||||
glScalef(aspect, aspect, 1.f);
|
||||
if (aspect <= 1.f) glScalef(aspect, aspect, 1.f);
|
||||
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);
|
||||
//qDebug() << pm;
|
||||
// pm.perspective(fov_, aspect, depth_start, depth_end);
|
||||
// qDebug() << pm;// << glMatrixPerspective(fov_, aspect, depth_start, depth_end);
|
||||
// qDebug() << pm;
|
||||
setGLMatrix(pm);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
pm.setToIdentity();
|
||||
@@ -55,17 +54,17 @@ void Camera::apply(const GLfloat & aspect) {
|
||||
pm.rotate(angles_.y(), 1., 0., 0.);
|
||||
pm.rotate(angles_.x(), 0., 1., 0.);
|
||||
pm.rotate(angles_.z(), 0., 0., 1.);
|
||||
//pm.translate(-aim_);
|
||||
// pm.translate(-aim_);
|
||||
if (parent_) {
|
||||
QMatrix4x4 pmat = parent_->worldTransform();
|
||||
offset_ = pmat.column(3).toVector3D();
|
||||
offset_ = pmat.column(3).toVector3D();
|
||||
pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
|
||||
pmat.translate(aim_);
|
||||
pm *= pmat.inverted();
|
||||
//qDebug() << pmat;
|
||||
// qDebug() << pmat;
|
||||
}
|
||||
setGLMatrix(pm);
|
||||
//qDebug() << angles_;
|
||||
// qDebug() << angles_;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,65 +76,65 @@ QMatrix4x4 Camera::offsetMatrix() const {
|
||||
|
||||
/*
|
||||
void Camera::localTransform(QMatrix4x4 & m) {
|
||||
return;
|
||||
if (parent_)
|
||||
m *= parent_->worldTransform();
|
||||
QMatrix4x4 ret;
|
||||
//qDebug() << "local camera";
|
||||
ret.translate(0., 0., -distance());
|
||||
ret.rotate(angles_.y(), 1., 0., 0.);
|
||||
ret.rotate(angles_.x(), 0., 1., 0.);
|
||||
ret.rotate(angles_.z(), 0., 0., 1.);
|
||||
//m *= ret.inverted();
|
||||
return;
|
||||
if (parent_)
|
||||
m *= parent_->worldTransform();
|
||||
QMatrix4x4 ret;
|
||||
//qDebug() << "local camera";
|
||||
ret.translate(0., 0., -distance());
|
||||
ret.rotate(angles_.y(), 1., 0., 0.);
|
||||
ret.rotate(angles_.x(), 0., 1., 0.);
|
||||
ret.rotate(angles_.z(), 0., 0., 1.);
|
||||
//m *= ret.inverted();
|
||||
}
|
||||
*/
|
||||
|
||||
void Camera::assign(const Camera & c) {
|
||||
pos_ = c.pos_;
|
||||
aim_ = c.aim_;
|
||||
fov_ = c.fov_;
|
||||
angles_ = c.angles_;
|
||||
pos_ = c.pos_;
|
||||
aim_ = c.aim_;
|
||||
fov_ = c.fov_;
|
||||
angles_ = c.angles_;
|
||||
angle_limit_lower_xy = c.angle_limit_lower_xy;
|
||||
angle_limit_upper_xy = c.angle_limit_upper_xy;
|
||||
mirror_x = c.mirror_x;
|
||||
mirror_y = c.mirror_y;
|
||||
depth_start = c.depth_start;
|
||||
depth_end = c.depth_end;
|
||||
mirror_x = c.mirror_x;
|
||||
mirror_y = c.mirror_y;
|
||||
depth_start = c.depth_start;
|
||||
depth_end = c.depth_end;
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
GLObjectBase * Camera::clone(bool withChildren) {
|
||||
Camera * o = new Camera(*this);
|
||||
//GLObjectBase::clone(withChildren);
|
||||
// GLObjectBase::clone(withChildren);
|
||||
o->is_init = false;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->view_ = nullptr;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->view_ = nullptr;
|
||||
o->children_.clear();
|
||||
if (withChildren) {
|
||||
for (int i = 0; i < children_.size(); ++i)
|
||||
o->addChild(children_[i]->clone(withChildren));
|
||||
}
|
||||
o->pos_ = pos_;
|
||||
o->aim_ = aim_;
|
||||
o->fov_ = fov_;
|
||||
o->angles_ = angles_;
|
||||
o->pos_ = pos_;
|
||||
o->aim_ = aim_;
|
||||
o->fov_ = fov_;
|
||||
o->angles_ = angles_;
|
||||
o->angle_limit_lower_xy = angle_limit_lower_xy;
|
||||
o->angle_limit_upper_xy = angle_limit_upper_xy;
|
||||
o->mirror_x = mirror_x;
|
||||
o->mirror_y = mirror_y;
|
||||
o->depth_start = depth_start;
|
||||
o->depth_end = depth_end;
|
||||
o->meta = meta;
|
||||
o->mirror_x = mirror_x;
|
||||
o->mirror_y = mirror_y;
|
||||
o->depth_start = depth_start;
|
||||
o->depth_end = depth_end;
|
||||
o->meta = meta;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
void Camera::panZ(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
angles_.setZ(angles_.z() + a);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
|
||||
aim_ = pos_ + dv;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -143,11 +142,11 @@ void Camera::panZ(const float & a) {
|
||||
|
||||
void Camera::panXY(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length(), tc;
|
||||
float tl = dv.length(), tc;
|
||||
angles_.setY(angles_.y() + a);
|
||||
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
aim_ = pos_ + dv * tl;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -155,9 +154,9 @@ void Camera::panXY(const float & a) {
|
||||
|
||||
void Camera::rotateZ(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
angles_.setZ(angles_.z() + a);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
|
||||
aim_ = pos_ + dv;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -165,11 +164,11 @@ void Camera::rotateZ(const float & a) {
|
||||
|
||||
void Camera::rotateXY(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length(), tc;
|
||||
float tl = dv.length(), tc;
|
||||
angles_.setY(angles_.y() + a);
|
||||
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
aim_ = pos_ + dv * tl;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -177,9 +176,9 @@ void Camera::rotateXY(const float & a) {
|
||||
|
||||
void Camera::orbitZ(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
angles_.setZ(angles_.z() + a);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
|
||||
pos_ = aim_ - dv;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -187,11 +186,11 @@ void Camera::orbitZ(const float & a) {
|
||||
|
||||
void Camera::orbitXY(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length(), tc;
|
||||
float tl = dv.length(), tc;
|
||||
angles_.setY(angles_.y() + a);
|
||||
angles_.setY(piClamp<GLfloat>(angles_.y(), angle_limit_lower_xy, angle_limit_upper_xy));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
pos_ = aim_ - dv * tl;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -199,9 +198,9 @@ void Camera::orbitXY(const float & a) {
|
||||
|
||||
void Camera::setAngleZ(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
float tl = QVector2D(dv.x(), dv.y()).length();
|
||||
angles_.setZ(a);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tl, cosf(angles_.z() * deg2rad) * tl, dv.z());
|
||||
aim_ = pos_ + dv;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -209,21 +208,21 @@ void Camera::setAngleZ(const float & a) {
|
||||
|
||||
void Camera::setAngleXY(const float & a) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length(), tc;
|
||||
float tl = dv.length(), tc;
|
||||
angles_.setY(a);
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
//pos_ = aim_ - dv;
|
||||
tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
// pos_ = aim_ - dv;
|
||||
aim_ = pos_ + dv * tl;
|
||||
buildTransform();
|
||||
//anglesFromPoints();
|
||||
// anglesFromPoints();
|
||||
}
|
||||
|
||||
|
||||
void Camera::moveForward(const float & x, bool withZ) {
|
||||
QVector3D dv;// = aim_ - pos_;
|
||||
QVector3D dv; // = aim_ - pos_;
|
||||
float tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, 0.);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, 0.);
|
||||
if (withZ) dv.setZ(-cosf(angles_.y() * deg2rad));
|
||||
dv.normalize();
|
||||
dv *= x;
|
||||
@@ -234,9 +233,9 @@ void Camera::moveForward(const float & x, bool withZ) {
|
||||
|
||||
|
||||
void Camera::moveLeft(const float & x, bool withZ) {
|
||||
QVector3D dv;// = aim_ - pos_;
|
||||
QVector3D dv; // = aim_ - pos_;
|
||||
float tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad - float(M_PI_2)) * tc, cosf(angles_.z() * deg2rad - float(M_PI_2)) * tc, 0.f);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad - float(M_PI_2)) * tc, cosf(angles_.z() * deg2rad - float(M_PI_2)) * tc, 0.f);
|
||||
if (withZ) dv.setZ(-sinf(angles_.x() * deg2rad));
|
||||
dv.normalize();
|
||||
dv *= x;
|
||||
@@ -252,7 +251,7 @@ void Camera::moveUp(const float & x, bool onlyZ) {
|
||||
dv = QVector3D(0., 0., x);
|
||||
else {
|
||||
float tc = cosf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -sinf(angles_.y() * deg2rad));
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -sinf(angles_.y() * deg2rad));
|
||||
dv.normalize();
|
||||
dv *= x;
|
||||
}
|
||||
@@ -265,7 +264,7 @@ void Camera::moveUp(const float & x, bool onlyZ) {
|
||||
void Camera::flyCloser(const float & s) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length() / (1.f + s), tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
pos_ = aim_ - dv * tl;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -274,7 +273,7 @@ void Camera::flyCloser(const float & s) {
|
||||
void Camera::flyFarer(const float & s) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tl = dv.length() * (1.f + s), tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
pos_ = aim_ - dv * tl;
|
||||
buildTransform();
|
||||
}
|
||||
@@ -282,9 +281,8 @@ void Camera::flyFarer(const float & s) {
|
||||
|
||||
void Camera::flyToDistance(const float & d) {
|
||||
QVector3D dv = aim_ - pos_;
|
||||
float tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
pos_ = aim_ - dv * d;
|
||||
float tc = -sinf(angles_.y() * deg2rad);
|
||||
dv = QVector3D(sinf(angles_.z() * deg2rad) * tc, cosf(angles_.z() * deg2rad) * tc, -cosf(angles_.y() * deg2rad));
|
||||
pos_ = aim_ - dv * d;
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -23,66 +23,101 @@
|
||||
|
||||
class Camera;
|
||||
|
||||
//extern QMatrix4x4 globCameraMatrix;
|
||||
//extern Camera * currentCamera;
|
||||
// extern QMatrix4x4 globCameraMatrix;
|
||||
// extern Camera * currentCamera;
|
||||
|
||||
class Camera: public GLObjectBase
|
||||
{
|
||||
class Camera: public GLObjectBase {
|
||||
friend class QGLView;
|
||||
friend class GLParticlesSystem;
|
||||
friend QDataStream & operator <<(QDataStream & s, const GLObjectBase * p);
|
||||
friend QDataStream & operator >>(QDataStream & s, GLObjectBase *& p);
|
||||
friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
|
||||
friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
|
||||
|
||||
public:
|
||||
Camera();
|
||||
|
||||
void setPos(const QVector3D & p) {pos_ = p; anglesFromPoints(); buildTransform();}
|
||||
void setAim(const QVector3D & p) {aim_ = p; anglesFromPoints(); buildTransform();}
|
||||
void move(const QVector3D & p) {pos_ += p; aim_ += p; buildTransform();}
|
||||
void move(const float & x, const float & y = 0., const float & z = 0.) {pos_ += QVector3D(x, y, z); aim_ += QVector3D(x, y, z); buildTransform();}
|
||||
void setPos(const QVector3D & p) {
|
||||
pos_ = p;
|
||||
anglesFromPoints();
|
||||
buildTransform();
|
||||
}
|
||||
void setAim(const QVector3D & p) {
|
||||
aim_ = p;
|
||||
anglesFromPoints();
|
||||
buildTransform();
|
||||
}
|
||||
void move(const QVector3D & p) {
|
||||
pos_ += p;
|
||||
aim_ += p;
|
||||
buildTransform();
|
||||
}
|
||||
void move(const float & x, const float & y = 0., const float & z = 0.) {
|
||||
pos_ += QVector3D(x, y, z);
|
||||
aim_ += QVector3D(x, y, z);
|
||||
buildTransform();
|
||||
}
|
||||
void moveForward(const float & x, bool withZ = true);
|
||||
void moveBackward(const float & x, bool withZ = true) {moveForward(-x, withZ);}
|
||||
void moveBackward(const float & x, bool withZ = true) { moveForward(-x, withZ); }
|
||||
void moveLeft(const float & x, bool withZ = true);
|
||||
void moveRight(const float & x, bool withZ = true) {moveLeft(-x, withZ);}
|
||||
void moveRight(const float & x, bool withZ = true) { moveLeft(-x, withZ); }
|
||||
void moveUp(const float & x, bool onlyZ = false);
|
||||
void moveDown(const float & x, bool onlyZ = false) {moveUp(-x, onlyZ);}
|
||||
void moveDown(const float & x, bool onlyZ = false) { moveUp(-x, onlyZ); }
|
||||
void rotateZ(const float & a);
|
||||
void rotateXY(const float & a);
|
||||
void rotateRoll(const float & a) {angles_.setX(angles_.x() + a); buildTransform();}
|
||||
void rotateRoll(const float & a) {
|
||||
angles_.setX(angles_.x() + a);
|
||||
buildTransform();
|
||||
}
|
||||
void orbitZ(const float & a);
|
||||
void orbitXY(const float & a);
|
||||
void panZ(const float & a);
|
||||
void panXY(const float & a);
|
||||
void setFOV(const float & f) {fov_ = f;}
|
||||
void setAngles(const QVector3D & a) {setRotation(a);}
|
||||
void setFOV(const float & f) { fov_ = f; }
|
||||
void setAngles(const QVector3D & a) { setRotation(a); }
|
||||
void setAngleZ(const float & a);
|
||||
void setAngleXY(const float & a);
|
||||
void setAngleRoll(const float & a) {angles_.setX(a); buildTransform();}
|
||||
void setAngleLowerLimitXY(const float & a) {angle_limit_lower_xy = a; buildTransform();}
|
||||
void setAngleUpperLimitXY(const float & a) {angle_limit_upper_xy = a; buildTransform();}
|
||||
void setAngleLimitsXY(const float & lower, const float & upper) {angle_limit_lower_xy = lower; angle_limit_upper_xy = upper; buildTransform();}
|
||||
void setDepthStart(const float & d) {depth_start = d;}
|
||||
void setDepthEnd(const float & d) {depth_end = d;}
|
||||
void setMirrorX(bool yes) {mirror_x = yes;}
|
||||
void setMirrorY(bool yes) {mirror_y = yes;}
|
||||
void setAngleRoll(const float & a) {
|
||||
angles_.setX(a);
|
||||
buildTransform();
|
||||
}
|
||||
void setAngleLowerLimitXY(const float & a) {
|
||||
angle_limit_lower_xy = a;
|
||||
buildTransform();
|
||||
}
|
||||
void setAngleUpperLimitXY(const float & a) {
|
||||
angle_limit_upper_xy = a;
|
||||
buildTransform();
|
||||
}
|
||||
void setAngleLimitsXY(const float & lower, const float & upper) {
|
||||
angle_limit_lower_xy = lower;
|
||||
angle_limit_upper_xy = upper;
|
||||
buildTransform();
|
||||
}
|
||||
void setDepthStart(const float & d) { depth_start = d; }
|
||||
void setDepthEnd(const float & d) { depth_end = d; }
|
||||
void setMirrorX(bool yes) { mirror_x = yes; }
|
||||
void setMirrorY(bool yes) { mirror_y = yes; }
|
||||
void flyCloser(const float & s);
|
||||
void flyFarer(const float & s);
|
||||
void flyToDistance(const float & d);
|
||||
|
||||
QVector3D aim() const {return aim_;}
|
||||
QVector3D angles() const {return rotation();}
|
||||
QVector3D direction() const {return (aim_ - pos_).normalized();}
|
||||
QVector3D directionXY() const {QVector3D tv = aim_ - pos_; return QVector3D(tv.x(), tv.y(), 0.).normalized();}
|
||||
float FOV() const {return fov_;}
|
||||
float distance() const {return (pos_ - aim_).length();}
|
||||
float angleZ() const {return angles_.z();}
|
||||
float angleXY() const {return angles_.y();}
|
||||
float angleRoll() const {return angles_.x();}
|
||||
float angleLowerLimitXY() const {return angle_limit_lower_xy;}
|
||||
float angleUpperLimitXY() const {return angle_limit_upper_xy;}
|
||||
float depthStart() const {return depth_start;}
|
||||
float depthEnd() const {return depth_end;}
|
||||
bool isMirrorX() const {return mirror_x;}
|
||||
bool isMirrorY() const {return mirror_y;}
|
||||
QVector3D aim() const { return aim_; }
|
||||
QVector3D angles() const { return rotation(); }
|
||||
QVector3D direction() const { return (aim_ - pos_).normalized(); }
|
||||
QVector3D directionXY() const {
|
||||
QVector3D tv = aim_ - pos_;
|
||||
return QVector3D(tv.x(), tv.y(), 0.).normalized();
|
||||
}
|
||||
float FOV() const { return fov_; }
|
||||
float distance() const { return (pos_ - aim_).length(); }
|
||||
float angleZ() const { return angles_.z(); }
|
||||
float angleXY() const { return angles_.y(); }
|
||||
float angleRoll() const { return angles_.x(); }
|
||||
float angleLowerLimitXY() const { return angle_limit_lower_xy; }
|
||||
float angleUpperLimitXY() const { return angle_limit_upper_xy; }
|
||||
float depthStart() const { return depth_start; }
|
||||
float depthEnd() const { return depth_end; }
|
||||
bool isMirrorX() const { return mirror_x; }
|
||||
bool isMirrorY() const { return mirror_y; }
|
||||
void anglesFromPoints();
|
||||
void apply(const GLfloat & aspect = 1.);
|
||||
void assign(const Camera & c);
|
||||
@@ -100,7 +135,6 @@ private:
|
||||
GLfloat angle_limit_upper_xy;
|
||||
bool mirror_x;
|
||||
bool mirror_y;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLCAMERA_H
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
|
||||
|
||||
GLFramebuffer::GLFramebuffer(int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum target__) {
|
||||
is_depth = withDepth;
|
||||
is_depth = withDepth;
|
||||
color_format = colorFormat_;
|
||||
target_ = target__;
|
||||
target_ = target__;
|
||||
colors.fill(0, colorAttachments_);
|
||||
fbo = drbo = 0;
|
||||
tex_d = 0;
|
||||
wid = hei = 0;
|
||||
tex_d = 0;
|
||||
wid = hei = 0;
|
||||
is_changed = false;
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ void GLFramebuffer::resize(int width, int height, bool force) {
|
||||
|
||||
|
||||
QImage GLFramebuffer::grab() const {
|
||||
//glReadPixels(0, 0, wid, hei, GL_RGBA, );
|
||||
//QImage ret();
|
||||
// glReadPixels(0, 0, wid, hei, GL_RGBA, );
|
||||
// QImage ret();
|
||||
return QImage();
|
||||
}
|
||||
|
||||
@@ -90,17 +90,17 @@ void GLFramebuffer::bind() {
|
||||
if (is_changed) resize(wid, hei);
|
||||
if (fbo == 0) return;
|
||||
initializeOpenGLFunctions();
|
||||
//glFlush();
|
||||
// glFlush();
|
||||
glGetIntegerv(GL_VIEWPORT, prev_view);
|
||||
//glClearError();
|
||||
// glClearError();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
//qDebug() << QString::number(glGetError(), 16);
|
||||
// qDebug() << QString::number(glGetError(), 16);
|
||||
QVector<GLenum> buffers;
|
||||
for (int i = 0; i < colors.size(); ++i)
|
||||
buffers << GL_COLOR_ATTACHMENT0 + i;
|
||||
glDrawBuffers(buffers.size(), buffers.constData());
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
// glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glViewport(0, 0, wid, hei);
|
||||
}
|
||||
|
||||
@@ -108,17 +108,17 @@ void GLFramebuffer::bind() {
|
||||
void GLFramebuffer::release() {
|
||||
is_changed = false;
|
||||
if (fbo == 0) return;
|
||||
//glFlush();
|
||||
// glFlush();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(prev_view[0], prev_view[1], prev_view[2], prev_view[3]);
|
||||
}
|
||||
|
||||
|
||||
void GLFramebuffer::setWriteBuffer(int index) {
|
||||
//QVector<GLenum> buffers; buffers << GL_COLOR_ATTACHMENT0 + index;
|
||||
// QVector<GLenum> buffers; buffers << GL_COLOR_ATTACHMENT0 + index;
|
||||
GLenum e = GL_COLOR_ATTACHMENT0 + index;
|
||||
glDrawBuffer(e);
|
||||
//glDrawBuffers(1, &e);
|
||||
// glDrawBuffers(1, &e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,48 +19,56 @@
|
||||
#ifndef GLFRAMEBUFFER_H
|
||||
#define GLFRAMEBUFFER_H
|
||||
|
||||
#include <QOpenGLExtraFunctions>
|
||||
#include "gltypes.h"
|
||||
|
||||
#include <QOpenGLExtraFunctions>
|
||||
|
||||
class GLFramebuffer : protected QOpenGLExtraFunctions
|
||||
{
|
||||
|
||||
class GLFramebuffer: protected QOpenGLExtraFunctions {
|
||||
public:
|
||||
GLFramebuffer(int colorAttachments = 1, bool withDepth = true, GLenum colorFormat = GL_RGBA8, GLenum target = GL_TEXTURE_2D);
|
||||
virtual ~GLFramebuffer();
|
||||
|
||||
GLuint id() const {return fbo;}
|
||||
GLuint colorTexture(int index = 0) const {return colors[index];}
|
||||
GLenum colorFormat() const {return color_format;}
|
||||
GLuint depthTexture() const {return tex_d;}
|
||||
GLenum target() const {return target_;}
|
||||
int width() const {return wid;}
|
||||
int height() const {return hei;}
|
||||
QSize size() const {return QSize(wid, hei);}
|
||||
GLuint id() const { return fbo; }
|
||||
GLuint colorTexture(int index = 0) const { return colors[index]; }
|
||||
GLenum colorFormat() const { return color_format; }
|
||||
GLuint depthTexture() const { return tex_d; }
|
||||
GLenum target() const { return target_; }
|
||||
int width() const { return wid; }
|
||||
int height() const { return hei; }
|
||||
QSize size() const { return QSize(wid, hei); }
|
||||
QImage grab() const;
|
||||
|
||||
void resize(int width, int height, bool force = false);
|
||||
void bind();
|
||||
void release();
|
||||
void setReadBuffer(int index) {glReadBuffer(GL_COLOR_ATTACHMENT0 + index);}
|
||||
void setReadBuffer(int index) { glReadBuffer(GL_COLOR_ATTACHMENT0 + index); }
|
||||
void setWriteBuffer(int index);
|
||||
void setWriteBuffers(int * indeces, int count);
|
||||
void setColorFormat(GLenum format) {color_format = format; is_changed = true;}
|
||||
void setColorFormat(GLenum format) {
|
||||
color_format = format;
|
||||
is_changed = true;
|
||||
}
|
||||
|
||||
void copyDepthFrom(GLuint tex) {;}
|
||||
void copyDepthFrom(GLuint tex) { ; }
|
||||
void bindColorTextures();
|
||||
void bindDepthTexture(int channel);
|
||||
|
||||
private:
|
||||
void deleteGLRenderbuffer(GLuint & drbo) {if (drbo != 0) glDeleteRenderbuffers(1, &drbo); drbo = 0;}
|
||||
void deleteGLFramebuffer(GLuint & fbo) {if (fbo != 0) glDeleteFramebuffers(1, &fbo); fbo = 0;}
|
||||
void deleteGLRenderbuffer(GLuint & drbo) {
|
||||
if (drbo != 0) glDeleteRenderbuffers(1, &drbo);
|
||||
drbo = 0;
|
||||
}
|
||||
void deleteGLFramebuffer(GLuint & fbo) {
|
||||
if (fbo != 0) glDeleteFramebuffers(1, &fbo);
|
||||
fbo = 0;
|
||||
}
|
||||
|
||||
bool is_depth, is_changed;
|
||||
QVector<GLuint> colors;
|
||||
GLenum color_format, target_;
|
||||
GLuint fbo, drbo, tex_d;
|
||||
GLint prev_view[4], wid, hei;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLFRAMEBUFFER_H
|
||||
|
||||
@@ -23,24 +23,24 @@ QStringList GLTextureManagerBase::search_pathes(".");
|
||||
|
||||
|
||||
bool GLCubeTexture::create() {
|
||||
//qDebug("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_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();
|
||||
// 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, nullptr);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
//qDebug() << glGetError();
|
||||
// qDebug() << glGetError();
|
||||
changed_ = false;
|
||||
return id_ > 0;
|
||||
}
|
||||
@@ -59,28 +59,41 @@ void GLCubeTexture::load() {
|
||||
|
||||
|
||||
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());
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString GLTextureManagerBase::findFile(const QString & path) {
|
||||
return ::findFile(path, search_pathes);
|
||||
}
|
||||
@@ -91,16 +104,16 @@ GLuint GLTextureManagerBase::loadTexture(const QString & path, bool ownership, b
|
||||
if (p.isEmpty()) return 0;
|
||||
int tid = textureID(p, bump);
|
||||
if (tid > 0) {
|
||||
//qDebug() << "[TextureManager] Found" << path << "as" << tid;
|
||||
// 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, __GLContext__::MipmapBindOption*/);
|
||||
//GLuint tid = 0;
|
||||
// qDebug() << p << image.width() << image.height() << image.format() << bump;
|
||||
/// tid = currentQGLView->bindTexture(image, GL_TEXTURE_2D/*, GL_RGBA, __GLContext__::MipmapBindOption*/);
|
||||
// GLuint tid = 0;
|
||||
GLuint _tid = tid;
|
||||
createGLTexture(_tid, image);///currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
||||
createGLTexture(_tid, image); /// currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
||||
tid = _tid;
|
||||
if (tid == 0) {
|
||||
qDebug() << "[TextureManager] Can`t load" << p;
|
||||
@@ -117,12 +130,12 @@ GLuint GLTextureManagerBase::loadTexture(const QImage & im, bool ownership, bool
|
||||
QImage image(im);
|
||||
if (bump) convertToNormal(image);
|
||||
GLuint tid = 0;
|
||||
createGLTexture(tid, im);///currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
||||
createGLTexture(tid, im); /// currentQGLView->bindTexture(image, GL_TEXTURE_2D);
|
||||
if (tid == 0) {
|
||||
qDebug() << "[TextureManager] Can`t load image";
|
||||
return tid;
|
||||
}
|
||||
//qDebug() << "[TextureManager] Loaded image as" << tid;
|
||||
// qDebug() << "[TextureManager] Loaded image as" << tid;
|
||||
if (ownership) tex_ids[bump ? 1 : 0].insert(QString(), tid);
|
||||
return tid;
|
||||
}
|
||||
@@ -150,21 +163,24 @@ void GLTextureManagerBase::reloadTexture(GLuint tid, const QImage & im) {
|
||||
|
||||
|
||||
Vector3d colorVector(QRgb c) {
|
||||
return Vector3d(((uchar*)(&c))[0] / 255., ((uchar*)(&c))[1] / 255., ((uchar*)(&c))[2] / 255.);
|
||||
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);
|
||||
float sum[3] = {0., 0., 0.};
|
||||
llong a = 0;
|
||||
QImage sim = im.convertToFormat(QImage::Format_ARGB32);
|
||||
float 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] += sd[a] / 255.f - 0.5f; ++a;
|
||||
sum[1] += sd[a] / 255.f - 0.5f; ++a;
|
||||
sum[0] += sd[a] / 255.f - 0.5f; ++a;
|
||||
sum[2] += sd[a] / 255.f - 0.5f;
|
||||
++a;
|
||||
sum[1] += sd[a] / 255.f - 0.5f;
|
||||
++a;
|
||||
sum[0] += sd[a] / 255.f - 0.5f;
|
||||
++a;
|
||||
++a;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +194,7 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
|
||||
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;
|
||||
a = 0;
|
||||
uchar * dd = dim.bits();
|
||||
for (int i = 0; i < sim.height(); i++) {
|
||||
for (int j = 0; j < sim.width(); j++) {
|
||||
@@ -187,40 +203,42 @@ void GLTextureManagerBase::convertToNormal(QImage & im) {
|
||||
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));
|
||||
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.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f);
|
||||
res.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f);
|
||||
tx = (j + 1) % w;
|
||||
ty = (i + 1) % h;
|
||||
p[1] = colorVector(sim.pixel(j, ty));
|
||||
p[2] = colorVector(sim.pixel(tx, i));
|
||||
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.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f);
|
||||
res.x = piClamp(0.5f + (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f);
|
||||
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;
|
||||
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");
|
||||
// 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;
|
||||
color_self_illumination = Qt::black;
|
||||
glass = false;
|
||||
transparency = reflectivity = 0.f;
|
||||
map_specularity.color_amount = 0.5f;
|
||||
map_specular.color_amount = 1.f;
|
||||
iof = 1.f;
|
||||
dispersion = 0.05f;
|
||||
map_specular.color_amount = 1.f;
|
||||
iof = 1.f;
|
||||
dispersion = 0.05f;
|
||||
}
|
||||
|
||||
|
||||
@@ -228,24 +246,24 @@ void Material::apply(QOpenGLShaderProgram * prog) {
|
||||
if (prog) {
|
||||
setUniformMaterial(prog, *this);
|
||||
} else {
|
||||
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
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] = map_diffuse.color_amount * color_diffuse.redF();
|
||||
mat_diffuse[1] = map_diffuse.color_amount * color_diffuse.greenF();
|
||||
mat_diffuse[2] = map_diffuse.color_amount * color_diffuse.blueF();
|
||||
mat_diffuse[3] = map_diffuse.color_amount * color_diffuse.alphaF() * (1.f - transparency);
|
||||
mat_specular[0] = map_specular.color_amount * color_specular.redF();
|
||||
mat_specular[1] = map_specular.color_amount * color_specular.greenF();
|
||||
mat_specular[2] = map_specular.color_amount * color_specular.blueF();
|
||||
mat_emission[0] = map_self_illumination.color_amount * color_self_illumination.redF();
|
||||
mat_emission[1] = map_self_illumination.color_amount * color_self_illumination.greenF();
|
||||
mat_emission[2] = map_self_illumination.color_amount * color_self_illumination.blueF();
|
||||
mat_diffuse[0] = map_diffuse.color_amount * color_diffuse.redF();
|
||||
mat_diffuse[1] = map_diffuse.color_amount * color_diffuse.greenF();
|
||||
mat_diffuse[2] = map_diffuse.color_amount * color_diffuse.blueF();
|
||||
mat_diffuse[3] = map_diffuse.color_amount * color_diffuse.alphaF() * (1.f - transparency);
|
||||
mat_specular[0] = map_specular.color_amount * color_specular.redF();
|
||||
mat_specular[1] = map_specular.color_amount * color_specular.greenF();
|
||||
mat_specular[2] = map_specular.color_amount * color_specular.blueF();
|
||||
mat_emission[0] = map_self_illumination.color_amount * color_self_illumination.redF();
|
||||
mat_emission[1] = map_self_illumination.color_amount * color_self_illumination.greenF();
|
||||
mat_emission[2] = map_self_illumination.color_amount * 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);
|
||||
//qDebug() << (map_specularity.color_amount)*128.;
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, (map_specularity.color_amount)*128.f);
|
||||
// qDebug() << (map_specularity.color_amount)*128.;
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, (map_specularity.color_amount) * 128.f);
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
|
||||
}
|
||||
@@ -253,7 +271,7 @@ void Material::apply(QOpenGLShaderProgram * prog) {
|
||||
|
||||
|
||||
void Material::loadTextures(GLTextureManagerBase * tm) {
|
||||
//qDebug() << "load textures";
|
||||
// qDebug() << "load textures";
|
||||
if (!tm) return;
|
||||
if (!map_diffuse.bitmap_path.isEmpty()) map_diffuse.bitmap_id = tm->loadTexture(map_diffuse.bitmap_path);
|
||||
if (!map_normal.bitmap_path.isEmpty()) map_normal.bitmap_id = tm->loadTexture(map_normal.bitmap_path, true, true);
|
||||
@@ -261,6 +279,6 @@ void Material::loadTextures(GLTextureManagerBase * tm) {
|
||||
if (!map_specularity.bitmap_path.isEmpty()) map_specularity.bitmap_id = tm->loadTexture(map_specularity.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);
|
||||
// if (!map_diffuse_2.bitmap_path.isEmpty()) map_diffuse_2.bitmap_id = tm->loadTexture(map_diffuse_2.bitmap_path);
|
||||
map_reflection.load();
|
||||
}
|
||||
|
||||
@@ -1,39 +1,55 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
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 Lesser General Public License for more details.
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLMATERIAL_H
|
||||
#define GLMATERIAL_H
|
||||
|
||||
#include "gltypes.h"
|
||||
#include "chunkstream.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_;}
|
||||
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_;
|
||||
@@ -43,27 +59,95 @@ private:
|
||||
|
||||
class GLCubeTexture {
|
||||
public:
|
||||
GLCubeTexture(int _size, const GLenum & _format = GL_RGBA8) {size = _size; format_ = _format; id_ = 0; changed_ = false; pathes.resize(6);}
|
||||
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 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 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;}
|
||||
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;
|
||||
@@ -78,28 +162,33 @@ class GLTextureManagerBase {
|
||||
public:
|
||||
GLTextureManagerBase() {}
|
||||
virtual ~GLTextureManagerBase() {}
|
||||
void addSearchPath(const QString & path) {search_pathes << path;}
|
||||
static QStringList searchPathes() {return search_pathes;}
|
||||
void addSearchPath(const QString & path) { search_pathes << path; }
|
||||
static QStringList searchPathes() { return search_pathes; }
|
||||
QString findFile(const QString & path);
|
||||
GLuint loadTexture(const QString & path, bool ownership = true, bool bump = false);
|
||||
GLuint loadTexture(const QImage & image, bool ownership = true, bool bump = false);
|
||||
void reloadTexture(GLuint tid, const QString & path);
|
||||
void reloadTexture(GLuint tid, const QImage & image);
|
||||
int textureID(const QString & path, bool bump = false) {return tex_ids[bump ? 1 : 0][path];}
|
||||
virtual void addTexture(const QString & path) = 0;
|
||||
int textureID(const QString & path, bool bump = false) { return tex_ids[bump ? 1 : 0][path]; }
|
||||
virtual void addTexture(const QString & path) = 0;
|
||||
virtual void addAnimation(const QString & dir, const QString & name) = 0;
|
||||
virtual bool loadTextures() = 0;
|
||||
virtual bool loadTextures() = 0;
|
||||
|
||||
protected:
|
||||
static void convertToNormal(QImage & im);
|
||||
static QStringList search_pathes;
|
||||
QMap<QString, GLuint> tex_ids[2];
|
||||
|
||||
};
|
||||
|
||||
class Map {
|
||||
public:
|
||||
Map() {bitmap_id = 0; color_amount = 1.f; color_offset = 0.f; animation_frame_rate = -1.f; bitmap_scale = QPointF(1., 1.);}
|
||||
Map() {
|
||||
bitmap_id = 0;
|
||||
color_amount = 1.f;
|
||||
color_offset = 0.f;
|
||||
animation_frame_rate = -1.f;
|
||||
bitmap_scale = QPointF(1., 1.);
|
||||
}
|
||||
QString bitmap_path;
|
||||
GLuint bitmap_id;
|
||||
QPointF bitmap_offset;
|
||||
@@ -137,12 +226,18 @@ public:
|
||||
};
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const Map & m) {
|
||||
inline QDataStream & operator<<(QDataStream & s, const Map & m) {
|
||||
ChunkStream cs;
|
||||
cs.add(1, m.bitmap_path).add(2, m.color_amount).add(3, m.color_offset).add(4, m.animation).add(5, m.animation_frame_rate).add(6, m.bitmap_scale);
|
||||
s << cs.data(); return s;
|
||||
cs.add(1, m.bitmap_path)
|
||||
.add(2, m.color_amount)
|
||||
.add(3, m.color_offset)
|
||||
.add(4, m.animation)
|
||||
.add(5, m.animation_frame_rate)
|
||||
.add(6, m.bitmap_scale);
|
||||
s << cs.data();
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator >>(QDataStream & s, Map & m) {
|
||||
inline QDataStream & operator>>(QDataStream & s, Map & m) {
|
||||
ChunkStream cs(s);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
@@ -157,14 +252,25 @@ inline QDataStream & operator >>(QDataStream & s, Map & m) {
|
||||
return s;
|
||||
}
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const Material & m) {
|
||||
inline QDataStream & operator<<(QDataStream & s, const Material & m) {
|
||||
ChunkStream cs;
|
||||
cs.add(1, m.name).add(2, m.color_diffuse).add(3, m.color_specular).add(4, m.color_self_illumination)
|
||||
.add(5, m.transparency).add(6, m.reflectivity).add(7, m.glass).add(8, m.map_diffuse).add(9, m.map_normal)
|
||||
.add(10, m.map_relief).add(11, m.map_specular).add(12, m.map_specularity).add(13, m.map_self_illumination);
|
||||
s << qCompress(cs.data()); return s;
|
||||
cs.add(1, m.name)
|
||||
.add(2, m.color_diffuse)
|
||||
.add(3, m.color_specular)
|
||||
.add(4, m.color_self_illumination)
|
||||
.add(5, m.transparency)
|
||||
.add(6, m.reflectivity)
|
||||
.add(7, m.glass)
|
||||
.add(8, m.map_diffuse)
|
||||
.add(9, m.map_normal)
|
||||
.add(10, m.map_relief)
|
||||
.add(11, m.map_specular)
|
||||
.add(12, m.map_specularity)
|
||||
.add(13, m.map_self_illumination);
|
||||
s << qCompress(cs.data());
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator >>(QDataStream & s, Material & m) {
|
||||
inline QDataStream & operator>>(QDataStream & s, Material & m) {
|
||||
QByteArray ba;
|
||||
s >> ba;
|
||||
ba = qUncompress(ba);
|
||||
|
||||
@@ -17,34 +17,35 @@
|
||||
*/
|
||||
|
||||
#include "globject.h"
|
||||
|
||||
#include "glcamera.h"
|
||||
#include "qglview.h"
|
||||
|
||||
|
||||
GLObjectBase::GLObjectBase() {
|
||||
type_ = glMesh;
|
||||
type_ = glMesh;
|
||||
render_mode = View;
|
||||
pass_ = Solid;
|
||||
geom_prim = Triangles;
|
||||
scale_ = QVector3D(1., 1., 1.);
|
||||
parent_ = nullptr;
|
||||
pass_ = Solid;
|
||||
geom_prim = Triangles;
|
||||
scale_ = QVector3D(1., 1., 1.);
|
||||
parent_ = nullptr;
|
||||
is_root = is_init = is_tex_loaded = selected_ = false;
|
||||
visible_ = accept_fog = accept_light = cast_shadow = rec_shadow = select_ = true;
|
||||
line_width = -1.;
|
||||
blend_src = GL_SRC_ALPHA;
|
||||
blend_dest = GL_ONE_MINUS_SRC_ALPHA;
|
||||
type_ = glMesh;
|
||||
raw_matrix = false;
|
||||
line_width = -1.;
|
||||
blend_src = GL_SRC_ALPHA;
|
||||
blend_dest = GL_ONE_MINUS_SRC_ALPHA;
|
||||
type_ = glMesh;
|
||||
raw_matrix = false;
|
||||
mat_.setToIdentity();
|
||||
view_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
GLObjectBase::~GLObjectBase() {
|
||||
//qDebug() << "del" << name() << view_;
|
||||
// qDebug() << "del" << name() << view_;
|
||||
if (parent_) parent_->children_.removeAll(this);
|
||||
if (view_) ((QGLView*)view_)->objectDeleted(this);
|
||||
foreach (GLObjectBase * c, children_) {
|
||||
if (view_) ((QGLView *)view_)->objectDeleted(this);
|
||||
foreach(GLObjectBase * c, children_) {
|
||||
c->parent_ = nullptr;
|
||||
delete c;
|
||||
}
|
||||
@@ -52,37 +53,37 @@ GLObjectBase::~GLObjectBase() {
|
||||
|
||||
|
||||
GLObjectBase * GLObjectBase::clone(bool withChildren) {
|
||||
GLObjectBase * o = new GLObjectBase();
|
||||
o->pass_ = pass_;
|
||||
o->is_init = false;
|
||||
o->accept_light = accept_light;
|
||||
o->accept_fog = accept_fog;
|
||||
o->visible_ = visible_;
|
||||
o->type_ = type_;
|
||||
o->raw_matrix = raw_matrix;
|
||||
o->mat_ = mat_;
|
||||
o->pos_ = pos_;
|
||||
o->angles_ = angles_;
|
||||
o->scale_ = scale_;
|
||||
o->itransform_ = itransform_;
|
||||
o->bound = bound;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->blend_src = blend_src;
|
||||
o->blend_dest = blend_dest;
|
||||
o->material_ = material_;
|
||||
o->pos_h = pos_h;
|
||||
o->points = points;
|
||||
o->puvws = puvws;
|
||||
o->faces = faces;
|
||||
o->uvws = uvws;
|
||||
o->norms = norms;
|
||||
o->normals = normals;
|
||||
o->vbo.vertices_ = vbo.vertices_;
|
||||
o->vbo.normals_ = vbo.normals_;
|
||||
GLObjectBase * o = new GLObjectBase();
|
||||
o->pass_ = pass_;
|
||||
o->is_init = false;
|
||||
o->accept_light = accept_light;
|
||||
o->accept_fog = accept_fog;
|
||||
o->visible_ = visible_;
|
||||
o->type_ = type_;
|
||||
o->raw_matrix = raw_matrix;
|
||||
o->mat_ = mat_;
|
||||
o->pos_ = pos_;
|
||||
o->angles_ = angles_;
|
||||
o->scale_ = scale_;
|
||||
o->itransform_ = itransform_;
|
||||
o->bound = bound;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->blend_src = blend_src;
|
||||
o->blend_dest = blend_dest;
|
||||
o->material_ = material_;
|
||||
o->pos_h = pos_h;
|
||||
o->points = points;
|
||||
o->puvws = puvws;
|
||||
o->faces = faces;
|
||||
o->uvws = uvws;
|
||||
o->norms = norms;
|
||||
o->normals = normals;
|
||||
o->vbo.vertices_ = vbo.vertices_;
|
||||
o->vbo.normals_ = vbo.normals_;
|
||||
o->vbo.texcoords_ = vbo.texcoords_;
|
||||
o->vbo.colors_ = vbo.colors_;
|
||||
o->meta = meta;
|
||||
o->view_ = nullptr;
|
||||
o->vbo.colors_ = vbo.colors_;
|
||||
o->meta = meta;
|
||||
o->view_ = nullptr;
|
||||
o->children_.clear();
|
||||
if (withChildren) {
|
||||
for (int i = 0; i < children_.size(); ++i)
|
||||
@@ -96,8 +97,8 @@ void GLObjectBase::init() {
|
||||
calculateBoundingBox();
|
||||
vbo.init();
|
||||
vbo.rebuffer();
|
||||
//material_.reflection.create();
|
||||
//qDebug() << "init" << vbo.buffer_;
|
||||
// material_.reflection.create();
|
||||
// qDebug() << "init" << vbo.buffer_;
|
||||
is_init = true;
|
||||
}
|
||||
|
||||
@@ -105,42 +106,41 @@ void GLObjectBase::init() {
|
||||
void GLObjectBase::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
vbo.draw(geom_prim, prog, simplest);
|
||||
/*if (!d_vertices.isEmpty()) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, d_uvs.constData());
|
||||
//glColorPointer(4, GL_FLOAT, 0, d_colors.constData());
|
||||
glNormalPointer(GL_FLOAT, 0, d_normals.constData());
|
||||
glDrawArrays(geom_prim, 0, d_vertices.size() / 3);*/
|
||||
/*if (pass_ == Reflection) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
}*/
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glVertexPointer(3, GL_FLOAT, 0, d_vertices.constData());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, d_uvs.constData());
|
||||
//glColorPointer(4, GL_FLOAT, 0, d_colors.constData());
|
||||
glNormalPointer(GL_FLOAT, 0, d_normals.constData());
|
||||
glDrawArrays(geom_prim, 0, d_vertices.size() / 3);*/
|
||||
/*if (pass_ == Reflection) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
||||
}*/
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::setView(QGLView * v) {
|
||||
view_ = v;
|
||||
foreach (GLObjectBase * c, children_)
|
||||
foreach(GLObjectBase * c, children_)
|
||||
c->setView(v);
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::addChild(GLObjectBase * o) {
|
||||
if (o == this) return;
|
||||
if (o->parent_)
|
||||
o->parent_->children_.removeAll(o);
|
||||
if (o->parent_) o->parent_->children_.removeAll(o);
|
||||
children_ << o;
|
||||
o->parent_ = this;
|
||||
o->setView((QGLView*)view_);
|
||||
o->setView((QGLView *)view_);
|
||||
o->buildTransform();
|
||||
if (view_) {
|
||||
view_->collectLights();
|
||||
QList<GLObjectBase*> cl = o->children(true);
|
||||
QList<GLObjectBase *> cl = o->children(true);
|
||||
cl << o;
|
||||
foreach (GLObjectBase * i, cl) {
|
||||
emit ((QGLView*)view_)->objectAdded(i);
|
||||
foreach(GLObjectBase * i, cl) {
|
||||
emit((QGLView *)view_)->objectAdded(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,8 +164,8 @@ void GLObjectBase::removeChild(int index) {
|
||||
|
||||
|
||||
void GLObjectBase::clearChildren(bool deleteAll) {
|
||||
foreach (GLObjectBase * i, children_) {
|
||||
i->view_ = nullptr;
|
||||
foreach(GLObjectBase * i, children_) {
|
||||
i->view_ = nullptr;
|
||||
i->parent_ = nullptr;
|
||||
i->clearChildren(deleteAll);
|
||||
if (deleteAll) {
|
||||
@@ -186,7 +186,7 @@ GLObjectBase * GLObjectBase::child(int index) {
|
||||
|
||||
|
||||
GLObjectBase * GLObjectBase::child(const QString & name) {
|
||||
foreach (GLObjectBase * i, children_)
|
||||
foreach(GLObjectBase * i, children_)
|
||||
if (i->name_ == name) return i;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -199,15 +199,15 @@ const GLObjectBase * GLObjectBase::child(int index) const {
|
||||
|
||||
|
||||
const GLObjectBase * GLObjectBase::child(const QString & name) const {
|
||||
foreach (GLObjectBase * i, children_)
|
||||
foreach(GLObjectBase * i, children_)
|
||||
if (i->name_ == name) return i;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
QList<GLObjectBase * > GLObjectBase::children(bool all_) {
|
||||
QList<GLObjectBase *> GLObjectBase::children(bool all_) {
|
||||
if (!all_) return children_;
|
||||
QList<GLObjectBase * > cl;
|
||||
QList<GLObjectBase *> cl;
|
||||
addChildren(cl, this);
|
||||
return cl;
|
||||
}
|
||||
@@ -230,8 +230,10 @@ void GLObjectBase::rotateY(GLfloat a) {
|
||||
void GLObjectBase::rotateZ(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
angles_.setZ(angles_.z() + a);
|
||||
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
|
||||
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
|
||||
while (angles_.z() < -360.f)
|
||||
angles_.setZ(angles_.z() + 360.f);
|
||||
while (angles_.z() > 360.f)
|
||||
angles_.setZ(angles_.z() - 360.f);
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
@@ -253,28 +255,30 @@ void GLObjectBase::setRotationY(GLfloat a) {
|
||||
void GLObjectBase::setRotationZ(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
angles_.setZ(a);
|
||||
while (angles_.z() < -360.f) angles_.setZ(angles_.z() + 360.f);
|
||||
while (angles_.z() > 360.f) angles_.setZ(angles_.z() - 360.f);
|
||||
while (angles_.z() < -360.f)
|
||||
angles_.setZ(angles_.z() + 360.f);
|
||||
while (angles_.z() > 360.f)
|
||||
angles_.setZ(angles_.z() - 360.f);
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::setRotation(const QVector3D & a) {
|
||||
raw_matrix = false;
|
||||
angles_= a;
|
||||
angles_ = a;
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::resetRotation() {
|
||||
raw_matrix = false;
|
||||
angles_ = QVector3D(0., 0., 0.);
|
||||
angles_ = QVector3D(0., 0., 0.);
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::addChildren(QList<GLObjectBase * > & list, GLObjectBase * where) {
|
||||
foreach (GLObjectBase * i, where->children_) {
|
||||
void GLObjectBase::addChildren(QList<GLObjectBase *> & list, GLObjectBase * where) {
|
||||
foreach(GLObjectBase * i, where->children_) {
|
||||
list << i;
|
||||
addChildren(list, i);
|
||||
}
|
||||
@@ -284,21 +288,22 @@ void GLObjectBase::addChildren(QList<GLObjectBase * > & list, GLObjectBase * whe
|
||||
void GLObjectBase::loadTextures(bool with_children) {
|
||||
material_.loadTextures(view_->textureManager());
|
||||
if (with_children)
|
||||
foreach (GLObjectBase * i, children_) i->loadTextures();
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->loadTextures();
|
||||
is_tex_loaded = true;
|
||||
checkPass();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::calculateBoundingBox() {
|
||||
bound = vbo.boundingBox();
|
||||
bound = vbo.boundingBox();
|
||||
QVector<QVector3D> c = bound.corners(), tc;
|
||||
//QMatrix4x4 mat = itransform_.inverted();
|
||||
//qDebug() << itransform_ << mat_ << mat;
|
||||
foreach (QVector3D p, c)
|
||||
// QMatrix4x4 mat = itransform_.inverted();
|
||||
// qDebug() << itransform_ << mat_ << mat;
|
||||
foreach(QVector3D p, c)
|
||||
tc << (itransform_ * QVector4D(p, 1)).toVector3D();
|
||||
bound = Box3D(tc);
|
||||
foreach (GLObjectBase * i, children_) {
|
||||
foreach(GLObjectBase * i, children_) {
|
||||
i->calculateBoundingBox();
|
||||
bound |= i->boundingBox();
|
||||
}
|
||||
@@ -328,25 +333,25 @@ void GLObjectBase::removeProperty(const QString & pn) {
|
||||
|
||||
void GLObjectBase::setTransform(const QMatrix4x4 & t) {
|
||||
raw_matrix = true;
|
||||
mat_ = t;
|
||||
pos_ = mat_.column(3).toVector3D();
|
||||
mat_ = t;
|
||||
pos_ = mat_.column(3).toVector3D();
|
||||
mat_.setColumn(3, QVector4D(0., 0., 0., 1.));
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::select() {
|
||||
//qDebug() << "select" << name() << view_;
|
||||
// qDebug() << "select" << name() << view_;
|
||||
selected_ = true;
|
||||
if (view_)
|
||||
((QGLView*)view_)->selectObject(this);
|
||||
if (view_) ((QGLView *)view_)->selectObject(this);
|
||||
}
|
||||
|
||||
|
||||
void GLObjectBase::setMaterial(const Material & m, bool with_children) {
|
||||
material_ = m;
|
||||
if (with_children)
|
||||
foreach (GLObjectBase * i, children_) i->setMaterial(m, true);
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->setMaterial(m, true);
|
||||
checkPass();
|
||||
is_tex_loaded = false;
|
||||
}
|
||||
@@ -355,16 +360,15 @@ void GLObjectBase::setMaterial(const Material & m, bool with_children) {
|
||||
void GLObjectBase::buildTransform() {
|
||||
itransform_.setToIdentity();
|
||||
GLObjectBase * p = parent_;
|
||||
if (p)
|
||||
itransform_ = p->itransform_;
|
||||
if (p) itransform_ = p->itransform_;
|
||||
if (raw_matrix) {
|
||||
itransform_.translate(pos_);
|
||||
itransform_ *= mat_;
|
||||
//qDebug() << "raw_matrix" << itransform_;
|
||||
// qDebug() << "raw_matrix" << itransform_;
|
||||
} else
|
||||
localTransform(itransform_);
|
||||
//qDebug() << name_ << itransform_;
|
||||
foreach (GLObjectBase * i, children_)
|
||||
// qDebug() << name_ << itransform_;
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->buildTransform();
|
||||
}
|
||||
|
||||
@@ -372,7 +376,8 @@ void GLObjectBase::buildTransform() {
|
||||
void GLObjectBase::initInternal() {
|
||||
init();
|
||||
loadTextures();
|
||||
foreach (GLObjectBase * i, children_) i->initInternal();
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->initInternal();
|
||||
}
|
||||
|
||||
|
||||
@@ -386,8 +391,10 @@ void GLObjectBase::localTransform(QMatrix4x4 & m) {
|
||||
|
||||
|
||||
void GLObjectBase::checkPass() {
|
||||
if (float(material_.color_diffuse.alphaF()) * (1.f - material_.transparency) < 1.f) pass_ = Transparent;
|
||||
else pass_ = Solid;
|
||||
if (float(material_.color_diffuse.alphaF()) * (1.f - material_.transparency) < 1.f)
|
||||
pass_ = Transparent;
|
||||
else
|
||||
pass_ = Solid;
|
||||
}
|
||||
|
||||
|
||||
@@ -406,30 +413,28 @@ QMatrix4x4 GLObjectBase::worldMatrix(QMatrix4x4 parent) const {
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
//glPushMatrix();
|
||||
///qglMultMatrix TODO
|
||||
// glPushMatrix();
|
||||
/// qglMultMatrix TODO
|
||||
material_.apply(nullptr);
|
||||
if (id != nullptr) {
|
||||
++(*id);
|
||||
ids->insert(*id, this);
|
||||
//glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
|
||||
//qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
|
||||
// glVertexAttrib1f(sh_id_loc, (*id) / 255.f);
|
||||
// qDebug() << "assign to" << sh_id_loc << (*id) / 255.f;
|
||||
}
|
||||
draw(nullptr);
|
||||
foreach (GLObjectBase * i, children_)
|
||||
foreach(GLObjectBase * i, children_)
|
||||
i->render(id, ids, sh_id_loc);
|
||||
//glPopMatrix();
|
||||
// glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Light::Light(): GLObjectBase(), shadow_map(0, true, GL_R16F) {
|
||||
type_ = glLight;
|
||||
light_type = Omni;
|
||||
intensity = 1.;
|
||||
type_ = glLight;
|
||||
light_type = Omni;
|
||||
intensity = 1.;
|
||||
angle_start = angle_end = 180.;
|
||||
decay_linear = decay_quadratic = decay_start = 0.;
|
||||
decay_const = decay_end = 1.;
|
||||
@@ -438,10 +443,10 @@ Light::Light(): GLObjectBase(), shadow_map(0, true, GL_R16F) {
|
||||
|
||||
|
||||
Light::Light(const QVector3D & p, const QColor & c, float i): GLObjectBase(), shadow_map(0, true, GL_R16F) {
|
||||
type_ = glLight;
|
||||
light_type = Omni;
|
||||
pos_ = p;
|
||||
intensity = i;
|
||||
type_ = glLight;
|
||||
light_type = Omni;
|
||||
pos_ = p;
|
||||
intensity = i;
|
||||
/*color_ = c;*/
|
||||
angle_start = angle_end = 180.;
|
||||
decay_linear = decay_quadratic = decay_start = 0.;
|
||||
@@ -451,25 +456,25 @@ Light::Light(const QVector3D & p, const QColor & c, float i): GLObjectBase(), sh
|
||||
|
||||
|
||||
GLObjectBase * Light::clone(bool withChildren) {
|
||||
Light * o = new Light(*this);
|
||||
//GLObjectBase::clone(withChildren);
|
||||
Light * o = new Light(*this);
|
||||
// GLObjectBase::clone(withChildren);
|
||||
o->is_init = false;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->view_ = nullptr;
|
||||
o->name_ = name_ + "_copy";
|
||||
o->view_ = nullptr;
|
||||
o->children_.clear();
|
||||
if (withChildren) {
|
||||
for (int i = 0; i < children_.size(); ++i)
|
||||
o->addChild(children_[i]->clone(withChildren));
|
||||
}
|
||||
o->light_type = light_type;
|
||||
o->direction = direction;
|
||||
o->angle_start = angle_start;
|
||||
o->angle_end = angle_end;
|
||||
o->intensity = intensity;
|
||||
o->decay_const = decay_const;
|
||||
o->decay_linear = decay_linear;
|
||||
o->light_type = light_type;
|
||||
o->direction = direction;
|
||||
o->angle_start = angle_start;
|
||||
o->angle_end = angle_end;
|
||||
o->intensity = intensity;
|
||||
o->decay_const = decay_const;
|
||||
o->decay_linear = decay_linear;
|
||||
o->decay_quadratic = decay_quadratic;
|
||||
o->meta = meta;
|
||||
o->meta = meta;
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -486,8 +491,7 @@ void Light::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
if (light_type != Omni) {
|
||||
glBegin(GL_LINES);
|
||||
QVector4D dir = QVector4D(direction);
|
||||
if (raw_matrix)
|
||||
dir = transform().inverted() * dir;
|
||||
if (raw_matrix) dir = transform().inverted() * dir;
|
||||
glVertex3f(0., 0., 0.);
|
||||
glVertex3f(dir.x() * s, dir.y() * s, dir.z() * s);
|
||||
glEnd();
|
||||
@@ -496,102 +500,174 @@ void Light::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
}
|
||||
|
||||
|
||||
QDataStream & operator <<(QDataStream & s, const GLObjectBase * p) {
|
||||
QDataStream & operator<<(QDataStream & s, const GLObjectBase * p) {
|
||||
ChunkStream cs;
|
||||
//qDebug() << "place" << p->name() << "...";
|
||||
// qDebug() << "place" << p->name() << "...";
|
||||
cs << cs.chunk(1, int(p->type_)) << cs.chunk(2, p->accept_light) << cs.chunk(3, p->accept_fog) << cs.chunk(4, p->visible_)
|
||||
<< cs.chunk(5, p->cast_shadow) << cs.chunk(6, p->rec_shadow) << cs.chunk(7, p->raw_matrix) << cs.chunk(8, p->line_width)
|
||||
<< cs.chunk(9, int(p->render_mode)) << cs.chunk(10, p->material_) << cs.chunk(11, p->pos_) << cs.chunk(12, p->angles_)
|
||||
<< cs.chunk(13, p->scale_) << cs.chunk(14, p->mat_) << cs.chunk(15, p->vbo) << cs.chunk(16, p->children_.size())
|
||||
<< cs.chunk(17, p->name_) << cs.chunk(18, p->meta);
|
||||
//qDebug() << "place self done";
|
||||
<< cs.chunk(5, p->cast_shadow) << cs.chunk(6, p->rec_shadow) << cs.chunk(7, p->raw_matrix) << cs.chunk(8, p->line_width)
|
||||
<< cs.chunk(9, int(p->render_mode)) << cs.chunk(10, p->material_) << cs.chunk(11, p->pos_) << cs.chunk(12, p->angles_)
|
||||
<< cs.chunk(13, p->scale_) << cs.chunk(14, p->mat_) << cs.chunk(15, p->vbo) << cs.chunk(16, p->children_.size())
|
||||
<< cs.chunk(17, p->name_) << cs.chunk(18, p->meta);
|
||||
// qDebug() << "place self done";
|
||||
if (p->type_ == GLObjectBase::glLight) {
|
||||
//qDebug() << "place light ...";
|
||||
const Light * l = (const Light*)p;
|
||||
// qDebug() << "place light ...";
|
||||
const Light * l = (const Light *)p;
|
||||
cs << cs.chunk(100, l->direction) << cs.chunk(101, l->angle_start) << cs.chunk(102, l->angle_end) << cs.chunk(103, l->intensity)
|
||||
<< cs.chunk(104, l->decay_const) << cs.chunk(105, l->decay_linear) << cs.chunk(106, l->decay_quadratic)
|
||||
<< cs.chunk(107, l->decay_start) << cs.chunk(108, l->decay_end) << cs.chunk(109, int(l->light_type));
|
||||
<< cs.chunk(104, l->decay_const) << cs.chunk(105, l->decay_linear) << cs.chunk(106, l->decay_quadratic)
|
||||
<< cs.chunk(107, l->decay_start) << cs.chunk(108, l->decay_end) << cs.chunk(109, int(l->light_type));
|
||||
}
|
||||
if (p->type_ == GLObjectBase::glCamera) {
|
||||
//qDebug() << "place camera ...";
|
||||
const Camera * c = (const Camera*)p;
|
||||
// qDebug() << "place camera ...";
|
||||
const Camera * c = (const Camera *)p;
|
||||
cs << cs.chunk(200, c->aim_) << cs.chunk(201, c->fov_) << cs.chunk(202, c->depth_start) << cs.chunk(203, c->depth_end)
|
||||
<< cs.chunk(204, c->angle_limit_lower_xy) << cs.chunk(205, c->angle_limit_upper_xy)
|
||||
<< cs.chunk(206, c->mirror_x) << cs.chunk(207, c->mirror_y);
|
||||
<< cs.chunk(204, c->angle_limit_lower_xy) << cs.chunk(205, c->angle_limit_upper_xy) << cs.chunk(206, c->mirror_x)
|
||||
<< cs.chunk(207, c->mirror_y);
|
||||
}
|
||||
//qDebug() << "place" << p->name() << cs.data().size() << s.device()->size();
|
||||
// qDebug() << "place" << p->name() << cs.data().size() << s.device()->size();
|
||||
s << cs.data();
|
||||
foreach (const GLObjectBase * c, p->children_)
|
||||
foreach(const GLObjectBase * c, p->children_)
|
||||
s << c;
|
||||
return s;
|
||||
}
|
||||
QDataStream & operator >>(QDataStream & s, GLObjectBase *& p) {
|
||||
QDataStream & operator>>(QDataStream & s, GLObjectBase *& p) {
|
||||
ChunkStream cs(s);
|
||||
p = nullptr;
|
||||
int ccnt = 0;
|
||||
Light * l = nullptr;
|
||||
p = nullptr;
|
||||
int ccnt = 0;
|
||||
Light * l = nullptr;
|
||||
Camera * c = nullptr;
|
||||
QVector3D cam_angles;
|
||||
//qDebug() << "read obj ...";
|
||||
// qDebug() << "read obj ...";
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1:
|
||||
{
|
||||
case 1: {
|
||||
GLObjectBase::Type type = (GLObjectBase::Type)cs.getData<int>();
|
||||
switch (type) {
|
||||
case GLObjectBase::glMesh: p = new GLObjectBase(); break;
|
||||
case GLObjectBase::glLight: p = new Light(); l = (Light*)p; break;
|
||||
case GLObjectBase::glCamera: p = new Camera(); c = (Camera*)p; break;
|
||||
default : break;
|
||||
case GLObjectBase::glLight:
|
||||
p = new Light();
|
||||
l = (Light *)p;
|
||||
break;
|
||||
case GLObjectBase::glCamera:
|
||||
p = new Camera();
|
||||
c = (Camera *)p;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (p) p->type_ = type;
|
||||
}
|
||||
} break;
|
||||
case 2:
|
||||
if (p) p->accept_light = cs.getData<bool>();
|
||||
break;
|
||||
case 3:
|
||||
if (p) p->accept_fog = cs.getData<bool>();
|
||||
break;
|
||||
case 4:
|
||||
if (p) p->visible_ = cs.getData<bool>();
|
||||
break;
|
||||
case 5:
|
||||
if (p) p->cast_shadow = cs.getData<bool>();
|
||||
break;
|
||||
case 6:
|
||||
if (p) p->rec_shadow = cs.getData<bool>();
|
||||
break;
|
||||
case 7:
|
||||
if (p) p->raw_matrix = cs.getData<bool>();
|
||||
break;
|
||||
case 8:
|
||||
if (p) p->line_width = cs.getData<float>();
|
||||
break;
|
||||
case 9:
|
||||
if (p) p->render_mode = (GLObjectBase::RenderMode)cs.getData<int>();
|
||||
break;
|
||||
case 10:
|
||||
if (p) p->material_ = cs.getData<Material>();
|
||||
break;
|
||||
case 11:
|
||||
if (p) p->pos_ = cs.getData<QVector3D>();
|
||||
break;
|
||||
case 2: if (p) p->accept_light = cs.getData<bool>(); break;
|
||||
case 3: if (p) p->accept_fog = cs.getData<bool>(); break;
|
||||
case 4: if (p) p->visible_ = cs.getData<bool>(); break;
|
||||
case 5: if (p) p->cast_shadow = cs.getData<bool>(); break;
|
||||
case 6: if (p) p->rec_shadow = cs.getData<bool>(); break;
|
||||
case 7: if (p) p->raw_matrix = cs.getData<bool>(); break;
|
||||
case 8: if (p) p->line_width = cs.getData<float>(); break;
|
||||
case 9: if (p) p->render_mode = (GLObjectBase::RenderMode)cs.getData<int>(); break;
|
||||
case 10: if (p) p->material_ = cs.getData<Material>(); break;
|
||||
case 11: if (p) p->pos_ = cs.getData<QVector3D>(); break;
|
||||
case 12:
|
||||
if (p) p->angles_ = cs.getData<QVector3D>();
|
||||
if (c) {
|
||||
c->setAngles(cs.getData<QVector3D>());
|
||||
cam_angles = c->angles();
|
||||
}
|
||||
break;
|
||||
case 13: if (p) p->scale_ = cs.getData<QVector3D>(); break;
|
||||
case 14: if (p) p->mat_ = cs.getData<QMatrix4x4>(); break;
|
||||
case 15: if (p) p->vbo = cs.getData<GLVBO>(); break;
|
||||
case 16: if (p) ccnt = cs.getData<int>(); break;
|
||||
case 17: if (p) p->name_ = cs.getData<QString>(); break;
|
||||
case 18: if (p) p->meta = cs.getData<QVariantMap>(); break;
|
||||
case 100: if (l) l->direction = cs.getData<QVector3D>(); break;
|
||||
case 101: if (l) l->angle_start = cs.getData<GLfloat>(); break;
|
||||
case 102: if (l) l->angle_end = cs.getData<GLfloat>(); break;
|
||||
case 103: if (l) l->intensity = cs.getData<GLfloat>(); break;
|
||||
case 104: if (l) l->decay_const = cs.getData<GLfloat>(); break;
|
||||
case 105: if (l) l->decay_linear = cs.getData<GLfloat>(); break;
|
||||
case 106: if (l) l->decay_quadratic = cs.getData<GLfloat>(); break;
|
||||
case 107: if (l) l->decay_start = cs.getData<GLfloat>(); break;
|
||||
case 108: if (l) l->decay_end = cs.getData<GLfloat>(); break;
|
||||
case 109: if (l) l->light_type = (Light::Type)cs.getData<int>(); break;
|
||||
case 200: if (c) c->setAim(cs.getData<QVector3D>()); break;
|
||||
case 201: if (c) c->setFOV(cs.getData<GLfloat>()); break;
|
||||
case 202: if (c) c->setDepthStart(cs.getData<GLfloat>()); break;
|
||||
case 203: if (c) c->setDepthEnd(cs.getData<GLfloat>()); break;
|
||||
case 204: if (c) c->setAngleLowerLimitXY(cs.getData<GLfloat>()); break;
|
||||
case 205: if (c) c->setAngleUpperLimitXY(cs.getData<GLfloat>()); break;
|
||||
case 206: if (c) c->mirror_x = cs.getData<bool>(); break;
|
||||
case 207: if (c) c->mirror_y = cs.getData<bool>(); break;
|
||||
break;
|
||||
case 13:
|
||||
if (p) p->scale_ = cs.getData<QVector3D>();
|
||||
break;
|
||||
case 14:
|
||||
if (p) p->mat_ = cs.getData<QMatrix4x4>();
|
||||
break;
|
||||
case 15:
|
||||
if (p) p->vbo = cs.getData<GLVBO>();
|
||||
break;
|
||||
case 16:
|
||||
if (p) ccnt = cs.getData<int>();
|
||||
break;
|
||||
case 17:
|
||||
if (p) p->name_ = cs.getData<QString>();
|
||||
break;
|
||||
case 18:
|
||||
if (p) p->meta = cs.getData<QVariantMap>();
|
||||
break;
|
||||
case 100:
|
||||
if (l) l->direction = cs.getData<QVector3D>();
|
||||
break;
|
||||
case 101:
|
||||
if (l) l->angle_start = cs.getData<GLfloat>();
|
||||
break;
|
||||
case 102:
|
||||
if (l) l->angle_end = cs.getData<GLfloat>();
|
||||
break;
|
||||
case 103:
|
||||
if (l) l->intensity = cs.getData<GLfloat>();
|
||||
break;
|
||||
case 104:
|
||||
if (l) l->decay_const = cs.getData<GLfloat>();
|
||||
break;
|
||||
case 105:
|
||||
if (l) l->decay_linear = cs.getData<GLfloat>();
|
||||
break;
|
||||
case 106:
|
||||
if (l) l->decay_quadratic = cs.getData<GLfloat>();
|
||||
break;
|
||||
case 107:
|
||||
if (l) l->decay_start = cs.getData<GLfloat>();
|
||||
break;
|
||||
case 108:
|
||||
if (l) l->decay_end = cs.getData<GLfloat>();
|
||||
break;
|
||||
case 109:
|
||||
if (l) l->light_type = (Light::Type)cs.getData<int>();
|
||||
break;
|
||||
case 200:
|
||||
if (c) c->setAim(cs.getData<QVector3D>());
|
||||
break;
|
||||
case 201:
|
||||
if (c) c->setFOV(cs.getData<GLfloat>());
|
||||
break;
|
||||
case 202:
|
||||
if (c) c->setDepthStart(cs.getData<GLfloat>());
|
||||
break;
|
||||
case 203:
|
||||
if (c) c->setDepthEnd(cs.getData<GLfloat>());
|
||||
break;
|
||||
case 204:
|
||||
if (c) c->setAngleLowerLimitXY(cs.getData<GLfloat>());
|
||||
break;
|
||||
case 205:
|
||||
if (c) c->setAngleUpperLimitXY(cs.getData<GLfloat>());
|
||||
break;
|
||||
case 206:
|
||||
if (c) c->mirror_x = cs.getData<bool>();
|
||||
break;
|
||||
case 207:
|
||||
if (c) c->mirror_y = cs.getData<bool>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c) c->setAngles(cam_angles);
|
||||
//qDebug() << p->name() << ccnt;
|
||||
// qDebug() << p->name() << ccnt;
|
||||
for (int i = 0; i < ccnt; ++i) {
|
||||
GLObjectBase * c = nullptr;
|
||||
s >> c;
|
||||
|
||||
@@ -19,101 +19,158 @@
|
||||
#ifndef GLOBJECT_H
|
||||
#define GLOBJECT_H
|
||||
|
||||
#include "glvbo.h"
|
||||
#include "glframebuffer.h"
|
||||
#include "glmaterial.h"
|
||||
#include "glvbo.h"
|
||||
|
||||
class Camera;
|
||||
class QGLView;
|
||||
|
||||
class GLObjectBase
|
||||
{
|
||||
class GLObjectBase {
|
||||
friend class QGLView;
|
||||
friend class GLRendererBase;
|
||||
friend QDataStream & operator <<(QDataStream & s, const GLObjectBase * p);
|
||||
friend QDataStream & operator >>(QDataStream & s, GLObjectBase *& p);
|
||||
friend QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
|
||||
friend QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
|
||||
friend GLObjectBase * loadFromQGLFile(const QString & filepath);
|
||||
|
||||
public:
|
||||
enum Type {glMesh, glLight, glCamera, glParticlesSystem};
|
||||
enum Pass {Solid, Transparent, Reflection, User};
|
||||
enum GeomPrimitives {Triangles = GL_TRIANGLES, Quads = GL_QUADS};
|
||||
enum RenderMode {View = 0, Point = GL_POINT, Line = GL_LINE, Fill = GL_FILL};
|
||||
enum Type {
|
||||
glMesh,
|
||||
glLight,
|
||||
glCamera,
|
||||
glParticlesSystem
|
||||
};
|
||||
enum Pass {
|
||||
Solid,
|
||||
Transparent,
|
||||
Reflection,
|
||||
User
|
||||
};
|
||||
enum GeomPrimitives {
|
||||
Triangles = GL_TRIANGLES,
|
||||
Quads = GL_QUADS
|
||||
};
|
||||
enum RenderMode {
|
||||
View = 0,
|
||||
Point = GL_POINT,
|
||||
Line = GL_LINE,
|
||||
Fill = GL_FILL
|
||||
};
|
||||
|
||||
explicit GLObjectBase();
|
||||
virtual ~GLObjectBase();
|
||||
|
||||
virtual GLObjectBase * clone(bool withChildren = true);
|
||||
|
||||
QString name() const {return name_;}
|
||||
void setName(const QString & name) {name_ = name;}
|
||||
//virtual GLuint hList() {return list;}
|
||||
QString name() const { return name_; }
|
||||
void setName(const QString & name) { name_ = name; }
|
||||
// virtual GLuint hList() {return list;}
|
||||
virtual void init();
|
||||
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
|
||||
virtual void update() {}
|
||||
bool isInit() const {return is_init;}
|
||||
bool isTexturesLoaded() const {return is_tex_loaded;}
|
||||
Type type() const {return type_;}
|
||||
bool isInit() const { return is_init; }
|
||||
bool isTexturesLoaded() const { return is_tex_loaded; }
|
||||
Type type() const { return type_; }
|
||||
|
||||
RenderMode renderMode() const {return render_mode;}
|
||||
void setRenderMode(RenderMode mode) {render_mode = mode;}
|
||||
RenderMode renderMode() const { return render_mode; }
|
||||
void setRenderMode(RenderMode mode) { render_mode = mode; }
|
||||
|
||||
float lineWidth() const {return line_width;}
|
||||
void setLineWidth(const float & width) {line_width = width;}
|
||||
float lineWidth() const { return line_width; }
|
||||
void setLineWidth(const float & width) { line_width = width; }
|
||||
|
||||
GLObjectBase * parent() {return parent_;}
|
||||
void setParent(GLObjectBase * o) {parent_ = o;}
|
||||
bool hasParent() const {return parent_ != nullptr;}
|
||||
bool hasChildren() const {return children_.size() != 0;}
|
||||
GLObjectBase * parent() { return parent_; }
|
||||
void setParent(GLObjectBase * o) { parent_ = o; }
|
||||
bool hasParent() const { return parent_ != nullptr; }
|
||||
bool hasChildren() const { return children_.size() != 0; }
|
||||
void setView(QGLView * v);
|
||||
|
||||
void addChild(GLObjectBase * o);
|
||||
void removeChild(GLObjectBase * o);
|
||||
void removeChild(int index);
|
||||
void clearChildren(bool deleteAll = false);
|
||||
int childCount() const {return children_.size();}
|
||||
int childCount() const { return children_.size(); }
|
||||
GLObjectBase * child(int index);
|
||||
GLObjectBase * child(const QString & name);
|
||||
const GLObjectBase * child(int index) const;
|
||||
const GLObjectBase * child(const QString & name) const;
|
||||
QList<GLObjectBase * > children(bool all_ = false);
|
||||
QList<GLObjectBase *> children(bool all_ = false);
|
||||
|
||||
bool isVisible() const {return visible_;}
|
||||
bool isHidden() const {return !visible_;}
|
||||
void setVisible(bool v) {visible_ = v;}
|
||||
void setHidden(bool v) {visible_ = !v;}
|
||||
void show() {visible_ = true;}
|
||||
void hide() {visible_ = false;}
|
||||
bool isVisible() const { return visible_; }
|
||||
bool isHidden() const { return !visible_; }
|
||||
void setVisible(bool v) { visible_ = v; }
|
||||
void setHidden(bool v) { visible_ = !v; }
|
||||
void show() { visible_ = true; }
|
||||
void hide() { visible_ = false; }
|
||||
|
||||
bool isReceiveShadows() const {return rec_shadow;}
|
||||
bool isCastShadows() const {return cast_shadow;}
|
||||
void setReceiveShadows(bool on) {rec_shadow = on;}
|
||||
void setCastShadows(bool on) {cast_shadow = on;}
|
||||
bool isReceiveShadows() const { return rec_shadow; }
|
||||
bool isCastShadows() const { return cast_shadow; }
|
||||
void setReceiveShadows(bool on) { rec_shadow = on; }
|
||||
void setCastShadows(bool on) { cast_shadow = on; }
|
||||
|
||||
void move(const QVector3D & dv) {pos_ += dv; buildTransform();}
|
||||
void moveTo(const QVector3D & dv) {pos_ = dv; buildTransform();}
|
||||
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {move(QVector3D(dx, dy, dz)); buildTransform();}
|
||||
void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {moveTo(QVector3D(dx, dy, dz)); buildTransform();}
|
||||
void moveX(GLfloat o) {pos_.setX(pos_.x() + o); buildTransform();}
|
||||
void moveY(GLfloat o) {pos_.setY(pos_.y() + o); buildTransform();}
|
||||
void moveZ(GLfloat o) {pos_.setZ(pos_.z() + o); buildTransform();}
|
||||
void setPosX(GLfloat o) {pos_.setX(o); buildTransform();}
|
||||
void setPosY(GLfloat o) {pos_.setY(o); buildTransform();}
|
||||
void setPosZ(GLfloat o) {pos_.setZ(o); buildTransform();}
|
||||
void setPos(GLfloat x, GLfloat y, GLfloat z) {pos_ = QVector3D(x, y, z); buildTransform();}
|
||||
void setPos(const QVector3D & p) {pos_ = p; buildTransform();}
|
||||
void resetPos() {pos_ = QVector3D(0., 0., 0.); buildTransform();}
|
||||
void move(const QVector3D & dv) {
|
||||
pos_ += dv;
|
||||
buildTransform();
|
||||
}
|
||||
void moveTo(const QVector3D & dv) {
|
||||
pos_ = dv;
|
||||
buildTransform();
|
||||
}
|
||||
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
|
||||
move(QVector3D(dx, dy, dz));
|
||||
buildTransform();
|
||||
}
|
||||
void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {
|
||||
moveTo(QVector3D(dx, dy, dz));
|
||||
buildTransform();
|
||||
}
|
||||
void moveX(GLfloat o) {
|
||||
pos_.setX(pos_.x() + o);
|
||||
buildTransform();
|
||||
}
|
||||
void moveY(GLfloat o) {
|
||||
pos_.setY(pos_.y() + o);
|
||||
buildTransform();
|
||||
}
|
||||
void moveZ(GLfloat o) {
|
||||
pos_.setZ(pos_.z() + o);
|
||||
buildTransform();
|
||||
}
|
||||
void setPosX(GLfloat o) {
|
||||
pos_.setX(o);
|
||||
buildTransform();
|
||||
}
|
||||
void setPosY(GLfloat o) {
|
||||
pos_.setY(o);
|
||||
buildTransform();
|
||||
}
|
||||
void setPosZ(GLfloat o) {
|
||||
pos_.setZ(o);
|
||||
buildTransform();
|
||||
}
|
||||
void setPos(GLfloat x, GLfloat y, GLfloat z) {
|
||||
pos_ = QVector3D(x, y, z);
|
||||
buildTransform();
|
||||
}
|
||||
void setPos(const QVector3D & p) {
|
||||
pos_ = p;
|
||||
buildTransform();
|
||||
}
|
||||
void resetPos() {
|
||||
pos_ = QVector3D(0., 0., 0.);
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
QVector3D pos() const {return pos_;}
|
||||
float posX() const {return pos_.x();}
|
||||
float posY() const {return pos_.y();}
|
||||
float posZ() const {return pos_.z();}
|
||||
QVector3D worldPos() const {return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D();}
|
||||
QMatrix4x4 worldTransform() const {return itransform_;}
|
||||
QVector3D pos() const { return pos_; }
|
||||
float posX() const { return pos_.x(); }
|
||||
float posY() const { return pos_.y(); }
|
||||
float posZ() const { return pos_.z(); }
|
||||
QVector3D worldPos() const { return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D(); }
|
||||
QMatrix4x4 worldTransform() const { return itransform_; }
|
||||
|
||||
QVector3D rotation() const {return angles_;}
|
||||
float rotationX() const {return angles_.x();}
|
||||
float rotationY() const {return angles_.y();}
|
||||
float rotationZ() const {return angles_.z();}
|
||||
QVector3D rotation() const { return angles_; }
|
||||
float rotationX() const { return angles_.x(); }
|
||||
float rotationY() const { return angles_.y(); }
|
||||
float rotationZ() const { return angles_.z(); }
|
||||
void rotateX(GLfloat a);
|
||||
void rotateY(GLfloat a);
|
||||
void rotateZ(GLfloat a);
|
||||
@@ -123,58 +180,113 @@ public:
|
||||
void setRotation(const QVector3D & a);
|
||||
void resetRotation();
|
||||
|
||||
QVector3D scale() {return scale_;}
|
||||
float scaleX() {return scale_.x();}
|
||||
float scaleY() {return scale_.y();}
|
||||
float scaleZ() {return scale_.z();}
|
||||
void scale(const QVector3D & sv) {raw_matrix = false; scale_ *= sv; buildTransform();}
|
||||
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {raw_matrix = false; scale(QVector3D(sx, sy, sz)); buildTransform();}
|
||||
void scale(GLfloat sx, GLfloat sy) {raw_matrix = false; scale(QVector3D(sx, sy, sy)); buildTransform();}
|
||||
void scale(GLfloat sx) {raw_matrix = false; scale(QVector3D(sx, sx, sx)); buildTransform();}
|
||||
void scaleX(GLfloat a) {raw_matrix = false; scale_.setX(scale_.x() + a); buildTransform();}
|
||||
void scaleY(GLfloat a) {raw_matrix = false; scale_.setY(scale_.y() + a); buildTransform();}
|
||||
void scaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(scale_.z() + a); buildTransform();}
|
||||
void setScale(const QVector3D & a) {raw_matrix = false; scale_ = a; buildTransform();}
|
||||
void setScale(GLfloat a) {raw_matrix = false; scale_ = QVector3D(a, a, a); buildTransform();}
|
||||
void setScaleX(GLfloat a) {raw_matrix = false; scale_.setX(a); buildTransform();}
|
||||
void setScaleY(GLfloat a) {raw_matrix = false; scale_.setY(a); buildTransform();}
|
||||
void setScaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(a); buildTransform();}
|
||||
void resetScale() {raw_matrix = false; scale_ = QVector3D(1., 1., 1.); buildTransform();}
|
||||
|
||||
QMatrix4x4 transform() {return mat_;}
|
||||
QVector3D scale() { return scale_; }
|
||||
float scaleX() { return scale_.x(); }
|
||||
float scaleY() { return scale_.y(); }
|
||||
float scaleZ() { return scale_.z(); }
|
||||
void scale(const QVector3D & sv) {
|
||||
raw_matrix = false;
|
||||
scale_ *= sv;
|
||||
buildTransform();
|
||||
}
|
||||
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {
|
||||
raw_matrix = false;
|
||||
scale(QVector3D(sx, sy, sz));
|
||||
buildTransform();
|
||||
}
|
||||
void scale(GLfloat sx, GLfloat sy) {
|
||||
raw_matrix = false;
|
||||
scale(QVector3D(sx, sy, sy));
|
||||
buildTransform();
|
||||
}
|
||||
void scale(GLfloat sx) {
|
||||
raw_matrix = false;
|
||||
scale(QVector3D(sx, sx, sx));
|
||||
buildTransform();
|
||||
}
|
||||
void scaleX(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
scale_.setX(scale_.x() + a);
|
||||
buildTransform();
|
||||
}
|
||||
void scaleY(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
scale_.setY(scale_.y() + a);
|
||||
buildTransform();
|
||||
}
|
||||
void scaleZ(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
scale_.setZ(scale_.z() + a);
|
||||
buildTransform();
|
||||
}
|
||||
void setScale(const QVector3D & a) {
|
||||
raw_matrix = false;
|
||||
scale_ = a;
|
||||
buildTransform();
|
||||
}
|
||||
void setScale(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
scale_ = QVector3D(a, a, a);
|
||||
buildTransform();
|
||||
}
|
||||
void setScaleX(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
scale_.setX(a);
|
||||
buildTransform();
|
||||
}
|
||||
void setScaleY(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
scale_.setY(a);
|
||||
buildTransform();
|
||||
}
|
||||
void setScaleZ(GLfloat a) {
|
||||
raw_matrix = false;
|
||||
scale_.setZ(a);
|
||||
buildTransform();
|
||||
}
|
||||
void resetScale() {
|
||||
raw_matrix = false;
|
||||
scale_ = QVector3D(1., 1., 1.);
|
||||
buildTransform();
|
||||
}
|
||||
|
||||
QMatrix4x4 transform() { return mat_; }
|
||||
void setTransform(const QMatrix4x4 & t);
|
||||
bool isRawMatrix() {return raw_matrix;}
|
||||
bool isRawMatrix() { return raw_matrix; }
|
||||
|
||||
bool isAcceptLight() const {return accept_light;}
|
||||
void setAcceptLight(bool yes) {accept_light = yes;}
|
||||
bool isAcceptLight() const { return accept_light; }
|
||||
void setAcceptLight(bool yes) { accept_light = yes; }
|
||||
|
||||
bool isAcceptFog() const {return accept_fog;}
|
||||
void setAcceptFog(bool yes) {accept_fog = yes;}
|
||||
bool isAcceptFog() const { return accept_fog; }
|
||||
void setAcceptFog(bool yes) { accept_fog = yes; }
|
||||
|
||||
bool isSelected() const {return selected_;}
|
||||
void setSelected(bool yes) {selected_ = yes;}
|
||||
bool isSelected() const { return selected_; }
|
||||
void setSelected(bool yes) { selected_ = yes; }
|
||||
void select();
|
||||
void deselect() {selected_ = false;}
|
||||
void deselect() { selected_ = false; }
|
||||
|
||||
bool isSelectable() const {return select_;}
|
||||
void setSelectable(bool yes) {select_ = yes;}
|
||||
bool isSelectable() const { return select_; }
|
||||
void setSelectable(bool yes) { select_ = yes; }
|
||||
/*
|
||||
bool isWriteDepth() const {return write_depth_;}
|
||||
void setWriteDepth(bool yes) {write_depth_ = yes;}*/
|
||||
|
||||
QColor color() const {return material_.color_diffuse;}
|
||||
void setColor(const QColor & c) {material_.color_diffuse = c; checkPass();}
|
||||
QColor color() const { return material_.color_diffuse; }
|
||||
void setColor(const QColor & c) {
|
||||
material_.color_diffuse = c;
|
||||
checkPass();
|
||||
}
|
||||
|
||||
GLenum srcAlpha() const {return blend_src;}
|
||||
GLenum destAlpha() const {return blend_dest;}
|
||||
void setSrcAlpha(GLenum mode) {blend_src = mode;}
|
||||
void setDestAlpha(GLenum mode) {blend_dest = mode;}
|
||||
GLenum srcAlpha() const { return blend_src; }
|
||||
GLenum destAlpha() const { return blend_dest; }
|
||||
void setSrcAlpha(GLenum mode) { blend_src = mode; }
|
||||
void setDestAlpha(GLenum mode) { blend_dest = mode; }
|
||||
|
||||
void setMaterial(const Material & m, bool with_children = false);
|
||||
Material & material() {return material_;}
|
||||
Material & material() { return material_; }
|
||||
|
||||
const Box3D & boundingBox(bool withChildren = true) const {return bound;}
|
||||
GLVBO & VBO() {return vbo;}
|
||||
const Box3D & boundingBox(bool withChildren = true) const { return bound; }
|
||||
GLVBO & VBO() { return vbo; }
|
||||
|
||||
void calculateBoundingBox();
|
||||
|
||||
@@ -188,21 +300,22 @@ public:
|
||||
QVector<Vector3i> faces, uvws, norms;
|
||||
QVector<Vector3d> normals;
|
||||
|
||||
//QVector<GLfloat> d_vertices, d_normals, d_uvs;
|
||||
// QVector<GLfloat> d_vertices, d_normals, d_uvs;
|
||||
|
||||
protected:
|
||||
void addChildren(QList<GLObjectBase * > & list, GLObjectBase * where);
|
||||
void addChildren(QList<GLObjectBase *> & list, GLObjectBase * where);
|
||||
void loadTextures(bool with_children = false);
|
||||
//void deleteTextures() {foreach (GLuint i, textures) currentQGLView->deleteTexture(i); textures.clear();}
|
||||
// void deleteTextures() {foreach (GLuint i, textures) currentQGLView->deleteTexture(i); textures.clear();}
|
||||
void buildTransform();
|
||||
void initInternal();
|
||||
void render(int * id = nullptr, QMap<int, GLObjectBase * > * ids = nullptr, int sh_id_loc = 0);
|
||||
void render(int * id = nullptr, QMap<int, GLObjectBase *> * ids = nullptr, int sh_id_loc = 0);
|
||||
void checkPass();
|
||||
virtual void localTransform(QMatrix4x4 & m);
|
||||
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
|
||||
|
||||
int pass_; // Pass
|
||||
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix;
|
||||
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_,
|
||||
raw_matrix;
|
||||
bool is_root;
|
||||
float line_width;
|
||||
Type type_;
|
||||
@@ -211,31 +324,40 @@ protected:
|
||||
Material material_;
|
||||
Box3D bound;
|
||||
QVector3D pos_, angles_, scale_;
|
||||
QList<GLObjectBase * > children_;
|
||||
QList<GLObjectBase *> children_;
|
||||
QList<GLuint> textures;
|
||||
QMatrix4x4 itransform_, mat_;
|
||||
//QColor color_;
|
||||
// QColor color_;
|
||||
QString name_;
|
||||
GLenum blend_src, blend_dest;
|
||||
GLObjectBase * parent_;
|
||||
QGLViewBase * view_;
|
||||
GLVBO vbo;
|
||||
QVariantMap meta;
|
||||
|
||||
};
|
||||
|
||||
inline bool operator <(const GLObjectBase & f, const GLObjectBase & s) {return f.pos_h.z() < s.pos_h.z();}
|
||||
inline bool operator<(const GLObjectBase & f, const GLObjectBase & s) {
|
||||
return f.pos_h.z() < s.pos_h.z();
|
||||
}
|
||||
|
||||
class Light: public GLObjectBase {
|
||||
friend class QGLView;
|
||||
friend class GLRendererBase;
|
||||
|
||||
public:
|
||||
enum Type {Omni, Directional, Cone};
|
||||
enum Type {
|
||||
Omni,
|
||||
Directional,
|
||||
Cone
|
||||
};
|
||||
|
||||
Light();
|
||||
Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.);
|
||||
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(QOpenGLShaderProgram * prog, bool simplest = false);
|
||||
|
||||
QVector3D direction, dir0, dir1;
|
||||
@@ -252,17 +374,20 @@ public:
|
||||
QMatrix4x4 shadow_matrix;
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T globject_cast(GLObjectBase * object) {return reinterpret_cast<T>(object);}
|
||||
template<class T>
|
||||
inline T globject_cast(GLObjectBase * object) {
|
||||
return reinterpret_cast<T>(object);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T globject_cast(const GLObjectBase * object) {return reinterpret_cast<T>(object);}
|
||||
template<class T>
|
||||
inline T globject_cast(const GLObjectBase * object) {
|
||||
return reinterpret_cast<T>(object);
|
||||
}
|
||||
|
||||
|
||||
QDataStream & operator <<(QDataStream & s, const GLObjectBase * p);
|
||||
QDataStream & operator >>(QDataStream & s, GLObjectBase *& p);
|
||||
QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
|
||||
QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
|
||||
|
||||
#endif // GLOBJECT_H
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
*/
|
||||
|
||||
#include "globject_editor.h"
|
||||
#include "ui_globject_editor.h"
|
||||
|
||||
#include "glcamera.h"
|
||||
#include "ui_globject_editor.h"
|
||||
|
||||
|
||||
GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) {
|
||||
@@ -37,11 +38,8 @@ GLObjectEditor::GLObjectEditor(QWidget * parent): QWidget(parent) {
|
||||
void GLObjectEditor::changeEvent(QEvent * e) {
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QEvent::LanguageChange: ui->retranslateUi(this); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +74,8 @@ void GLObjectEditor::setObject(GLObjectBase * o) {
|
||||
ui->groupLight->setEnabled(object->type() == GLObjectBase::glLight);
|
||||
ui->groupLight->setVisible(object->type() == GLObjectBase::glLight);
|
||||
if (object->type() == GLObjectBase::glLight) {
|
||||
Light * l = globject_cast<Light * >(object);
|
||||
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
|
||||
Light * l = globject_cast<Light *>(object);
|
||||
// bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
|
||||
ui->buttonLightColor->setColor(l->color());
|
||||
ui->comboLightType->setCurrentIndex(l->light_type);
|
||||
ui->spinLightIntensity->setValue(l->intensity);
|
||||
@@ -93,7 +91,7 @@ void GLObjectEditor::setObject(GLObjectBase * o) {
|
||||
ui->groupCamera->setEnabled(object->type() == GLObjectBase::glCamera);
|
||||
ui->groupCamera->setVisible(object->type() == GLObjectBase::glCamera);
|
||||
if (object->type() == GLObjectBase::glCamera) {
|
||||
Camera * c = globject_cast<Camera * >(object);
|
||||
Camera * c = globject_cast<Camera *>(object);
|
||||
ui->checkCameraMirrorX->setChecked(c->isMirrorX());
|
||||
ui->checkCameraMirrorY->setChecked(c->isMirrorY());
|
||||
ui->spinCameraFOV->setValue(c->FOV());
|
||||
@@ -125,20 +123,21 @@ void GLObjectEditor::objectChanged() {
|
||||
object->setReceiveShadows(ui->checkReceiveShadows->isChecked());
|
||||
object->setRenderMode((GLObjectBase::RenderMode)rmodes[ui->comboRenderMode->currentIndex()]);
|
||||
if (object->type() == GLObjectBase::glLight) {
|
||||
Light * l = globject_cast<Light * >(object);
|
||||
//bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
|
||||
Light * l = globject_cast<Light *>(object);
|
||||
// bool is_dir = l->light_type == Light::Directional, is_cone = l->light_type == Light::Cone;
|
||||
l->setColor(ui->buttonLightColor->color());
|
||||
l->light_type = (Light::Type)ui->comboLightType->currentIndex();
|
||||
l->intensity = ui->spinLightIntensity->value();
|
||||
l->decay_const = ui->spinLightDecayConst->value();
|
||||
l->decay_linear = ui->spinLightDecayLinear->value();
|
||||
l->light_type = (Light::Type)ui->comboLightType->currentIndex();
|
||||
l->intensity = ui->spinLightIntensity->value();
|
||||
l->decay_const = ui->spinLightDecayConst->value();
|
||||
l->decay_linear = ui->spinLightDecayLinear->value();
|
||||
l->decay_quadratic = ui->spinLightDecayQuadratic->value();
|
||||
l->angle_start = ui->spinLightAngleStart->value();
|
||||
l->angle_end = ui->spinLightAngleEnd->value();
|
||||
l->direction = QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized();
|
||||
l->angle_start = ui->spinLightAngleStart->value();
|
||||
l->angle_end = ui->spinLightAngleEnd->value();
|
||||
l->direction =
|
||||
QVector3D(ui->spinLightDirectionX->value(), ui->spinLightDirectionY->value(), ui->spinLightDirectionZ->value()).normalized();
|
||||
}
|
||||
if (object->type() == GLObjectBase::glCamera) {
|
||||
Camera * c = globject_cast<Camera * >(object);
|
||||
Camera * c = globject_cast<Camera *>(object);
|
||||
c->setMirrorX(ui->checkCameraMirrorX->isChecked());
|
||||
c->setMirrorY(ui->checkCameraMirrorY->isChecked());
|
||||
c->setFOV(ui->spinCameraFOV->value());
|
||||
@@ -150,14 +149,12 @@ void GLObjectEditor::objectChanged() {
|
||||
|
||||
|
||||
void GLObjectEditor::on_spinLightAngleStart_valueChanged(double v) {
|
||||
if (ui->spinLightAngleEnd->value() < v)
|
||||
ui->spinLightAngleEnd->setValue(v);
|
||||
if (ui->spinLightAngleEnd->value() < v) ui->spinLightAngleEnd->setValue(v);
|
||||
}
|
||||
|
||||
|
||||
void GLObjectEditor::on_spinLightAngleEnd_valueChanged(double v) {
|
||||
if (ui->spinLightAngleStart->value() > v)
|
||||
ui->spinLightAngleStart->setValue(v);
|
||||
if (ui->spinLightAngleStart->value() > v) ui->spinLightAngleStart->setValue(v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
#include "globject.h"
|
||||
|
||||
namespace Ui {
|
||||
class GLObjectEditor;
|
||||
class GLObjectEditor;
|
||||
};
|
||||
|
||||
class GLObjectEditor: public QWidget
|
||||
{
|
||||
class GLObjectEditor: public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GLObjectEditor(QWidget * parent = 0);
|
||||
|
||||
void setObject(GLObjectBase * o);
|
||||
GLObjectBase * getObject() {return object;}
|
||||
GLObjectBase * getObject() { return object; }
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent * e);
|
||||
@@ -50,7 +50,6 @@ private slots:
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
};
|
||||
|
||||
#endif // GLOBJECT_EDITOR_H
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
|
||||
|
||||
GLParticlesSystem::GLParticlesSystem(const QVector3D & pos): GLObjectBase() {
|
||||
pass_ = GLObjectBase::Transparent;
|
||||
freq = 40.f;
|
||||
birthRate_ = 10.f;
|
||||
lifeDuration_ = 2.f;
|
||||
fade_time = 0.5f;
|
||||
size_ = 1.f;
|
||||
pass_ = GLObjectBase::Transparent;
|
||||
freq = 40.f;
|
||||
birthRate_ = 10.f;
|
||||
lifeDuration_ = 2.f;
|
||||
fade_time = 0.5f;
|
||||
size_ = 1.f;
|
||||
additionalSpeed = 0.f;
|
||||
initialSpeed_ = 1.f;
|
||||
need_birth = -1.f;
|
||||
initialSpeed_ = 1.f;
|
||||
need_birth = -1.f;
|
||||
tex_rect.setRect(0., 0., 1., 1.);
|
||||
tex_scale = QSizeF();
|
||||
tex_scale = QSizeF();
|
||||
emitterPosition_ = pos;
|
||||
emitterDirection_.setZ(1.);
|
||||
speedDirection_.setZ(1.);
|
||||
@@ -38,64 +38,65 @@ GLParticlesSystem::GLParticlesSystem(const QVector3D & pos): GLObjectBase() {
|
||||
lifeDurationJitter_ = speedJitter_ = speedDirectionJitter_ = sizeJitter_ = angleJitter_ = 0.f;
|
||||
active_ = birthEnabled_ = true;
|
||||
is_diffuse_anim = add_vert_face = false;
|
||||
emitterType_ = Cone;
|
||||
tick_life = 1.f / freq;
|
||||
tick_birth = birthRate_ / freq;
|
||||
emitterType_ = Cone;
|
||||
tick_life = 1.f / freq;
|
||||
tick_birth = birthRate_ / freq;
|
||||
}
|
||||
|
||||
|
||||
void GLParticlesSystem::update() {
|
||||
//qDebug() << "update" << need_birth << tick_birth;
|
||||
// qDebug() << "update" << need_birth << tick_birth;
|
||||
if (!active_) return;
|
||||
//QMutexLocker locker(&mutex);
|
||||
// QMutexLocker locker(&mutex);
|
||||
Particle cp(lifeDuration_);
|
||||
if (birthEnabled_) need_birth += tick_birth;
|
||||
qDebug() << "update" << particles.size();
|
||||
if (need_birth >= 1.f) {
|
||||
cp.pos = emitterPosition_;
|
||||
//qDebug() << "speed" << cp.speed;
|
||||
cp.pos = emitterPosition_;
|
||||
// qDebug() << "speed" << cp.speed;
|
||||
cp.speedDecay = 1.f + speedDecay_;
|
||||
for (int i = 0; i < floor(need_birth); ++i) {
|
||||
cp.lifeDuration = lifeDuration_ + urand(lifeDurationJitter_);
|
||||
switch (emitterType_) {
|
||||
case Omni:
|
||||
cp.speed = QVector3D(urand(), urand(), urand()).normalized() * initialSpeed_ * (1.f + urand(speedJitter_));
|
||||
break;
|
||||
case Cone: case Box:
|
||||
case Omni: cp.speed = QVector3D(urand(), urand(), urand()).normalized() * initialSpeed_ * (1.f + urand(speedJitter_)); break;
|
||||
case Cone:
|
||||
case Box:
|
||||
cp.speed = emitterDirection_ * initialSpeed_ * (1.f + urand(speedJitter_));
|
||||
cp.speed += orthToVector(cp.speed, speedDirectionJitter_);
|
||||
break;
|
||||
}
|
||||
if (emitterType_ == Box)
|
||||
cp.pos = emitterRect_.randomPoint();
|
||||
//qDebug() << "before" << cp.speed.length();
|
||||
if (emitterType_ == Box) cp.pos = emitterRect_.randomPoint();
|
||||
// qDebug() << "before" << cp.speed.length();
|
||||
lengthenVector(cp.speed, additionalSpeed);
|
||||
//qDebug() << "after" << cp.speed.length();
|
||||
cp.size = size_ + urand(sizeJitter_);
|
||||
cp.angle = initialAngle_ + urand(angleJitter_);
|
||||
// qDebug() << "after" << cp.speed.length();
|
||||
cp.size = size_ + urand(sizeJitter_);
|
||||
cp.angle = initialAngle_ + urand(angleJitter_);
|
||||
cp.enlargeSpeed = (enlargeSpeed_ + urand(enlargeSpeedJitter_)) * tick_life;
|
||||
/*if (is_diffuse_anim) {
|
||||
if (material_.diffuse.animation_frame_rate < 0 && animation->bitmaps.size() > 0)
|
||||
cp.animationFrameRate = animation->bitmaps.size() / cp.lifeDuration;
|
||||
else
|
||||
cp.animationFrameRate = material_.diffuse.animation_frame_rate;
|
||||
if (material_.diffuse.animation_frame_rate < 0 && animation->bitmaps.size() > 0)
|
||||
cp.animationFrameRate = animation->bitmaps.size() / cp.lifeDuration;
|
||||
else
|
||||
cp.animationFrameRate = material_.diffuse.animation_frame_rate;
|
||||
}*/
|
||||
if (tex_scale.isEmpty()) cp.tex_rect.setSize(tex_rect.size());
|
||||
else cp.tex_rect.setSize(tex_rect.size() * tex_scale);
|
||||
cp.tex_rect.moveTopLeft(tex_rect.topLeft() + QPointF(uprand(tex_rect.width() - cp.tex_rect.width()), uprand(tex_rect.height() - cp.tex_rect.height())));
|
||||
//cp.tex_rect = tex_rect;
|
||||
if (tex_scale.isEmpty())
|
||||
cp.tex_rect.setSize(tex_rect.size());
|
||||
else
|
||||
cp.tex_rect.setSize(tex_rect.size() * tex_scale);
|
||||
cp.tex_rect.moveTopLeft(tex_rect.topLeft() + QPointF(uprand(tex_rect.width() - cp.tex_rect.width()),
|
||||
uprand(tex_rect.height() - cp.tex_rect.height())));
|
||||
// cp.tex_rect = tex_rect;
|
||||
particles.push_back(cp);
|
||||
}
|
||||
need_birth -= floor(need_birth);
|
||||
}
|
||||
for (int i = 0; i < particles.size(); ++i) {
|
||||
Particle & c(particles[i]);
|
||||
foreach (const QVector3D & f, forces)
|
||||
foreach(const QVector3D & f, forces)
|
||||
c.speed += f;
|
||||
c.lifeCurrent += tick_life;
|
||||
//qDebug() << "life" << c.lifeCurrent << c.lifeDuration;
|
||||
// qDebug() << "life" << c.lifeCurrent << c.lifeDuration;
|
||||
if (c.lifeCurrent > c.lifeDuration) {
|
||||
//qDebug() << "remove" << i;
|
||||
// qDebug() << "remove" << i;
|
||||
particles.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
@@ -103,7 +104,7 @@ void GLParticlesSystem::update() {
|
||||
c.pos += c.speed * tick_life;
|
||||
c.speed /= c.speedDecay;
|
||||
c.size += c.enlargeSpeed;
|
||||
//if (c.lifeCurrent > 1.) c.angle += urand(5.);
|
||||
// if (c.lifeCurrent > 1.) c.angle += urand(5.);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,31 +115,30 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
|
||||
pass_ = GLObjectBase::Transparent;
|
||||
Camera * camera(view_->camera());
|
||||
QVector3D apos = camera->pos(), dir = camera->direction();
|
||||
//qDebug() << dir;
|
||||
//qDebug() << camera.angles();
|
||||
//qDebug() << camera.angle_xy;
|
||||
// qDebug() << dir;
|
||||
// qDebug() << camera.angles();
|
||||
// qDebug() << camera.angle_xy;
|
||||
GLfloat cxyc, czs, czc;
|
||||
GLfloat dx, dy, cdx, cdy, cdz, a, tr_r = material_.color_diffuse.redF(),
|
||||
tr_g = material_.color_diffuse.greenF(),
|
||||
GLfloat dx, dy, cdx, cdy, cdz, a, tr_r = material_.color_diffuse.redF(), tr_g = material_.color_diffuse.greenF(),
|
||||
tr_b = material_.color_diffuse.blueF(),
|
||||
tr_a = material_.color_diffuse.alphaF() * (1.f - material_.transparency);
|
||||
//cxys = sin(camera.angle_xy * deg2rad);
|
||||
cxyc = cosf(camera->angles_.y() * deg2rad);
|
||||
czs = sinf(camera->angles_.z() * deg2rad);
|
||||
czc = cosf(camera->angles_.z() * deg2rad);
|
||||
// cxys = sin(camera.angle_xy * deg2rad);
|
||||
cxyc = cosf(camera->angles_.y() * deg2rad);
|
||||
czs = sinf(camera->angles_.z() * deg2rad);
|
||||
czc = cosf(camera->angles_.z() * deg2rad);
|
||||
|
||||
dx = -czc;
|
||||
dy = czs;
|
||||
dx = -czc;
|
||||
dy = czs;
|
||||
vertices.clear();
|
||||
texcoords.clear();
|
||||
colors.clear();
|
||||
for (int i = 0; i < particles.size(); ++i)
|
||||
//particles[i].pos_h.setZ((particles[i].pos - apos).lengthSquared());
|
||||
// particles[i].pos_h.setZ((particles[i].pos - apos).lengthSquared());
|
||||
particles[i].pos_h.setZ(particles[i].pos.distanceToPlane(apos, dir));
|
||||
std::sort(particles.begin(), particles.end());
|
||||
glBegin(GL_POINTS);
|
||||
foreach (const Particle & i, particles) {
|
||||
//glVertex3f(i.pos.x(), i.pos.y(), i.pos.z());
|
||||
foreach(const Particle & i, particles) {
|
||||
// glVertex3f(i.pos.x(), i.pos.y(), i.pos.z());
|
||||
a = (i.lifeDuration - i.lifeCurrent) / fade_time;
|
||||
if (a > 1.f) a = 1.f;
|
||||
a *= tr_a;
|
||||
@@ -182,12 +182,12 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
//bool cae = glIsEnabled(GL_COLOR_ARRAY), nae = glIsEnabled(GL_NORMAL_ARRAY);
|
||||
// bool cae = glIsEnabled(GL_COLOR_ARRAY), nae = glIsEnabled(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
//glNormal3f(vn.x(), vn.y(), vn.z());
|
||||
// glNormal3f(vn.x(), vn.y(), vn.z());
|
||||
glNormal3f(0., 0., 1.);
|
||||
glDepthMask(false);
|
||||
glEnable(GL_COLOR_ARRAY);
|
||||
@@ -195,21 +195,20 @@ void GLParticlesSystem::draw(QOpenGLShaderProgram * prog, bool) {
|
||||
glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, texcoords.constData());
|
||||
glColorPointer(4, GL_FLOAT, 0, colors.constData());
|
||||
//glEnable(GL_ALPHA_TEST);
|
||||
//glAlphaFunc();
|
||||
// glEnable(GL_ALPHA_TEST);
|
||||
// glAlphaFunc();
|
||||
glDrawArrays(GL_QUADS, 0, vertices.size() / 3);
|
||||
glDepthMask(true);
|
||||
//glDisable(GL_ALPHA_TEST);
|
||||
//if (!cae) glDisable(GL_COLOR_ARRAY);
|
||||
//if (nae) glEnable(GL_NORMAL_ARRAY);
|
||||
// glDisable(GL_ALPHA_TEST);
|
||||
// if (!cae) glDisable(GL_COLOR_ARRAY);
|
||||
// if (nae) glEnable(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLParticlesSystem::Particle::Particle(float life_dur) {
|
||||
size = 1.;
|
||||
size = 1.;
|
||||
angle = lifeCurrent = 0.;
|
||||
speedDecay = 0.;
|
||||
lifeDuration = life_dur;
|
||||
tex_rect = QRectF(0, 0, 1, 1);
|
||||
speedDecay = 0.;
|
||||
lifeDuration = life_dur;
|
||||
tex_rect = QRectF(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
@@ -19,13 +19,16 @@
|
||||
#ifndef GLPARTICLES_SYSTEM_H
|
||||
#define GLPARTICLES_SYSTEM_H
|
||||
|
||||
#include <QMutex>
|
||||
#include "gltexture_manager.h"
|
||||
#include "globject.h"
|
||||
#include "glcamera.h"
|
||||
#include "globject.h"
|
||||
#include "gltexture_manager.h"
|
||||
|
||||
class GLParticlesSystem: public QObject, public GLObjectBase, protected QOpenGLFunctions
|
||||
{
|
||||
#include <QMutex>
|
||||
|
||||
class GLParticlesSystem
|
||||
: public QObject
|
||||
, public GLObjectBase
|
||||
, protected QOpenGLFunctions {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float birthRate READ birthRate WRITE setBirthRate)
|
||||
Q_PROPERTY(float lifeDuration READ lifeDuration WRITE setLifeDuration)
|
||||
@@ -47,11 +50,16 @@ class GLParticlesSystem: public QObject, public GLObjectBase, protected QOpenGLF
|
||||
Q_PROPERTY(bool active READ isActive WRITE setActive)
|
||||
Q_PROPERTY(bool birthEnabled READ isBirthEnabled WRITE setBirthEnabled)
|
||||
Q_PROPERTY(float fadeTime READ fadeTime WRITE setFadeTime)
|
||||
|
||||
public:
|
||||
GLParticlesSystem(const QVector3D & pos = QVector3D());
|
||||
~GLParticlesSystem() {;}
|
||||
~GLParticlesSystem() { ; }
|
||||
|
||||
enum Type {Cone, Omni, Box};
|
||||
enum Type {
|
||||
Cone,
|
||||
Omni,
|
||||
Box
|
||||
};
|
||||
|
||||
struct Particle {
|
||||
Particle(float life_dur = 40.);
|
||||
@@ -71,62 +79,65 @@ public:
|
||||
void update();
|
||||
void draw(QOpenGLShaderProgram * prog, bool);
|
||||
|
||||
float birthRate() const {return birthRate_;}
|
||||
float lifeDuration() const {return lifeDuration_;}
|
||||
float size() const {return size_;}
|
||||
float enlargeSpeed() const {return enlargeSpeed_;}
|
||||
float initialAngle() const {return initialAngle_;}
|
||||
float initialSpeed() const {return initialSpeed_;}
|
||||
float speedDecay() const {return speedDecay_;}
|
||||
float baseAngle() const {return baseAngle_;}
|
||||
QVector3D speedDirection() const {return speedDirection_;}
|
||||
QVector3D emitterPosition() const {return emitterPosition_;}
|
||||
QVector3D emitterDirection() const {return emitterDirection_;}
|
||||
Box3D emitterRect() const {return emitterRect_;}
|
||||
float lifeDurationJitter() const {return lifeDurationJitter_;}
|
||||
float speedJitter() const {return speedJitter_;}
|
||||
float speedDirectionJitter() const {return speedDirectionJitter_;}
|
||||
float sizeJitter() const {return sizeJitter_;}
|
||||
float enlargeSpeedJitter() const {return enlargeSpeedJitter_;}
|
||||
float angleJitter() const {return angleJitter_;}
|
||||
bool isActive() const {return active_;}
|
||||
bool isBirthEnabled() const {return birthEnabled_;}
|
||||
GLParticlesSystem::Type emitterType() const {return emitterType_;}
|
||||
float fadeTime() const {return fade_time;}
|
||||
bool isAddVerticalFaceEnabled() const {return add_vert_face;}
|
||||
float birthRate() const { return birthRate_; }
|
||||
float lifeDuration() const { return lifeDuration_; }
|
||||
float size() const { return size_; }
|
||||
float enlargeSpeed() const { return enlargeSpeed_; }
|
||||
float initialAngle() const { return initialAngle_; }
|
||||
float initialSpeed() const { return initialSpeed_; }
|
||||
float speedDecay() const { return speedDecay_; }
|
||||
float baseAngle() const { return baseAngle_; }
|
||||
QVector3D speedDirection() const { return speedDirection_; }
|
||||
QVector3D emitterPosition() const { return emitterPosition_; }
|
||||
QVector3D emitterDirection() const { return emitterDirection_; }
|
||||
Box3D emitterRect() const { return emitterRect_; }
|
||||
float lifeDurationJitter() const { return lifeDurationJitter_; }
|
||||
float speedJitter() const { return speedJitter_; }
|
||||
float speedDirectionJitter() const { return speedDirectionJitter_; }
|
||||
float sizeJitter() const { return sizeJitter_; }
|
||||
float enlargeSpeedJitter() const { return enlargeSpeedJitter_; }
|
||||
float angleJitter() const { return angleJitter_; }
|
||||
bool isActive() const { return active_; }
|
||||
bool isBirthEnabled() const { return birthEnabled_; }
|
||||
GLParticlesSystem::Type emitterType() const { return emitterType_; }
|
||||
float fadeTime() const { return fade_time; }
|
||||
bool isAddVerticalFaceEnabled() const { return add_vert_face; }
|
||||
|
||||
void setBirthRate(const float & arg) {birthRate_ = arg; tick_birth = birthRate_ / freq;}
|
||||
void setLifeDuration(const float & arg) {lifeDuration_ = arg;}
|
||||
void setSize(const float & arg) {size_ = arg;}
|
||||
void setEnlargeSpeed(const float & arg) {enlargeSpeed_ = arg;}
|
||||
void setInitialAngle(const float & arg) {initialAngle_ = arg;}
|
||||
void setInitialSpeed(const float & arg) {initialSpeed_ = arg;}
|
||||
void setBaseAngle(const float & arg) {baseAngle_ = arg;}
|
||||
void setSpeedDecay(const float & arg) {speedDecay_ = arg;}
|
||||
void setSpeedDirection(const QVector3D & arg) {speedDirection_ = arg;}
|
||||
void setEmitterPosition(const QVector3D & arg) {emitterPosition_ = arg;}
|
||||
void setEmitterDirection(const QVector3D & arg) {emitterDirection_ = arg.normalized();}
|
||||
void setEmitterRect(const Box3D & arg) {emitterRect_ = arg;}
|
||||
void setLifeDurationJitter(const float & arg) {lifeDurationJitter_ = arg;}
|
||||
void setSpeedJitter(const float & arg) {speedJitter_ = arg;}
|
||||
void setSpeedDirectionJitter(const float & arg) {speedDirectionJitter_ = arg;}
|
||||
void setSizeJitter(const float & arg) {sizeJitter_ = arg;}
|
||||
void setEnlargeSpeedJitter(const float & arg) {enlargeSpeedJitter_ = arg;}
|
||||
void setActive(const bool & arg) {active_ = arg;}
|
||||
void setAngleJitter(const float & arg) {angleJitter_ = arg;}
|
||||
void setBirthEnabled(const bool & arg) {birthEnabled_ = arg;}
|
||||
void setEmitterType(const GLParticlesSystem::Type & arg) {emitterType_ = arg;}
|
||||
void setFadeTime(const float & arg) {fade_time = arg;}
|
||||
void setAddVerticalFaceEnabled(const bool & arg) {add_vert_face = arg;}
|
||||
void setTextureRect(const QRectF & arg) {tex_rect = arg;}
|
||||
void setTextureScale(const float & x, const float & y) {tex_scale = QSizeF(x, y);}
|
||||
void setTextureScale(const QSizeF & arg) {tex_scale = arg;}
|
||||
void setBirthRate(const float & arg) {
|
||||
birthRate_ = arg;
|
||||
tick_birth = birthRate_ / freq;
|
||||
}
|
||||
void setLifeDuration(const float & arg) { lifeDuration_ = arg; }
|
||||
void setSize(const float & arg) { size_ = arg; }
|
||||
void setEnlargeSpeed(const float & arg) { enlargeSpeed_ = arg; }
|
||||
void setInitialAngle(const float & arg) { initialAngle_ = arg; }
|
||||
void setInitialSpeed(const float & arg) { initialSpeed_ = arg; }
|
||||
void setBaseAngle(const float & arg) { baseAngle_ = arg; }
|
||||
void setSpeedDecay(const float & arg) { speedDecay_ = arg; }
|
||||
void setSpeedDirection(const QVector3D & arg) { speedDirection_ = arg; }
|
||||
void setEmitterPosition(const QVector3D & arg) { emitterPosition_ = arg; }
|
||||
void setEmitterDirection(const QVector3D & arg) { emitterDirection_ = arg.normalized(); }
|
||||
void setEmitterRect(const Box3D & arg) { emitterRect_ = arg; }
|
||||
void setLifeDurationJitter(const float & arg) { lifeDurationJitter_ = arg; }
|
||||
void setSpeedJitter(const float & arg) { speedJitter_ = arg; }
|
||||
void setSpeedDirectionJitter(const float & arg) { speedDirectionJitter_ = arg; }
|
||||
void setSizeJitter(const float & arg) { sizeJitter_ = arg; }
|
||||
void setEnlargeSpeedJitter(const float & arg) { enlargeSpeedJitter_ = arg; }
|
||||
void setActive(const bool & arg) { active_ = arg; }
|
||||
void setAngleJitter(const float & arg) { angleJitter_ = arg; }
|
||||
void setBirthEnabled(const bool & arg) { birthEnabled_ = arg; }
|
||||
void setEmitterType(const GLParticlesSystem::Type & arg) { emitterType_ = arg; }
|
||||
void setFadeTime(const float & arg) { fade_time = arg; }
|
||||
void setAddVerticalFaceEnabled(const bool & arg) { add_vert_face = arg; }
|
||||
void setTextureRect(const QRectF & arg) { tex_rect = arg; }
|
||||
void setTextureScale(const float & x, const float & y) { tex_scale = QSizeF(x, y); }
|
||||
void setTextureScale(const QSizeF & arg) { tex_scale = arg; }
|
||||
|
||||
void addForce(const QVector3D & f) {forces << f;}
|
||||
void birthParticles(int count) {need_birth += count;}
|
||||
void addForce(const QVector3D & f) { forces << f; }
|
||||
void birthParticles(int count) { need_birth += count; }
|
||||
|
||||
float frequency() const {return freq;}
|
||||
void setFrequency(const float & f) {freq = f;}
|
||||
float frequency() const { return freq; }
|
||||
void setFrequency(const float & f) { freq = f; }
|
||||
|
||||
float additionalSpeed;
|
||||
|
||||
@@ -145,9 +156,10 @@ private:
|
||||
float lifeDurationJitter_, speedJitter_, speedDirectionJitter_, sizeJitter_, angleJitter_, initialAngle_;
|
||||
float enlargeSpeed_, enlargeSpeedJitter_, baseAngle_;
|
||||
bool active_, birthEnabled_, is_diffuse_anim, add_vert_face;
|
||||
|
||||
};
|
||||
|
||||
inline bool operator <(const GLParticlesSystem::Particle & f, const GLParticlesSystem::Particle & s) {return f.pos_h.z() > s.pos_h.z();}
|
||||
inline bool operator<(const GLParticlesSystem::Particle & f, const GLParticlesSystem::Particle & s) {
|
||||
return f.pos_h.z() > s.pos_h.z();
|
||||
}
|
||||
|
||||
#endif // GLPARTICLES_SYSTEM_H
|
||||
|
||||
@@ -28,7 +28,6 @@ void GLPrimitivePoint::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLPrimitiveLine::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
glColor3f(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF());
|
||||
glBegin(GL_LINES);
|
||||
@@ -38,24 +37,24 @@ void GLPrimitiveLine::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLPrimitiveCube::GLPrimitiveCube(float width, float length, float height, QVector3D pos): GLObjectBase() {
|
||||
geom_prim = Quads;
|
||||
w = width;
|
||||
l = length;
|
||||
h = height;
|
||||
w = width;
|
||||
l = length;
|
||||
h = height;
|
||||
moveTo(pos);
|
||||
//init();
|
||||
// init();
|
||||
}
|
||||
|
||||
|
||||
void GLPrimitiveCube::init() {
|
||||
float hw = w / 2.f, hl = l / 2.f, hh = h / 2.f;
|
||||
//list = glGenLists(1);
|
||||
//glNewList(list, GL_COMPILE);
|
||||
//glColor4d(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF(), material_.color_diffuse.alphaF());
|
||||
// list = glGenLists(1);
|
||||
// glNewList(list, GL_COMPILE);
|
||||
// glColor4d(material_.color_diffuse.redF(), material_.color_diffuse.greenF(), material_.color_diffuse.blueF(),
|
||||
// material_.color_diffuse.alphaF());
|
||||
vbo.init();
|
||||
QVector<GLfloat> & d_vertices(vbo.vertices()), & d_normals(vbo.normals()), & d_uvs(vbo.texcoords());
|
||||
QVector<GLfloat> &d_vertices(vbo.vertices()), &d_normals(vbo.normals()), &d_uvs(vbo.texcoords());
|
||||
d_vertices.clear();
|
||||
d_normals.clear();
|
||||
d_uvs.clear();
|
||||
@@ -108,13 +107,13 @@ void GLPrimitiveCube::init() {
|
||||
|
||||
GLPrimitiveEllipsoid::GLPrimitiveEllipsoid(float width, float length, float height, int seg_wl, int seg_h, QVector3D pos) {
|
||||
geom_prim = GLObjectBase::Triangles;
|
||||
w = width;
|
||||
l = length;
|
||||
h = height;
|
||||
swl = seg_wl;
|
||||
sh = seg_h;
|
||||
w = width;
|
||||
l = length;
|
||||
h = height;
|
||||
swl = seg_wl;
|
||||
sh = seg_h;
|
||||
moveTo(pos);
|
||||
//init();
|
||||
// init();
|
||||
}
|
||||
|
||||
|
||||
@@ -125,9 +124,12 @@ void GLPrimitiveEllipsoid::putTriangle(const QVector3D & v0, const QVector3D & v
|
||||
vbo.normals() << n.x() << n.y() << n.z();
|
||||
return;
|
||||
QVector3D s(w, l, h);
|
||||
n = (v0 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z();
|
||||
n = (v1 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z();
|
||||
n = (v2 * s).normalized(); vbo.normals() << n.x() << n.y() << n.z();
|
||||
n = (v0 * s).normalized();
|
||||
vbo.normals() << n.x() << n.y() << n.z();
|
||||
n = (v1 * s).normalized();
|
||||
vbo.normals() << n.x() << n.y() << n.z();
|
||||
n = (v2 * s).normalized();
|
||||
vbo.normals() << n.x() << n.y() << n.z();
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +137,7 @@ void GLPrimitiveEllipsoid::init() {
|
||||
QVector<QVector3D> points;
|
||||
vbo.clear();
|
||||
vbo.init();
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
int hseg = sh + 1, wlseg = swl + 1;
|
||||
float crw, crl, a, ch, twl;
|
||||
QVector3D cp(0., 0., -h / 2.f);
|
||||
@@ -161,7 +163,8 @@ void GLPrimitiveEllipsoid::init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i == 1) putTriangle(points[0], points[ret - wlseg * 2 + 1], points[ret]);
|
||||
if (i == 1)
|
||||
putTriangle(points[0], points[ret - wlseg * 2 + 1], points[ret]);
|
||||
else {
|
||||
putTriangle(points[ret - wlseg * 2 + 1], points[ret], points[ret - wlseg * 2]);
|
||||
putTriangle(points[ret - wlseg * 2 + 1], points[ret - wlseg * 2], points[ret - wlseg * 4 + 1]);
|
||||
@@ -178,43 +181,43 @@ void GLPrimitiveEllipsoid::init() {
|
||||
|
||||
|
||||
void GLPrimitiveAxis::draw(QOpenGLShaderProgram * prog, bool simplest) {
|
||||
float bs = 1.f;
|
||||
float as = 0.1f;
|
||||
float aw = 0.07f;
|
||||
float bs = 1.f;
|
||||
float as = 0.1f;
|
||||
float aw = 0.07f;
|
||||
float cr_x = 0.8f, cg_y = 0.75f, cb_z = 0.8f;
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(cr_x, 0, 0);
|
||||
glVertex3f(-bs, 0, 0);
|
||||
glVertex3f(bs, 0, 0);
|
||||
glVertex3f(bs, 0, 0);
|
||||
glVertex3f(bs-as, aw, 0);
|
||||
glVertex3f(bs - as, aw, 0);
|
||||
glVertex3f(bs, 0, 0);
|
||||
glVertex3f(bs-as, -aw, 0);
|
||||
glVertex3f(bs - as, -aw, 0);
|
||||
glVertex3f(bs, 0, 0);
|
||||
glVertex3f(bs-as, 0, aw);
|
||||
glVertex3f(bs - as, 0, aw);
|
||||
glVertex3f(bs, 0, 0);
|
||||
glVertex3f(bs-as, 0, -aw);
|
||||
glVertex3f(bs - as, 0, -aw);
|
||||
glColor3f(0, cg_y, 0);
|
||||
glVertex3f(0, -bs, 0);
|
||||
glVertex3f(0, bs, 0);
|
||||
glVertex3f(0, bs, 0);
|
||||
glVertex3f(0, bs-as, aw);
|
||||
glVertex3f(0, bs - as, aw);
|
||||
glVertex3f(0, bs, 0);
|
||||
glVertex3f(0, bs-as, -aw);
|
||||
glVertex3f(0, bs - as, -aw);
|
||||
glVertex3f(0, bs, 0);
|
||||
glVertex3f(aw, bs-as, 0);
|
||||
glVertex3f(aw, bs - as, 0);
|
||||
glVertex3f(0, bs, 0);
|
||||
glVertex3f(-aw, bs-as, 0);
|
||||
glVertex3f(-aw, bs - as, 0);
|
||||
glColor3f(0, 0, cb_z);
|
||||
glVertex3f(0, 0, -bs);
|
||||
glVertex3f(0, 0, bs);
|
||||
glVertex3f(0, 0, bs);
|
||||
glVertex3f(aw, 0, bs-as);
|
||||
glVertex3f(aw, 0, bs - as);
|
||||
glVertex3f(0, 0, bs);
|
||||
glVertex3f(-aw, 0, bs-as);
|
||||
glVertex3f(-aw, 0, bs - as);
|
||||
glVertex3f(0, 0, bs);
|
||||
glVertex3f(0, aw, bs-as);
|
||||
glVertex3f(0, aw, bs - as);
|
||||
glVertex3f(0, 0, bs);
|
||||
glVertex3f(0, -aw, bs-as);
|
||||
glVertex3f(0, -aw, bs - as);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -22,51 +22,53 @@
|
||||
#include "globject.h"
|
||||
|
||||
|
||||
class GLPrimitivePoint: public GLObjectBase
|
||||
{
|
||||
class GLPrimitivePoint: public GLObjectBase {
|
||||
public:
|
||||
GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) {sz = 8.;}
|
||||
GLPrimitivePoint(double size = 1., QVector3D pos = QVector3D()) { sz = 8.; }
|
||||
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
|
||||
|
||||
private:
|
||||
double sz;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class GLPrimitiveLine: public GLObjectBase
|
||||
{
|
||||
class GLPrimitiveLine: public GLObjectBase {
|
||||
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(QOpenGLShaderProgram * prog, bool simplest = false);
|
||||
QVector3D point0() const {return p0;}
|
||||
QVector3D point1() const {return p1;}
|
||||
void setPoint0(const QVector3D & p) {p0 = p;}
|
||||
void setPoint1(const QVector3D & p) {p1 = p;}
|
||||
QVector3D point0() const { return p0; }
|
||||
QVector3D point1() const { return p1; }
|
||||
void setPoint0(const QVector3D & p) { p0 = p; }
|
||||
void setPoint1(const QVector3D & p) { p1 = p; }
|
||||
|
||||
private:
|
||||
QVector3D p0, p1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class GLPrimitiveCube: public GLObjectBase
|
||||
{
|
||||
class GLPrimitiveCube: public GLObjectBase {
|
||||
public:
|
||||
GLPrimitiveCube(float width = 1., float length = 1., float height = 1., QVector3D pos = QVector3D());
|
||||
virtual void init();
|
||||
|
||||
private:
|
||||
float w, l, h;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class GLPrimitiveEllipsoid: public GLObjectBase
|
||||
{
|
||||
class GLPrimitiveEllipsoid: public GLObjectBase {
|
||||
public:
|
||||
GLPrimitiveEllipsoid(float width = 1., float length = 1., float height = 1., int seg_wl = 10, int seg_h = 10, QVector3D pos = QVector3D());
|
||||
GLPrimitiveEllipsoid(float width = 1.,
|
||||
float length = 1.,
|
||||
float height = 1.,
|
||||
int seg_wl = 10,
|
||||
int seg_h = 10,
|
||||
QVector3D pos = QVector3D());
|
||||
virtual void init();
|
||||
|
||||
private:
|
||||
void putTriangle(const QVector3D & v0, const QVector3D & v1, const QVector3D & v2);
|
||||
float w, l, h;
|
||||
@@ -74,10 +76,9 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class GLPrimitiveAxis: public GLObjectBase
|
||||
{
|
||||
class GLPrimitiveAxis: public GLObjectBase {
|
||||
public:
|
||||
GLPrimitiveAxis() {accept_fog = accept_light = cast_shadow = rec_shadow = select_ = false;}
|
||||
GLPrimitiveAxis() { accept_fog = accept_light = cast_shadow = rec_shadow = select_ = false; }
|
||||
virtual void draw(QOpenGLShaderProgram * prog, bool simplest = false);
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "glrendererbase.h"
|
||||
|
||||
#include "globject.h"
|
||||
#include "qglview.h"
|
||||
|
||||
@@ -25,7 +26,7 @@ GLRendererBase::GLRendererBase(QGLView * view_): view(*view_) {
|
||||
white_image = QImage(1, 1, QImage::Format_ARGB32);
|
||||
white_image.fill(0xFFFFFFFF);
|
||||
white_image_id = 0;
|
||||
violent_image = QImage(1, 1, QImage::Format_ARGB32);
|
||||
violent_image = QImage(1, 1, QImage::Format_ARGB32);
|
||||
violent_image.fill(QColor(127, 127, 255));
|
||||
violent_image_id = 0;
|
||||
}
|
||||
@@ -36,18 +37,18 @@ void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index)
|
||||
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.f;
|
||||
col[1] = l.visible_ ? l.color().greenF() * l.intensity : 0.f;
|
||||
col[2] = l.visible_ ? l.color().blueF() * l.intensity : 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.f;
|
||||
col[1] = l.visible_ ? l.color().greenF() * l.intensity : 0.f;
|
||||
col[2] = l.visible_ ? l.color().blueF() * l.intensity : 0.f;
|
||||
glEnable(gl_index);
|
||||
//glLightfv(gl_index, GL_AMBIENT, ambient);
|
||||
// glLightfv(gl_index, GL_AMBIENT, ambient);
|
||||
glLightfv(gl_index, GL_DIFFUSE, col);
|
||||
glLightfv(gl_index, GL_SPECULAR, col);
|
||||
glLightfv(gl_index, GL_POSITION, pos);
|
||||
@@ -57,11 +58,12 @@ void GLRendererBase::setupLight(const Light & l, int inpass_index, int gl_index)
|
||||
if (l.light_type == Light::Cone) {
|
||||
glLightfv(gl_index, GL_SPOT_DIRECTION, dir);
|
||||
glLightf(gl_index, GL_SPOT_CUTOFF, l.angle_end / 2.f);
|
||||
glLightf(gl_index, GL_SPOT_EXPONENT, (1.f - piClamp<float>((l.angle_end - l.angle_start) / (l.angle_end + 0.001f), 0., 1.f)) * 128.f);
|
||||
glLightf(gl_index,
|
||||
GL_SPOT_EXPONENT,
|
||||
(1.f - piClamp<float>((l.angle_end - l.angle_start) / (l.angle_end + 0.001f), 0., 1.f)) * 128.f);
|
||||
} else {
|
||||
glLightf(gl_index, GL_SPOT_CUTOFF, 180.);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -78,18 +80,21 @@ void GLRendererBase::setupAmbientLight(const QColor & a, bool first_pass) {
|
||||
|
||||
void GLRendererBase::setupShadersLights(int lights_count) {
|
||||
/*foreach (QOpenGLShaderProgram * i, view.shaders_ppl) {
|
||||
i->bind();
|
||||
i->setUniformValue("lightsCount", lights_count);
|
||||
i->setUniformValue("acc_light", lights_count > 0);
|
||||
//i->setUniformValue("mat", mvm);
|
||||
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; \
|
||||
glActiveTexture(GL_TEXTURE0 + ch); glBindTexture(GL_TEXTURE_2D, mat.map.bitmap_id); \
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.feature(QGLView::qglAnisotropicLevel).toInt());}
|
||||
#define BIND_TEXTURE(ch, map) \
|
||||
if (rp.prev_tex[ch] != mat.map.bitmap_id) { \
|
||||
rp.prev_tex[ch] = mat.map.bitmap_id; \
|
||||
glActiveTexture(GL_TEXTURE0 + ch); \
|
||||
glBindTexture(GL_TEXTURE_2D, mat.map.bitmap_id); \
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, view.feature(QGLView::qglAnisotropicLevel).toInt()); \
|
||||
}
|
||||
|
||||
void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingParameters & rp, bool first_object) {
|
||||
if (first_object) {
|
||||
@@ -99,12 +104,30 @@ void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingPa
|
||||
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 (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 (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)
|
||||
@@ -123,7 +146,7 @@ void GLRendererBase::setupTextures(GLObjectBase & o, GLRendererBase::RenderingPa
|
||||
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());
|
||||
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);
|
||||
@@ -154,19 +177,20 @@ void GLRendererBase::applyFilteringParameters() {
|
||||
|
||||
void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, bool textures, bool light, bool fog) {
|
||||
RenderingParameters rpl;
|
||||
rpl.pass = pass;
|
||||
rpl.pass = pass;
|
||||
rpl.light_pass = light_pass;
|
||||
rpl.shaders = shaders;
|
||||
rpl.textures = textures;
|
||||
rpl.shaders = shaders;
|
||||
rpl.textures = textures;
|
||||
rpl.light = rpl.prev_light = light;
|
||||
rpl.fog = rpl.prev_fog = fog;
|
||||
rpl.view_matrix = rp.view_matrix;
|
||||
rpl.prev_view_matrix = rp.prev_view_matrix;
|
||||
rpl.proj_matrix = rp.proj_matrix;
|
||||
rpl.prev_proj_matrix = rp.prev_proj_matrix;
|
||||
rpl.cam_offset_matrix = view.camera()->offsetMatrix();
|
||||
//qDebug() << "view:" << rp.view_matrix;
|
||||
for (int i = 0; i < 32; ++i) rpl.prev_tex[i] = 0;
|
||||
rpl.view_matrix = rp.view_matrix;
|
||||
rpl.prev_view_matrix = rp.prev_view_matrix;
|
||||
rpl.proj_matrix = rp.proj_matrix;
|
||||
rpl.prev_proj_matrix = rp.prev_proj_matrix;
|
||||
rpl.cam_offset_matrix = view.camera()->offsetMatrix();
|
||||
// qDebug() << "view:" << rp.view_matrix;
|
||||
for (int i = 0; i < 32; ++i)
|
||||
rpl.prev_tex[i] = 0;
|
||||
setupTextures(view.objects_, rpl, true);
|
||||
glSetLightEnabled(rpl.prev_light);
|
||||
glSetFogEnabled(rpl.prev_fog);
|
||||
@@ -181,16 +205,15 @@ void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, boo
|
||||
|
||||
|
||||
void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rpl) {
|
||||
if (!o.isInit())
|
||||
o.init();
|
||||
if (!o.isTexturesLoaded())
|
||||
o.loadTextures();
|
||||
if (!o.isInit()) o.init();
|
||||
if (!o.isTexturesLoaded()) o.loadTextures();
|
||||
if (!o.visible_) return;
|
||||
if (rpl.pass == o.pass_) {
|
||||
Material & mat(o.material_);
|
||||
QMatrix4x4 curview = rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_, prevview = rpl.prev_view_matrix * rpl.cam_offset_matrix * o.itransform_;
|
||||
QMatrix4x4 curview = rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_,
|
||||
prevview = rpl.prev_view_matrix * rpl.cam_offset_matrix * o.itransform_;
|
||||
setupTextures(o, rpl, false);
|
||||
mat.apply((QOpenGLShaderProgram*)rpl.shaders);
|
||||
mat.apply((QOpenGLShaderProgram *)rpl.shaders);
|
||||
glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
|
||||
glLineWidth(o.line_width > 0.f ? o.line_width : view.lineWidth_);
|
||||
glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_);
|
||||
@@ -199,9 +222,12 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters &
|
||||
glActiveTexture(GL_TEXTURE0 + 3);
|
||||
if (mat.reflectivity > 0.f) {
|
||||
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 (!mat.map_reflection.isEmpty())
|
||||
mat.map_reflection.bind();
|
||||
else
|
||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
} else
|
||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
if (rpl.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);
|
||||
@@ -211,21 +237,21 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters &
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, bc);
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, gm);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
///glLoadTransposeMatrixf(gm);
|
||||
/// glLoadTransposeMatrixf(gm);
|
||||
glScalef(-1., -1., -1.);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
if (rpl.shaders) {
|
||||
//qDebug() << o.name() << curview << curview.determinant();
|
||||
setUniformMatrices((QOpenGLShaderProgram*)rpl.shaders, rpl.proj_matrix, curview, rpl.prev_proj_matrix, prevview);
|
||||
// qDebug() << o.name() << curview << curview.determinant();
|
||||
setUniformMatrices((QOpenGLShaderProgram *)rpl.shaders, rpl.proj_matrix, curview, rpl.prev_proj_matrix, prevview);
|
||||
} else {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
setGLMatrix(curview);
|
||||
}
|
||||
o.draw((QOpenGLShaderProgram*)rpl.shaders);
|
||||
o.draw((QOpenGLShaderProgram *)rpl.shaders);
|
||||
}
|
||||
foreach (GLObjectBase * i, o.children_)
|
||||
foreach(GLObjectBase * i, o.children_)
|
||||
renderSingleObject(*i, rpl);
|
||||
}
|
||||
|
||||
@@ -245,60 +271,58 @@ void GLRendererBase::renderShadow(Light * l, QOpenGLShaderProgram * prog, QMatri
|
||||
cam.rotateXY(-l->angle_end);
|
||||
cam.rotateZ(l->angle_end);
|
||||
l->dir1 = cam.direction() - rdir;*/
|
||||
//qDebug() << rdir << l->dir0 << l->dir1;
|
||||
// qDebug() << rdir << l->dir0 << l->dir1;
|
||||
RenderingParameters rpl;
|
||||
rpl.pass = GLObjectBase::Solid;
|
||||
rpl.shaders = prog;
|
||||
rpl.pass = GLObjectBase::Solid;
|
||||
rpl.shaders = prog;
|
||||
rpl.textures = rpl.light = rpl.fog = false;
|
||||
rpl.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
rpl.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
rpl.cam_offset_matrix = cam.offsetMatrix();
|
||||
rpl.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
rpl.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
rpl.cam_offset_matrix = cam.offsetMatrix();
|
||||
QMatrix4x4 mbias;
|
||||
mbias.scale(0.5, 0.5, 0.5);
|
||||
mbias.translate(1., 1., 1.);
|
||||
l->shadow_matrix = mbias*rpl.proj_matrix*rpl.view_matrix*rpl.cam_offset_matrix*mat;//;// * mbias;
|
||||
//qDebug() << mbias;
|
||||
//glPushMatrix();
|
||||
l->shadow_matrix = mbias * rpl.proj_matrix * rpl.view_matrix * rpl.cam_offset_matrix * mat; //;// * mbias;
|
||||
// qDebug() << mbias;
|
||||
// glPushMatrix();
|
||||
renderSingleShadow(view.objects_, rpl);
|
||||
//glPopMatrix();
|
||||
// glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void GLRendererBase::renderSingleShadow(GLObjectBase & o, RenderingParameters & rpl) {
|
||||
if (!o.isInit())
|
||||
o.init();
|
||||
if (!o.isInit()) o.init();
|
||||
if (!o.visible_) return;
|
||||
if (rpl.shaders) {
|
||||
//qDebug() << o.name() << curview << curview.determinant();
|
||||
setUniformMatrices((QOpenGLShaderProgram*)rpl.shaders, rpl.proj_matrix, rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_);
|
||||
// qDebug() << o.name() << curview << curview.determinant();
|
||||
setUniformMatrices((QOpenGLShaderProgram *)rpl.shaders, rpl.proj_matrix, rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_);
|
||||
} else {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
setGLMatrix(rpl.view_matrix * rpl.cam_offset_matrix * o.itransform_);
|
||||
}
|
||||
glPolygonMode(GL_FRONT_AND_BACK, o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
|
||||
glPolygonMode(GL_FRONT_AND_BACK,
|
||||
o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
|
||||
glLineWidth(o.line_width > 0.f ? o.line_width : view.lineWidth_);
|
||||
glPointSize(o.line_width > 0.f ? o.line_width : view.lineWidth_);
|
||||
o.draw((QOpenGLShaderProgram*)rpl.shaders, true);
|
||||
foreach (GLObjectBase * i, o.children_)
|
||||
o.draw((QOpenGLShaderProgram *)rpl.shaders, true);
|
||||
foreach(GLObjectBase * i, o.children_)
|
||||
renderSingleShadow(*i, rpl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
GLRendererBase::RenderingParameters::RenderingParameters() {
|
||||
shaders = nullptr;
|
||||
shaders = nullptr;
|
||||
cur_shader = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void GLRendererBase::RenderingParameters::prepare() {
|
||||
proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
viewproj_matrix = proj_matrix * view_matrix;
|
||||
normal_matrix = view_matrix.normalMatrix();
|
||||
proj_matrix_i = proj_matrix.inverted();
|
||||
view_matrix_i = view_matrix.inverted();
|
||||
proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
viewproj_matrix = proj_matrix * view_matrix;
|
||||
normal_matrix = view_matrix.normalMatrix();
|
||||
proj_matrix_i = proj_matrix.inverted();
|
||||
view_matrix_i = view_matrix.inverted();
|
||||
viewproj_matrix_i = viewproj_matrix.inverted();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
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 Lesser General Public License for more details.
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLRENDERERBASE_H
|
||||
@@ -22,13 +22,15 @@
|
||||
#include "glcamera.h"
|
||||
#include "glshaders.h"
|
||||
|
||||
class GLRendererBase: public QObject , protected QOpenGLExtraFunctions
|
||||
{
|
||||
class GLRendererBase
|
||||
: public QObject
|
||||
, protected QOpenGLExtraFunctions {
|
||||
friend class QGLView;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GLRendererBase(QGLView * view_);
|
||||
virtual void prepareScene() {;}
|
||||
virtual void prepareScene() { ; }
|
||||
virtual void renderScene() = 0;
|
||||
|
||||
struct RenderingParameters {
|
||||
@@ -74,7 +76,6 @@ protected:
|
||||
QGLView & view;
|
||||
QImage white_image, violent_image;
|
||||
GLuint white_image_id, violent_image_id;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLRENDERERBASE_H
|
||||
|
||||
@@ -32,77 +32,74 @@ const char qgl_vertex_head[] =
|
||||
"in vec3 qgl_Vertex;\n"
|
||||
"vec4 qgl_ftransform() {return qgl_ModelViewProjectionMatrix * vec4(qgl_Vertex, 1);}\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_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_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 = 8;\n"
|
||||
"struct QGLLight {\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 position;\n"
|
||||
" vec4 direction;\n"
|
||||
" float intensity;\n"
|
||||
" float startAngle;\n"
|
||||
" float startAngleCos;\n"
|
||||
" float endAngle;\n"
|
||||
" float endAngleCos;\n"
|
||||
" float constantAttenuation;\n"
|
||||
" float linearAttenuation;\n"
|
||||
" float quadraticAttenuation;\n"
|
||||
" sampler2DShadow shadow;\n"
|
||||
//" sampler2D shadowColor\n"
|
||||
" mat4 shadowMatrix;\n"
|
||||
//" vec4 shadowDir0;\n"
|
||||
//" vec4 shadowDir1;\n"
|
||||
"};\n"
|
||||
"struct QGLMap {\n"
|
||||
" float offset;\n"
|
||||
" float amount;\n"
|
||||
" vec2 scale;\n"
|
||||
" sampler2D map;\n"
|
||||
"};\n"
|
||||
"struct QGLMaterial {\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_normal;\n"
|
||||
" QGLMap map_relief;\n"
|
||||
" QGLMap map_self_illumination;\n"
|
||||
" QGLMap map_specularity;\n"
|
||||
" QGLMap map_specular;\n"
|
||||
"};\n"
|
||||
"uniform QGLLight qgl_AmbientLight;\n"
|
||||
"uniform QGLLight qgl_Light[qgl_MaxLights];\n"
|
||||
"uniform QGLMaterial qgl_Material;\n";
|
||||
const char qgl_structs[] = "const int qgl_MaxLights = 8;\n"
|
||||
"struct QGLLight {\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 position;\n"
|
||||
" vec4 direction;\n"
|
||||
" float intensity;\n"
|
||||
" float startAngle;\n"
|
||||
" float startAngleCos;\n"
|
||||
" float endAngle;\n"
|
||||
" float endAngleCos;\n"
|
||||
" float constantAttenuation;\n"
|
||||
" float linearAttenuation;\n"
|
||||
" float quadraticAttenuation;\n"
|
||||
" sampler2DShadow shadow;\n"
|
||||
//" sampler2D shadowColor\n"
|
||||
" mat4 shadowMatrix;\n"
|
||||
//" vec4 shadowDir0;\n"
|
||||
//" vec4 shadowDir1;\n"
|
||||
"};\n"
|
||||
"struct QGLMap {\n"
|
||||
" float offset;\n"
|
||||
" float amount;\n"
|
||||
" vec2 scale;\n"
|
||||
" sampler2D map;\n"
|
||||
"};\n"
|
||||
"struct QGLMaterial {\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_normal;\n"
|
||||
" QGLMap map_relief;\n"
|
||||
" QGLMap map_self_illumination;\n"
|
||||
" QGLMap map_specularity;\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(QOpenGLShaderProgram * prog, QOpenGLShader::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 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);
|
||||
@@ -117,7 +114,7 @@ QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType ty
|
||||
all.insert(ip + 1, qgl_uniform);
|
||||
}
|
||||
prog->addShaderFromSourceCode(type, all);
|
||||
//qDebug() << "********" << all;
|
||||
// qDebug() << "********" << all;
|
||||
return all;
|
||||
}
|
||||
|
||||
@@ -126,20 +123,20 @@ bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QStrin
|
||||
prog->removeAllShaders();
|
||||
QDir d(dir);
|
||||
QFileInfoList sl;
|
||||
//qDebug() << "[QGLView] Shader \"" + name + "\" load shaders from" << d.absolutePath();
|
||||
// qDebug() << "[QGLView] Shader \"" + name + "\" load shaders from" << d.absolutePath();
|
||||
sl = d.entryInfoList(QStringList(name + ".geom"), QDir::Files | QDir::NoDotAndDotDot);
|
||||
foreach (const QFileInfo & i, sl) {
|
||||
//qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName();
|
||||
foreach(const QFileInfo & i, sl) {
|
||||
// qDebug() << "[QGLView] Shader \"" + name + "\" add geometry shader:" << i.fileName();
|
||||
loadShaderFile(prog, QOpenGLShader::Geometry, i.absoluteFilePath());
|
||||
}
|
||||
sl = d.entryInfoList(QStringList(name + ".vert"), QDir::Files | QDir::NoDotAndDotDot);
|
||||
foreach (const QFileInfo & i, sl) {
|
||||
//qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
|
||||
foreach(const QFileInfo & i, sl) {
|
||||
// qDebug() << "[QGLView] Shader \"" + name + "\" add vertex shader:" << i.fileName();
|
||||
loadShaderFile(prog, QOpenGLShader::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();
|
||||
foreach(const QFileInfo & i, sl) {
|
||||
// qDebug() << "[QGLView] Shader \"" + name + "\" add fragment shader:" << i.fileName();
|
||||
loadShaderFile(prog, QOpenGLShader::Fragment, i.absoluteFilePath());
|
||||
}
|
||||
if (!prog->link()) {
|
||||
@@ -153,17 +150,17 @@ bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QStrin
|
||||
void setUniformMatrices(QOpenGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view, QMatrix4x4 prevproj, QMatrix4x4 prevview) {
|
||||
if (!prog) return;
|
||||
if (!prog->isLinked()) return;
|
||||
QMatrix4x4 mvpm = proj * view;
|
||||
QMatrix4x4 mvpm = proj * view;
|
||||
QMatrix4x4 pmvpm = prevproj * prevview;
|
||||
QMatrix3x3 nm = view.normalMatrix();
|
||||
//nm.in;
|
||||
QMatrix3x3 nm = view.normalMatrix();
|
||||
// nm.in;
|
||||
prog->setUniformValue("qgl_ModelViewMatrix", view);
|
||||
prog->setUniformValue("qgl_ProjectionMatrix", proj);
|
||||
prog->setUniformValue("prev_ModelViewProjectioMatrix", pmvpm);
|
||||
prog->setUniformValue("prev_ModelViewMatrix", prevview);
|
||||
prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm);
|
||||
prog->setUniformValue("qgl_NormalMatrix", nm);
|
||||
//prog->setUniformValue("qgl_BumpMatrix", nm.);
|
||||
// prog->setUniformValue("qgl_BumpMatrix", nm.);
|
||||
prog->setUniformValue("qgl_ModelViewMatrixTranspose", view.transposed());
|
||||
prog->setUniformValue("qgl_ProjectionMatrixTranspose", proj.transposed());
|
||||
prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed());
|
||||
@@ -183,12 +180,12 @@ void setUniformMap(QOpenGLShaderProgram * prog, QString map_name, const Map & ma
|
||||
void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat) {
|
||||
if (!prog) return;
|
||||
if (!prog->isLinked()) return;
|
||||
QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions();
|
||||
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);
|
||||
QOpenGLFunctions * glFuncs = QOpenGLContext::currentContext()->functions();
|
||||
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);
|
||||
glFuncs->glVertexAttrib4f(prog->attributeLocation("qgl_Color"), mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
|
||||
prog->setUniformValue("qgl_Material.transparency", mat.transparency);
|
||||
prog->setUniformValue("qgl_Material.reflectivity", mat.reflectivity);
|
||||
@@ -203,11 +200,10 @@ void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat) {
|
||||
setUniformMap(prog, "map_self_illumination", mat.map_self_illumination, 3, 6);
|
||||
setUniformMap(prog, "map_specularity", mat.map_specularity, 4, 6);
|
||||
setUniformMap(prog, "map_specular", mat.map_specular, 5, 6);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light*> & lights, const QMatrix4x4 & mat, int shadow_start) {
|
||||
void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light *> & lights, const QMatrix4x4 & mat, int shadow_start) {
|
||||
for (int i = 0; i < lights.size(); ++i)
|
||||
setUniformLight(prog, lights[i], QString("qgl_Light[%1]").arg(i), mat, shadow_start + i);
|
||||
}
|
||||
@@ -228,13 +224,12 @@ void setUniformLight(QOpenGLShaderProgram * prog, Light * light, QString ulightn
|
||||
if (!prog) return;
|
||||
if (!prog->isLinked()) return;
|
||||
QMatrix4x4 m = mat * light->worldTransform();
|
||||
QVector4D pos(0, 0, 0, 1.), dir(light->direction, 1);//, dir0(light->dir0), dir1(light->dir1);
|
||||
pos = m * pos;
|
||||
dir = ((m * dir) - pos).normalized();
|
||||
QVector4D pos(0, 0, 0, 1.), dir(light->direction, 1); //, dir0(light->dir0), dir1(light->dir1);
|
||||
pos = m * pos;
|
||||
dir = ((m * dir) - pos).normalized();
|
||||
float ang_start = light->angle_start / 2.f, ang_end = light->angle_end / 2.f;
|
||||
if (light->light_type == Light::Omni)
|
||||
ang_start = ang_end = 180.;
|
||||
//qDebug() << "light" << light->name() << ulightn << pos;
|
||||
if (light->light_type == Light::Omni) ang_start = ang_end = 180.;
|
||||
// qDebug() << "light" << light->name() << ulightn << pos;
|
||||
prog->setUniformValue((ulightn + ".position").toLatin1().constData(), pos);
|
||||
prog->setUniformValue((ulightn + ".direction").toLatin1().constData(), dir);
|
||||
prog->setUniformValue((ulightn + ".intensity").toLatin1().constData(), GLfloat(light->intensity));
|
||||
@@ -249,8 +244,8 @@ void setUniformLight(QOpenGLShaderProgram * prog, Light * light, QString ulightn
|
||||
prog->setUniformValue((ulightn + ".shadow").toLatin1().constData(), shadow);
|
||||
prog->setUniformValue((ulightn + ".shadowColor").toLatin1().constData(), shadow);
|
||||
prog->setUniformValue((ulightn + ".shadowMatrix").toLatin1().constData(), light->shadow_matrix);
|
||||
//qDebug() << light->shadow_matrix;
|
||||
//prog->setUniformValue((ulightn + ".shadowDir0").toLatin1().constData(), (mat * dir0));
|
||||
//prog->setUniformValue((ulightn + ".shadowDir1").toLatin1().constData(), (mat * dir1));
|
||||
//qDebug() << light->direction << light->dir0 << light->dir1;
|
||||
// qDebug() << light->shadow_matrix;
|
||||
// prog->setUniformValue((ulightn + ".shadowDir0").toLatin1().constData(), (mat * dir0));
|
||||
// prog->setUniformValue((ulightn + ".shadowDir1").toLatin1().constData(), (mat * dir1));
|
||||
// qDebug() << light->direction << light->dir0 << light->dir1;
|
||||
}
|
||||
|
||||
@@ -27,9 +27,13 @@ class Light;
|
||||
|
||||
QString loadShaderFile(QOpenGLShaderProgram * prog, QOpenGLShader::ShaderType type, const QString & file);
|
||||
bool loadShaders(QOpenGLShaderProgram * prog, const QString & name, const QString & dir = QString());
|
||||
void setUniformMatrices(QOpenGLShaderProgram * prog, QMatrix4x4 proj, QMatrix4x4 view, QMatrix4x4 prevproj = QMatrix4x4(), QMatrix4x4 prevview = QMatrix4x4());
|
||||
void setUniformMatrices(QOpenGLShaderProgram * prog,
|
||||
QMatrix4x4 proj,
|
||||
QMatrix4x4 view,
|
||||
QMatrix4x4 prevproj = QMatrix4x4(),
|
||||
QMatrix4x4 prevview = QMatrix4x4());
|
||||
void setUniformMap(QOpenGLShaderProgram * prog, const Map & map, int channel, int def_channel);
|
||||
void setUniformMaterial(QOpenGLShaderProgram * prog, const Material & mat);
|
||||
void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light*> & lights, const QMatrix4x4 & mat, int shadow_start);
|
||||
void setUniformLights(QOpenGLShaderProgram * prog, const QVector<Light *> & lights, const QMatrix4x4 & mat, int shadow_start);
|
||||
void setUniformLight(QOpenGLShaderProgram * prog, Light * light, QString ulightn, const QMatrix4x4 & mat = QMatrix4x4(), int shadow = 0);
|
||||
#endif // GLSHADERS_H
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
|
||||
|
||||
bool GLTextureManager::loadTextures() {
|
||||
//glGenTextures();
|
||||
// glGenTextures();
|
||||
QFileInfoList fil;
|
||||
Animation anim;
|
||||
for (int i = 0; i < anim_pathes.size(); ++i) {
|
||||
anim.path = anim_pathes[i].second;
|
||||
anim.bitmaps.clear();
|
||||
fil = QDir(anim_pathes[i].first).entryInfoList(QDir::Files, QDir::Name);
|
||||
foreach (const QFileInfo & fi, fil) {
|
||||
foreach(const QFileInfo & fi, fil) {
|
||||
if (fi.baseName().indexOf(anim_pathes[i].second) < 0) continue;
|
||||
anim.bitmaps << loadTexture(fi.filePath(), false);
|
||||
}
|
||||
@@ -35,7 +35,7 @@ bool GLTextureManager::loadTextures() {
|
||||
anim_ids << QPair<QString, Animation>(anim_pathes[i].second, anim);
|
||||
}
|
||||
anim_pathes.clear();
|
||||
foreach (const QString & i, tex_pathes)
|
||||
foreach(const QString & i, tex_pathes)
|
||||
loadTexture(i, true);
|
||||
tex_pathes.clear();
|
||||
return true;
|
||||
|
||||
@@ -20,34 +20,40 @@
|
||||
#define GLTEXTUREMANAGER_H
|
||||
|
||||
#include "glmaterial.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
class GLTextureManager: public GLTextureManagerBase
|
||||
{
|
||||
class GLTextureManager: public GLTextureManagerBase {
|
||||
public:
|
||||
GLTextureManager() {;}
|
||||
~GLTextureManager() {deleteTextures();}
|
||||
GLTextureManager() { ; }
|
||||
~GLTextureManager() { deleteTextures(); }
|
||||
|
||||
struct Animation {
|
||||
QString path;
|
||||
QVector<GLuint> bitmaps;
|
||||
GLuint bitmapID(const int frame) {if (frame < 0 || frame >= bitmaps.size()) return 0; return bitmaps[frame];}
|
||||
GLuint bitmapID(const int frame) {
|
||||
if (frame < 0 || frame >= bitmaps.size()) return 0;
|
||||
return bitmaps[frame];
|
||||
}
|
||||
};
|
||||
|
||||
void addTexture(const QString & path) {tex_pathes << path;}
|
||||
void addAnimation(const QString & dir, const QString & name) {anim_pathes << QPair<QString, QString>(dir, name);}
|
||||
void addTexture(const QString & path) { tex_pathes << path; }
|
||||
void addAnimation(const QString & dir, const QString & name) { anim_pathes << QPair<QString, QString>(dir, name); }
|
||||
bool loadTextures();
|
||||
void deleteTextures();
|
||||
void deleteTexture(const QString & name);
|
||||
Animation * findAnimation(const QString & name) {for (int i = 0; i < anim_ids.size(); ++i) if (anim_ids[i].first == name) return &(anim_ids[i].second); return 0;}
|
||||
Animation * findAnimation(const QString & name) {
|
||||
for (int i = 0; i < anim_ids.size(); ++i)
|
||||
if (anim_ids[i].first == name) return &(anim_ids[i].second);
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVector<QPair<QString, Animation> > anim_ids;
|
||||
QVector<QPair<QString, Animation>> anim_ids;
|
||||
|
||||
private:
|
||||
QStringList tex_pathes;
|
||||
QList<QPair<QString, QString> > anim_pathes;
|
||||
|
||||
QList<QPair<QString, QString>> anim_pathes;
|
||||
};
|
||||
|
||||
#endif // GLTEXTUREMANAGER_H
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <QPainter>
|
||||
|
||||
//__GLWidget__ * currentQGLView;
|
||||
//QMutex globMutex;
|
||||
// QMutex globMutex;
|
||||
|
||||
|
||||
QString readCharsUntilNull(QDataStream & s) {
|
||||
@@ -39,15 +39,14 @@ QString readCharsUntilNull(QDataStream & s) {
|
||||
|
||||
QString findFile(const QString & file, const QStringList & pathes) {
|
||||
QFileInfo fi(QString(file).replace("\\", "/"));
|
||||
//qDebug() << "search" << file << "in" << pathes;
|
||||
// qDebug() << "search" << file << "in" << pathes;
|
||||
if (fi.exists()) return fi.absoluteFilePath();
|
||||
QString fn = fi.fileName();
|
||||
if (fn.contains("/")) fn = fn.mid(fn.lastIndexOf("/"));
|
||||
foreach (QString p, pathes) {
|
||||
foreach(QString p, pathes) {
|
||||
QFileInfoList fil = QDir(p).entryInfoList(QStringList(fn), QDir::Files | QDir::NoDotAndDotDot);
|
||||
//qDebug() << "findFile" << fn << "in" << p << "->" << fil.size();
|
||||
if (!fil.isEmpty())
|
||||
return fil[0].absoluteFilePath();
|
||||
// qDebug() << "findFile" << fn << "in" << p << "->" << fil.size();
|
||||
if (!fil.isEmpty()) return fil[0].absoluteFilePath();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
@@ -58,22 +57,28 @@ void glDrawQuad(QOpenGLShaderProgram * prog, QVector4D * corner_dirs, GLfloat x,
|
||||
glSetPolygonMode(GL_FILL);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
int loc = prog ? prog->attributeLocation("qgl_Color") : -1,
|
||||
locv = prog ? prog->attributeLocation("qgl_Vertex") : -1,
|
||||
loct = prog ? prog->attributeLocation("qgl_Texture") : -1,
|
||||
locc = prog ? prog->attributeLocation("view_corner") : -1;
|
||||
//if (prog) {qDebug() << locv << loct << locc;}
|
||||
int loc = prog ? prog->attributeLocation("qgl_Color") : -1, locv = prog ? prog->attributeLocation("qgl_Vertex") : -1,
|
||||
loct = prog ? prog->attributeLocation("qgl_Texture") : -1, locc = prog ? prog->attributeLocation("view_corner") : -1;
|
||||
// if (prog) {qDebug() << locv << loct << locc;}
|
||||
QOpenGLFunctions * glFuncs = QOpenGLContext::currentContext()->functions();
|
||||
if (prog) {
|
||||
static const GLfloat cols [] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
|
||||
static const GLfloat verts[] = {x, y, x+w, y, x, y+h, x+w, y+h};
|
||||
static const GLfloat texs [] = {0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f};
|
||||
GLfloat vcs[] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
|
||||
static const GLfloat cols[] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
|
||||
static const GLfloat verts[] = {x, y, x + w, y, x, y + h, x + w, y + h};
|
||||
static const GLfloat texs[] = {0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f};
|
||||
GLfloat vcs[] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
|
||||
if (corner_dirs) {
|
||||
vcs[0] = corner_dirs[0].x(); vcs[1] = corner_dirs[0].y(); vcs[2] = corner_dirs[0].z();
|
||||
vcs[3] = corner_dirs[1].x(); vcs[4] = corner_dirs[1].y(); vcs[5] = corner_dirs[1].z();
|
||||
vcs[6] = corner_dirs[2].x(); vcs[7] = corner_dirs[2].y(); vcs[8] = corner_dirs[2].z();
|
||||
vcs[9] = corner_dirs[3].x(); vcs[10] = corner_dirs[3].y(); vcs[11] = corner_dirs[3].z();
|
||||
vcs[0] = corner_dirs[0].x();
|
||||
vcs[1] = corner_dirs[0].y();
|
||||
vcs[2] = corner_dirs[0].z();
|
||||
vcs[3] = corner_dirs[1].x();
|
||||
vcs[4] = corner_dirs[1].y();
|
||||
vcs[5] = corner_dirs[1].z();
|
||||
vcs[6] = corner_dirs[2].x();
|
||||
vcs[7] = corner_dirs[2].y();
|
||||
vcs[8] = corner_dirs[2].z();
|
||||
vcs[9] = corner_dirs[3].x();
|
||||
vcs[10] = corner_dirs[3].y();
|
||||
vcs[11] = corner_dirs[3].z();
|
||||
}
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
@@ -96,10 +101,14 @@ void glDrawQuad(QOpenGLShaderProgram * prog, QVector4D * corner_dirs, GLfloat x,
|
||||
} else {
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
glTexCoord2f(0.f, 0.f); glVertex2f(x, y);
|
||||
glTexCoord2f(1.f, 0.f); glVertex2f(x+w, y);
|
||||
glTexCoord2f(0.f, 1.f); glVertex2f(x, y+h);
|
||||
glTexCoord2f(1.f, 1.f); glVertex2f(x+w, y+h);
|
||||
glTexCoord2f(0.f, 0.f);
|
||||
glVertex2f(x, y);
|
||||
glTexCoord2f(1.f, 0.f);
|
||||
glVertex2f(x + w, y);
|
||||
glTexCoord2f(0.f, 1.f);
|
||||
glVertex2f(x, y + h);
|
||||
glTexCoord2f(1.f, 1.f);
|
||||
glVertex2f(x + w, y + h);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
@@ -141,21 +150,19 @@ void createGLTexture(GLuint & tex, int width, int height, const GLenum & format,
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(target, tex);
|
||||
}
|
||||
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_COMPONENT16 || format == GL_DEPTH_COMPONENT24 || format == GL_DEPTH_COMPONENT32)
|
||||
glTexImage2D(target, 0, format, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, nullptr);
|
||||
else {
|
||||
int t = GL_UNSIGNED_BYTE;
|
||||
int f = GL_RGBA;
|
||||
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGBA32F || format == GL_RGBA16F)
|
||||
t = GL_FLOAT;
|
||||
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGB8 || format == GL_RGB)
|
||||
f = GL_RGB;
|
||||
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGBA32F || format == GL_RGBA16F) t = GL_FLOAT;
|
||||
if (format == GL_RGB32F || format == GL_RGB16F || format == GL_RGB8 || format == GL_RGB) f = GL_RGB;
|
||||
glTexImage2D(target, 0, format, width, height, 0, f, t, nullptr);
|
||||
//glGenerateMipmap(target);
|
||||
//qDebug() << "glTexImage2D" << width << height << QString::number(t, 16);
|
||||
// glGenerateMipmap(target);
|
||||
// qDebug() << "glTexImage2D" << width << height << QString::number(t, 16);
|
||||
}
|
||||
//qDebug() << QString::number(glGetError(), 16);
|
||||
// qDebug() << QString::number(glGetError(), 16);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,9 +172,9 @@ void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format,
|
||||
}
|
||||
glBindTexture(target, tex);
|
||||
QImage im = image.mirrored(false, true).convertToFormat(QImage::Format_ARGB32, Qt::ColorOnly);
|
||||
//const QImage & cim(im);
|
||||
//glClearError();
|
||||
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
// const QImage & cim(im);
|
||||
// glClearError();
|
||||
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D || target == GL_TEXTURE_3D) {
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
@@ -177,7 +184,7 @@ void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format,
|
||||
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
}
|
||||
glTexImage2D(target, 0, format, im.width(), im.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, im.bits());
|
||||
//qDebug() << tex << im.width() << im.height() << im.bits() << glGetError();
|
||||
// qDebug() << tex << im.width() << im.height() << im.bits() << glGetError();
|
||||
}
|
||||
|
||||
|
||||
@@ -186,8 +193,8 @@ QMatrix4x4 glMatrixPerspective(float angle, float aspect, float near_, float far
|
||||
float t = 1.f / (tanf(angle * deg2rad / 2.f)), e = 2.4e-7f;
|
||||
ret(0, 0) = t / aspect;
|
||||
ret(1, 1) = t;
|
||||
ret(2, 2) = e - 1.f;//far_ / (far_ - near_) - 1.;
|
||||
ret(2, 3) = (e - 2.f) * near_;//2. * far_ * near_ / (far_ - near_);
|
||||
ret(2, 2) = e - 1.f; // far_ / (far_ - near_) - 1.;
|
||||
ret(2, 3) = (e - 2.f) * near_; // 2. * far_ * near_ / (far_ - near_);
|
||||
ret(3, 2) = -1.f;
|
||||
ret(3, 3) = 0.f;
|
||||
return ret;
|
||||
@@ -214,14 +221,15 @@ QImage rotateQImageRight(const QImage & im) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QColor colorFromString(const QString & str) {
|
||||
QString s = str.trimmed();
|
||||
int i = s.indexOf("\t");
|
||||
int i = s.indexOf("\t");
|
||||
float r, g, b;
|
||||
r = s.left(i).toFloat(); s = s.right(s.length() - i - 1); i = s.indexOf("\t");
|
||||
g = s.left(i).toFloat(); s = s.right(s.length() - i - 1);
|
||||
r = s.left(i).toFloat();
|
||||
s = s.right(s.length() - i - 1);
|
||||
i = s.indexOf("\t");
|
||||
g = s.left(i).toFloat();
|
||||
s = s.right(s.length() - i - 1);
|
||||
b = s.toFloat();
|
||||
return QColor(r * 255.f, g * 255.f, b * 255.f);
|
||||
}
|
||||
@@ -230,9 +238,12 @@ QColor colorFromString(const QString & str) {
|
||||
QVector3D orthToVector(const QVector3D & v, const float & scale) {
|
||||
if (v.isNull()) return QVector3D();
|
||||
QVector3D rv, fn, sn;
|
||||
if (v.x() != 0.f) rv.setZ(1.);
|
||||
else if (v.y() != 0.f) rv.setX(1.);
|
||||
else rv.setY(1.);
|
||||
if (v.x() != 0.f)
|
||||
rv.setZ(1.);
|
||||
else if (v.y() != 0.f)
|
||||
rv.setX(1.);
|
||||
else
|
||||
rv.setY(1.);
|
||||
fn = QVector3D::crossProduct(v, rv).normalized();
|
||||
sn = QVector3D::crossProduct(v, fn).normalized();
|
||||
return fn * urand(scale) + sn * urand(scale);
|
||||
@@ -266,25 +277,31 @@ void lengthenVector(QVector3D & v, const float & l) {
|
||||
|
||||
Vector3d::Vector3d(const QString & str) {
|
||||
QString s = str.trimmed();
|
||||
int i = s.indexOf("\t");
|
||||
x = s.left(i).toFloat(); s = s.right(s.length() - i - 1); i = s.indexOf("\t");
|
||||
y = s.left(i).toFloat(); s = s.right(s.length() - i - 1);
|
||||
z = s.toFloat();
|
||||
int i = s.indexOf("\t");
|
||||
x = s.left(i).toFloat();
|
||||
s = s.right(s.length() - i - 1);
|
||||
i = s.indexOf("\t");
|
||||
y = s.left(i).toFloat();
|
||||
s = s.right(s.length() - i - 1);
|
||||
z = s.toFloat();
|
||||
}
|
||||
|
||||
|
||||
Vector3i::Vector3i(const QString & str) {
|
||||
QString s = str.trimmed();
|
||||
int i = s.indexOf("\t");
|
||||
p0 = s.left(i).toInt(); s = s.right(s.length() - i - 1); i = s.indexOf("\t");
|
||||
p1 = s.left(i).toInt(); s = s.right(s.length() - i - 1);
|
||||
p2 = s.toInt();
|
||||
int i = s.indexOf("\t");
|
||||
p0 = s.left(i).toInt();
|
||||
s = s.right(s.length() - i - 1);
|
||||
i = s.indexOf("\t");
|
||||
p1 = s.left(i).toInt();
|
||||
s = s.right(s.length() - i - 1);
|
||||
p2 = s.toInt();
|
||||
}
|
||||
|
||||
|
||||
void glEnableDepth() {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
//glDepthFunc(GL_GREATER);
|
||||
// glDepthFunc(GL_GREATER);
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
@@ -298,7 +315,7 @@ void glDisableDepth() {
|
||||
|
||||
void glClearFramebuffer(const QColor & color, bool depth) {
|
||||
glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
||||
//glClearDepth(0.);
|
||||
// glClearDepth(0.);
|
||||
if (depth)
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
else
|
||||
@@ -306,10 +323,8 @@ void glClearFramebuffer(const QColor & color, bool depth) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QGLViewBase::QGLViewBase() {
|
||||
camera_ = new Camera();
|
||||
camera_ = new Camera();
|
||||
textures_manager = new GLTextureManager();
|
||||
}
|
||||
|
||||
@@ -347,13 +362,16 @@ Box3D::Box3D(const QVector<QVector3D> & points) {
|
||||
iy = ay = points[0].y();
|
||||
iz = az = points[0].z();
|
||||
for (int i = 1; i < points.size(); ++i) {
|
||||
ix = qMin<float>(ix, points[i].x()); ax = qMax<float>(ax, points[i].x());
|
||||
iy = qMin<float>(iy, points[i].y()); ay = qMax<float>(ay, points[i].y());
|
||||
iz = qMin<float>(iz, points[i].z()); az = qMax<float>(az, points[i].z());
|
||||
ix = qMin<float>(ix, points[i].x());
|
||||
ax = qMax<float>(ax, points[i].x());
|
||||
iy = qMin<float>(iy, points[i].y());
|
||||
ay = qMax<float>(ay, points[i].y());
|
||||
iz = qMin<float>(iz, points[i].z());
|
||||
az = qMax<float>(az, points[i].z());
|
||||
}
|
||||
x = ix;
|
||||
y = iy;
|
||||
z = iz;
|
||||
x = ix;
|
||||
y = iy;
|
||||
z = iz;
|
||||
length = ax - ix;
|
||||
width = ay - iy;
|
||||
height = az - iz;
|
||||
@@ -363,20 +381,27 @@ Box3D::Box3D(const QVector<QVector3D> & points) {
|
||||
QVector<QVector3D> Box3D::corners() const {
|
||||
QVector<QVector3D> ret;
|
||||
ret << QVector3D(x, y, z) << QVector3D(x, y + width, z) << QVector3D(x, y, z + height) << QVector3D(x, y + width, z + height)
|
||||
<< QVector3D(x + length, y, z) << QVector3D(x + length, y + width, z)
|
||||
<< QVector3D(x + length, y, z + height) << QVector3D(x + length, y + width, z + height);
|
||||
<< QVector3D(x + length, y, z) << QVector3D(x + length, y + width, z) << QVector3D(x + length, y, z + height)
|
||||
<< QVector3D(x + length, y + width, z + height);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Box3D & Box3D::operator |=(const Box3D & o) {
|
||||
if (isEmpty()) *this = o;
|
||||
Box3D & Box3D::operator|=(const Box3D & o) {
|
||||
if (isEmpty())
|
||||
*this = o;
|
||||
else {
|
||||
GLfloat mx = x + length, my = y + width, mz = z + height;
|
||||
GLfloat omx = o.x + o.length, omy = o.y + o.width, omz = o.z + o.height;
|
||||
x = qMin(x, o.x); y = qMin(y, o.y); z = qMin(z, o.z);
|
||||
mx = qMax(mx, omx); my = qMax(my, omy); mz = qMax(mz, omz);
|
||||
length = mx - x; width = my - y; height = mz - z;
|
||||
x = qMin(x, o.x);
|
||||
y = qMin(y, o.y);
|
||||
z = qMin(z, o.z);
|
||||
mx = qMax(mx, omx);
|
||||
my = qMax(my, omy);
|
||||
mz = qMax(mz, omz);
|
||||
length = mx - x;
|
||||
width = my - y;
|
||||
height = mz - z;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
#endif
|
||||
#ifndef WINDOWS
|
||||
# ifndef QNX
|
||||
# ifndef MAC
|
||||
# define LINUX
|
||||
# endif
|
||||
# ifndef MAC
|
||||
# define LINUX
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if __GNUC__
|
||||
@@ -45,44 +45,44 @@
|
||||
#include <QObject>
|
||||
#ifndef WINDOWS
|
||||
# ifdef MAC
|
||||
# include <OpenGL/gl.h>
|
||||
# include <OpenGL/glu.h>
|
||||
# include <GLUT/glut.h>
|
||||
# include <GLUT/glut.h>
|
||||
# include <OpenGL/gl.h>
|
||||
# include <OpenGL/glu.h>
|
||||
# else
|
||||
# include <GL/gl.h>
|
||||
# include <GL/glext.h>
|
||||
# include <GL/glu.h>
|
||||
# include <GL/gl.h>
|
||||
# include <GL/glext.h>
|
||||
# include <GL/glu.h>
|
||||
# endif
|
||||
#endif
|
||||
#include <QColor>
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include <QMatrix4x4>
|
||||
#include <QMutex>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLShader>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <cmath>
|
||||
#include <float.h>
|
||||
#include <QMatrix4x4>
|
||||
#include <QDebug>
|
||||
#include <QDataStream>
|
||||
#include <QColor>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <QImage>
|
||||
#include <QMutex>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <cmath>
|
||||
#include <float.h>
|
||||
#ifndef QNX
|
||||
# include <cmath>
|
||||
# include <complex>
|
||||
# include <cmath>
|
||||
# include <complex>
|
||||
#else
|
||||
# include <math.h>
|
||||
# include <complex.h>
|
||||
# include <complex.h>
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#ifdef WINDOWS
|
||||
# define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||
# define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
# define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
@@ -114,75 +114,166 @@ const float deg2rad = atanf(1.f) / 45.f;
|
||||
const float rad2deg = 45.f / atanf(1.f);
|
||||
|
||||
# ifdef WINDOWS
|
||||
inline int random() {return rand();}
|
||||
inline int random() {
|
||||
return rand();
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
#define random randomi
|
||||
# define random randomi
|
||||
#endif
|
||||
|
||||
#ifdef CC_VC
|
||||
inline float round(const float & v) {return floor(v + 0.5);}
|
||||
inline float round(const float & v) {
|
||||
return floor(v + 0.5);
|
||||
}
|
||||
#endif
|
||||
inline float randomu() {return float(random()) / RAND_MAX;}
|
||||
inline float randomu() {
|
||||
return float(random()) / RAND_MAX;
|
||||
}
|
||||
|
||||
inline const QSizeF operator *(const QSizeF & f, const QSizeF & s) {return QSizeF(f.width() * s.width(), f.height() * s.height());}
|
||||
inline const QSizeF operator*(const QSizeF & f, const QSizeF & s) {
|
||||
return QSizeF(f.width() * s.width(), f.height() * s.height());
|
||||
}
|
||||
#ifndef PIP_VERSION
|
||||
template<typename T> inline void piSwap(T & f, T & s) {T t(f); f = s; s = t;}
|
||||
template<typename Type> inline Type piMin(const Type & f, const Type & s) {return (f > s) ? s : f;}
|
||||
template<typename Type> inline Type piMin(const Type & f, const Type & s, const Type & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);}
|
||||
template<typename Type> inline Type piMax(const Type & f, const Type & s) {return (f < s) ? s : f;}
|
||||
template<typename Type> inline Type piMax(const Type & f, const Type & s, const Type & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);}
|
||||
template<typename Type> inline Type piClamp(const Type & v, const Type & min, const Type & max) {return (v > max ? max : (v < min ? min : v));}
|
||||
inline ushort letobe_s(ushort v) {return (v << 8) | (v >> 8);}
|
||||
template<typename T>
|
||||
inline void piSwap(T & f, T & s) {
|
||||
T t(f);
|
||||
f = s;
|
||||
s = t;
|
||||
}
|
||||
template<typename Type>
|
||||
inline Type piMin(const Type & f, const Type & s) {
|
||||
return (f > s) ? s : f;
|
||||
}
|
||||
template<typename Type>
|
||||
inline Type piMin(const Type & f, const Type & s, const Type & t) {
|
||||
return (f < s && f < t) ? f : ((s < t) ? s : t);
|
||||
}
|
||||
template<typename Type>
|
||||
inline Type piMax(const Type & f, const Type & s) {
|
||||
return (f < s) ? s : f;
|
||||
}
|
||||
template<typename Type>
|
||||
inline Type piMax(const Type & f, const Type & s, const Type & t) {
|
||||
return (f > s && f > t) ? f : ((s > t) ? s : t);
|
||||
}
|
||||
template<typename Type>
|
||||
inline Type piClamp(const Type & v, const Type & min, const Type & max) {
|
||||
return (v > max ? max : (v < min ? min : v));
|
||||
}
|
||||
inline ushort letobe_s(ushort v) {
|
||||
return (v << 8) | (v >> 8);
|
||||
}
|
||||
#endif
|
||||
// return [-1, 1]
|
||||
inline float urand(const float & scale = 1.) {return ((float)rand() / RAND_MAX - .5f) * (scale + scale);}
|
||||
inline float urand(const float & scale = 1.) {
|
||||
return ((float)rand() / RAND_MAX - .5f) * (scale + scale);
|
||||
}
|
||||
// return [0, 1]
|
||||
inline float uprand(const float & scale = 1.) {return ((float)rand() / RAND_MAX) * scale;}
|
||||
inline float uprand(const float & scale = 1.) {
|
||||
return ((float)rand() / RAND_MAX) * scale;
|
||||
}
|
||||
QString readCharsUntilNull(QDataStream & s);
|
||||
QString findFile(const QString & file, const QStringList & pathes);
|
||||
inline QColor operator *(const QColor & c, float v) {return QColor(piClamp<int>(c.red() * v, 0, 255), piClamp<int>(c.green() * v, 0, 255), piClamp<int>(c.blue() * v, 0, 255), piClamp<int>(c.alpha() * v, 0, 255));}
|
||||
inline QColor operator /(const QColor & c, float v) {return QColor(piClamp<int>(c.red() / v, 0, 255), piClamp<int>(c.green() / v, 0, 255), piClamp<int>(c.blue() / v, 0, 255), piClamp<int>(c.alpha() / v, 0, 255));}
|
||||
inline QColor operator*(const QColor & c, float v) {
|
||||
return QColor(piClamp<int>(c.red() * v, 0, 255),
|
||||
piClamp<int>(c.green() * v, 0, 255),
|
||||
piClamp<int>(c.blue() * v, 0, 255),
|
||||
piClamp<int>(c.alpha() * v, 0, 255));
|
||||
}
|
||||
inline QColor operator/(const QColor & c, float v) {
|
||||
return QColor(piClamp<int>(c.red() / v, 0, 255),
|
||||
piClamp<int>(c.green() / v, 0, 255),
|
||||
piClamp<int>(c.blue() / v, 0, 255),
|
||||
piClamp<int>(c.alpha() / v, 0, 255));
|
||||
}
|
||||
|
||||
//extern __GLWidget__ * currentQGLView;
|
||||
// extern __GLWidget__ * currentQGLView;
|
||||
|
||||
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 glEnableDepth();
|
||||
void glDisableDepth();
|
||||
inline void glResetAllTransforms() {glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}
|
||||
inline void glClearError() {int c = 100; while (glGetError() != GL_NO_ERROR && --c > 0) glGetError();}
|
||||
inline void glClearAccumulation(const QColor & color = Qt::black) {glClearAccum(color.redF(), color.greenF(), color.blueF(), color.alphaF()); glClear(GL_ACCUM_BUFFER_BIT);}
|
||||
inline void glResetAllTransforms() {
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
inline void glClearError() {
|
||||
int c = 100;
|
||||
while (glGetError() != GL_NO_ERROR && --c > 0)
|
||||
glGetError();
|
||||
}
|
||||
inline void glClearAccumulation(const QColor & color = Qt::black) {
|
||||
glClearAccum(color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
||||
glClear(GL_ACCUM_BUFFER_BIT);
|
||||
}
|
||||
void glClearFramebuffer(const QColor & color = Qt::black, bool depth = true);
|
||||
inline void glSetCapEnabled(GLenum cap, bool on = true) {if (on) glEnable(cap); else glDisable(cap);}
|
||||
inline void glSetLightEnabled(bool on) {if (on) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING);}
|
||||
inline void glSetFogEnabled(bool on) {if (on) glEnable(GL_FOG); else glDisable(GL_FOG);}
|
||||
inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);}
|
||||
void glDrawQuad(QOpenGLShaderProgram * prog = 0, QVector4D * corner_dirs = 0, GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f);
|
||||
inline void glSetCapEnabled(GLenum cap, bool on = true) {
|
||||
if (on)
|
||||
glEnable(cap);
|
||||
else
|
||||
glDisable(cap);
|
||||
}
|
||||
inline void glSetLightEnabled(bool on) {
|
||||
if (on)
|
||||
glEnable(GL_LIGHTING);
|
||||
else
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
inline void glSetFogEnabled(bool on) {
|
||||
if (on)
|
||||
glEnable(GL_FOG);
|
||||
else
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
inline void glSetPolygonMode(GLenum mode) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, mode);
|
||||
}
|
||||
void glDrawQuad(QOpenGLShaderProgram * prog = 0,
|
||||
QVector4D * corner_dirs = 0,
|
||||
GLfloat x = -1.f,
|
||||
GLfloat y = -1.f,
|
||||
GLfloat w = 2.f,
|
||||
GLfloat h = 2.f);
|
||||
QMatrix4x4 getGLMatrix(GLenum matrix);
|
||||
void setGLMatrix(QMatrix4x4 matrix);
|
||||
inline void deleteGLTexture(GLuint & tex) {if (tex != 0) glDeleteTextures(1, &tex); tex = 0;}
|
||||
//# define QGLCI if (!QOpenGLContext::currentContext()) return; QOpenGLFunctions gf(QOpenGLContext::currentContext());
|
||||
//# define QGLC gf.
|
||||
//inline void glActiveTextureChannel(int channel) {QGLCI gf.glActiveTexture(GL_TEXTURE0 + channel);}
|
||||
//inline void glDisableTextures(int channels = 8) {QGLCI for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP);}}
|
||||
//inline void glReleaseTextures(int channels = 8) {QGLCI for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}}
|
||||
//inline void glReleaseFramebuffer() {QGLCI gf.glBindFramebuffer(GL_FRAMEBUFFER, 0);}
|
||||
//inline void glReleaseShaders() {QGLCI gf.glUseProgram(0);}
|
||||
//inline void deleteGLFramebuffer(GLuint & fbo) {QGLCI if (fbo != 0) gf.glDeleteFramebuffers(1, &fbo); fbo = 0;}
|
||||
//inline void deleteGLRenderbuffer(GLuint & drbo) {QGLCI if (drbo != 0) gf.glDeleteRenderbuffers(1, &drbo); drbo = 0;}
|
||||
//inline void deleteGLBuffer(GLuint & bo) {QGLCI if (bo != 0) gf.glDeleteBuffers(1, &bo); bo = 0;}
|
||||
//inline void deleteGLVertexArray(GLuint & va) {QGLCI if (va != 0) gf.glDeleteVertexArrays(1, &va); va = 0;}
|
||||
inline void deleteGLTexture(GLuint & tex) {
|
||||
if (tex != 0) glDeleteTextures(1, &tex);
|
||||
tex = 0;
|
||||
}
|
||||
// # define QGLCI if (!QOpenGLContext::currentContext()) return; QOpenGLFunctions gf(QOpenGLContext::currentContext());
|
||||
// # define QGLC gf.
|
||||
// inline void glActiveTextureChannel(int channel) {QGLCI gf.glActiveTexture(GL_TEXTURE0 + channel);}
|
||||
// inline void glDisableTextures(int channels = 8) {QGLCI for (int i = channels - 1; i >= 0; --i) {glActiveTextureChannel(i);
|
||||
// glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP);}} inline void glReleaseTextures(int channels = 8) {QGLCI for (int i = channels
|
||||
// - 1; i >= 0; --i) {glActiveTextureChannel(i); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);}} inline void
|
||||
// glReleaseFramebuffer() {QGLCI gf.glBindFramebuffer(GL_FRAMEBUFFER, 0);} inline void glReleaseShaders() {QGLCI gf.glUseProgram(0);} inline
|
||||
// void deleteGLFramebuffer(GLuint & fbo) {QGLCI if (fbo != 0) gf.glDeleteFramebuffers(1, &fbo); fbo = 0;} inline void
|
||||
// deleteGLRenderbuffer(GLuint & drbo) {QGLCI if (drbo != 0) gf.glDeleteRenderbuffers(1, &drbo); drbo = 0;} inline void
|
||||
// deleteGLBuffer(GLuint & bo) {QGLCI if (bo != 0) gf.glDeleteBuffers(1, &bo); bo = 0;} inline void deleteGLVertexArray(GLuint & va) {QGLCI
|
||||
// if (va != 0) gf.glDeleteVertexArrays(1, &va); va = 0;}
|
||||
void createGLTexture(GLuint & tex, int width, int height, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
|
||||
void createGLTexture(GLuint & tex, const QImage & image, const GLenum & format = GL_RGBA8, const GLenum & target = GL_TEXTURE_2D);
|
||||
inline void qglTranslate(const QVector3D & v) {glTranslatef(v.x(), v.y(), v.z());}
|
||||
inline void qglScale(const QVector3D & v) {glScalef(v.x(), v.y(), v.z());}
|
||||
inline void qglTranslate(const QVector3D & v) {
|
||||
glTranslatef(v.x(), v.y(), v.z());
|
||||
}
|
||||
inline void qglScale(const QVector3D & v) {
|
||||
glScalef(v.x(), v.y(), v.z());
|
||||
}
|
||||
QMatrix4x4 glMatrixPerspective(float angle, float aspect, float near_, float far_);
|
||||
QImage rotateQImageLeft(const QImage & im);
|
||||
QImage rotateQImageRight(const QImage & im);
|
||||
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);}
|
||||
//const double deg2rad = atan(1.) / 45.;
|
||||
//const double rad2deg = 45. / atan(1.);
|
||||
inline QImage rotateQImage180(const QImage & im) {
|
||||
return im.mirrored(true, true);
|
||||
}
|
||||
// const double deg2rad = atan(1.) / 45.;
|
||||
// const double rad2deg = 45. / atan(1.);
|
||||
|
||||
struct Box3D {
|
||||
GLfloat x;
|
||||
@@ -194,27 +285,72 @@ struct Box3D {
|
||||
GLfloat angle_z;
|
||||
GLfloat angle_xy;
|
||||
GLfloat angle_roll;
|
||||
Box3D() {x = y = z = width = length = height = angle_z = angle_xy = angle_roll = 0.f;}
|
||||
Box3D(const QVector3D & center, GLfloat hwid, GLfloat hlen, GLfloat hhei) {x = center.x() - hwid; y = center.y() - hlen; z = center.z() - hhei; width = 2 * hwid; length = 2 * hlen; height = 2 * hhei; angle_z = angle_xy = angle_roll = 0.f;}
|
||||
Box3D() { x = y = z = width = length = height = angle_z = angle_xy = angle_roll = 0.f; }
|
||||
Box3D(const QVector3D & center, GLfloat hwid, GLfloat hlen, GLfloat hhei) {
|
||||
x = center.x() - hwid;
|
||||
y = center.y() - hlen;
|
||||
z = center.z() - hhei;
|
||||
width = 2 * hwid;
|
||||
length = 2 * hlen;
|
||||
height = 2 * hhei;
|
||||
angle_z = angle_xy = angle_roll = 0.f;
|
||||
}
|
||||
Box3D(const QVector<QVector3D> & points);
|
||||
bool isEmpty() const {return (qAbs(width) < 1E-6f) || (qAbs(length) < 1E-6f) || (qAbs(height) < 1E-6f);}
|
||||
QVector3D randomPoint() const {return QVector3D(uprand(length) + x, uprand(width) + y, uprand(height) + z);}
|
||||
QVector3D pos() const {return QVector3D(x, y, z);}
|
||||
QVector3D size() const {return QVector3D(length, width, height);}
|
||||
QVector3D center() const {return QVector3D(length / 2.f + x, width / 2.f + y, height / 2.f + z);}
|
||||
QVector3D angles() const {return QVector3D(angle_xy, angle_roll, angle_z);}
|
||||
bool isEmpty() const { return (qAbs(width) < 1E-6f) || (qAbs(length) < 1E-6f) || (qAbs(height) < 1E-6f); }
|
||||
QVector3D randomPoint() const { return QVector3D(uprand(length) + x, uprand(width) + y, uprand(height) + z); }
|
||||
QVector3D pos() const { return QVector3D(x, y, z); }
|
||||
QVector3D size() const { return QVector3D(length, width, height); }
|
||||
QVector3D center() const { return QVector3D(length / 2.f + x, width / 2.f + y, height / 2.f + z); }
|
||||
QVector3D angles() const { return QVector3D(angle_xy, angle_roll, angle_z); }
|
||||
QVector<QVector3D> corners() const;
|
||||
void setPos(const QVector3D & p) {x = p.x(); y = p.y(); z = p.z();}
|
||||
void setAngles(const QVector3D & a) {angle_xy = a.x(); angle_roll = a.y(); angle_z = a.z();}
|
||||
void setSize(const QVector3D & s) {length = s.x(); width = s.y(); height = s.z();}
|
||||
Box3D & moveTo(const QVector3D & v) {x = v.x(); y = v.y(); z = v.z(); return *this;}
|
||||
Box3D & move(const QVector3D & v) {x += v.x(); y += v.y(); z += v.z(); return *this;}
|
||||
Box3D movedTo(const QVector3D & v) const {Box3D t(*this); t.x = v.x(); t.y = v.y(); t.z = v.z(); return t;}
|
||||
Box3D moved(const QVector3D & v) const {Box3D t(*this); t.x += v.x(); t.y += v.y(); t.z += v.z(); return t;}
|
||||
Box3D & operator |=(const Box3D & o);
|
||||
void setPos(const QVector3D & p) {
|
||||
x = p.x();
|
||||
y = p.y();
|
||||
z = p.z();
|
||||
}
|
||||
void setAngles(const QVector3D & a) {
|
||||
angle_xy = a.x();
|
||||
angle_roll = a.y();
|
||||
angle_z = a.z();
|
||||
}
|
||||
void setSize(const QVector3D & s) {
|
||||
length = s.x();
|
||||
width = s.y();
|
||||
height = s.z();
|
||||
}
|
||||
Box3D & moveTo(const QVector3D & v) {
|
||||
x = v.x();
|
||||
y = v.y();
|
||||
z = v.z();
|
||||
return *this;
|
||||
}
|
||||
Box3D & move(const QVector3D & v) {
|
||||
x += v.x();
|
||||
y += v.y();
|
||||
z += v.z();
|
||||
return *this;
|
||||
}
|
||||
Box3D movedTo(const QVector3D & v) const {
|
||||
Box3D t(*this);
|
||||
t.x = v.x();
|
||||
t.y = v.y();
|
||||
t.z = v.z();
|
||||
return t;
|
||||
}
|
||||
Box3D moved(const QVector3D & v) const {
|
||||
Box3D t(*this);
|
||||
t.x += v.x();
|
||||
t.y += v.y();
|
||||
t.z += v.z();
|
||||
return t;
|
||||
}
|
||||
Box3D & operator|=(const Box3D & o);
|
||||
};
|
||||
|
||||
inline QDebug operator <<(QDebug d, const Box3D & v) {d << "Box3D {start (" << v.x << "," << v.y << "," << v.z << "), size (" << v.length << "," << v.width << "," << v.height << ")}"; return d;}
|
||||
inline QDebug operator<<(QDebug d, const Box3D & v) {
|
||||
d << "Box3D {start (" << v.x << "," << v.y << "," << v.z << "), size (" << v.length << "," << v.width << "," << v.height << ")}";
|
||||
return d;
|
||||
}
|
||||
|
||||
struct Vector3d;
|
||||
|
||||
@@ -224,89 +360,196 @@ struct Vector3d {
|
||||
GLfloat x;
|
||||
GLfloat y;
|
||||
GLfloat z;
|
||||
Vector3d(GLfloat x_ = 0., GLfloat y_ = 0., GLfloat z_ = 0.) {x = x_; y = y_; z = z_;}
|
||||
Vector3d(const QVector3D & v) {x = v.x(); y = v.y(); z = v.z();}
|
||||
Vector3d(GLfloat x_ = 0., GLfloat y_ = 0., GLfloat z_ = 0.) {
|
||||
x = x_;
|
||||
y = y_;
|
||||
z = z_;
|
||||
}
|
||||
Vector3d(const QVector3D & v) {
|
||||
x = v.x();
|
||||
y = v.y();
|
||||
z = v.z();
|
||||
}
|
||||
Vector3d(const QString & str);
|
||||
inline void clear() {x = y = z = 0.;}
|
||||
inline GLfloat length() const {return sqrtf(x*x + y*y + z*z);}
|
||||
inline GLfloat lengthSquared() const {return x*x + y*y + z*z;}
|
||||
inline void clear() { x = y = z = 0.; }
|
||||
inline GLfloat length() const { return sqrtf(x * x + y * y + z * z); }
|
||||
inline GLfloat lengthSquared() const { return x * x + y * y + z * z; }
|
||||
Vector3d & normalize() {
|
||||
GLfloat l = length();
|
||||
if (l == 0.f) return *this;
|
||||
x /= l; y /= l; z /= l;
|
||||
x /= l;
|
||||
y /= l;
|
||||
z /= l;
|
||||
return *this;
|
||||
}
|
||||
Vector3d normalized() {return Vector3d(*this).normalize();}
|
||||
Vector3d projectTo(Vector3d dir) {dir.normalize(); return dir * dot(dir, *this);}
|
||||
Vector3d operator *(const GLfloat v) {return Vector3d(x*v, y*v, z*v);}
|
||||
Vector3d operator /(const GLfloat v) {return Vector3d(x/v, y/v, z/v);}
|
||||
Vector3d operator +(const GLfloat v) {return Vector3d(x+v, y+v, z+v);}
|
||||
Vector3d operator -(const GLfloat v) {return Vector3d(x-v, y-v, z-v);}
|
||||
Vector3d operator +(const Vector3d & v) {return Vector3d(x + v.x, y + v.y, z + v.z);}
|
||||
Vector3d operator -(const Vector3d & v) {return Vector3d(x - v.x, y - v.y, z - v.z);}
|
||||
Vector3d operator -() {return Vector3d(-x, -y, -z);}
|
||||
Vector3d & operator *=(const GLfloat & v) {x *= v; y *= v; z *= v; return *this;}
|
||||
Vector3d & operator /=(const GLfloat & v) {x /= v; y /= v; z /= v; return *this;}
|
||||
Vector3d & operator +=(const GLfloat & v) {x += v; y += v; z += v; return *this;}
|
||||
Vector3d & operator -=(const GLfloat & v) {x -= v; y -= v; z -= v; return *this;}
|
||||
Vector3d & operator +=(const Vector3d & v) {x += v.x; y += v.y; z += v.z; return *this;}
|
||||
Vector3d & operator -=(const Vector3d & v) {x -= v.x; y -= v.y; z -= v.z; return *this;}
|
||||
bool operator ==(const Vector3d & v) {return x == v.x && y == v.y && z == v.z;}
|
||||
QVector3D toQVector3D() const {return QVector3D(x, y, z);}
|
||||
Vector3d normalized() { return Vector3d(*this).normalize(); }
|
||||
Vector3d projectTo(Vector3d dir) {
|
||||
dir.normalize();
|
||||
return dir * dot(dir, *this);
|
||||
}
|
||||
Vector3d operator*(const GLfloat v) { return Vector3d(x * v, y * v, z * v); }
|
||||
Vector3d operator/(const GLfloat v) { return Vector3d(x / v, y / v, z / v); }
|
||||
Vector3d operator+(const GLfloat v) { return Vector3d(x + v, y + v, z + v); }
|
||||
Vector3d operator-(const GLfloat v) { return Vector3d(x - v, y - v, z - v); }
|
||||
Vector3d operator+(const Vector3d & v) { return Vector3d(x + v.x, y + v.y, z + v.z); }
|
||||
Vector3d operator-(const Vector3d & v) { return Vector3d(x - v.x, y - v.y, z - v.z); }
|
||||
Vector3d operator-() { return Vector3d(-x, -y, -z); }
|
||||
Vector3d & operator*=(const GLfloat & v) {
|
||||
x *= v;
|
||||
y *= v;
|
||||
z *= v;
|
||||
return *this;
|
||||
}
|
||||
Vector3d & operator/=(const GLfloat & v) {
|
||||
x /= v;
|
||||
y /= v;
|
||||
z /= v;
|
||||
return *this;
|
||||
}
|
||||
Vector3d & operator+=(const GLfloat & v) {
|
||||
x += v;
|
||||
y += v;
|
||||
z += v;
|
||||
return *this;
|
||||
}
|
||||
Vector3d & operator-=(const GLfloat & v) {
|
||||
x -= v;
|
||||
y -= v;
|
||||
z -= v;
|
||||
return *this;
|
||||
}
|
||||
Vector3d & operator+=(const Vector3d & v) {
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
return *this;
|
||||
}
|
||||
Vector3d & operator-=(const Vector3d & v) {
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const Vector3d & v) { return x == v.x && y == v.y && z == v.z; }
|
||||
QVector3D toQVector3D() const { return QVector3D(x, y, z); }
|
||||
};
|
||||
|
||||
inline Vector3d operator *(const Vector3d & v0, const Vector3d & v1) {
|
||||
inline Vector3d operator*(const Vector3d & v0, const Vector3d & v1) {
|
||||
return Vector3d(v0.y * v1.z - v1.y * v0.z, v1.x * v0.z - v0.x * v1.z, v0.x * v1.y - v1.x * v0.y);
|
||||
}
|
||||
inline GLfloat dot(const Vector3d & v0, const Vector3d & v1) {return v0.x*v1.x + v0.y*v1.y + v0.z*v1.z;}
|
||||
inline GLfloat dot(const Vector3d & v0, const Vector3d & v1) {
|
||||
return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
|
||||
}
|
||||
|
||||
struct Vector2d {
|
||||
GLfloat x;
|
||||
GLfloat y;
|
||||
Vector2d(GLfloat x_ = 0., GLfloat y_ = 0.) {x = x_; y = y_;}
|
||||
Vector2d(const Vector3d & v3) {x = v3.x; y = v3.y;}
|
||||
Vector2d operator *(const GLfloat v) {return Vector2d(x*v, y*v);}
|
||||
Vector2d operator /(const GLfloat v) {return Vector2d(x/v, y/v);}
|
||||
Vector2d operator +(const GLfloat v) {return Vector2d(x+v, y+v);}
|
||||
Vector2d operator -(const GLfloat v) {return Vector2d(x-v, y-v);}
|
||||
Vector2d operator +(const Vector3d & v) {return Vector3d(x + v.x, y + v.y);}
|
||||
Vector2d operator -(const Vector3d & v) {return Vector3d(x - v.x, y - v.y);}
|
||||
Vector2d operator +(const Vector2d & v) {return Vector2d(x + v.x, y + v.y);}
|
||||
Vector2d operator -(const Vector2d & v) {return Vector2d(x - v.x, y - v.y);}
|
||||
Vector2d & operator *=(const GLfloat & v) {x *= v; y *= v; return *this;}
|
||||
Vector2d & operator /=(const GLfloat & v) {x /= v; y /= v; return *this;}
|
||||
Vector2d & operator +=(const GLfloat & v) {x += v; y += v; return *this;}
|
||||
Vector2d & operator -=(const GLfloat & v) {x -= v; y -= v; return *this;}
|
||||
Vector2d & operator +=(const Vector3d & v) {x += v.x; y += v.y;; return *this;}
|
||||
Vector2d & operator -=(const Vector3d & v) {x -= v.x; y -= v.y;; return *this;}
|
||||
Vector2d(GLfloat x_ = 0., GLfloat y_ = 0.) {
|
||||
x = x_;
|
||||
y = y_;
|
||||
}
|
||||
Vector2d(const Vector3d & v3) {
|
||||
x = v3.x;
|
||||
y = v3.y;
|
||||
}
|
||||
Vector2d operator*(const GLfloat v) { return Vector2d(x * v, y * v); }
|
||||
Vector2d operator/(const GLfloat v) { return Vector2d(x / v, y / v); }
|
||||
Vector2d operator+(const GLfloat v) { return Vector2d(x + v, y + v); }
|
||||
Vector2d operator-(const GLfloat v) { return Vector2d(x - v, y - v); }
|
||||
Vector2d operator+(const Vector3d & v) { return Vector3d(x + v.x, y + v.y); }
|
||||
Vector2d operator-(const Vector3d & v) { return Vector3d(x - v.x, y - v.y); }
|
||||
Vector2d operator+(const Vector2d & v) { return Vector2d(x + v.x, y + v.y); }
|
||||
Vector2d operator-(const Vector2d & v) { return Vector2d(x - v.x, y - v.y); }
|
||||
Vector2d & operator*=(const GLfloat & v) {
|
||||
x *= v;
|
||||
y *= v;
|
||||
return *this;
|
||||
}
|
||||
Vector2d & operator/=(const GLfloat & v) {
|
||||
x /= v;
|
||||
y /= v;
|
||||
return *this;
|
||||
}
|
||||
Vector2d & operator+=(const GLfloat & v) {
|
||||
x += v;
|
||||
y += v;
|
||||
return *this;
|
||||
}
|
||||
Vector2d & operator-=(const GLfloat & v) {
|
||||
x -= v;
|
||||
y -= v;
|
||||
return *this;
|
||||
}
|
||||
Vector2d & operator+=(const Vector3d & v) {
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
;
|
||||
return *this;
|
||||
}
|
||||
Vector2d & operator-=(const Vector3d & v) {
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct Vector3i {
|
||||
Vector3i(int p0_ = 0, int p1_ = 0, int p2_ = 0) {p0 = p0_; p1 = p1_; p2 = p2_;}
|
||||
Vector3i(int p0_ = 0, int p1_ = 0, int p2_ = 0) {
|
||||
p0 = p0_;
|
||||
p1 = p1_;
|
||||
p2 = p2_;
|
||||
}
|
||||
Vector3i(const QString & str);
|
||||
Vector3i movedX(const int & o) {return Vector3i(p0 + o, p1, p2);}
|
||||
Vector3i movedY(const int & o) {return Vector3i(p0, p1 + o, p2);}
|
||||
Vector3i movedZ(const int & o) {return Vector3i(p0, p1, p2 + o);}
|
||||
Vector3i moved(const int & x, const int & y, const int & z) {return Vector3i(p0 + x, p1 + y, p2 + z);}
|
||||
Vector3i movedX(const int & o) { return Vector3i(p0 + o, p1, p2); }
|
||||
Vector3i movedY(const int & o) { return Vector3i(p0, p1 + o, p2); }
|
||||
Vector3i movedZ(const int & o) { return Vector3i(p0, p1, p2 + o); }
|
||||
Vector3i moved(const int & x, const int & y, const int & z) { return Vector3i(p0 + x, p1 + y, p2 + z); }
|
||||
int p0;
|
||||
int p1;
|
||||
int p2;
|
||||
bool operator ==(const Vector3i & o) const {return p0 == o.p0 && p1 == o.p1 && p2 == o.p2;}
|
||||
bool operator !=(const Vector3i & o) const {return p0 != o.p0 || p1 != o.p1 || p2 != o.p2;}
|
||||
QVector3D toQVector3D() const {return QVector3D(p0, p1, p2);}
|
||||
bool operator==(const Vector3i & o) const { return p0 == o.p0 && p1 == o.p1 && p2 == o.p2; }
|
||||
bool operator!=(const Vector3i & o) const { return p0 != o.p0 || p1 != o.p1 || p2 != o.p2; }
|
||||
QVector3D toQVector3D() const { return QVector3D(p0, p1, p2); }
|
||||
};
|
||||
|
||||
inline Vector3i operator +(const Vector3i & f, const Vector3i & s) {return Vector3i(f.p0 + s.p0, f.p1 + s.p1, f.p2 + s.p2);}
|
||||
inline Vector3i operator -(const Vector3i & f, const Vector3i & s) {return Vector3i(f.p0 - s.p0, f.p1 - s.p1, f.p2 - s.p2);}
|
||||
inline Vector3i operator /(const Vector3i & f, const int & s) {return Vector3i(f.p0 / s, f.p1 / s, f.p2 / s);}
|
||||
inline uint qHash(const Vector3i & v) {return v.p0 + v.p1 * 1024 + v.p2 * 1024 * 1024;}
|
||||
inline QDebug operator <<(QDebug d, const Vector3d& v) {d.nospace() << "{" << v.x << ", " << v.y << ", " << v.z << "}"; return d.space();}
|
||||
inline QDebug operator <<(QDebug d, const Vector3i & v) {d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}"; return d.space();}
|
||||
inline Vector3i operator+(const Vector3i & f, const Vector3i & s) {
|
||||
return Vector3i(f.p0 + s.p0, f.p1 + s.p1, f.p2 + s.p2);
|
||||
}
|
||||
inline Vector3i operator-(const Vector3i & f, const Vector3i & s) {
|
||||
return Vector3i(f.p0 - s.p0, f.p1 - s.p1, f.p2 - s.p2);
|
||||
}
|
||||
inline Vector3i operator/(const Vector3i & f, const int & s) {
|
||||
return Vector3i(f.p0 / s, f.p1 / s, f.p2 / s);
|
||||
}
|
||||
inline uint qHash(const Vector3i & v) {
|
||||
return v.p0 + v.p1 * 1024 + v.p2 * 1024 * 1024;
|
||||
}
|
||||
inline QDebug operator<<(QDebug d, const Vector3d & v) {
|
||||
d.nospace() << "{" << v.x << ", " << v.y << ", " << v.z << "}";
|
||||
return d.space();
|
||||
}
|
||||
inline QDebug operator<<(QDebug d, const Vector3i & v) {
|
||||
d.nospace() << "{" << v.p0 << ", " << v.p1 << ", " << v.p2 << "}";
|
||||
return d.space();
|
||||
}
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const 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, Vector3i & v) {s >> v.p0 >> v.p1 >> v.p2; 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, Vector3i & v) {
|
||||
s >> v.p0 >> v.p1 >> v.p2;
|
||||
return s;
|
||||
}
|
||||
|
||||
QColor colorFromString(const QString & str);
|
||||
inline float cosABV(const QVector3D & v0, const QVector3D & v1) {
|
||||
@@ -314,14 +557,23 @@ inline float cosABV(const QVector3D & v0, const QVector3D & v1) {
|
||||
if (l == 0.f) return 0.;
|
||||
return (QVector3D::dotProduct(v0, v1)) / l;
|
||||
}
|
||||
inline QVector3D projection(const QVector3D & v, const QVector3D & to) {return to.normalized() * v.length() * cosABV(v, to);}
|
||||
inline QVector3D projection(const QVector3D & v, const QVector3D & to) {
|
||||
return to.normalized() * v.length() * cosABV(v, to);
|
||||
}
|
||||
QVector3D orthToVector(const QVector3D & v, const float & scale = 1.);
|
||||
QVector3D rotateVector(const QVector3D & v, const QVector3D & a);
|
||||
void setVectorLength(QVector3D & v, const float & l);
|
||||
void lengthenVector(QVector3D & v, const float & l);
|
||||
inline float squareLength(const QVector3D & from, const QVector3D & to) {return (to.x() - from.x())*(to.x() - from.x()) + (to.y() - from.y())*(to.y() - from.y()) + (to.z() - from.z())*(to.z() - from.z());}
|
||||
inline QVector3D directionFromAngles(const QVector3D & a) {return rotateVector(QVector3D(1., 0., 0.), a);}
|
||||
inline float frac(const float & x, const float & b) {return x - int(x / b) * b;}
|
||||
inline float squareLength(const QVector3D & from, const QVector3D & to) {
|
||||
return (to.x() - from.x()) * (to.x() - from.x()) + (to.y() - from.y()) * (to.y() - from.y()) +
|
||||
(to.z() - from.z()) * (to.z() - from.z());
|
||||
}
|
||||
inline QVector3D directionFromAngles(const QVector3D & a) {
|
||||
return rotateVector(QVector3D(1., 0., 0.), a);
|
||||
}
|
||||
inline float frac(const float & x, const float & b) {
|
||||
return x - int(x / b) * b;
|
||||
}
|
||||
|
||||
class GLObjectBase;
|
||||
class QGLView;
|
||||
@@ -329,9 +581,9 @@ class Light;
|
||||
class Camera;
|
||||
class GLTextureManagerBase;
|
||||
|
||||
class QGLViewBase
|
||||
{
|
||||
class QGLViewBase {
|
||||
friend class GLObjectBase;
|
||||
|
||||
public:
|
||||
QGLViewBase();
|
||||
virtual ~QGLViewBase();
|
||||
@@ -339,6 +591,7 @@ public:
|
||||
const Camera * camera() const;
|
||||
void setCamera(Camera * camera);
|
||||
GLTextureManagerBase * textureManager();
|
||||
|
||||
protected:
|
||||
virtual void collectLights() = 0;
|
||||
Camera * camera_;
|
||||
|
||||
@@ -21,21 +21,21 @@
|
||||
|
||||
GLVBO::GLVBO(GLenum usage_) {
|
||||
buffer_ = 0;
|
||||
va_ = 0;
|
||||
usage = usage_;
|
||||
va_ = 0;
|
||||
usage = usage_;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
GLVBO::~GLVBO() {
|
||||
//destroy();
|
||||
// destroy();
|
||||
}
|
||||
|
||||
|
||||
void GLVBO::init() {
|
||||
initializeOpenGLFunctions();
|
||||
if (!isInit()) {
|
||||
//glGenVertexArrays(1, &va_);
|
||||
// glGenVertexArrays(1, &va_);
|
||||
glGenBuffers(1, &buffer_);
|
||||
}
|
||||
changed = true;
|
||||
@@ -45,8 +45,8 @@ void GLVBO::init() {
|
||||
void GLVBO::destroy() {
|
||||
if (buffer_ != 0) glDeleteFramebuffers(1, &buffer_);
|
||||
buffer_ = 0;
|
||||
// if (va_ != 0) glDeleteVertexArrays(1, &va_);
|
||||
// va_ = 0;
|
||||
// if (va_ != 0) glDeleteVertexArrays(1, &va_);
|
||||
// va_ = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,9 +57,9 @@ void GLVBO::calculateBinormals() {
|
||||
int vcnt = vertices_.size() / 3;
|
||||
if (texcoords_.size() != vcnt * 2) return;
|
||||
int tcnt = vcnt / 3;
|
||||
//qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "...";
|
||||
// qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "...";
|
||||
for (int t = 0; t < tcnt; ++t) {
|
||||
int vi = t*9, ti = t*6;
|
||||
int vi = t * 9, ti = t * 6;
|
||||
Vector3d v0(vertices_[vi + 0], vertices_[vi + 1], vertices_[vi + 2]);
|
||||
Vector3d v1(vertices_[vi + 3], vertices_[vi + 4], vertices_[vi + 5]);
|
||||
Vector3d v2(vertices_[vi + 6], vertices_[vi + 7], vertices_[vi + 8]);
|
||||
@@ -70,49 +70,53 @@ void GLVBO::calculateBinormals() {
|
||||
Vector2d dt1 = t1 - t0, dt2 = t2 - t0;
|
||||
Vector3d tan;
|
||||
Vector3d bitan;
|
||||
tan = (dv1 * dt2.y - dv2 * dt1.y).normalize();
|
||||
tan = (dv1 * dt2.y - dv2 * dt1.y).normalize();
|
||||
bitan = (dv2 * dt1.x - dv1 * dt2.x).normalize();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
tangents_ << tan.x << tan.y << tan.z;
|
||||
bitangents_ << bitan.x << bitan.y << bitan.z;
|
||||
}
|
||||
//qDebug() << " t" << t << vi << ti << dv1.toQVector3D() << "...";
|
||||
// qDebug() << " t" << t << vi << ti << dv1.toQVector3D() << "...";
|
||||
}
|
||||
//qDebug() << "calculateBinormals" << vcnt << tcnt << tangents_.size();
|
||||
// qDebug() << "calculateBinormals" << vcnt << tcnt << tangents_.size();
|
||||
}
|
||||
|
||||
|
||||
bool GLVBO::rebuffer(bool clear_) {
|
||||
initializeOpenGLFunctions();
|
||||
QVector<GLfloat> data;
|
||||
//data.clear();
|
||||
// data.clear();
|
||||
calculateBinormals();
|
||||
data << vertices_;
|
||||
if (!normals_.isEmpty()) {
|
||||
data << normals_;
|
||||
has_normals = true;
|
||||
} else has_normals = false;
|
||||
} else
|
||||
has_normals = false;
|
||||
if (!texcoords_.isEmpty()) {
|
||||
data << texcoords_;
|
||||
has_texcoords = true;
|
||||
} else has_texcoords = false;
|
||||
} else
|
||||
has_texcoords = false;
|
||||
if (!colors_.isEmpty()) {
|
||||
data << colors_;
|
||||
has_colors = true;
|
||||
} else has_colors = false;
|
||||
} else
|
||||
has_colors = false;
|
||||
if (!tangents_.isEmpty()) {
|
||||
data << tangents_ << bitangents_;
|
||||
has_binormals = true;
|
||||
} else has_binormals = false;
|
||||
//glBindVertexArray(va_);
|
||||
//qDebug() << "load buffer" << data.size() << buffer_;
|
||||
} else
|
||||
has_binormals = false;
|
||||
// glBindVertexArray(va_);
|
||||
// qDebug() << "load buffer" << data.size() << buffer_;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer_);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.constData(), usage);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
//glBindVertexArray(0);
|
||||
// glBindVertexArray(0);
|
||||
vert_count = vertices_.size() / 3;
|
||||
changed = false;
|
||||
//qDebug() << "rebuff" << buffer_ << vert_count;
|
||||
changed = false;
|
||||
// qDebug() << "rebuff" << buffer_ << vert_count;
|
||||
if (clear_) clear();
|
||||
return !isEmpty();
|
||||
}
|
||||
@@ -121,26 +125,26 @@ bool GLVBO::rebuffer(bool clear_) {
|
||||
void GLVBO::draw(GLenum type, QOpenGLShaderProgram * prog, bool simplest) {
|
||||
if (buffer_ == 0 || vert_count == 0) return;
|
||||
if (changed) rebuffer();
|
||||
//qDebug() << "draw" << vert_count;
|
||||
void * offset = (void*)(vert_count * 3 * sizeof(GLfloat));
|
||||
//glBindVertexArray(va_);
|
||||
// qDebug() << "draw" << vert_count;
|
||||
void * offset = (void *)(vert_count * 3 * sizeof(GLfloat));
|
||||
// glBindVertexArray(va_);
|
||||
void * offsets[5] = {0, 0, 0, 0, 0};
|
||||
if (!simplest) {
|
||||
if (has_normals) {
|
||||
offsets[0] = offset;
|
||||
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
||||
offset = (void *)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
||||
}
|
||||
if (has_texcoords) {
|
||||
offsets[1] = offset;
|
||||
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
|
||||
offset = (void *)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
|
||||
}
|
||||
if (has_colors) {
|
||||
offsets[2] = offset;
|
||||
offset = (void*)(llong(offset) + vert_count * 4 * sizeof(GLfloat));
|
||||
offset = (void *)(llong(offset) + vert_count * 4 * sizeof(GLfloat));
|
||||
}
|
||||
if (has_binormals) {
|
||||
offsets[3] = offset;
|
||||
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
||||
offset = (void *)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
|
||||
offsets[4] = offset;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +182,7 @@ void GLVBO::draw(GLenum type, QOpenGLShaderProgram * prog, bool simplest) {
|
||||
locs << loc;
|
||||
} else
|
||||
glDisableVertexAttribArray(loc);
|
||||
loc = prog->attributeLocation("qgl_Tangent");
|
||||
loc = prog->attributeLocation("qgl_Tangent");
|
||||
int loc2 = prog->attributeLocation("qgl_Bitangent");
|
||||
if (has_binormals) {
|
||||
glEnableVertexAttribArray(loc);
|
||||
@@ -198,22 +202,25 @@ void GLVBO::draw(GLenum type, QOpenGLShaderProgram * prog, bool simplest) {
|
||||
if (has_normals) {
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, 0, offsets[0]);
|
||||
} else glDisableClientState(GL_NORMAL_ARRAY);
|
||||
} else
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
if (has_texcoords) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, offsets[1]);
|
||||
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
} else
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
if (has_colors) {
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glColorPointer(4, GL_FLOAT, 0, offsets[2]);
|
||||
} else glDisableClientState(GL_COLOR_ARRAY);
|
||||
} else
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
//qDebug() << "draw" << vert_count << buffer_ << offsets[0] << offsets[1] << offsets[3];
|
||||
// qDebug() << "draw" << vert_count << buffer_ << offsets[0] << offsets[1] << offsets[3];
|
||||
glDrawArrays(type, 0, vert_count);
|
||||
//qDebug() << "draw" << vert_count << buffer_ << "done";
|
||||
// qDebug() << "draw" << vert_count << buffer_ << "done";
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
foreach (int l, locs)
|
||||
foreach(int l, locs)
|
||||
glDisableVertexAttribArray(l);
|
||||
}
|
||||
|
||||
@@ -290,7 +297,7 @@ bool GLVBO::loadFromFile(const QString & filename) {
|
||||
Box3D GLVBO::boundingBox() const {
|
||||
if (vertices_.size() < 3) return Box3D();
|
||||
int vcnt = vertices_.size() / 3;
|
||||
//qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "...";
|
||||
// qDebug() << "calculateBinormals" << vcnt << tcnt << vertices_.size() << texcoords_.size() << "...";
|
||||
GLfloat mix, miy, miz, max, may, maz;
|
||||
Vector3d v0(vertices_[0], vertices_[1], vertices_[2]);
|
||||
mix = max = v0.x;
|
||||
@@ -298,7 +305,7 @@ Box3D GLVBO::boundingBox() const {
|
||||
miz = maz = v0.z;
|
||||
Box3D bound;
|
||||
for (int t = 1; t < vcnt; ++t) {
|
||||
int vi = t*3;
|
||||
int vi = t * 3;
|
||||
Vector3d v(vertices_[vi + 0], vertices_[vi + 1], vertices_[vi + 2]);
|
||||
if (mix > v.x) mix = v.x;
|
||||
if (max < v.x) max = v.x;
|
||||
@@ -307,9 +314,9 @@ Box3D GLVBO::boundingBox() const {
|
||||
if (miz > v.z) miz = v.z;
|
||||
if (maz < v.z) maz = v.z;
|
||||
}
|
||||
bound.x = mix;
|
||||
bound.y = miy;
|
||||
bound.z = miz;
|
||||
bound.x = mix;
|
||||
bound.y = miy;
|
||||
bound.z = miz;
|
||||
bound.length = max - mix;
|
||||
bound.width = may - miy;
|
||||
bound.height = maz - miz;
|
||||
|
||||
@@ -19,19 +19,19 @@
|
||||
#ifndef GLVBO_H
|
||||
#define GLVBO_H
|
||||
|
||||
#include "gltypes.h"
|
||||
#include "chunkstream.h"
|
||||
#include "gltypes.h"
|
||||
|
||||
class GLVBO : protected QOpenGLFunctions
|
||||
{
|
||||
class GLVBO: protected QOpenGLFunctions {
|
||||
friend class GLObjectBase;
|
||||
friend QDataStream & operator <<(QDataStream & s, const GLVBO & m);
|
||||
friend QDataStream & operator >>(QDataStream & s, GLVBO & m);
|
||||
friend QDataStream & operator<<(QDataStream & s, const GLVBO & m);
|
||||
friend QDataStream & operator>>(QDataStream & s, GLVBO & m);
|
||||
|
||||
public:
|
||||
GLVBO(GLenum usage = GL_DYNAMIC_DRAW);
|
||||
~GLVBO();
|
||||
|
||||
//GLVBO & operator =(const GLVBO & o) {return *this;}
|
||||
// GLVBO & operator =(const GLVBO & o) {return *this;}
|
||||
|
||||
void init();
|
||||
void destroy();
|
||||
@@ -39,15 +39,27 @@ public:
|
||||
void draw(GLenum type, QOpenGLShaderProgram * prog, bool simplest = false);
|
||||
void clear();
|
||||
|
||||
GLuint buffer() const {return buffer_;}
|
||||
int verticesCount() const {return vertices_.size() / 3;}
|
||||
bool isInit() const {return buffer_ != 0;}
|
||||
bool isEmpty() const {return vertices_.size() < 3;}
|
||||
GLuint buffer() const { return buffer_; }
|
||||
int verticesCount() const { return vertices_.size() / 3; }
|
||||
bool isInit() const { return buffer_ != 0; }
|
||||
bool isEmpty() const { return vertices_.size() < 3; }
|
||||
|
||||
QVector<GLfloat> & vertices() {changed = true; return vertices_;}
|
||||
QVector<GLfloat> & normals() {changed = true; return normals_;}
|
||||
QVector<GLfloat> & texcoords() {changed = true; return texcoords_;}
|
||||
QVector<GLfloat> & colors() {changed = true; return colors_;}
|
||||
QVector<GLfloat> & vertices() {
|
||||
changed = true;
|
||||
return vertices_;
|
||||
}
|
||||
QVector<GLfloat> & normals() {
|
||||
changed = true;
|
||||
return normals_;
|
||||
}
|
||||
QVector<GLfloat> & texcoords() {
|
||||
changed = true;
|
||||
return texcoords_;
|
||||
}
|
||||
QVector<GLfloat> & colors() {
|
||||
changed = true;
|
||||
return colors_;
|
||||
}
|
||||
|
||||
void translatePoints(const QVector3D & dp);
|
||||
void scalePoints(const QVector3D & dp);
|
||||
@@ -66,29 +78,30 @@ private:
|
||||
GLuint buffer_, va_;
|
||||
int vert_count;
|
||||
bool changed, has_normals, has_texcoords, has_colors, has_binormals;
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const GLVBO & m) {
|
||||
inline QDataStream & operator<<(QDataStream & s, const GLVBO & m) {
|
||||
ChunkStream cs;
|
||||
//qDebug() << "place VBO" << m.vertices_.size() << m.normals_.size() << m.texcoords_.size() << m.colors_.size() << "...";
|
||||
cs << cs.chunk(1, m.vertices_) << cs.chunk(2, m.normals_) << cs.chunk(3, m.texcoords_) << cs.chunk(4, m.colors_) << cs.chunk(5, m.usage);
|
||||
//qDebug() << "place VBO done" << cs.data().size() << "...";
|
||||
s << qCompress(cs.data()); return s;
|
||||
// qDebug() << "place VBO" << m.vertices_.size() << m.normals_.size() << m.texcoords_.size() << m.colors_.size() << "...";
|
||||
cs << cs.chunk(1, m.vertices_) << cs.chunk(2, m.normals_) << cs.chunk(3, m.texcoords_) << cs.chunk(4, m.colors_)
|
||||
<< cs.chunk(5, m.usage);
|
||||
// qDebug() << "place VBO done" << cs.data().size() << "...";
|
||||
s << qCompress(cs.data());
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator >>(QDataStream & s, GLVBO & m) {
|
||||
inline QDataStream & operator>>(QDataStream & s, GLVBO & m) {
|
||||
QByteArray ba;
|
||||
s >> ba;
|
||||
ba = qUncompress(ba);
|
||||
ChunkStream cs(ba);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: m.vertices_ = cs.getData<QVector<GLfloat> >(); break;
|
||||
case 2: m.normals_ = cs.getData<QVector<GLfloat> >(); break;
|
||||
case 3: m.texcoords_ = cs.getData<QVector<GLfloat> >(); break;
|
||||
case 4: m.colors_ = cs.getData<QVector<GLfloat> >(); break;
|
||||
case 5: m.usage = cs.getData<GLenum>(); break;
|
||||
case 1: m.vertices_ = cs.getData<QVector<GLfloat>>(); break;
|
||||
case 2: m.normals_ = cs.getData<QVector<GLfloat>>(); break;
|
||||
case 3: m.texcoords_ = cs.getData<QVector<GLfloat>>(); break;
|
||||
case 4: m.colors_ = cs.getData<QVector<GLfloat>>(); break;
|
||||
case 5: m.usage = cs.getData<GLenum>(); break;
|
||||
}
|
||||
}
|
||||
m.changed = true;
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#include "glwidget.h"
|
||||
#include "renderer_simple.h"
|
||||
|
||||
#include "renderer_deferred_shading.h"
|
||||
#include "renderer_simple.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
||||
GLWidget::GLWidget(QWidget *parent) : QWidget(parent) {
|
||||
GLWidget::GLWidget(QWidget * parent): QWidget(parent) {
|
||||
view_ = new QGLView();
|
||||
view_->setFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||
container = QWidget::createWindowContainer(view_, this);
|
||||
lay = new QVBoxLayout(this);
|
||||
lay = new QVBoxLayout(this);
|
||||
lay->addWidget(container);
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
lay->setSpacing(0);
|
||||
@@ -68,8 +70,7 @@ bool GLWidget::isMouseSelectionEnabled() const {
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isCameraOrbit() const
|
||||
{
|
||||
bool GLWidget::isCameraOrbit() const {
|
||||
return view_->isCameraOrbit();
|
||||
}
|
||||
|
||||
@@ -105,7 +106,7 @@ qreal GLWidget::selectionHaloFillAlpha() const {
|
||||
|
||||
|
||||
void GLWidget::addObject(GLObjectBase * o) {
|
||||
view_->addObject(o);
|
||||
view_->addObject(o);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +115,7 @@ QByteArray GLWidget::saveCamera() {
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::restoreCamera(const QByteArray &ba) {
|
||||
void GLWidget::restoreCamera(const QByteArray & ba) {
|
||||
view_->restoreCamera(ba);
|
||||
}
|
||||
|
||||
@@ -219,18 +220,18 @@ void GLWidget::setSelectionHaloFillAlpha(const qreal & arg) {
|
||||
|
||||
|
||||
void GLWidget::viewDoubleClicked() {
|
||||
// qDebug() << "click widget!!";
|
||||
// qDebug() << "click widget!!";
|
||||
if (view_->windowState() == Qt::WindowFullScreen) {
|
||||
// view_->hide();
|
||||
// view_->hide();
|
||||
container = QWidget::createWindowContainer(view_, this);
|
||||
lay->addWidget(container);
|
||||
container->show();
|
||||
// show();
|
||||
// show();
|
||||
} else {
|
||||
// hide();
|
||||
// hide();
|
||||
view_->setParent(nullptr);
|
||||
view_->showFullScreen();
|
||||
lay->removeWidget(container);
|
||||
}
|
||||
// qDebug() << "click widge done!";
|
||||
// qDebug() << "click widge done!";
|
||||
}
|
||||
|
||||
@@ -8,28 +8,28 @@ class QGLView;
|
||||
class GLRendererBase;
|
||||
class GLObjectBase;
|
||||
|
||||
class GLWidget : public QWidget
|
||||
{
|
||||
class GLWidget: public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor)
|
||||
Q_PROPERTY (qreal lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY (qreal FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY (qreal depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY (qreal depthEnd READ depthEnd WRITE setDepthEnd)
|
||||
Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor)
|
||||
Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY (qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY (qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
Q_PROPERTY(QColor backColor READ backColor WRITE setBackColor)
|
||||
Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY(qreal FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY(qreal depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY(qreal depthEnd READ depthEnd WRITE setDepthEnd)
|
||||
Q_PROPERTY(QColor ambientColor READ ambientColor WRITE setAmbientColor)
|
||||
Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY(bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY(bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY(bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY(bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY(QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY(qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY(bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY(QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY(qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
|
||||
public:
|
||||
explicit GLWidget(QWidget *parent = nullptr);
|
||||
QGLView * view() {return view_;}
|
||||
explicit GLWidget(QWidget * parent = nullptr);
|
||||
QGLView * view() { return view_; }
|
||||
|
||||
QColor backColor() const;
|
||||
qreal lineWidth() const;
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
qreal selectionHaloFillAlpha() const;
|
||||
|
||||
void addObject(GLObjectBase * o);
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
|
||||
public slots:
|
||||
void stop();
|
||||
|
||||
@@ -20,21 +20,21 @@
|
||||
|
||||
|
||||
void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
|
||||
QVector<GLfloat> & vertices(o->VBO().vertices()), & normals(o->VBO().normals()), & uvs(o->VBO().texcoords());
|
||||
QVector<Vector3d> & points(o->points), & puvws(o->puvws), fnormals;
|
||||
QVector<GLfloat> &vertices(o->VBO().vertices()), &normals(o->VBO().normals()), &uvs(o->VBO().texcoords());
|
||||
QVector<Vector3d> &points(o->points), &puvws(o->puvws), fnormals;
|
||||
QVector<Vector3i> & faces(o->faces);
|
||||
Vector3d pos = Vector3d(o->pos());
|
||||
bool has_uv = !puvws.isEmpty();
|
||||
bool has_uv = !puvws.isEmpty();
|
||||
Vector3i cf;
|
||||
Vector3d v0, v1, v2, cn0, cn1, cn2;
|
||||
fnormals.resize(faces.size());
|
||||
for (int i = 0; i < points.size(); ++i)
|
||||
points[i] -= pos;
|
||||
for (int i = 0; i < fnormals.size(); ++i) {
|
||||
cf = faces[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
cf = faces[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
fnormals[i] = ((v1 - v0) * (v2 - v0)).normalized();
|
||||
}
|
||||
int fcnt = faces.size() * 3;
|
||||
@@ -43,56 +43,80 @@ void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
|
||||
if (has_uv) uvs.resize(fcnt * 2);
|
||||
int ind = 0, induv = 0, ncnt0, ncnt1, ncnt2;
|
||||
uint csg;
|
||||
//qDebug() << faces.size();
|
||||
// qDebug() << faces.size();
|
||||
if (smooth.isEmpty()) {
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
cf = faces[i];
|
||||
cn0 = fnormals[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
vertices[ind] = v0.x; normals[ind] = cn0.x; ++ind;
|
||||
vertices[ind] = v0.y; normals[ind] = cn0.y; ++ind;
|
||||
vertices[ind] = v0.z; normals[ind] = cn0.z; ++ind;
|
||||
vertices[ind] = v1.x; normals[ind] = cn0.x; ++ind;
|
||||
vertices[ind] = v1.y; normals[ind] = cn0.y; ++ind;
|
||||
vertices[ind] = v1.z; normals[ind] = cn0.z; ++ind;
|
||||
vertices[ind] = v2.x; normals[ind] = cn0.x; ++ind;
|
||||
vertices[ind] = v2.y; normals[ind] = cn0.y; ++ind;
|
||||
vertices[ind] = v2.z; normals[ind] = cn0.z; ++ind;
|
||||
cf = faces[i];
|
||||
cn0 = fnormals[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
vertices[ind] = v0.x;
|
||||
normals[ind] = cn0.x;
|
||||
++ind;
|
||||
vertices[ind] = v0.y;
|
||||
normals[ind] = cn0.y;
|
||||
++ind;
|
||||
vertices[ind] = v0.z;
|
||||
normals[ind] = cn0.z;
|
||||
++ind;
|
||||
vertices[ind] = v1.x;
|
||||
normals[ind] = cn0.x;
|
||||
++ind;
|
||||
vertices[ind] = v1.y;
|
||||
normals[ind] = cn0.y;
|
||||
++ind;
|
||||
vertices[ind] = v1.z;
|
||||
normals[ind] = cn0.z;
|
||||
++ind;
|
||||
vertices[ind] = v2.x;
|
||||
normals[ind] = cn0.x;
|
||||
++ind;
|
||||
vertices[ind] = v2.y;
|
||||
normals[ind] = cn0.y;
|
||||
++ind;
|
||||
vertices[ind] = v2.z;
|
||||
normals[ind] = cn0.z;
|
||||
++ind;
|
||||
if (has_uv) {
|
||||
uvs[induv] = puvws[cf.p0].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p0].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p1].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p1].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p2].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p2].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p0].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p0].y;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p1].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p1].y;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p2].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p2].y;
|
||||
++induv;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
cf = faces[i];
|
||||
cf = faces[i];
|
||||
csg = smooth[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
|
||||
cn0 = cn1 = cn2 = fnormals[i];
|
||||
ncnt0 = ncnt1 = ncnt2 = 1;
|
||||
for (int j = 0; j < faces.size(); ++j) {
|
||||
if (csg != smooth[j] || j == i) continue;
|
||||
if (faces[j].p0 == cf.p0 || faces[j].p1 == cf.p0 || faces[j].p2 == cf.p0 ||
|
||||
points[faces[j].p0] == v0 || points[faces[j].p1] == v0 || points[faces[j].p2] == v0) {
|
||||
if (faces[j].p0 == cf.p0 || faces[j].p1 == cf.p0 || faces[j].p2 == cf.p0 || points[faces[j].p0] == v0 ||
|
||||
points[faces[j].p1] == v0 || points[faces[j].p2] == v0) {
|
||||
cn0 += fnormals[j];
|
||||
++ncnt0;
|
||||
}
|
||||
if (faces[j].p0 == cf.p1 || faces[j].p1 == cf.p1 || faces[j].p2 == cf.p1 ||
|
||||
points[faces[j].p0] == v1 || points[faces[j].p1] == v1 || points[faces[j].p2] == v1) {
|
||||
if (faces[j].p0 == cf.p1 || faces[j].p1 == cf.p1 || faces[j].p2 == cf.p1 || points[faces[j].p0] == v1 ||
|
||||
points[faces[j].p1] == v1 || points[faces[j].p2] == v1) {
|
||||
cn1 += fnormals[j];
|
||||
++ncnt1;
|
||||
}
|
||||
if (faces[j].p0 == cf.p2 || faces[j].p1 == cf.p2 || faces[j].p2 == cf.p2 ||
|
||||
points[faces[j].p0] == v2 || points[faces[j].p1] == v2 || points[faces[j].p2] == v2) {
|
||||
if (faces[j].p0 == cf.p2 || faces[j].p1 == cf.p2 || faces[j].p2 == cf.p2 || points[faces[j].p0] == v2 ||
|
||||
points[faces[j].p1] == v2 || points[faces[j].p2] == v2) {
|
||||
cn2 += fnormals[j];
|
||||
++ncnt2;
|
||||
}
|
||||
@@ -100,22 +124,46 @@ void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
|
||||
cn0 /= ncnt0;
|
||||
cn1 /= ncnt1;
|
||||
cn2 /= ncnt2;
|
||||
vertices[ind] = v0.x; normals[ind] = cn0.x; ++ind;
|
||||
vertices[ind] = v0.y; normals[ind] = cn0.y; ++ind;
|
||||
vertices[ind] = v0.z; normals[ind] = cn0.z; ++ind;
|
||||
vertices[ind] = v1.x; normals[ind] = cn1.x; ++ind;
|
||||
vertices[ind] = v1.y; normals[ind] = cn1.y; ++ind;
|
||||
vertices[ind] = v1.z; normals[ind] = cn1.z; ++ind;
|
||||
vertices[ind] = v2.x; normals[ind] = cn2.x; ++ind;
|
||||
vertices[ind] = v2.y; normals[ind] = cn2.y; ++ind;
|
||||
vertices[ind] = v2.z; normals[ind] = cn2.z; ++ind;
|
||||
vertices[ind] = v0.x;
|
||||
normals[ind] = cn0.x;
|
||||
++ind;
|
||||
vertices[ind] = v0.y;
|
||||
normals[ind] = cn0.y;
|
||||
++ind;
|
||||
vertices[ind] = v0.z;
|
||||
normals[ind] = cn0.z;
|
||||
++ind;
|
||||
vertices[ind] = v1.x;
|
||||
normals[ind] = cn1.x;
|
||||
++ind;
|
||||
vertices[ind] = v1.y;
|
||||
normals[ind] = cn1.y;
|
||||
++ind;
|
||||
vertices[ind] = v1.z;
|
||||
normals[ind] = cn1.z;
|
||||
++ind;
|
||||
vertices[ind] = v2.x;
|
||||
normals[ind] = cn2.x;
|
||||
++ind;
|
||||
vertices[ind] = v2.y;
|
||||
normals[ind] = cn2.y;
|
||||
++ind;
|
||||
vertices[ind] = v2.z;
|
||||
normals[ind] = cn2.z;
|
||||
++ind;
|
||||
if (has_uv) {
|
||||
uvs[induv] = puvws[cf.p0].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p0].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p1].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p1].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p2].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p2].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p0].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p0].y;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p1].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p1].y;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p2].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p2].y;
|
||||
++induv;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,9 +171,8 @@ void Loader3DS::init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth) {
|
||||
|
||||
|
||||
Material Loader3DS::materialByName(const QVector<Material> & materials, const QString & name) {
|
||||
foreach (const Material & m, materials)
|
||||
if (m.name == name)
|
||||
return m;
|
||||
foreach(const Material & m, materials)
|
||||
if (m.name == name) return m;
|
||||
return Material();
|
||||
}
|
||||
|
||||
@@ -141,7 +188,7 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, float scale) {
|
||||
QVector<Material> materials;
|
||||
QVector<uint> smooth;
|
||||
QVector<ushort> face_mats;
|
||||
GLObjectBase * root = new GLObjectBase(), * co = nullptr;
|
||||
GLObjectBase *root = new GLObjectBase(), *co = nullptr;
|
||||
Material mat;
|
||||
Loader3DS::Chunk cc;
|
||||
Loader3DS::Face face;
|
||||
@@ -155,188 +202,180 @@ GLObjectBase * loadFrom3DSFile(const QString & filepath, float scale) {
|
||||
uint col;
|
||||
root->setName(QFileInfo(f).baseName());
|
||||
while (!stream.atEnd()) {
|
||||
stream.readRawData((char * )&cc, sizeof(cc));
|
||||
stream.readRawData((char *)&cc, sizeof(cc));
|
||||
switch (cc.id) {
|
||||
case LOADER_3DS_CHUNK_MAIN: /*qDebug() << "main" << cc.size;*/ break;
|
||||
case LOADER_3DS_CHUNK_OBJECTS: /*qDebug() << " objects" << cc.size;*/ break;
|
||||
case LOADER_3DS_CHUNK_OBJECT:
|
||||
if (co != nullptr) {
|
||||
Loader3DS::init3DSMesh(co, smooth);
|
||||
root->addChild(co);
|
||||
}
|
||||
co = new GLObjectBase();
|
||||
co->setName(readCharsUntilNull(stream));
|
||||
smooth.clear();
|
||||
//qDebug() << " object" << co->name();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MESH: /*qDebug() << " mesh" << cc.size;*/ break;
|
||||
case LOADER_3DS_CHUNK_VERTLIST:
|
||||
stream.readRawData((char * )&cnt, sizeof(ushort));
|
||||
co->points.resize(cnt);
|
||||
//qDebug() << " vertices" << cnt;
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
stream.readRawData((char * )&co->points[i].x, sizeof(float));
|
||||
stream.readRawData((char * )&co->points[i].y, sizeof(float));
|
||||
stream.readRawData((char * )&co->points[i].z, sizeof(float));
|
||||
co->points[i] *= scale;
|
||||
}
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_FACELIST:
|
||||
stream.readRawData((char * )&cnt, sizeof(ushort));
|
||||
co->faces.resize(cnt);
|
||||
//qDebug() << " faces" << cnt;
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
stream.readRawData((char * )&face, sizeof(Loader3DS::Face));
|
||||
co->faces[i].p0 = face.v0;
|
||||
co->faces[i].p1 = face.v1;
|
||||
co->faces[i].p2 = face.v2;
|
||||
}
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_FACEMAT:
|
||||
name = readCharsUntilNull(stream);
|
||||
stream.readRawData((char * )&cnt, sizeof(ushort));
|
||||
face_mats.resize(cnt);
|
||||
for (int i = 0; i < cnt; ++i)
|
||||
stream.readRawData((char * )&(face_mats[i]), sizeof(ushort));
|
||||
//qDebug() << " facemat name" << name << cnt;
|
||||
co->material().name = name;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MAPLIST:
|
||||
stream.readRawData((char * )&cnt, sizeof(ushort));
|
||||
co->puvws.resize(cnt);
|
||||
//qDebug() << " texcoords" << cnt;
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
stream.readRawData((char * )&co->puvws[i].x, sizeof(float));
|
||||
stream.readRawData((char * )&co->puvws[i].y, sizeof(float));
|
||||
}
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_SMOOTH:
|
||||
cnt = co->faces.size();
|
||||
smooth.resize(cnt);
|
||||
//qDebug() << " smooth" << cnt;
|
||||
for (int i = 0; i < cnt; ++i)
|
||||
stream.readRawData((char * )&smooth[i], sizeof(uint));
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_TRMATRIX:
|
||||
//qDebug() << co->name();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; ++j)
|
||||
stream.readRawData((char * )&(matrix[i][j]), sizeof(float));
|
||||
//qDebug() << matrix[i][0] << matrix[i][1] << matrix[i][2];
|
||||
}
|
||||
stream.readRawData((char * )&pos, sizeof(Vector3d));
|
||||
pos *= scale;
|
||||
//qDebug() << "pos =" << pos;
|
||||
co->setPos(pos.toQVector3D());
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_LIGHT:
|
||||
//qDebug() << " light" << cc.size;
|
||||
str = co->name();
|
||||
delete co;
|
||||
co = new Light();
|
||||
co->setName(str);
|
||||
stream.readRawData((char * )&pos, sizeof(Vector3d));
|
||||
pos *= scale;
|
||||
co->setPos(pos.toQVector3D());
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_SPOTLIGHT:
|
||||
stream.readRawData((char * )&pos, sizeof(Vector3d));
|
||||
pos *= scale;
|
||||
globject_cast<Light * >(co)->light_type = Light::Cone;
|
||||
globject_cast<Light * >(co)->direction = (pos.toQVector3D() - co->pos()).normalized();
|
||||
stream.readRawData((char * )&fl1, sizeof(float));
|
||||
stream.readRawData((char * )&fl, sizeof(float));
|
||||
globject_cast<Light * >(co)->angle_start = fl1;
|
||||
globject_cast<Light * >(co)->angle_end = fl;
|
||||
//qDebug() << "spotlight" << globject_cast<Light * >(co)->direction << globject_cast<Light * >(co)->angle_spread;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_LIGHT_OFF:
|
||||
stream.skipRawData(cc.size - 6);
|
||||
co->hide();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_ATTENUATION_ON:
|
||||
stream.skipRawData(cc.size - 6);
|
||||
fl = globject_cast<Light * >(co)->decay_end;
|
||||
//fl1 = globject_cast<Light * >(co)->decay_start;
|
||||
globject_cast<Light * >(co)->decay_quadratic = 4.f / fl;
|
||||
//qDebug() << "decay" << globject_cast<Light * >(co)->decay_quadratic;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_COLOR_F:
|
||||
stream.readRawData((char * )&pos, sizeof(Vector3d));
|
||||
co->setColor(QColor::fromRgbF(pos.x, pos.y, pos.z));
|
||||
//qDebug() << " color_f" << co->color();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_COLOR_B:
|
||||
stream.readRawData((char * )&col, 3);
|
||||
co->setColor(QColor::fromRgb(((uchar * )&col)[0], ((uchar * )&col)[1], ((uchar * )&col)[2]));
|
||||
//qDebug() << " color_b" << co->color();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MULTIPLIER:
|
||||
stream.readRawData((char * )&fl, sizeof(float));
|
||||
globject_cast<Light * >(co)->intensity = fl;
|
||||
//qDebug() << " multiplier" << fl;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_RANGE_START:
|
||||
stream.readRawData((char * )&fl, sizeof(float));
|
||||
globject_cast<Light * >(co)->decay_start = fl;
|
||||
//qDebug() << " range start" << fl;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_RANGE_END:
|
||||
stream.readRawData((char * )&fl, sizeof(float));
|
||||
globject_cast<Light * >(co)->decay_end = fl;
|
||||
//qDebug() << " range end" << fl;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MATERIAL:
|
||||
//stream.skipRawData(cc.size - 6);
|
||||
if (!mat.name.isEmpty())
|
||||
materials << mat;
|
||||
mat = Material();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MATERIAL_NAME:
|
||||
mat.name = readCharsUntilNull(stream);
|
||||
//qDebug() << "matname" << mat.name;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_AMBIENT_COLOR:
|
||||
stream.skipRawData(cc.size - 9);
|
||||
stream.readRawData((char * )&col, 3);
|
||||
mat.color_self_illumination = QColor::fromRgb(((uchar * )&col)[0], ((uchar * )&col)[1], ((uchar * )&col)[2]);
|
||||
//qDebug() << "mat diffuse" << mat.color_diffuse;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_DIFFUSE_COLOR:
|
||||
stream.skipRawData(cc.size - 9);
|
||||
stream.readRawData((char * )&col, 3);
|
||||
mat.color_diffuse = QColor::fromRgb(((uchar * )&col)[0], ((uchar * )&col)[1], ((uchar * )&col)[2]);
|
||||
//qDebug() << "mat diffuse" << mat.color_diffuse;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_SPECULAR_COLOR:
|
||||
stream.skipRawData(cc.size - 9);
|
||||
stream.readRawData((char * )&col, 3);
|
||||
mat.color_specular = QColor::fromRgb(((uchar * )&col)[0], ((uchar * )&col)[1], ((uchar * )&col)[2]);
|
||||
//qDebug() << "mat diffuse" << mat.color_diffuse;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_TEXTURE_MAP:
|
||||
cur_map = LOADER_3DS_CHUNK_TEXTURE_MAP;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_BUMP_MAP:
|
||||
cur_map = LOADER_3DS_CHUNK_BUMP_MAP;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_REFLECTION_MAP:
|
||||
cur_map = LOADER_3DS_CHUNK_REFLECTION_MAP;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MAP_FILENAME:
|
||||
name = readCharsUntilNull(stream);
|
||||
//qDebug() << " mat map" << QString::number(cur_map, 16) << name;
|
||||
switch (cur_map) {
|
||||
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.map_diffuse.bitmap_path = name; break;
|
||||
case LOADER_3DS_CHUNK_BUMP_MAP: mat.map_normal.bitmap_path = name; break;
|
||||
}
|
||||
break;
|
||||
default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6);
|
||||
case LOADER_3DS_CHUNK_MAIN: /*qDebug() << "main" << cc.size;*/ break;
|
||||
case LOADER_3DS_CHUNK_OBJECTS: /*qDebug() << " objects" << cc.size;*/ break;
|
||||
case LOADER_3DS_CHUNK_OBJECT:
|
||||
if (co != nullptr) {
|
||||
Loader3DS::init3DSMesh(co, smooth);
|
||||
root->addChild(co);
|
||||
}
|
||||
co = new GLObjectBase();
|
||||
co->setName(readCharsUntilNull(stream));
|
||||
smooth.clear();
|
||||
// qDebug() << " object" << co->name();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MESH: /*qDebug() << " mesh" << cc.size;*/ break;
|
||||
case LOADER_3DS_CHUNK_VERTLIST:
|
||||
stream.readRawData((char *)&cnt, sizeof(ushort));
|
||||
co->points.resize(cnt);
|
||||
// qDebug() << " vertices" << cnt;
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
stream.readRawData((char *)&co->points[i].x, sizeof(float));
|
||||
stream.readRawData((char *)&co->points[i].y, sizeof(float));
|
||||
stream.readRawData((char *)&co->points[i].z, sizeof(float));
|
||||
co->points[i] *= scale;
|
||||
}
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_FACELIST:
|
||||
stream.readRawData((char *)&cnt, sizeof(ushort));
|
||||
co->faces.resize(cnt);
|
||||
// qDebug() << " faces" << cnt;
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
stream.readRawData((char *)&face, sizeof(Loader3DS::Face));
|
||||
co->faces[i].p0 = face.v0;
|
||||
co->faces[i].p1 = face.v1;
|
||||
co->faces[i].p2 = face.v2;
|
||||
}
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_FACEMAT:
|
||||
name = readCharsUntilNull(stream);
|
||||
stream.readRawData((char *)&cnt, sizeof(ushort));
|
||||
face_mats.resize(cnt);
|
||||
for (int i = 0; i < cnt; ++i)
|
||||
stream.readRawData((char *)&(face_mats[i]), sizeof(ushort));
|
||||
// qDebug() << " facemat name" << name << cnt;
|
||||
co->material().name = name;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MAPLIST:
|
||||
stream.readRawData((char *)&cnt, sizeof(ushort));
|
||||
co->puvws.resize(cnt);
|
||||
// qDebug() << " texcoords" << cnt;
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
stream.readRawData((char *)&co->puvws[i].x, sizeof(float));
|
||||
stream.readRawData((char *)&co->puvws[i].y, sizeof(float));
|
||||
}
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_SMOOTH:
|
||||
cnt = co->faces.size();
|
||||
smooth.resize(cnt);
|
||||
// qDebug() << " smooth" << cnt;
|
||||
for (int i = 0; i < cnt; ++i)
|
||||
stream.readRawData((char *)&smooth[i], sizeof(uint));
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_TRMATRIX:
|
||||
// qDebug() << co->name();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; ++j)
|
||||
stream.readRawData((char *)&(matrix[i][j]), sizeof(float));
|
||||
// qDebug() << matrix[i][0] << matrix[i][1] << matrix[i][2];
|
||||
}
|
||||
stream.readRawData((char *)&pos, sizeof(Vector3d));
|
||||
pos *= scale;
|
||||
// qDebug() << "pos =" << pos;
|
||||
co->setPos(pos.toQVector3D());
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_LIGHT:
|
||||
// qDebug() << " light" << cc.size;
|
||||
str = co->name();
|
||||
delete co;
|
||||
co = new Light();
|
||||
co->setName(str);
|
||||
stream.readRawData((char *)&pos, sizeof(Vector3d));
|
||||
pos *= scale;
|
||||
co->setPos(pos.toQVector3D());
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_SPOTLIGHT:
|
||||
stream.readRawData((char *)&pos, sizeof(Vector3d));
|
||||
pos *= scale;
|
||||
globject_cast<Light *>(co)->light_type = Light::Cone;
|
||||
globject_cast<Light *>(co)->direction = (pos.toQVector3D() - co->pos()).normalized();
|
||||
stream.readRawData((char *)&fl1, sizeof(float));
|
||||
stream.readRawData((char *)&fl, sizeof(float));
|
||||
globject_cast<Light *>(co)->angle_start = fl1;
|
||||
globject_cast<Light *>(co)->angle_end = fl;
|
||||
// qDebug() << "spotlight" << globject_cast<Light * >(co)->direction << globject_cast<Light * >(co)->angle_spread;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_LIGHT_OFF:
|
||||
stream.skipRawData(cc.size - 6);
|
||||
co->hide();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_ATTENUATION_ON:
|
||||
stream.skipRawData(cc.size - 6);
|
||||
fl = globject_cast<Light *>(co)->decay_end;
|
||||
// fl1 = globject_cast<Light * >(co)->decay_start;
|
||||
globject_cast<Light *>(co)->decay_quadratic = 4.f / fl;
|
||||
// qDebug() << "decay" << globject_cast<Light * >(co)->decay_quadratic;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_COLOR_F:
|
||||
stream.readRawData((char *)&pos, sizeof(Vector3d));
|
||||
co->setColor(QColor::fromRgbF(pos.x, pos.y, pos.z));
|
||||
// qDebug() << " color_f" << co->color();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_COLOR_B:
|
||||
stream.readRawData((char *)&col, 3);
|
||||
co->setColor(QColor::fromRgb(((uchar *)&col)[0], ((uchar *)&col)[1], ((uchar *)&col)[2]));
|
||||
// qDebug() << " color_b" << co->color();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MULTIPLIER:
|
||||
stream.readRawData((char *)&fl, sizeof(float));
|
||||
globject_cast<Light *>(co)->intensity = fl;
|
||||
// qDebug() << " multiplier" << fl;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_RANGE_START:
|
||||
stream.readRawData((char *)&fl, sizeof(float));
|
||||
globject_cast<Light *>(co)->decay_start = fl;
|
||||
// qDebug() << " range start" << fl;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_RANGE_END:
|
||||
stream.readRawData((char *)&fl, sizeof(float));
|
||||
globject_cast<Light *>(co)->decay_end = fl;
|
||||
// qDebug() << " range end" << fl;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MATERIAL:
|
||||
// stream.skipRawData(cc.size - 6);
|
||||
if (!mat.name.isEmpty()) materials << mat;
|
||||
mat = Material();
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_MATERIAL_NAME:
|
||||
mat.name = readCharsUntilNull(stream);
|
||||
// qDebug() << "matname" << mat.name;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_AMBIENT_COLOR:
|
||||
stream.skipRawData(cc.size - 9);
|
||||
stream.readRawData((char *)&col, 3);
|
||||
mat.color_self_illumination = QColor::fromRgb(((uchar *)&col)[0], ((uchar *)&col)[1], ((uchar *)&col)[2]);
|
||||
// qDebug() << "mat diffuse" << mat.color_diffuse;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_DIFFUSE_COLOR:
|
||||
stream.skipRawData(cc.size - 9);
|
||||
stream.readRawData((char *)&col, 3);
|
||||
mat.color_diffuse = QColor::fromRgb(((uchar *)&col)[0], ((uchar *)&col)[1], ((uchar *)&col)[2]);
|
||||
// qDebug() << "mat diffuse" << mat.color_diffuse;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_SPECULAR_COLOR:
|
||||
stream.skipRawData(cc.size - 9);
|
||||
stream.readRawData((char *)&col, 3);
|
||||
mat.color_specular = QColor::fromRgb(((uchar *)&col)[0], ((uchar *)&col)[1], ((uchar *)&col)[2]);
|
||||
// qDebug() << "mat diffuse" << mat.color_diffuse;
|
||||
break;
|
||||
case LOADER_3DS_CHUNK_TEXTURE_MAP: cur_map = LOADER_3DS_CHUNK_TEXTURE_MAP; break;
|
||||
case LOADER_3DS_CHUNK_BUMP_MAP: cur_map = LOADER_3DS_CHUNK_BUMP_MAP; break;
|
||||
case LOADER_3DS_CHUNK_REFLECTION_MAP: cur_map = LOADER_3DS_CHUNK_REFLECTION_MAP; break;
|
||||
case LOADER_3DS_CHUNK_MAP_FILENAME:
|
||||
name = readCharsUntilNull(stream);
|
||||
// qDebug() << " mat map" << QString::number(cur_map, 16) << name;
|
||||
switch (cur_map) {
|
||||
case LOADER_3DS_CHUNK_TEXTURE_MAP: mat.map_diffuse.bitmap_path = name; break;
|
||||
case LOADER_3DS_CHUNK_BUMP_MAP: mat.map_normal.bitmap_path = name; break;
|
||||
}
|
||||
break;
|
||||
default: /*qDebug() << "???" << QString::number(cc.id, 16).rightJustified(4, '0') << cc.size;*/ stream.skipRawData(cc.size - 6);
|
||||
}
|
||||
}
|
||||
if (!mat.name.isEmpty())
|
||||
materials << mat;
|
||||
foreach (const Material & m, materials)
|
||||
if (!mat.name.isEmpty()) materials << mat;
|
||||
foreach(const Material & m, materials)
|
||||
qDebug() << m.name;
|
||||
if (co != nullptr) {
|
||||
Loader3DS::init3DSMesh(co, smooth);
|
||||
|
||||
@@ -19,58 +19,59 @@
|
||||
#ifndef LOADER_3DS_H
|
||||
#define LOADER_3DS_H
|
||||
|
||||
#include "gltexture_manager.h"
|
||||
#include "globject.h"
|
||||
#include <QFileInfo>
|
||||
#include <QDateTime>
|
||||
#include "gltexture_manager.h"
|
||||
|
||||
#define LOADER_3DS_CHUNK_MAIN 0x4D4D // [-] сцена
|
||||
#define LOADER_3DS_CHUNK_COLOR_F 0x0010 // [+] цвет во float
|
||||
#define LOADER_3DS_CHUNK_COLOR_B 0x0011 // [+] цвет в byte
|
||||
#define LOADER_3DS_CHUNK_OBJECTS 0x3D3D // [-] всяческие объекты
|
||||
#define LOADER_3DS_CHUNK_OBJECT 0x4000 // [+] объект
|
||||
#define LOADER_3DS_CHUNK_MESH 0x4100 // [-] mesh-объект
|
||||
#define LOADER_3DS_CHUNK_VERTLIST 0x4110 // [+] список вершин
|
||||
#define LOADER_3DS_CHUNK_FACELIST 0x4120 // [+] список граней
|
||||
#define LOADER_3DS_CHUNK_FACEMAT 0x4130 // [+] материалы граней
|
||||
#define LOADER_3DS_CHUNK_MAPLIST 0x4140 // [+] текстурные координаты
|
||||
#define LOADER_3DS_CHUNK_SMOOTH 0x4150 // [+] группы сглаживания
|
||||
#define LOADER_3DS_CHUNK_TRMATRIX 0x4160 // [+] матрица перевода
|
||||
#define LOADER_3DS_CHUNK_LIGHT 0x4600 // [+] источник света
|
||||
#define LOADER_3DS_CHUNK_SPOTLIGHT 0x4610 // [+]
|
||||
#define LOADER_3DS_CHUNK_LIGHT_OFF 0x4620 // [+]
|
||||
#define LOADER_3DS_CHUNK_ATTENUATION_ON 0x4625 // [+]
|
||||
#define LOADER_3DS_CHUNK_RANGE_START 0x4659 // [+]
|
||||
#define LOADER_3DS_CHUNK_RANGE_END 0x465A // [+]
|
||||
#define LOADER_3DS_CHUNK_MULTIPLIER 0x465B // [+]
|
||||
#define LOADER_3DS_CHUNK_CAMERA 0x4700 // [+] объект-камера
|
||||
#define LOADER_3DS_CHUNK_MATERIAL 0xAFFF // [-] материал
|
||||
#define LOADER_3DS_CHUNK_MATERIAL_NAME 0xA000
|
||||
#define LOADER_3DS_CHUNK_AMBIENT_COLOR 0xA010
|
||||
#define LOADER_3DS_CHUNK_DIFFUSE_COLOR 0xA020
|
||||
#define LOADER_3DS_CHUNK_SPECULAR_COLOR 0xA030
|
||||
#define LOADER_3DS_CHUNK_TEXTURE_MAP 0xA200
|
||||
#define LOADER_3DS_CHUNK_BUMP_MAP 0xA230
|
||||
#define LOADER_3DS_CHUNK_REFLECTION_MAP 0xA220
|
||||
#define LOADER_3DS_CHUNK_MAP_FILENAME 0xA300
|
||||
#define LOADER_3DS_CHUNK_MAP_PARAMETERS 0xA351
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
|
||||
#define LOADER_3DS_CHUNK_MAIN 0x4D4D // [-] сцена
|
||||
#define LOADER_3DS_CHUNK_COLOR_F 0x0010 // [+] цвет во float
|
||||
#define LOADER_3DS_CHUNK_COLOR_B 0x0011 // [+] цвет в byte
|
||||
#define LOADER_3DS_CHUNK_OBJECTS 0x3D3D // [-] всяческие объекты
|
||||
#define LOADER_3DS_CHUNK_OBJECT 0x4000 // [+] объект
|
||||
#define LOADER_3DS_CHUNK_MESH 0x4100 // [-] mesh-объект
|
||||
#define LOADER_3DS_CHUNK_VERTLIST 0x4110 // [+] список вершин
|
||||
#define LOADER_3DS_CHUNK_FACELIST 0x4120 // [+] список граней
|
||||
#define LOADER_3DS_CHUNK_FACEMAT 0x4130 // [+] материалы граней
|
||||
#define LOADER_3DS_CHUNK_MAPLIST 0x4140 // [+] текстурные координаты
|
||||
#define LOADER_3DS_CHUNK_SMOOTH 0x4150 // [+] группы сглаживания
|
||||
#define LOADER_3DS_CHUNK_TRMATRIX 0x4160 // [+] матрица перевода
|
||||
#define LOADER_3DS_CHUNK_LIGHT 0x4600 // [+] источник света
|
||||
#define LOADER_3DS_CHUNK_SPOTLIGHT 0x4610 // [+]
|
||||
#define LOADER_3DS_CHUNK_LIGHT_OFF 0x4620 // [+]
|
||||
#define LOADER_3DS_CHUNK_ATTENUATION_ON 0x4625 // [+]
|
||||
#define LOADER_3DS_CHUNK_RANGE_START 0x4659 // [+]
|
||||
#define LOADER_3DS_CHUNK_RANGE_END 0x465A // [+]
|
||||
#define LOADER_3DS_CHUNK_MULTIPLIER 0x465B // [+]
|
||||
#define LOADER_3DS_CHUNK_CAMERA 0x4700 // [+] объект-камера
|
||||
#define LOADER_3DS_CHUNK_MATERIAL 0xAFFF // [-] материал
|
||||
#define LOADER_3DS_CHUNK_MATERIAL_NAME 0xA000
|
||||
#define LOADER_3DS_CHUNK_AMBIENT_COLOR 0xA010
|
||||
#define LOADER_3DS_CHUNK_DIFFUSE_COLOR 0xA020
|
||||
#define LOADER_3DS_CHUNK_SPECULAR_COLOR 0xA030
|
||||
#define LOADER_3DS_CHUNK_TEXTURE_MAP 0xA200
|
||||
#define LOADER_3DS_CHUNK_BUMP_MAP 0xA230
|
||||
#define LOADER_3DS_CHUNK_REFLECTION_MAP 0xA220
|
||||
#define LOADER_3DS_CHUNK_MAP_FILENAME 0xA300
|
||||
#define LOADER_3DS_CHUNK_MAP_PARAMETERS 0xA351
|
||||
|
||||
namespace Loader3DS {
|
||||
#pragma pack(push, 1)
|
||||
struct Chunk {
|
||||
ushort id;
|
||||
uint size;
|
||||
};
|
||||
struct Face {
|
||||
ushort v0;
|
||||
ushort v1;
|
||||
ushort v2;
|
||||
ushort flags;
|
||||
};
|
||||
struct Chunk {
|
||||
ushort id;
|
||||
uint size;
|
||||
};
|
||||
struct Face {
|
||||
ushort v0;
|
||||
ushort v1;
|
||||
ushort v2;
|
||||
ushort flags;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
void init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth);
|
||||
Material materialByName(const QVector<Material> & materials, const QString & name);
|
||||
}
|
||||
void init3DSMesh(GLObjectBase * o, const QVector<uint> & smooth);
|
||||
Material materialByName(const QVector<Material> & materials, const QString & name);
|
||||
} // namespace Loader3DS
|
||||
|
||||
GLObjectBase * loadFrom3DSFile(const QString & filepath, float scale = 1.0);
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
|
||||
void LoaderASE::initASEMesh(GLObjectBase * o) {
|
||||
QVector<GLfloat> & vertices(o->VBO().vertices()), & normals(o->VBO().normals()), & uvs(o->VBO().texcoords());
|
||||
QVector<Vector3d> & points(o->points), & puvws(o->puvws), & fnormals(o->normals);
|
||||
QVector<GLfloat> &vertices(o->VBO().vertices()), &normals(o->VBO().normals()), &uvs(o->VBO().texcoords());
|
||||
QVector<Vector3d> &points(o->points), &puvws(o->puvws), &fnormals(o->normals);
|
||||
QVector<Vector3i> & faces(o->faces);
|
||||
Vector3d pos = Vector3d(o->pos());
|
||||
bool has_uv = !puvws.isEmpty(), has_norms = !fnormals.isEmpty();
|
||||
@@ -33,14 +33,17 @@ void LoaderASE::initASEMesh(GLObjectBase * o) {
|
||||
if (!has_norms) {
|
||||
fnormals.resize(faces.size() * 3);
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
cf = faces[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
cn0 = ((v1 - v0) * (v2 - v0)).normalized();
|
||||
fnormals[ni] = cn0; ++ni;
|
||||
fnormals[ni] = cn0; ++ni;
|
||||
fnormals[ni] = cn0; ++ni;
|
||||
cf = faces[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
cn0 = ((v1 - v0) * (v2 - v0)).normalized();
|
||||
fnormals[ni] = cn0;
|
||||
++ni;
|
||||
fnormals[ni] = cn0;
|
||||
++ni;
|
||||
fnormals[ni] = cn0;
|
||||
++ni;
|
||||
}
|
||||
}
|
||||
int fcnt = faces.size() * 3;
|
||||
@@ -51,29 +54,56 @@ void LoaderASE::initASEMesh(GLObjectBase * o) {
|
||||
qDebug() << "init ase" << faces.size() << "faces";
|
||||
ni = 0;
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
cf = faces[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
cn0 = fnormals[ni]; ++ni;
|
||||
cn1 = fnormals[ni]; ++ni;
|
||||
cn2 = fnormals[ni]; ++ni;
|
||||
vertices[ind] = v0.x; normals[ind] = cn0.x; ++ind;
|
||||
vertices[ind] = v0.y; normals[ind] = cn0.y; ++ind;
|
||||
vertices[ind] = v0.z; normals[ind] = cn0.z; ++ind;
|
||||
vertices[ind] = v1.x; normals[ind] = cn1.x; ++ind;
|
||||
vertices[ind] = v1.y; normals[ind] = cn1.y; ++ind;
|
||||
vertices[ind] = v1.z; normals[ind] = cn1.z; ++ind;
|
||||
vertices[ind] = v2.x; normals[ind] = cn2.x; ++ind;
|
||||
vertices[ind] = v2.y; normals[ind] = cn2.y; ++ind;
|
||||
vertices[ind] = v2.z; normals[ind] = cn2.z; ++ind;
|
||||
cf = faces[i];
|
||||
v0 = points[cf.p0];
|
||||
v1 = points[cf.p1];
|
||||
v2 = points[cf.p2];
|
||||
cn0 = fnormals[ni];
|
||||
++ni;
|
||||
cn1 = fnormals[ni];
|
||||
++ni;
|
||||
cn2 = fnormals[ni];
|
||||
++ni;
|
||||
vertices[ind] = v0.x;
|
||||
normals[ind] = cn0.x;
|
||||
++ind;
|
||||
vertices[ind] = v0.y;
|
||||
normals[ind] = cn0.y;
|
||||
++ind;
|
||||
vertices[ind] = v0.z;
|
||||
normals[ind] = cn0.z;
|
||||
++ind;
|
||||
vertices[ind] = v1.x;
|
||||
normals[ind] = cn1.x;
|
||||
++ind;
|
||||
vertices[ind] = v1.y;
|
||||
normals[ind] = cn1.y;
|
||||
++ind;
|
||||
vertices[ind] = v1.z;
|
||||
normals[ind] = cn1.z;
|
||||
++ind;
|
||||
vertices[ind] = v2.x;
|
||||
normals[ind] = cn2.x;
|
||||
++ind;
|
||||
vertices[ind] = v2.y;
|
||||
normals[ind] = cn2.y;
|
||||
++ind;
|
||||
vertices[ind] = v2.z;
|
||||
normals[ind] = cn2.z;
|
||||
++ind;
|
||||
if (has_uv) {
|
||||
uvs[induv] = puvws[cf.p0].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p0].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p1].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p1].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p2].x; ++induv;
|
||||
uvs[induv] = puvws[cf.p2].y; ++induv;
|
||||
uvs[induv] = puvws[cf.p0].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p0].y;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p1].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p1].y;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p2].x;
|
||||
++induv;
|
||||
uvs[induv] = puvws[cf.p2].y;
|
||||
++induv;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,8 +116,8 @@ GLObjectBase * loadFromASEFile(const QString & filepath, float scale) {
|
||||
return nullptr;
|
||||
}
|
||||
f.open(QIODevice::ReadOnly);
|
||||
//QVector<Material> materials;
|
||||
GLObjectBase * root = new GLObjectBase(), * co = nullptr;
|
||||
// QVector<Material> materials;
|
||||
GLObjectBase *root = new GLObjectBase(), *co = nullptr;
|
||||
root->setName(QFileInfo(f).baseName());
|
||||
QTextStream stream(&f);
|
||||
QVector<Material> materials;
|
||||
@@ -95,7 +125,7 @@ GLObjectBase * loadFromASEFile(const QString & filepath, float scale) {
|
||||
QVector<Vector3i> faces, uvws;
|
||||
QVector<Vector3d> normals;
|
||||
Vector3d cv;
|
||||
int mst = -1;//, mat_ind;
|
||||
int mst = -1; //, mat_ind;
|
||||
qint64 pst;
|
||||
QString line, cname;
|
||||
|
||||
@@ -103,65 +133,85 @@ GLObjectBase * loadFromASEFile(const QString & filepath, float scale) {
|
||||
/// Parse materials
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MATERIAL_LIST {");
|
||||
mst = line.indexOf("MATERIAL_LIST {");
|
||||
}
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MATERIAL_COUNT");
|
||||
mst = line.indexOf("MATERIAL_COUNT");
|
||||
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) {
|
||||
materials[i].map_diffuse.bitmap_id = 0;
|
||||
mst = -1;
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MATERIAL " + QString::number(i) + " {");
|
||||
mst = line.indexOf("MATERIAL " + QString::number(i) + " {");
|
||||
}
|
||||
/// Parse material i
|
||||
while (line != "}" && !stream.atEnd()) {
|
||||
line = stream.readLine().trimmed();
|
||||
if (line.left(17) == "*MATERIAL_DIFFUSE") {materials[i].color_diffuse = colorFromString(line.right(line.length() - 18)); continue;} //qDebug() << "diffuse " << i << " = " << colorFromString(line.right(line.length() - 18));
|
||||
if (line.left(18) == "*MATERIAL_SPECULAR") {materials[i].color_specular = colorFromString(line.right(line.length() - 19)); continue;} //qDebug() << "specular " << i << " = " << colorFromString(line.right(line.length() - 19));
|
||||
if (line.left(23) == "*MATERIAL_SHINESTRENGTH") {materials[i].map_specular.color_amount = line.right(line.length() - 24).toFloat(); continue;}
|
||||
if (line.left(15) == "*MATERIAL_SHINE") {materials[i].map_specularity.color_amount = 2.f / expf(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(17) == "*MATERIAL_DIFFUSE") {
|
||||
materials[i].color_diffuse = colorFromString(line.right(line.length() - 18));
|
||||
continue;
|
||||
} // qDebug() << "diffuse " << i << " = " << colorFromString(line.right(line.length() - 18));
|
||||
if (line.left(18) == "*MATERIAL_SPECULAR") {
|
||||
materials[i].color_specular = colorFromString(line.right(line.length() - 19));
|
||||
continue;
|
||||
} // qDebug() << "specular " << i << " = " << colorFromString(line.right(line.length() - 19));
|
||||
if (line.left(23) == "*MATERIAL_SHINESTRENGTH") {
|
||||
materials[i].map_specular.color_amount = line.right(line.length() - 24).toFloat();
|
||||
continue;
|
||||
}
|
||||
if (line.left(15) == "*MATERIAL_SHINE") {
|
||||
materials[i].map_specularity.color_amount = 2.f / expf(line.right(line.length() - 16).toFloat());
|
||||
continue;
|
||||
}
|
||||
if (line.left(22) == "*MATERIAL_TRANSPARENCY") {
|
||||
materials[i].transparency = line.right(line.length() - 23).toFloat();
|
||||
continue;
|
||||
}
|
||||
if (line.left(12) == "*MAP_DIFFUSE") {
|
||||
line = stream.readLine().trimmed();
|
||||
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd()) line = stream.readLine().trimmed();
|
||||
while (line.left(11) != "*MAP_AMOUNT" && !stream.atEnd())
|
||||
line = stream.readLine().trimmed();
|
||||
materials[i].map_normal.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].map_diffuse.bitmap_path = line.mid(9, line.length() - 10);
|
||||
/*if (!materials[i].diffuse.bitmap_path.isEmpty()) {
|
||||
materials[i].diffuse.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].diffuse.bitmap_path));
|
||||
parent->textures << materials[i].diffuse.bitmap_id;
|
||||
materials[i].diffuse.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].diffuse.bitmap_path));
|
||||
parent->textures << materials[i].diffuse.bitmap_id;
|
||||
}
|
||||
qDebug() << materials[i].diffuse.bitmap_path << ", bind to" << materials[i].diffuse.bitmap_id;*/
|
||||
while (line != "}" && !stream.atEnd()) line = stream.readLine().trimmed();
|
||||
while (line != "}" && !stream.atEnd())
|
||||
line = stream.readLine().trimmed();
|
||||
line = "";
|
||||
continue;
|
||||
}
|
||||
if (line.left(9) == "*MAP_BUMP") {
|
||||
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].map_normal.color_amount = line.right(line.length() - 12).toFloat();
|
||||
//qDebug() << "bump amount" << materials[i].bump.color_amount;
|
||||
while (line.left(7) != "*BITMAP" && !stream.atEnd()) line = stream.readLine().trimmed();
|
||||
// qDebug() << "bump amount" << materials[i].bump.color_amount;
|
||||
while (line.left(7) != "*BITMAP" && !stream.atEnd())
|
||||
line = stream.readLine().trimmed();
|
||||
materials[i].map_normal.bitmap_path = line.mid(9, line.length() - 10);
|
||||
/*if (!materials[i].bump.bitmap_path.isEmpty()) {
|
||||
materials[i].bump.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].bump.bitmap_path));
|
||||
parent->textures << materials[i].bump.bitmap_id;
|
||||
materials[i].bump.bitmap_id = currentQGLView->bindTexture(QImage(materials[i].bump.bitmap_path));
|
||||
parent->textures << materials[i].bump.bitmap_id;
|
||||
}
|
||||
qDebug() << materials[i].bump.bitmap_path << ", bind to" << materials[i].bump.bitmap_id;*/
|
||||
while (line != "}" && !stream.atEnd()) line = stream.readLine().trimmed();
|
||||
while (line != "}" && !stream.atEnd())
|
||||
line = stream.readLine().trimmed();
|
||||
line = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//bs << materials;
|
||||
// bs << materials;
|
||||
/// Geometry objects
|
||||
int cotype = 0;
|
||||
mst = -1;
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
if (line.indexOf("GEOMOBJECT {") >= 0 || line.indexOf("LIGHTOBJECT {") >= 0) {
|
||||
@@ -169,17 +219,17 @@ GLObjectBase * loadFromASEFile(const QString & filepath, float scale) {
|
||||
if (line.indexOf("LIGHTOBJECT {") >= 0) cotype = 1;
|
||||
mst = -1;
|
||||
if (co != nullptr) {
|
||||
co->points = points;
|
||||
co->faces = faces;
|
||||
co->points = points;
|
||||
co->faces = faces;
|
||||
co->normals = normals;
|
||||
co->uvws = uvws;
|
||||
co->uvws = uvws;
|
||||
LoaderASE::initASEMesh(co);
|
||||
root->addChild(co);
|
||||
}
|
||||
co = new GLObjectBase();
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("NODE_NAME");
|
||||
mst = line.indexOf("NODE_NAME");
|
||||
}
|
||||
cname = line.right(line.length() - mst - 10);
|
||||
co->setName(cname.mid(1, cname.length() - 2));
|
||||
@@ -188,94 +238,101 @@ GLObjectBase * loadFromASEFile(const QString & filepath, float scale) {
|
||||
mst = -1;
|
||||
switch (cotype) {
|
||||
case 0:
|
||||
//qDebug() << "object";
|
||||
// qDebug() << "object";
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH {");
|
||||
mst = line.indexOf("MESH {");
|
||||
}
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_NUMVERTEX ");
|
||||
mst = line.indexOf("MESH_NUMVERTEX ");
|
||||
}
|
||||
points.resize(line.right(line.length() - mst - 15).toInt());
|
||||
//qDebug() << points.size() << "vertices";
|
||||
// qDebug() << points.size() << "vertices";
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_NUMFACES ");
|
||||
mst = line.indexOf("MESH_NUMFACES ");
|
||||
}
|
||||
faces.resize(line.right(line.length() - mst - 14).toInt());
|
||||
normals.resize(faces.size() * 3);
|
||||
//qDebug() << faces.size() << "faces";
|
||||
//uvws.resize(faces.size());
|
||||
// qDebug() << faces.size() << "faces";
|
||||
// uvws.resize(faces.size());
|
||||
/// Points
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_VERTEX_LIST {");
|
||||
mst = line.indexOf("MESH_VERTEX_LIST {");
|
||||
}
|
||||
for (int i = 0; i < points.size(); ++i) {
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MESH_VERTEX");
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MESH_VERTEX");
|
||||
points[i] = Vector3d(line.right(line.length() - mst - 17)) * scale;
|
||||
//qDebug() << points[i];
|
||||
// qDebug() << points[i];
|
||||
}
|
||||
/// Faces
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_FACE_LIST {");
|
||||
mst = line.indexOf("MESH_FACE_LIST {");
|
||||
}
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MESH_FACE");
|
||||
line = line.right(line.length() - mst - 15);
|
||||
mst = line.indexOf("A:"); line = line.right(line.length() - mst - 2);
|
||||
mst = line.indexOf("B:");
|
||||
faces[i].p0 = line.left(mst).toInt(); line = line.right(line.length() - mst - 2);
|
||||
mst = line.indexOf("C:");
|
||||
faces[i].p1 = line.left(mst).toInt(); line = line.right(line.length() - mst - 2);
|
||||
mst = line.indexOf("AB");
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MESH_FACE");
|
||||
line = line.right(line.length() - mst - 15);
|
||||
mst = line.indexOf("A:");
|
||||
line = line.right(line.length() - mst - 2);
|
||||
mst = line.indexOf("B:");
|
||||
faces[i].p0 = line.left(mst).toInt();
|
||||
line = line.right(line.length() - mst - 2);
|
||||
mst = line.indexOf("C:");
|
||||
faces[i].p1 = line.left(mst).toInt();
|
||||
line = line.right(line.length() - mst - 2);
|
||||
mst = line.indexOf("AB");
|
||||
faces[i].p2 = line.left(mst).toInt();
|
||||
//qDebug() << faces[i];
|
||||
// qDebug() << faces[i];
|
||||
}
|
||||
/// Texture coordinates
|
||||
mst = -1;
|
||||
pst = stream.pos();
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_NUMTVERTEX ");
|
||||
mst = line.indexOf("MESH_NUMTVERTEX ");
|
||||
}
|
||||
if (mst >= 0) {
|
||||
puvws.resize(line.right(line.length() - mst - 16).toInt());
|
||||
//qDebug() << puvws.size() << "tvertices";
|
||||
// qDebug() << puvws.size() << "tvertices";
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_TVERTLIST {");
|
||||
mst = line.indexOf("MESH_TVERTLIST {");
|
||||
}
|
||||
for (int i = 0; i < puvws.size(); ++i) {
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MESH_TVERT"); line = line.right(line.length() - mst - 10);
|
||||
mst = line.indexOf("\t"); line = line.right(line.length() - mst - 1);
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MESH_TVERT");
|
||||
line = line.right(line.length() - mst - 10);
|
||||
mst = line.indexOf("\t");
|
||||
line = line.right(line.length() - mst - 1);
|
||||
puvws[i] = Vector3d(line);
|
||||
}
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_NUMTVFACES ");
|
||||
mst = line.indexOf("MESH_NUMTVFACES ");
|
||||
}
|
||||
uvws.resize(line.right(line.length() - mst - 16).toInt());
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_TFACELIST {");
|
||||
mst = line.indexOf("MESH_TFACELIST {");
|
||||
}
|
||||
for (int i = 0; i < uvws.size(); ++i) {
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MESH_TFACE"); line = line.right(line.length() - mst - 10);
|
||||
mst = line.indexOf("\t"); line = line.right(line.length() - mst - 1);
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf("MESH_TFACE");
|
||||
line = line.right(line.length() - mst - 10);
|
||||
mst = line.indexOf("\t");
|
||||
line = line.right(line.length() - mst - 1);
|
||||
uvws[i] = Vector3i(line);
|
||||
}
|
||||
} else {
|
||||
@@ -288,26 +345,32 @@ GLObjectBase * loadFromASEFile(const QString & filepath, float scale) {
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_NORMALS {");
|
||||
mst = line.indexOf("MESH_NORMALS {");
|
||||
}
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
line = stream.readLine();
|
||||
line = stream.readLine().trimmed(); mst = line.indexOf(" ");
|
||||
line = line.right(line.length() - mst - 1); normals[i * 3] = Vector3d(line);
|
||||
line = stream.readLine().trimmed(); mst = line.indexOf(" ");
|
||||
line = line.right(line.length() - mst - 1); normals[i * 3 + 1] = Vector3d(line);
|
||||
line = stream.readLine().trimmed(); mst = line.indexOf(" ");
|
||||
line = line.right(line.length() - mst - 1); normals[i * 3 + 2] = Vector3d(line);
|
||||
//qDebug() << normals[i][0] << normals[i][1] << normals[i][2];
|
||||
line = stream.readLine();
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf(" ");
|
||||
line = line.right(line.length() - mst - 1);
|
||||
normals[i * 3] = Vector3d(line);
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf(" ");
|
||||
line = line.right(line.length() - mst - 1);
|
||||
normals[i * 3 + 1] = Vector3d(line);
|
||||
line = stream.readLine().trimmed();
|
||||
mst = line.indexOf(" ");
|
||||
line = line.right(line.length() - mst - 1);
|
||||
normals[i * 3 + 2] = Vector3d(line);
|
||||
// qDebug() << normals[i][0] << normals[i][1] << normals[i][2];
|
||||
}
|
||||
/// Material index
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MATERIAL_REF ");
|
||||
mst = line.indexOf("MATERIAL_REF ");
|
||||
}
|
||||
//mat_ind = line.right(line.length() - mst - 13).toInt();
|
||||
//qDebug() << mat_ind.back();
|
||||
// mat_ind = line.right(line.length() - mst - 13).toInt();
|
||||
// qDebug() << mat_ind.back();
|
||||
if (points.size() == 0 || faces.size() == 0) {
|
||||
mst = -1;
|
||||
continue;
|
||||
@@ -316,51 +379,51 @@ GLObjectBase * loadFromASEFile(const QString & filepath, float scale) {
|
||||
/// Compiling into GLList
|
||||
/*glNewList(model, GL_COMPILE);
|
||||
if (mat_ind < 0 || mat_ind >= materials.size()) {
|
||||
mat_diffuse[0] = cfr;
|
||||
mat_diffuse[1] = cfg;
|
||||
mat_diffuse[2] = cfb;
|
||||
glColor3f(cfr, cfg, cfb);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_none);
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, 0.);
|
||||
mat_diffuse[0] = cfr;
|
||||
mat_diffuse[1] = cfg;
|
||||
mat_diffuse[2] = cfb;
|
||||
glColor3f(cfr, cfg, cfb);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_none);
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, 0.);
|
||||
} else {
|
||||
materials[mat_ind].apply();
|
||||
//parent->material_ = materials[mat_ind];
|
||||
materials[mat_ind].apply();
|
||||
//parent->material_ = materials[mat_ind];
|
||||
}
|
||||
glBegin(GL_TRIANGLES);
|
||||
if (normals_) {
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
glNormal3d(normals[i][0].x, normals[i][0].y, normals[i][0].z);
|
||||
glTexCoord3d(puvws[uvws[i].p0].x, puvws[uvws[i].p0].y, puvws[uvws[i].p0].z);
|
||||
cv = points[faces[i].p0] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
glNormal3d(normals[i][1].x, normals[i][1].y, normals[i][1].z);
|
||||
glTexCoord3d(puvws[uvws[i].p1].x, puvws[uvws[i].p1].y, puvws[uvws[i].p1].z);
|
||||
cv = points[faces[i].p1] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
glNormal3d(normals[i][2].x, normals[i][2].y, normals[i][2].z);
|
||||
glTexCoord3d(puvws[uvws[i].p2].x, puvws[uvws[i].p2].y, puvws[uvws[i].p2].z);
|
||||
cv = points[faces[i].p2] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
}
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
glNormal3d(normals[i][0].x, normals[i][0].y, normals[i][0].z);
|
||||
glTexCoord3d(puvws[uvws[i].p0].x, puvws[uvws[i].p0].y, puvws[uvws[i].p0].z);
|
||||
cv = points[faces[i].p0] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
glNormal3d(normals[i][1].x, normals[i][1].y, normals[i][1].z);
|
||||
glTexCoord3d(puvws[uvws[i].p1].x, puvws[uvws[i].p1].y, puvws[uvws[i].p1].z);
|
||||
cv = points[faces[i].p1] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
glNormal3d(normals[i][2].x, normals[i][2].y, normals[i][2].z);
|
||||
glTexCoord3d(puvws[uvws[i].p2].x, puvws[uvws[i].p2].y, puvws[uvws[i].p2].z);
|
||||
cv = points[faces[i].p2] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
glTexCoord3d(puvws[uvws[i].p0].x, puvws[uvws[i].p0].y, puvws[uvws[i].p0].z);
|
||||
cv = points[faces[i].p0] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
glTexCoord3d(puvws[uvws[i].p1].x, puvws[uvws[i].p1].y, puvws[uvws[i].p1].z);
|
||||
cv = points[faces[i].p1] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
glTexCoord3d(puvws[uvws[i].p2].x, puvws[uvws[i].p2].y, puvws[uvws[i].p2].z);
|
||||
cv = points[faces[i].p2] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
}
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
glTexCoord3d(puvws[uvws[i].p0].x, puvws[uvws[i].p0].y, puvws[uvws[i].p0].z);
|
||||
cv = points[faces[i].p0] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
glTexCoord3d(puvws[uvws[i].p1].x, puvws[uvws[i].p1].y, puvws[uvws[i].p1].z);
|
||||
cv = points[faces[i].p1] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
glTexCoord3d(puvws[uvws[i].p2].x, puvws[uvws[i].p2].y, puvws[uvws[i].p2].z);
|
||||
cv = points[faces[i].p2] * scale; glVertex3d(cv.x, cv.y, cv.z);
|
||||
}
|
||||
}
|
||||
glEnd();*/
|
||||
|
||||
///// Save binary
|
||||
//bs << mat_ind << points << faces << puvws << uvws << normals;
|
||||
// bs << mat_ind << points << faces << puvws << uvws << normals;
|
||||
break;
|
||||
case 1:
|
||||
qDebug() << "light";
|
||||
mst = -1;
|
||||
while (mst < 0 && !stream.atEnd()) {
|
||||
line = stream.readLine();
|
||||
mst = line.indexOf("MESH_NORMALS {");
|
||||
mst = line.indexOf("MESH_NORMALS {");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -369,10 +432,10 @@ GLObjectBase * loadFromASEFile(const QString & filepath, float scale) {
|
||||
}
|
||||
f.close();
|
||||
if (co != nullptr) {
|
||||
co->points = points;
|
||||
co->faces = faces;
|
||||
co->points = points;
|
||||
co->faces = faces;
|
||||
co->normals = normals;
|
||||
co->uvws = uvws;
|
||||
co->uvws = uvws;
|
||||
LoaderASE::initASEMesh(co);
|
||||
root->addChild(co);
|
||||
}
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
#define LOADER_ASE_H
|
||||
|
||||
#include "globject.h"
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace LoaderASE {
|
||||
void initASEMesh(GLObjectBase * o);
|
||||
void initASEMesh(GLObjectBase * o);
|
||||
}
|
||||
|
||||
GLObjectBase * loadFromASEFile(const QString & filepath, float scale = 1.0);
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
*/
|
||||
|
||||
#include "loader_dae.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QUrl>
|
||||
|
||||
|
||||
Material LoaderDAE::materialByName(const QVector<Material> & materials, const QString & name) {
|
||||
foreach (const Material & m, materials) {
|
||||
//qDebug() << m.name << " ??? " << name;
|
||||
if (m.name == name)
|
||||
return m;
|
||||
foreach(const Material & m, materials) {
|
||||
// qDebug() << m.name << " ??? " << name;
|
||||
if (m.name == name) return m;
|
||||
}
|
||||
return Material();
|
||||
}
|
||||
@@ -79,21 +79,21 @@ QString readXMLTexture(QDomElement n, QDomElement prof, QDomElement li) {
|
||||
tag = tex;
|
||||
} else {
|
||||
bool found = false;
|
||||
int cnt = 0;
|
||||
int cnt = 0;
|
||||
while (!tex.isEmpty() && !found && cnt < 10) {
|
||||
found = false;
|
||||
cnt++;
|
||||
for (int i = 0; i < elist.count(); ++i) {
|
||||
QDomNode dn = elist.at(i);
|
||||
if (dn.attributes().namedItem("sid").nodeValue() == tex) {
|
||||
//qDebug() << "found!";
|
||||
// qDebug() << "found!";
|
||||
if (dn.firstChild().nodeName() == "sampler2D") {
|
||||
tex = dn.firstChildElement("sampler2D").firstChildElement("source").firstChild().nodeValue();
|
||||
break;
|
||||
}
|
||||
if (dn.firstChild().nodeName() == "surface") {
|
||||
tag = dn.firstChildElement("surface").firstChildElement("init_from").firstChild().nodeValue();
|
||||
//qDebug() << tex << "->" << tag;
|
||||
// qDebug() << tex << "->" << tag;
|
||||
tex.clear();
|
||||
found = true;
|
||||
break;
|
||||
@@ -103,7 +103,7 @@ QString readXMLTexture(QDomElement n, QDomElement prof, QDomElement li) {
|
||||
}
|
||||
if (cnt == 10) return QString();
|
||||
}
|
||||
//qDebug() << tag;
|
||||
// qDebug() << tag;
|
||||
if (tag.isEmpty()) return QString();
|
||||
elist = li.elementsByTagName("image");
|
||||
for (int i = 0; i < elist.count(); ++i) {
|
||||
@@ -112,7 +112,7 @@ QString readXMLTexture(QDomElement n, QDomElement prof, QDomElement li) {
|
||||
tex = dn.firstChildElement("init_from").firstChild().nodeValue();
|
||||
tex.replace("\\", "/");
|
||||
if (tex.startsWith("file:") && tex.mid(5, 3) != "///") tex.insert(6, "/");
|
||||
//qDebug() << "found" << tex << QUrl(tex).toLocalFile();
|
||||
// qDebug() << "found" << tex << QUrl(tex).toLocalFile();
|
||||
tex = QUrl(tex).toLocalFile();
|
||||
if (tex == "/") tex.clear();
|
||||
return tex;
|
||||
@@ -128,12 +128,12 @@ QVector<Material> LoaderDAE::readMaterials(QDomElement le, QDomElement li, bool
|
||||
for (int i = 0; i < elist.count(); ++i) {
|
||||
QDomNode dn = elist.at(i);
|
||||
Material mat;
|
||||
mat.name = dn.attributes().namedItem("id").nodeValue();
|
||||
mat.name = dn.attributes().namedItem("id").nodeValue();
|
||||
QDomElement prof = dn.firstChildElement("profile_COMMON");
|
||||
QDomNode pn = prof.firstChildElement("technique").firstChild();
|
||||
QDomNode pn = prof.firstChildElement("technique").firstChild();
|
||||
QColor col;
|
||||
QString text;
|
||||
|
||||
|
||||
col = readXMLColor(pn.firstChildElement("emission"));
|
||||
if (col.isValid()) mat.color_self_illumination = col;
|
||||
col = readXMLColor(pn.firstChildElement("diffuse"));
|
||||
@@ -141,17 +141,17 @@ QVector<Material> LoaderDAE::readMaterials(QDomElement le, QDomElement li, bool
|
||||
col = readXMLColor(pn.firstChildElement("specular"));
|
||||
if (col.isValid()) mat.color_specular = col;
|
||||
mat.map_specularity.color_amount = 2.f / expf(readXMLFloat(pn.firstChildElement("shininess")));
|
||||
mat.transparency = readXMLFloat(pn.firstChildElement("transparency"));
|
||||
mat.transparency = readXMLFloat(pn.firstChildElement("transparency"));
|
||||
if (!fbx) mat.transparency = 1.f - mat.transparency;
|
||||
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
|
||||
if (!text.isEmpty()) mat.map_diffuse.bitmap_path = text;
|
||||
text = readXMLTexture(pn.firstChildElement("diffuse"), prof, li);
|
||||
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);
|
||||
if (!text.isEmpty()) mat.map_normal.bitmap_path = text;
|
||||
|
||||
|
||||
ret << mat;
|
||||
qDebug() << "** Material" << mat.name;
|
||||
qDebug() << " emission" << mat.color_self_illumination;
|
||||
@@ -173,13 +173,13 @@ QMatrix4x4 readXMLTransformations(QDomElement n) {
|
||||
}
|
||||
|
||||
|
||||
void readScene(QDomElement n, QMatrix4x4 cm, QVector<QPair<QPair<QString, QString>, QMatrix4x4> > & ret, QString last_name = QString()) {
|
||||
void readScene(QDomElement n, QMatrix4x4 cm, QVector<QPair<QPair<QString, QString>, QMatrix4x4>> & ret, QString last_name = QString()) {
|
||||
QDomNodeList evsl = n.childNodes();
|
||||
if (n.hasAttribute("name")) last_name = n.attribute("name");
|
||||
for (int i = 0; i < evsl.count(); ++i) {
|
||||
QDomElement dt = evsl.at(i).toElement();
|
||||
QVector4D v;
|
||||
//qDebug() << dt.nodeName();
|
||||
// qDebug() << dt.nodeName();
|
||||
if (dt.nodeName() == "translate") {
|
||||
v = readXMLVector(dt);
|
||||
cm.translate(v.toVector3D());
|
||||
@@ -207,11 +207,11 @@ void readScene(QDomElement n, QMatrix4x4 cm, QVector<QPair<QPair<QString, QStrin
|
||||
if (dt.nodeName() == "instance_geometry" || dt.nodeName() == "instance_light") {
|
||||
QString gid = dt.attribute("url");
|
||||
if (gid.startsWith("#")) gid.remove(0, 1);
|
||||
//qDebug() << "matrix" << gid << cm;
|
||||
// qDebug() << "matrix" << gid << cm;
|
||||
ret << QPair<QPair<QString, QString>, QMatrix4x4>(QPair<QString, QString>(gid, last_name), cm);
|
||||
continue;
|
||||
}
|
||||
//qDebug() << name << m;
|
||||
// qDebug() << name << m;
|
||||
}
|
||||
ret << QPair<QPair<QString, QString>, QMatrix4x4>(QPair<QString, QString>("", last_name), cm);
|
||||
}
|
||||
@@ -228,21 +228,26 @@ GLObjectBase * loadFromDAEFile(const QString & filepath, float scale) {
|
||||
qDebug() << "[Loader DAE] Error: can`t parse \"" + filepath + "\"";
|
||||
return nullptr;
|
||||
}
|
||||
//qDebug() << "parse" << tm.elapsed();
|
||||
// qDebug() << "parse" << tm.elapsed();
|
||||
QDomElement maine = dom.firstChildElement("COLLADA");
|
||||
bool fbx = maine.firstChildElement("asset").firstChildElement("contributor").firstChildElement("authoring_tool").firstChild().nodeValue().startsWith("FBX");
|
||||
QVector<Material> materials = LoaderDAE::readMaterials(maine.firstChildElement("library_effects"),
|
||||
maine.firstChildElement("library_images"), fbx);
|
||||
GLObjectBase * root = new GLObjectBase(), * co = nullptr;
|
||||
QMap<QString, QVector<GLObjectBase * > > objects;
|
||||
|
||||
bool fbx = maine.firstChildElement("asset")
|
||||
.firstChildElement("contributor")
|
||||
.firstChildElement("authoring_tool")
|
||||
.firstChild()
|
||||
.nodeValue()
|
||||
.startsWith("FBX");
|
||||
QVector<Material> materials =
|
||||
LoaderDAE::readMaterials(maine.firstChildElement("library_effects"), maine.firstChildElement("library_images"), fbx);
|
||||
GLObjectBase *root = new GLObjectBase(), *co = nullptr;
|
||||
QMap<QString, QVector<GLObjectBase *>> objects;
|
||||
|
||||
QMap<QString, QString> mat_names;
|
||||
QDomElement mvse = maine.firstChildElement("library_visual_scenes").firstChildElement("visual_scene");
|
||||
QDomElement mvse = maine.firstChildElement("library_visual_scenes").firstChildElement("visual_scene");
|
||||
QDomNodeList evsl = mvse.elementsByTagName("instance_material");
|
||||
QDomNodeList matl = maine.firstChildElement("library_materials").elementsByTagName("material");
|
||||
for (int i = 0; i < evsl.count(); ++i) {
|
||||
QDomElement dn = evsl.at(i).toElement();
|
||||
QString tn = dn.attribute("target");
|
||||
QString tn = dn.attribute("target");
|
||||
if (tn.startsWith("#")) tn.remove(0, 1);
|
||||
for (int j = 0; j < matl.count(); ++j) {
|
||||
QDomElement dm = matl.at(j).toElement();
|
||||
@@ -250,34 +255,33 @@ GLObjectBase * loadFromDAEFile(const QString & filepath, float scale) {
|
||||
QString en = dm.firstChildElement("instance_effect").attribute("url");
|
||||
if (en.startsWith("#")) en.remove(0, 1);
|
||||
mat_names[dn.attribute("symbol")] = en;
|
||||
//qDebug() << dn.attribute("symbol") << "->" << en;
|
||||
// qDebug() << dn.attribute("symbol") << "->" << en;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QDomNodeList elist = maine.firstChildElement("library_geometries").elementsByTagName("geometry");
|
||||
for (int i = 0; i < elist.count(); ++i) {
|
||||
QDomNode dn = elist.at(i);
|
||||
QDomNode dn = elist.at(i);
|
||||
QString name = dn.attributes().namedItem("name").nodeValue();
|
||||
QString gid = dn.attributes().namedItem("id").nodeValue();
|
||||
QString gid = dn.attributes().namedItem("id").nodeValue();
|
||||
if (name.isEmpty()) continue;
|
||||
dn = dn.firstChildElement("mesh");
|
||||
QMap<QString, QString> source_names;
|
||||
QMap<QString, QVector<Vector3d> > source_data;
|
||||
QMap<QString, QVector<Vector3d>> source_data;
|
||||
QDomNodeList esrc = dn.toElement().elementsByTagName("source");
|
||||
for (int j = 0; j < esrc.count(); ++j) {
|
||||
QDomNode ds = esrc.at(j);
|
||||
QString id = ds.attributes().namedItem("id").nodeValue();
|
||||
QDomNode ds = esrc.at(j);
|
||||
QString id = ds.attributes().namedItem("id").nodeValue();
|
||||
QDomNodeList evert = dn.toElement().elementsByTagName("vertices");
|
||||
for (int k = 0; k < evert.count(); ++k) {
|
||||
QDomNode dv = evert.at(k);
|
||||
QString vid = dv.attributes().namedItem("id").nodeValue();
|
||||
if (dv.firstChildElement("input").attribute("source") == ("#" + id))
|
||||
source_names[vid] = id;
|
||||
//qDebug() << " found source sin" << vid;
|
||||
if (dv.firstChildElement("input").attribute("source") == ("#" + id)) source_names[vid] = id;
|
||||
// qDebug() << " found source sin" << vid;
|
||||
}
|
||||
QVector<Vector3d> & sd(source_data[id]);
|
||||
int stride = ds.firstChildElement("technique_common").firstChildElement("accessor").attribute("stride").toInt();
|
||||
int stride = ds.firstChildElement("technique_common").firstChildElement("accessor").attribute("stride").toInt();
|
||||
QString astr = ds.firstChildElement("float_array").firstChild().nodeValue().trimmed();
|
||||
astr.replace("\n", " ");
|
||||
astr.remove("\r");
|
||||
@@ -291,37 +295,46 @@ GLObjectBase * loadFromDAEFile(const QString & filepath, float scale) {
|
||||
if (stride >= 3) v.z = sl[c + 2].toFloat();
|
||||
sd << v;
|
||||
}
|
||||
//qDebug() << " found source" << id << "stride =" << stride << ":" << sd;
|
||||
//qDebug() << " readed" << sd.size();
|
||||
// qDebug() << " found source" << id << "stride =" << stride << ":" << sd;
|
||||
// qDebug() << " readed" << sd.size();
|
||||
}
|
||||
QDomNodeList etr = dn.toElement().elementsByTagName("triangles");
|
||||
//QMatrix4x4 m = matrices.value(gid);
|
||||
//qDebug() << "found geom" << name;
|
||||
QVector<GLObjectBase * > ol;
|
||||
// QMatrix4x4 m = matrices.value(gid);
|
||||
// qDebug() << "found geom" << name;
|
||||
QVector<GLObjectBase *> ol;
|
||||
for (int j = 0; j < etr.count(); ++j) {
|
||||
QDomElement ds = etr.at(j).toElement();
|
||||
QDomElement ds = etr.at(j).toElement();
|
||||
QString matname = mat_names[ds.attribute("material")];
|
||||
QVector<int> p;
|
||||
QStringList psl = ds.firstChildElement("p").firstChild().nodeValue().trimmed().split(" ");
|
||||
foreach (const QString & s, psl)
|
||||
foreach(const QString & s, psl)
|
||||
p << s.toInt();
|
||||
QDomNodeList einp = ds.elementsByTagName("input");
|
||||
int pbv = einp.count();//, tc = qMin(ds.attribute("count").toInt(), p.size() / pbv);
|
||||
co = new GLObjectBase();
|
||||
int pbv = einp.count(); //, tc = qMin(ds.attribute("count").toInt(), p.size() / pbv);
|
||||
co = new GLObjectBase();
|
||||
co->setName(name + "_" + QString::number(j));
|
||||
//co->setTransform(m);
|
||||
// co->setTransform(m);
|
||||
co->material() = LoaderDAE::materialByName(materials, matname);
|
||||
qDebug() << " tri" << co->material().name << matname;
|
||||
QVector<GLfloat> & vertices(co->VBO().vertices()), & normals(co->VBO().normals()), & uvs(co->VBO().texcoords());
|
||||
QVector<GLfloat> &vertices(co->VBO().vertices()), &normals(co->VBO().normals()), &uvs(co->VBO().texcoords());
|
||||
for (int k = 0; k < einp.count(); ++k) {
|
||||
QDomElement di = einp.at(k).toElement();
|
||||
QString src = di.attribute("source"), sem = di.attribute("semantic").toLower();
|
||||
int offset = di.attribute("offset").toInt();
|
||||
int offset = di.attribute("offset").toInt();
|
||||
QVector<GLfloat> * curv = nullptr;
|
||||
int pccnt = 0;
|
||||
if (sem == "vertex") {curv = &vertices; pccnt = 3;}
|
||||
if (sem == "normal") {curv = &normals; pccnt = 3;}
|
||||
if (sem == "texcoord") {curv = &uvs; pccnt = 2;}
|
||||
int pccnt = 0;
|
||||
if (sem == "vertex") {
|
||||
curv = &vertices;
|
||||
pccnt = 3;
|
||||
}
|
||||
if (sem == "normal") {
|
||||
curv = &normals;
|
||||
pccnt = 3;
|
||||
}
|
||||
if (sem == "texcoord") {
|
||||
curv = &uvs;
|
||||
pccnt = 2;
|
||||
}
|
||||
if (curv == nullptr) continue;
|
||||
if (src.startsWith("#")) src.remove(0, 1);
|
||||
QVector<Vector3d> & data(source_data[source_names.value(src, src)]);
|
||||
@@ -332,24 +345,26 @@ GLObjectBase * loadFromDAEFile(const QString & filepath, float scale) {
|
||||
if (pccnt == 3) (*curv) << v.z;
|
||||
}
|
||||
}
|
||||
//qDebug() << " input" << sem << "from" << data.size() << "->" << (*curv) << pbv;
|
||||
// qDebug() << " input" << sem << "from" << data.size() << "->" << (*curv) << pbv;
|
||||
}
|
||||
//qDebug() << "geom" << gid << co;
|
||||
// qDebug() << "geom" << gid << co;
|
||||
ol << co;
|
||||
}
|
||||
objects[gid] = ol;
|
||||
}
|
||||
|
||||
|
||||
elist = maine.firstChildElement("library_lights").elementsByTagName("light");
|
||||
for (int i = 0; i < elist.count(); ++i) {
|
||||
QDomElement dn = elist.at(i).toElement();
|
||||
QString name = dn.attributes().namedItem("name").nodeValue();
|
||||
QString gid = dn.attributes().namedItem("id").nodeValue();
|
||||
QString name = dn.attributes().namedItem("name").nodeValue();
|
||||
QString gid = dn.attributes().namedItem("id").nodeValue();
|
||||
if (name.isEmpty() || name == "EnvironmentAmbientLight") continue;
|
||||
QDomElement dl = dn.firstChildElement("technique_common").firstChild().toElement();
|
||||
Light * lo = new Light();
|
||||
if (dl.nodeName() == "point") lo->light_type = Light::Omni;
|
||||
else if (dl.nodeName() == "spot") lo->light_type = Light::Cone;
|
||||
Light * lo = new Light();
|
||||
if (dl.nodeName() == "point")
|
||||
lo->light_type = Light::Omni;
|
||||
else if (dl.nodeName() == "spot")
|
||||
lo->light_type = Light::Cone;
|
||||
else {
|
||||
delete lo;
|
||||
continue;
|
||||
@@ -361,62 +376,67 @@ GLObjectBase * loadFromDAEFile(const QString & filepath, float scale) {
|
||||
if (!ml.isEmpty()) lo->intensity = ml.at(0).firstChild().nodeValue().toFloat();
|
||||
lo->setColor(lo->color() / lo->intensity);
|
||||
QString sv;
|
||||
sv = dl.firstChildElement("constant_attenuation").firstChild().nodeValue(); if (!sv.isEmpty()) lo->decay_const = sv.toFloat();
|
||||
sv = dl.firstChildElement("linear_attenuation").firstChild().nodeValue(); if (!sv.isEmpty()) lo->decay_linear = sv.toFloat();
|
||||
sv = dl.firstChildElement("quadratic_attenuation").firstChild().nodeValue(); if (!sv.isEmpty()) lo->decay_quadratic = sv.toFloat();
|
||||
///lo->setTransform(matrices.value(name));
|
||||
sv = dl.firstChildElement("constant_attenuation").firstChild().nodeValue();
|
||||
if (!sv.isEmpty()) lo->decay_const = sv.toFloat();
|
||||
sv = dl.firstChildElement("linear_attenuation").firstChild().nodeValue();
|
||||
if (!sv.isEmpty()) lo->decay_linear = sv.toFloat();
|
||||
sv = dl.firstChildElement("quadratic_attenuation").firstChild().nodeValue();
|
||||
if (!sv.isEmpty()) lo->decay_quadratic = sv.toFloat();
|
||||
/// lo->setTransform(matrices.value(name));
|
||||
if (lo->light_type == Light::Cone) {
|
||||
ml = dn.elementsByTagName("decay_falloff"); if (!ml.isEmpty()) lo->angle_end = ml.at(0).firstChild().nodeValue().toFloat();
|
||||
ml = dn.elementsByTagName("hotspot_beam"); if (!ml.isEmpty()) lo->angle_start = ml.at(0).firstChild().nodeValue().toFloat();
|
||||
ml = dn.elementsByTagName("decay_falloff");
|
||||
if (!ml.isEmpty()) lo->angle_end = ml.at(0).firstChild().nodeValue().toFloat();
|
||||
ml = dn.elementsByTagName("hotspot_beam");
|
||||
if (!ml.isEmpty()) lo->angle_start = ml.at(0).firstChild().nodeValue().toFloat();
|
||||
}
|
||||
QVector<GLObjectBase*> ol;
|
||||
QVector<GLObjectBase *> ol;
|
||||
ol << lo;
|
||||
objects[gid] = ol;
|
||||
//qDebug() << "light" << name;
|
||||
// qDebug() << "light" << name;
|
||||
}
|
||||
//qDebug() << "readed" << objects.size();
|
||||
|
||||
QVector<QPair<QPair<QString, QString>, QMatrix4x4> > scene;
|
||||
// qDebug() << "readed" << objects.size();
|
||||
|
||||
QVector<QPair<QPair<QString, QString>, QMatrix4x4>> scene;
|
||||
readScene(mvse, QMatrix4x4(), scene);
|
||||
for (int i = 0; i < scene.size(); ++i) {
|
||||
QPair<QPair<QString, QString>, QMatrix4x4> so = scene[i];
|
||||
if (so.first.first.isEmpty()) continue;
|
||||
QVector<GLObjectBase * > ol = objects.value(so.first.first);
|
||||
foreach (GLObjectBase * o, ol) {
|
||||
QVector<GLObjectBase *> ol = objects.value(so.first.first);
|
||||
foreach(GLObjectBase * o, ol) {
|
||||
o = o->clone();
|
||||
o->setName(so.first.second);
|
||||
o->setTransform(so.second);
|
||||
root->addChild(o);
|
||||
//qDebug() << " add" << so.first.second << o->name();
|
||||
// qDebug() << " add" << so.first.second << o->name();
|
||||
}
|
||||
//qDebug() << "add" << so.first << ol.size();
|
||||
// qDebug() << "add" << so.first << ol.size();
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < root->childCount(); ++i) {
|
||||
GLObjectBase * o = root->child(i);
|
||||
if (o->type() == GLObjectBase::glLight) {
|
||||
Light * l = (Light*)o;
|
||||
Light * l = (Light *)o;
|
||||
if (l->light_type == Light::Directional || l->light_type == Light::Cone) {
|
||||
QString tn = l->name() + ".Target";
|
||||
//qDebug() << "search target" << tn;
|
||||
// qDebug() << "search target" << tn;
|
||||
for (int s = 0; s < scene.size(); ++s) {
|
||||
QPair<QPair<QString, QString>, QMatrix4x4> so = scene[s];
|
||||
if (so.first.second == tn) {
|
||||
//qDebug() << "found target" << tn;
|
||||
// qDebug() << "found target" << tn;
|
||||
QVector3D tp = so.second.column(3).toVector3D();
|
||||
l->direction = (tp - l->pos()).normalized();
|
||||
//qDebug() << "dir" << l->direction;
|
||||
// qDebug() << "dir" << l->direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<QVector<GLObjectBase * > > dol = objects.values();
|
||||
|
||||
QList<QVector<GLObjectBase *>> dol = objects.values();
|
||||
for (int i = 0; i < dol.size(); ++i)
|
||||
for (int j = 0; j < dol[i].size(); ++j)
|
||||
delete dol[i][j];
|
||||
|
||||
|
||||
root->setScale(0.001f);
|
||||
qDebug() << "[Loader DAE] Loaded" << root->childCount() << "objects from" << filepath;
|
||||
return root;
|
||||
|
||||
@@ -19,16 +19,17 @@
|
||||
#ifndef LOADER_DAE_H
|
||||
#define LOADER_DAE_H
|
||||
|
||||
#include "gltexture_manager.h"
|
||||
#include "globject.h"
|
||||
#include <QFileInfo>
|
||||
#include "gltexture_manager.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDomElement>
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace LoaderDAE {
|
||||
Material materialByName(const QVector<Material> & materials, const QString & name);
|
||||
QVector<Material> readMaterials(QDomElement le, QDomElement li, bool fbx);
|
||||
}
|
||||
Material materialByName(const QVector<Material> & materials, const QString & name);
|
||||
QVector<Material> readMaterials(QDomElement le, QDomElement li, bool fbx);
|
||||
} // namespace LoaderDAE
|
||||
|
||||
GLObjectBase * loadFromDAEFile(const QString & filepath, float scale = 1.0);
|
||||
|
||||
|
||||
@@ -19,51 +19,78 @@
|
||||
#include "loader_obj.h"
|
||||
|
||||
|
||||
void LoaderOBJ::initOBJMesh(GLObjectBase * o, const QVector<Vector3d> & src_vertices, const QVector<Vector3d> & src_normals, const QVector<Vector3d> & src_texcoords) {
|
||||
QVector<GLfloat> & vertices(o->VBO().vertices()), & normals(o->VBO().normals()), & uvs(o->VBO().texcoords());
|
||||
QVector<Vector3i> & faces(o->faces), & uvws(o->uvws), & norms(o->norms);
|
||||
//Vector3d pos = Vector3d(o->pos());
|
||||
void LoaderOBJ::initOBJMesh(GLObjectBase * o,
|
||||
const QVector<Vector3d> & src_vertices,
|
||||
const QVector<Vector3d> & src_normals,
|
||||
const QVector<Vector3d> & src_texcoords) {
|
||||
QVector<GLfloat> &vertices(o->VBO().vertices()), &normals(o->VBO().normals()), &uvs(o->VBO().texcoords());
|
||||
QVector<Vector3i> &faces(o->faces), &uvws(o->uvws), &norms(o->norms);
|
||||
// Vector3d pos = Vector3d(o->pos());
|
||||
bool has_uv = !uvws.isEmpty();
|
||||
Vector3i cf, ct, cn;
|
||||
Vector3d v[3], t[3], n[3];
|
||||
//for (int i = 0; i < points.size(); ++i)
|
||||
// for (int i = 0; i < points.size(); ++i)
|
||||
// points[i] -= pos;
|
||||
int fcnt = faces.size() * 3;
|
||||
vertices.resize(fcnt * 3);
|
||||
normals.resize(vertices.size());
|
||||
if (has_uv) uvs.resize(fcnt * 2);
|
||||
int ind = 0, induv = 0;
|
||||
//qDebug() << "initOBJMesh" << faces.size();
|
||||
// qDebug() << "initOBJMesh" << faces.size();
|
||||
for (int i = 0; i < faces.size(); ++i) {
|
||||
cf = faces[i];
|
||||
ct = uvws[i];
|
||||
cn = norms[i];
|
||||
v[0] = src_vertices[cf.p0];
|
||||
v[1] = src_vertices[cf.p1];
|
||||
v[2] = src_vertices[cf.p2];
|
||||
n[0] = src_normals[cn.p0];
|
||||
n[1] = src_normals[cn.p1];
|
||||
n[2] = src_normals[cn.p2];
|
||||
vertices[ind] = v[0].x; normals[ind] = n[0].x; ++ind;
|
||||
vertices[ind] = v[0].y; normals[ind] = n[0].y; ++ind;
|
||||
vertices[ind] = v[0].z; normals[ind] = n[0].z; ++ind;
|
||||
vertices[ind] = v[1].x; normals[ind] = n[1].x; ++ind;
|
||||
vertices[ind] = v[1].y; normals[ind] = n[1].y; ++ind;
|
||||
vertices[ind] = v[1].z; normals[ind] = n[1].z; ++ind;
|
||||
vertices[ind] = v[2].x; normals[ind] = n[2].x; ++ind;
|
||||
vertices[ind] = v[2].y; normals[ind] = n[2].y; ++ind;
|
||||
vertices[ind] = v[2].z; normals[ind] = n[2].z; ++ind;
|
||||
cf = faces[i];
|
||||
ct = uvws[i];
|
||||
cn = norms[i];
|
||||
v[0] = src_vertices[cf.p0];
|
||||
v[1] = src_vertices[cf.p1];
|
||||
v[2] = src_vertices[cf.p2];
|
||||
n[0] = src_normals[cn.p0];
|
||||
n[1] = src_normals[cn.p1];
|
||||
n[2] = src_normals[cn.p2];
|
||||
vertices[ind] = v[0].x;
|
||||
normals[ind] = n[0].x;
|
||||
++ind;
|
||||
vertices[ind] = v[0].y;
|
||||
normals[ind] = n[0].y;
|
||||
++ind;
|
||||
vertices[ind] = v[0].z;
|
||||
normals[ind] = n[0].z;
|
||||
++ind;
|
||||
vertices[ind] = v[1].x;
|
||||
normals[ind] = n[1].x;
|
||||
++ind;
|
||||
vertices[ind] = v[1].y;
|
||||
normals[ind] = n[1].y;
|
||||
++ind;
|
||||
vertices[ind] = v[1].z;
|
||||
normals[ind] = n[1].z;
|
||||
++ind;
|
||||
vertices[ind] = v[2].x;
|
||||
normals[ind] = n[2].x;
|
||||
++ind;
|
||||
vertices[ind] = v[2].y;
|
||||
normals[ind] = n[2].y;
|
||||
++ind;
|
||||
vertices[ind] = v[2].z;
|
||||
normals[ind] = n[2].z;
|
||||
++ind;
|
||||
if (has_uv) {
|
||||
if ((ct.p0 >= 0) && (ct.p1 >= 0) && (ct.p2 >= 0)) {
|
||||
t[0] = src_texcoords[ct.p0];
|
||||
t[1] = src_texcoords[ct.p1];
|
||||
t[2] = src_texcoords[ct.p2];
|
||||
uvs[induv] = t[0].x; ++induv;
|
||||
uvs[induv] = t[0].y; ++induv;
|
||||
uvs[induv] = t[1].x; ++induv;
|
||||
uvs[induv] = t[1].y; ++induv;
|
||||
uvs[induv] = t[2].x; ++induv;
|
||||
uvs[induv] = t[2].y; ++induv;
|
||||
t[0] = src_texcoords[ct.p0];
|
||||
t[1] = src_texcoords[ct.p1];
|
||||
t[2] = src_texcoords[ct.p2];
|
||||
uvs[induv] = t[0].x;
|
||||
++induv;
|
||||
uvs[induv] = t[0].y;
|
||||
++induv;
|
||||
uvs[induv] = t[1].x;
|
||||
++induv;
|
||||
uvs[induv] = t[1].y;
|
||||
++induv;
|
||||
uvs[induv] = t[2].x;
|
||||
++induv;
|
||||
uvs[induv] = t[2].y;
|
||||
++induv;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,7 +100,8 @@ void LoaderOBJ::initOBJMesh(GLObjectBase * o, const QVector<Vector3d> & src_vert
|
||||
Vector3d readVector3d(QString s) {
|
||||
Vector3d ret;
|
||||
QStringList sl(s.trimmed().split(" "));
|
||||
sl.removeAll(""); sl.removeAll(" ");
|
||||
sl.removeAll("");
|
||||
sl.removeAll(" ");
|
||||
if (sl.size() > 0) ret.x = sl[0].toFloat();
|
||||
if (sl.size() > 1) ret.y = sl[1].toFloat();
|
||||
if (sl.size() > 2) ret.z = sl[2].toFloat();
|
||||
@@ -84,7 +112,8 @@ Vector3d readVector3d(QString s) {
|
||||
Vector2d readVector2d(QString s) {
|
||||
Vector2d ret;
|
||||
QStringList sl(s.trimmed().split(" "));
|
||||
sl.removeAll(""); sl.removeAll(" ");
|
||||
sl.removeAll("");
|
||||
sl.removeAll(" ");
|
||||
if (sl.size() > 0) ret.x = sl[0].toFloat();
|
||||
if (sl.size() > 1) ret.y = sl[1].toFloat();
|
||||
return ret;
|
||||
@@ -99,7 +128,8 @@ QColor readColor(QString s) {
|
||||
|
||||
void readFaces(QString s, GLObjectBase * co) {
|
||||
QStringList sl(s.trimmed().split(" "));
|
||||
sl.removeAll(""); sl.removeAll(" ");
|
||||
sl.removeAll("");
|
||||
sl.removeAll(" ");
|
||||
static Vector3i inds[4];
|
||||
for (int i = 0; i < sl.size(); ++i) {
|
||||
inds[i].p0 = inds[i].p1 = inds[i].p2 = 0;
|
||||
@@ -111,15 +141,15 @@ void readFaces(QString s, GLObjectBase * co) {
|
||||
}
|
||||
if (sl.size() == 3) {
|
||||
co->faces << Vector3i(inds[0].p0 - 1, inds[1].p0 - 1, inds[2].p0 - 1);
|
||||
co->uvws << Vector3i(inds[0].p1 - 1, inds[1].p1 - 1, inds[2].p1 - 1);
|
||||
co->uvws << Vector3i(inds[0].p1 - 1, inds[1].p1 - 1, inds[2].p1 - 1);
|
||||
co->norms << Vector3i(inds[0].p2 - 1, inds[1].p2 - 1, inds[2].p2 - 1);
|
||||
}
|
||||
if (sl.size() == 4) {
|
||||
co->faces << Vector3i(inds[0].p0 - 1, inds[1].p0 - 1, inds[2].p0 - 1);
|
||||
co->uvws << Vector3i(inds[0].p1 - 1, inds[1].p1 - 1, inds[2].p1 - 1);
|
||||
co->uvws << Vector3i(inds[0].p1 - 1, inds[1].p1 - 1, inds[2].p1 - 1);
|
||||
co->norms << Vector3i(inds[0].p2 - 1, inds[1].p2 - 1, inds[2].p2 - 1);
|
||||
co->faces << Vector3i(inds[0].p0 - 1, inds[2].p0 - 1, inds[3].p0 - 1);
|
||||
co->uvws << Vector3i(inds[0].p1 - 1, inds[2].p1 - 1, inds[3].p1 - 1);
|
||||
co->uvws << Vector3i(inds[0].p1 - 1, inds[2].p1 - 1, inds[3].p1 - 1);
|
||||
co->norms << Vector3i(inds[0].p2 - 1, inds[2].p2 - 1, inds[3].p2 - 1);
|
||||
}
|
||||
}
|
||||
@@ -140,9 +170,8 @@ QVector<Material> readMTL(QString obj_path, QString path) {
|
||||
while (!stream.atEnd()) {
|
||||
QString line = stream.readLine().trimmed();
|
||||
if (line.startsWith("newmtl")) {
|
||||
if (!mat.name.isEmpty())
|
||||
ret << mat;
|
||||
mat = Material();
|
||||
if (!mat.name.isEmpty()) ret << mat;
|
||||
mat = Material();
|
||||
mat.name = line.mid(6).trimmed();
|
||||
continue;
|
||||
}
|
||||
@@ -155,12 +184,12 @@ QVector<Material> readMTL(QString obj_path, QString path) {
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("Ks")) {
|
||||
Vector3d v = readVector3d(line.mid(2).trimmed());
|
||||
Vector3d v = readVector3d(line.mid(2).trimmed());
|
||||
mat.map_specular.color_amount = v.length();
|
||||
float mc = qMax(v.x, qMax(v.y, v.z));
|
||||
float mc = qMax(v.x, qMax(v.y, v.z));
|
||||
if (mc > 0.f) v /= mc;
|
||||
mat.color_specular = QColor::fromRgbF(v.x, v.y, v.z);
|
||||
//qDebug() << mat.shine_strength << mat.color_specular;
|
||||
// qDebug() << mat.shine_strength << mat.color_specular;
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("Ns")) {
|
||||
@@ -178,27 +207,25 @@ QVector<Material> readMTL(QString obj_path, QString path) {
|
||||
if (line.startsWith("map_bump")) {
|
||||
line = line.mid(8).trimmed();
|
||||
if (line.startsWith("-bm")) {
|
||||
line = line.mid(3).trimmed();
|
||||
QString sv = line.left(line.indexOf(" "));
|
||||
line = line.mid(sv.size()).trimmed();
|
||||
line = line.mid(3).trimmed();
|
||||
QString sv = line.left(line.indexOf(" "));
|
||||
line = line.mid(sv.size()).trimmed();
|
||||
mat.map_normal.color_amount = sv.toFloat();
|
||||
}
|
||||
mat.map_normal.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;
|
||||
}
|
||||
}
|
||||
if (!mat.name.isEmpty())
|
||||
ret << mat;
|
||||
if (!mat.name.isEmpty()) ret << mat;
|
||||
qDebug() << "load from MTL" << f.fileName() << ret.size() << "materials";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Material LoaderOBJ::materialByName(const QVector<Material> & materials, const QString & name) {
|
||||
foreach (const Material & m, materials)
|
||||
if (m.name == name)
|
||||
return m;
|
||||
foreach(const Material & m, materials)
|
||||
if (m.name == name) return m;
|
||||
return Material();
|
||||
}
|
||||
|
||||
@@ -213,13 +240,13 @@ GLObjectBase * loadFromOBJFile(const QString & filepath, float scale) {
|
||||
QTextStream stream(&f);
|
||||
QVector<Vector3d> vertices, normals, texcoords;
|
||||
QVector<Material> materials;
|
||||
GLObjectBase * root = new GLObjectBase(), * co = nullptr;
|
||||
GLObjectBase *root = new GLObjectBase(), *co = nullptr;
|
||||
QString name, line, pline;
|
||||
root->setName(QFileInfo(f).baseName());
|
||||
int cnt = 0;
|
||||
while (!stream.atEnd()) {
|
||||
pline = line;
|
||||
line = stream.readLine().trimmed();
|
||||
line = stream.readLine().trimmed();
|
||||
if (line.startsWith("mtllib")) {
|
||||
materials = readMTL(filepath, line.mid(6).trimmed());
|
||||
continue;
|
||||
@@ -245,7 +272,7 @@ GLObjectBase * loadFromOBJFile(const QString & filepath, float scale) {
|
||||
}
|
||||
co = new GLObjectBase();
|
||||
co->setName(name);
|
||||
//qDebug() << "new object" << co->name();
|
||||
// qDebug() << "new object" << co->name();
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("f ")) {
|
||||
|
||||
@@ -19,23 +19,27 @@
|
||||
#ifndef LOADER_OBJ_H
|
||||
#define LOADER_OBJ_H
|
||||
|
||||
#include "gltexture_manager.h"
|
||||
#include "globject.h"
|
||||
#include <QFileInfo>
|
||||
#include "gltexture_manager.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace LoaderOBJ {
|
||||
#pragma pack(push, 1)
|
||||
struct Face {
|
||||
ushort v0;
|
||||
ushort v1;
|
||||
ushort v2;
|
||||
ushort flags;
|
||||
};
|
||||
struct Face {
|
||||
ushort v0;
|
||||
ushort v1;
|
||||
ushort v2;
|
||||
ushort flags;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
void initOBJMesh(GLObjectBase * o, const QVector<Vector3d> & vertices, const QVector<Vector3d> & normals, const QVector<Vector3d> & texcoords);
|
||||
Material materialByName(const QVector<Material> & materials, const QString & name);
|
||||
}
|
||||
void initOBJMesh(GLObjectBase * o,
|
||||
const QVector<Vector3d> & vertices,
|
||||
const QVector<Vector3d> & normals,
|
||||
const QVector<Vector3d> & texcoords);
|
||||
Material materialByName(const QVector<Material> & materials, const QString & name);
|
||||
} // namespace LoaderOBJ
|
||||
|
||||
GLObjectBase * loadFromOBJFile(const QString & filepath, float scale = 1.0);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "loader_qgl.h"
|
||||
|
||||
#include "chunkstream.h"
|
||||
|
||||
|
||||
@@ -36,8 +37,8 @@ GLObjectBase * loadFromQGLFile(const QString & filepath) {
|
||||
return 0;
|
||||
}
|
||||
GLObjectBase * root = 0;
|
||||
ushort version = 0xFFFF;
|
||||
f.peek((char*)&version, 2);
|
||||
ushort version = 0xFFFF;
|
||||
f.peek((char *)&version, 2);
|
||||
if (version == 1) {
|
||||
s.skipRawData(2);
|
||||
s >> root;
|
||||
@@ -46,8 +47,7 @@ GLObjectBase * loadFromQGLFile(const QString & filepath) {
|
||||
return 0;
|
||||
}
|
||||
root->buildTransform();
|
||||
if (root->name().isEmpty())
|
||||
root->setName(QFileInfo(f).baseName());
|
||||
if (root->name().isEmpty()) root->setName(QFileInfo(f).baseName());
|
||||
qDebug() << "[Loader QGL] Loaded" << root->childCount() << "objects from" << filepath;
|
||||
return root;
|
||||
}
|
||||
@@ -55,15 +55,14 @@ GLObjectBase * loadFromQGLFile(const QString & filepath) {
|
||||
|
||||
bool saveToQGLFile(const QString & filepath, const GLObjectBase * o) {
|
||||
QFile f(filepath);
|
||||
if (!f.open(QIODevice::ReadWrite))
|
||||
return false;
|
||||
if (!f.open(QIODevice::ReadWrite)) return false;
|
||||
f.resize(0);
|
||||
QDataStream s(&f);
|
||||
s.setVersion(QDataStream::Qt_4_8);
|
||||
char sign[4] = {'Q', 'G', 'L', 'F'};
|
||||
char sign[4] = {'Q', 'G', 'L', 'F'};
|
||||
ushort version = 1;
|
||||
s.writeRawData(sign, 4);
|
||||
s.writeRawData((char*)&version, 2);
|
||||
s.writeRawData((char *)&version, 2);
|
||||
s << o;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#define LOADER_QGL_H
|
||||
|
||||
#include "globject.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace LoaderQGL {
|
||||
}
|
||||
namespace LoaderQGL {}
|
||||
|
||||
GLObjectBase * loadFromQGLFile(const QString & filepath);
|
||||
bool saveToQGLFile(const QString & filepath, const GLObjectBase * o);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "material_editor.h"
|
||||
|
||||
#include "ui_material_editor.h"
|
||||
|
||||
|
||||
@@ -31,11 +32,8 @@ MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) {
|
||||
void MaterialEditor::changeEvent(QEvent * e) {
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QEvent::LanguageChange: ui->retranslateUi(this); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,32 +54,38 @@ void MaterialEditor::setMaterial(const Material & m) {
|
||||
ui->mapSpecularity->setMap(m.map_specularity);
|
||||
ui->mapBump->setMap(m.map_normal);
|
||||
ui->mapRelief->setMap(m.map_relief);
|
||||
ui->lineReflFront->setProperty("GLpath", m.map_reflection.path(0)); ui->lineReflFront->setText(QFileInfo(m.map_reflection.path(0)).fileName());
|
||||
ui->lineReflBack->setProperty("GLpath", m.map_reflection.path(1)); ui->lineReflBack->setText(QFileInfo(m.map_reflection.path(1)).fileName());
|
||||
ui->lineReflLeft->setProperty("GLpath", m.map_reflection.path(2)); ui->lineReflLeft->setText(QFileInfo(m.map_reflection.path(2)).fileName());
|
||||
ui->lineReflRight->setProperty("GLpath", m.map_reflection.path(3)); ui->lineReflRight->setText(QFileInfo(m.map_reflection.path(3)).fileName());
|
||||
ui->lineReflTop->setProperty("GLpath", m.map_reflection.path(4)); ui->lineReflTop->setText(QFileInfo(m.map_reflection.path(4)).fileName());
|
||||
ui->lineReflBottom->setProperty("GLpath", m.map_reflection.path(5)); ui->lineReflBottom->setText(QFileInfo(m.map_reflection.path(5)).fileName());
|
||||
ui->lineReflFront->setProperty("GLpath", m.map_reflection.path(0));
|
||||
ui->lineReflFront->setText(QFileInfo(m.map_reflection.path(0)).fileName());
|
||||
ui->lineReflBack->setProperty("GLpath", m.map_reflection.path(1));
|
||||
ui->lineReflBack->setText(QFileInfo(m.map_reflection.path(1)).fileName());
|
||||
ui->lineReflLeft->setProperty("GLpath", m.map_reflection.path(2));
|
||||
ui->lineReflLeft->setText(QFileInfo(m.map_reflection.path(2)).fileName());
|
||||
ui->lineReflRight->setProperty("GLpath", m.map_reflection.path(3));
|
||||
ui->lineReflRight->setText(QFileInfo(m.map_reflection.path(3)).fileName());
|
||||
ui->lineReflTop->setProperty("GLpath", m.map_reflection.path(4));
|
||||
ui->lineReflTop->setText(QFileInfo(m.map_reflection.path(4)).fileName());
|
||||
ui->lineReflBottom->setProperty("GLpath", m.map_reflection.path(5));
|
||||
ui->lineReflBottom->setText(QFileInfo(m.map_reflection.path(5)).fileName());
|
||||
active = true;
|
||||
}
|
||||
|
||||
|
||||
Material MaterialEditor::material() {
|
||||
Material m;
|
||||
m.color_diffuse = ui->colorDiffuse->color();
|
||||
m.color_specular = ui->colorSpecular->color();
|
||||
m.color_diffuse = ui->colorDiffuse->color();
|
||||
m.color_specular = ui->colorSpecular->color();
|
||||
m.color_self_illumination = ui->colorSelfIllum->color();
|
||||
m.glass = ui->checkGlass->isChecked();
|
||||
m.transparency = ui->spinTransparent->value();
|
||||
m.reflectivity = ui->spinReflect->value();
|
||||
m.iof = ui->spinIOF->value();
|
||||
m.dispersion = ui->spinDispersion->value();
|
||||
m.map_diffuse = ui->mapDiffuse->map();
|
||||
m.map_specular = ui->mapSpecular->map();
|
||||
m.map_self_illumination = ui->mapSelfIllum->map();
|
||||
m.map_specularity = ui->mapSpecularity->map();
|
||||
m.map_normal = ui->mapBump->map();
|
||||
m.map_relief = ui->mapRelief->map();
|
||||
m.glass = ui->checkGlass->isChecked();
|
||||
m.transparency = ui->spinTransparent->value();
|
||||
m.reflectivity = ui->spinReflect->value();
|
||||
m.iof = ui->spinIOF->value();
|
||||
m.dispersion = ui->spinDispersion->value();
|
||||
m.map_diffuse = ui->mapDiffuse->map();
|
||||
m.map_specular = ui->mapSpecular->map();
|
||||
m.map_self_illumination = ui->mapSelfIllum->map();
|
||||
m.map_specularity = ui->mapSpecularity->map();
|
||||
m.map_normal = ui->mapBump->map();
|
||||
m.map_relief = ui->mapRelief->map();
|
||||
m.map_reflection.setPath(0, ui->lineReflFront->property("GLpath").toString());
|
||||
m.map_reflection.setPath(1, ui->lineReflBack->property("GLpath").toString());
|
||||
m.map_reflection.setPath(2, ui->lineReflLeft->property("GLpath").toString());
|
||||
@@ -93,7 +97,10 @@ Material MaterialEditor::material() {
|
||||
|
||||
|
||||
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;
|
||||
ui->lineReflFront->setProperty("GLpath", str);
|
||||
ui->lineReflFront->setText(QFileInfo(str).fileName());
|
||||
@@ -102,7 +109,10 @@ void MaterialEditor::on_buttonReflFrontSelect_clicked() {
|
||||
|
||||
|
||||
void MaterialEditor::on_buttonReflBackSelect_clicked() {
|
||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflBack->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
QString str = QFileDialog::getOpenFileName(this,
|
||||
"Select image",
|
||||
ui->lineReflBack->property("GLpath").toString(),
|
||||
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
if (str.isEmpty()) return;
|
||||
ui->lineReflBack->setProperty("GLpath", str);
|
||||
ui->lineReflBack->setText(QFileInfo(str).fileName());
|
||||
@@ -111,7 +121,10 @@ void MaterialEditor::on_buttonReflBackSelect_clicked() {
|
||||
|
||||
|
||||
void MaterialEditor::on_buttonReflLeftSelect_clicked() {
|
||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflLeft->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
QString str = QFileDialog::getOpenFileName(this,
|
||||
"Select image",
|
||||
ui->lineReflLeft->property("GLpath").toString(),
|
||||
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
if (str.isEmpty()) return;
|
||||
ui->lineReflLeft->setProperty("GLpath", str);
|
||||
ui->lineReflLeft->setText(QFileInfo(str).fileName());
|
||||
@@ -120,7 +133,10 @@ void MaterialEditor::on_buttonReflLeftSelect_clicked() {
|
||||
|
||||
|
||||
void MaterialEditor::on_buttonReflRightSelect_clicked() {
|
||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflRight->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
QString str = QFileDialog::getOpenFileName(this,
|
||||
"Select image",
|
||||
ui->lineReflRight->property("GLpath").toString(),
|
||||
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
if (str.isEmpty()) return;
|
||||
ui->lineReflRight->setProperty("GLpath", str);
|
||||
ui->lineReflRight->setText(QFileInfo(str).fileName());
|
||||
@@ -129,7 +145,10 @@ void MaterialEditor::on_buttonReflRightSelect_clicked() {
|
||||
|
||||
|
||||
void MaterialEditor::on_buttonReflTopSelect_clicked() {
|
||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflTop->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
QString str = QFileDialog::getOpenFileName(this,
|
||||
"Select image",
|
||||
ui->lineReflTop->property("GLpath").toString(),
|
||||
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
if (str.isEmpty()) return;
|
||||
ui->lineReflTop->setProperty("GLpath", str);
|
||||
ui->lineReflTop->setText(QFileInfo(str).fileName());
|
||||
@@ -138,7 +157,10 @@ void MaterialEditor::on_buttonReflTopSelect_clicked() {
|
||||
|
||||
|
||||
void MaterialEditor::on_buttonReflBottomSelect_clicked() {
|
||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->lineReflBottom->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
QString str = QFileDialog::getOpenFileName(this,
|
||||
"Select image",
|
||||
ui->lineReflBottom->property("GLpath").toString(),
|
||||
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
if (str.isEmpty()) return;
|
||||
ui->lineReflBottom->setProperty("GLpath", str);
|
||||
ui->lineReflBottom->setText(QFileInfo(str).fileName());
|
||||
@@ -194,12 +216,18 @@ void MaterialEditor::on_buttonLoadCubeDir_clicked() {
|
||||
GLCubeTexture cb(0);
|
||||
cb.loadPathesFromDirectory(dir);
|
||||
active = false;
|
||||
ui->lineReflFront->setProperty("GLpath", cb.path(0)); ui->lineReflFront->setText(QFileInfo(cb.path(0)).fileName());
|
||||
ui->lineReflBack->setProperty("GLpath", cb.path(1)); ui->lineReflBack->setText(QFileInfo(cb.path(1)).fileName());
|
||||
ui->lineReflLeft->setProperty("GLpath", cb.path(2)); ui->lineReflLeft->setText(QFileInfo(cb.path(2)).fileName());
|
||||
ui->lineReflRight->setProperty("GLpath", cb.path(3)); ui->lineReflRight->setText(QFileInfo(cb.path(3)).fileName());
|
||||
ui->lineReflTop->setProperty("GLpath", cb.path(4)); ui->lineReflTop->setText(QFileInfo(cb.path(4)).fileName());
|
||||
ui->lineReflBottom->setProperty("GLpath", cb.path(5)); ui->lineReflBottom->setText(QFileInfo(cb.path(5)).fileName());
|
||||
ui->lineReflFront->setProperty("GLpath", cb.path(0));
|
||||
ui->lineReflFront->setText(QFileInfo(cb.path(0)).fileName());
|
||||
ui->lineReflBack->setProperty("GLpath", cb.path(1));
|
||||
ui->lineReflBack->setText(QFileInfo(cb.path(1)).fileName());
|
||||
ui->lineReflLeft->setProperty("GLpath", cb.path(2));
|
||||
ui->lineReflLeft->setText(QFileInfo(cb.path(2)).fileName());
|
||||
ui->lineReflRight->setProperty("GLpath", cb.path(3));
|
||||
ui->lineReflRight->setText(QFileInfo(cb.path(3)).fileName());
|
||||
ui->lineReflTop->setProperty("GLpath", cb.path(4));
|
||||
ui->lineReflTop->setText(QFileInfo(cb.path(4)).fileName());
|
||||
ui->lineReflBottom->setProperty("GLpath", cb.path(5));
|
||||
ui->lineReflBottom->setText(QFileInfo(cb.path(5)).fileName());
|
||||
active = true;
|
||||
materialChanged();
|
||||
}
|
||||
|
||||
@@ -19,16 +19,17 @@
|
||||
#ifndef MATERIAL_EDITOR_H
|
||||
#define MATERIAL_EDITOR_H
|
||||
|
||||
#include <QFileDialog>
|
||||
#include "glmaterial.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
namespace Ui {
|
||||
class MaterialEditor;
|
||||
class MaterialEditor;
|
||||
};
|
||||
|
||||
class MaterialEditor: public QWidget
|
||||
{
|
||||
class MaterialEditor: public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MaterialEditor(QWidget * parent = 0);
|
||||
|
||||
@@ -42,7 +43,9 @@ protected:
|
||||
Ui::MaterialEditor * ui;
|
||||
|
||||
private slots:
|
||||
void materialChanged() {if (active) emit changed();}
|
||||
void materialChanged() {
|
||||
if (active) emit changed();
|
||||
}
|
||||
void on_buttonReflFrontSelect_clicked();
|
||||
void on_buttonReflFrontClear_clicked();
|
||||
void on_buttonReflBackSelect_clicked();
|
||||
@@ -59,7 +62,6 @@ private slots:
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
};
|
||||
|
||||
#endif // MATERIAL_EDITOR_H
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "material_map_editor.h"
|
||||
|
||||
#include "ui_material_map_editor.h"
|
||||
|
||||
|
||||
@@ -30,11 +31,8 @@ MaterialMapEditor::MaterialMapEditor(QWidget * parent): QWidget(parent) {
|
||||
void MaterialMapEditor::changeEvent(QEvent * e) {
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QEvent::LanguageChange: ui->retranslateUi(this); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +54,8 @@ void MaterialMapEditor::setMap(const Map & m) {
|
||||
ui->sliderOffset->setValue(m.color_offset);
|
||||
ui->spinScaleX->setValue(m.bitmap_scale.x());
|
||||
ui->spinScaleY->setValue(m.bitmap_scale.y());
|
||||
ui->linePath->setProperty("GLpath", m.bitmap_path); ui->linePath->setText(QFileInfo(m.bitmap_path).fileName());
|
||||
ui->linePath->setProperty("GLpath", m.bitmap_path);
|
||||
ui->linePath->setText(QFileInfo(m.bitmap_path).fileName());
|
||||
updateIcon();
|
||||
active = true;
|
||||
}
|
||||
@@ -74,7 +73,10 @@ Map MaterialMapEditor::map() {
|
||||
|
||||
|
||||
void MaterialMapEditor::on_buttonSelect_clicked() {
|
||||
QString str = QFileDialog::getOpenFileName(this, "Select image", ui->linePath->property("GLpath").toString(), "Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
QString str = QFileDialog::getOpenFileName(this,
|
||||
"Select image",
|
||||
ui->linePath->property("GLpath").toString(),
|
||||
"Images(*.bmp *.jpg *.jpeg *.png *.tif *.tiff *.tga);;All files(*)");
|
||||
if (str.isEmpty()) return;
|
||||
ui->linePath->setProperty("GLpath", str);
|
||||
ui->linePath->setText(QFileInfo(str).fileName());
|
||||
|
||||
@@ -19,16 +19,17 @@
|
||||
#ifndef MATERIAL_MAP_EDITOR_H
|
||||
#define MATERIAL_MAP_EDITOR_H
|
||||
|
||||
#include <QFileDialog>
|
||||
#include "glmaterial.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
namespace Ui {
|
||||
class MaterialMapEditor;
|
||||
class MaterialMapEditor;
|
||||
};
|
||||
|
||||
class MaterialMapEditor: public QWidget
|
||||
{
|
||||
class MaterialMapEditor: public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MaterialMapEditor(QWidget * parent = 0);
|
||||
|
||||
@@ -44,13 +45,14 @@ protected:
|
||||
Ui::MaterialMapEditor * ui;
|
||||
|
||||
private slots:
|
||||
void mapChanged() {if (active) emit changed();}
|
||||
void mapChanged() {
|
||||
if (active) emit changed();
|
||||
}
|
||||
void on_buttonSelect_clicked();
|
||||
void on_buttonClear_clicked();
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
};
|
||||
|
||||
#endif // MATERIAL_MAP_EDITOR_H
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "openglwindow.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLPaintDevice>
|
||||
@@ -6,11 +7,7 @@
|
||||
#include <qopenglext.h>
|
||||
|
||||
|
||||
OpenGLWindow::OpenGLWindow(QWindow *parent)
|
||||
: QWindow(parent)
|
||||
, m_context(nullptr)
|
||||
, m_device(nullptr)
|
||||
{
|
||||
OpenGLWindow::OpenGLWindow(QWindow * parent): QWindow(parent), m_context(nullptr), m_device(nullptr) {
|
||||
setFlags(flags() | Qt::FramelessWindowHint);
|
||||
setSurfaceType(QWindow::OpenGLSurface);
|
||||
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
|
||||
@@ -25,7 +22,7 @@ OpenGLWindow::OpenGLWindow(QWindow *parent)
|
||||
#endif
|
||||
format.setDepthBufferSize(24);
|
||||
format.setSamples(8);
|
||||
// format.setStencilBufferSize(8);
|
||||
// format.setStencilBufferSize(8);
|
||||
setFormat(format);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
}
|
||||
@@ -36,21 +33,19 @@ OpenGLWindow::~OpenGLWindow() {
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::render(QPainter *painter) {
|
||||
}
|
||||
void OpenGLWindow::render(QPainter * painter) {}
|
||||
|
||||
|
||||
void OpenGLWindow::initialize() {
|
||||
}
|
||||
void OpenGLWindow::initialize() {}
|
||||
|
||||
|
||||
void OpenGLWindow::render() {
|
||||
// if (!m_device) m_device = new QOpenGLPaintDevice;
|
||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
// m_device->setSize(size() * devicePixelRatio());
|
||||
// m_device->setDevicePixelRatio(devicePixelRatio());
|
||||
// QPainter painter(m_device);
|
||||
// render(&painter);
|
||||
// if (!m_device) m_device = new QOpenGLPaintDevice;
|
||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
// m_device->setSize(size() * devicePixelRatio());
|
||||
// m_device->setDevicePixelRatio(devicePixelRatio());
|
||||
// QPainter painter(m_device);
|
||||
// render(&painter);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,25 +54,21 @@ void OpenGLWindow::renderLater() {
|
||||
}
|
||||
|
||||
|
||||
bool OpenGLWindow::event(QEvent *event) {
|
||||
bool OpenGLWindow::event(QEvent * event) {
|
||||
switch (event->type()) {
|
||||
case QEvent::UpdateRequest:
|
||||
renderNow();
|
||||
return true;
|
||||
default:
|
||||
return QWindow::event(event);
|
||||
case QEvent::UpdateRequest: renderNow(); return true;
|
||||
default: return QWindow::event(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::exposeEvent(QExposeEvent *event) {
|
||||
void OpenGLWindow::exposeEvent(QExposeEvent * event) {
|
||||
if (isExposed()) renderNow();
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::renderNow() {
|
||||
if (!isExposed())
|
||||
return;
|
||||
if (!isExposed()) return;
|
||||
bool needsInitialize = false;
|
||||
if (!m_context) {
|
||||
m_context = new QOpenGLContext(this);
|
||||
@@ -93,4 +84,3 @@ void OpenGLWindow::renderNow() {
|
||||
render();
|
||||
m_context->swapBuffers(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,36 +1,37 @@
|
||||
#include <QWindow>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QWindow>
|
||||
|
||||
class QPainter;
|
||||
class QOpenGLContext;
|
||||
class QOpenGLPaintDevice;
|
||||
|
||||
|
||||
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
|
||||
{
|
||||
class OpenGLWindow
|
||||
: public QWindow
|
||||
, protected QOpenGLFunctions {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OpenGLWindow(QWindow *parent = nullptr);
|
||||
explicit OpenGLWindow(QWindow * parent = nullptr);
|
||||
~OpenGLWindow();
|
||||
|
||||
virtual void render(QPainter *painter);
|
||||
virtual void render(QPainter * painter);
|
||||
virtual void render();
|
||||
|
||||
virtual void initialize();
|
||||
|
||||
QOpenGLContext * context() {return m_context;}
|
||||
QOpenGLContext * context() { return m_context; }
|
||||
|
||||
public slots:
|
||||
void renderLater();
|
||||
void renderNow();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
bool event(QEvent * event) override;
|
||||
|
||||
void exposeEvent(QExposeEvent *event) override;
|
||||
void exposeEvent(QExposeEvent * event) override;
|
||||
|
||||
private:
|
||||
QOpenGLContext *m_context;
|
||||
QOpenGLPaintDevice *m_device;
|
||||
QOpenGLContext * m_context;
|
||||
QOpenGLPaintDevice * m_device;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
#include "qglview_designerplugin.h"
|
||||
|
||||
#include "qglviewplugin.h"
|
||||
|
||||
|
||||
QGLViewDesignerPlugin::QGLViewDesignerPlugin(QObject * parent): QObject(parent)
|
||||
{
|
||||
QGLViewDesignerPlugin::QGLViewDesignerPlugin(QObject * parent): QObject(parent) {
|
||||
m_widgets.append(new QGLViewPlugin(this));
|
||||
}
|
||||
|
||||
|
||||
QList<QDesignerCustomWidgetInterface * > QGLViewDesignerPlugin::customWidgets() const {
|
||||
QList<QDesignerCustomWidgetInterface *> QGLViewDesignerPlugin::customWidgets() const {
|
||||
return m_widgets;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
#ifndef QGLVIEW_DESIGNERPLUGIN_H
|
||||
#define QGLVIEW_DESIGNERPLUGIN_H
|
||||
|
||||
#include <QtDesigner/QtDesigner>
|
||||
#include <QtCore/qplugin.h>
|
||||
#include <QtDesigner/QtDesigner>
|
||||
|
||||
|
||||
class QGLViewDesignerPlugin: public QObject, public QDesignerCustomWidgetCollectionInterface
|
||||
{
|
||||
class QGLViewDesignerPlugin
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetCollectionInterface {
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "qad.qglview")
|
||||
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
|
||||
|
||||
public:
|
||||
QGLViewDesignerPlugin(QObject * parent = 0);
|
||||
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
|
||||
virtual QList<QDesignerCustomWidgetInterface *> customWidgets() const;
|
||||
|
||||
private:
|
||||
QList<QDesignerCustomWidgetInterface * > m_widgets;
|
||||
|
||||
QList<QDesignerCustomWidgetInterface *> m_widgets;
|
||||
};
|
||||
|
||||
#endif // QGLVIEW_DESIGNERPLUGIN_H
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "glwidget.h"
|
||||
#include "qglviewplugin.h"
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
#include "glprimitives.h"
|
||||
#include "glwidget.h"
|
||||
#include "qglview.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
QGLViewPlugin::QGLViewPlugin(QObject * parent): QObject(parent) {
|
||||
m_initialized = false;
|
||||
@@ -11,8 +13,7 @@ QGLViewPlugin::QGLViewPlugin(QObject * parent): QObject(parent) {
|
||||
|
||||
|
||||
void QGLViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
if (m_initialized) return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
@@ -30,21 +31,24 @@ QWidget * QGLViewPlugin::createWidget(QWidget * parent) {
|
||||
if (m_initialized) {
|
||||
auto axis = new GLObjectBase();
|
||||
GLObjectBase * obj;
|
||||
float al = 1.;
|
||||
obj = new GLPrimitiveLine(QVector3D(0, 0, -al), QVector3D(0, 0, al));
|
||||
obj->material().color_diffuse = Qt::darkBlue; obj->setAcceptLight(false);
|
||||
float al = 1.;
|
||||
obj = new GLPrimitiveLine(QVector3D(0, 0, -al), QVector3D(0, 0, al));
|
||||
obj->material().color_diffuse = Qt::darkBlue;
|
||||
obj->setAcceptLight(false);
|
||||
obj->setSelectable(false);
|
||||
axis->addChild(obj);
|
||||
obj = new GLPrimitiveLine(QVector3D(-al, 0, 0), QVector3D(al, 0, 0));
|
||||
obj->material().color_diffuse = Qt::darkRed; obj->setAcceptLight(false);
|
||||
obj = new GLPrimitiveLine(QVector3D(-al, 0, 0), QVector3D(al, 0, 0));
|
||||
obj->material().color_diffuse = Qt::darkRed;
|
||||
obj->setAcceptLight(false);
|
||||
obj->setSelectable(false);
|
||||
axis->addChild(obj);
|
||||
obj = new GLPrimitiveLine(QVector3D(0, -al, 0), QVector3D(0, al, 0));
|
||||
obj->material().color_diffuse = Qt::darkGreen; obj->setAcceptLight(false);
|
||||
obj = new GLPrimitiveLine(QVector3D(0, -al, 0), QVector3D(0, al, 0));
|
||||
obj->material().color_diffuse = Qt::darkGreen;
|
||||
obj->setAcceptLight(false);
|
||||
obj->setSelectable(false);
|
||||
axis->addChild(obj);
|
||||
w->view()->addObject(axis);
|
||||
auto cam_light = new Light();
|
||||
auto cam_light = new Light();
|
||||
cam_light->intensity = 0.5;
|
||||
cam_light->setName("Camera_Light");
|
||||
w->view()->camera()->addChild(cam_light);
|
||||
@@ -92,4 +96,3 @@ QString QGLViewPlugin::domXml() const {
|
||||
QString QGLViewPlugin::includeFile() const {
|
||||
return QLatin1String("glwidget.h");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
|
||||
|
||||
|
||||
class QGLViewPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
class QGLViewPlugin
|
||||
: public QObject
|
||||
, public QDesignerCustomWidgetInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
@@ -27,7 +28,6 @@ public:
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif //QGLVIEWPLUGIN_H
|
||||
#endif // QGLVIEWPLUGIN_H
|
||||
|
||||
@@ -1,54 +1,127 @@
|
||||
#include "propertyeditor.h"
|
||||
|
||||
#include "clineedit.h"
|
||||
#include "colorbutton.h"
|
||||
#include "qpointedit.h"
|
||||
#include "qrectedit.h"
|
||||
#include "clineedit.h"
|
||||
#include <QPainter>
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QPainter>
|
||||
#include <QSpinBox>
|
||||
|
||||
|
||||
QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & index) const {
|
||||
QWidget * w = 0;
|
||||
int type = 0;
|
||||
QWidget * w = 0;
|
||||
int type = 0;
|
||||
QVariant value = index.data(Qt::UserRole);
|
||||
if (index.data(Qt::UserRole + 2).toString() == "__flags") return 0;
|
||||
if (index.data(Qt::UserRole + 1).toString() == "__flag") {
|
||||
qulonglong key = index.data(Qt::UserRole).toULongLong();
|
||||
value = index.parent().data(Qt::UserRole);
|
||||
w = new QCheckBox(parent); type = 14; ((QCheckBox*)w)->setChecked(((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0));
|
||||
((QCheckBox*)w)->setText("0x" + QString::number(key, 16).toUpper());
|
||||
connect((QCheckBox*)w, SIGNAL(clicked(bool)), this, SLOT(changedFlag()));
|
||||
//qDebug() << prop.enumerator().name();
|
||||
value = index.parent().data(Qt::UserRole);
|
||||
w = new QCheckBox(parent);
|
||||
type = 14;
|
||||
((QCheckBox *)w)->setChecked(((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0));
|
||||
((QCheckBox *)w)->setText("0x" + QString::number(key, 16).toUpper());
|
||||
connect((QCheckBox *)w, SIGNAL(clicked(bool)), this, SLOT(changedFlag()));
|
||||
// qDebug() << prop.enumerator().name();
|
||||
} else {
|
||||
if (value.canConvert<PropertyValuePair>()) {
|
||||
PropertyValuePair prop = value.value<PropertyValuePair>();
|
||||
if (prop.first.isEnumType()) {
|
||||
w = new QComboBox(parent); type = 13; ((QComboBox*)w)->setCurrentIndex(value.toInt());
|
||||
w = new QComboBox(parent);
|
||||
type = 13;
|
||||
((QComboBox *)w)->setCurrentIndex(value.toInt());
|
||||
w->setProperty("__prop", QVariant::fromValue<QMetaProperty>(prop.first));
|
||||
QMetaEnum menum = prop.first.enumerator();
|
||||
for (int i = 0; i < menum.keyCount(); ++i) {
|
||||
((QComboBox*)w)->addItem(QString(menum.key(i)) + " (0x" + QString::number(menum.value(i), 16).toUpper() + ")", menum.value(i));
|
||||
if (menum.value(i) == prop.second.toInt())
|
||||
((QComboBox*)w)->setCurrentIndex(i);
|
||||
((QComboBox *)w)
|
||||
->addItem(QString(menum.key(i)) + " (0x" + QString::number(menum.value(i), 16).toUpper() + ")", menum.value(i));
|
||||
if (menum.value(i) == prop.second.toInt()) ((QComboBox *)w)->setCurrentIndex(i);
|
||||
}
|
||||
connect((QComboBox*)w, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
|
||||
connect((QComboBox *)w, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
|
||||
}
|
||||
} else {
|
||||
switch (value.type()) {
|
||||
case QVariant::Int: w = new QSpinBox(parent); type = 2; ((QSpinBox*)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break;
|
||||
case QVariant::UInt: w = new QSpinBox(parent); type = 3; ((QSpinBox*)w)->setRange(0, 0xFFFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break;
|
||||
case QVariant::LongLong: w = new QSpinBox(parent); type = 4; ((QSpinBox*)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break;
|
||||
case QVariant::ULongLong: w = new QSpinBox(parent); type = 5; ((QSpinBox*)w)->setRange(0, 0xFFFFFFFF); connect((QSpinBox*)w, SIGNAL(valueChanged(int)), this, SLOT(changed())); break;
|
||||
case QVariant::Double: w = new QDoubleSpinBox(parent); type = 6; ((QDoubleSpinBox*)w)->setRange(-999999999, 999999999); ((QDoubleSpinBox*)w)->setDecimals(3); connect((QDoubleSpinBox*)w, SIGNAL(valueChanged(double)), this, SLOT(changed())); break;
|
||||
case QVariant::Bool: w = new QCheckBox(parent); type = 7; ((QCheckBox*)w)->setChecked(value.toBool()); connect((QCheckBox*)w, SIGNAL(toggled(bool)), this, SLOT(changed())); break;
|
||||
case QVariant::Color: w = new ColorButton(parent); type = 8; ((ColorButton*)w)->setUseAlphaChannel(true); ((ColorButton*)w)->setColor(value.value<QColor>()); connect((ColorButton*)w, SIGNAL(colorChanged(QColor)), this, SLOT(changed())); break;
|
||||
case QVariant::Point: w = new QPointEdit(parent); type = 9; ((QPointEdit*)w)->setDecimals(0); ((QPointEdit*)w)->setValue(QPointF(value.toPoint())); connect((QPointEdit*)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed())); break;
|
||||
case QVariant::PointF: w = new QPointEdit(parent); type = 10; ((QPointEdit*)w)->setDecimals(3); ((QPointEdit*)w)->setValue(value.toPointF()); connect((QPointEdit*)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed())); break;
|
||||
case QVariant::Rect: w = new QRectEdit(parent); type = 11; ((QRectEdit*)w)->setDecimals(0); ((QRectEdit*)w)->setValue(QRectF(value.toRect())); connect((QRectEdit*)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed())); break;
|
||||
case QVariant::RectF: w = new QRectEdit(parent); type = 12; ((QRectEdit*)w)->setDecimals(3); ((QRectEdit*)w)->setValue(value.toRectF()); connect((QRectEdit*)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed())); break;
|
||||
case QVariant::String: default: w = new CLineEdit(parent); type = 1; ((CLineEdit*)w)->setDefaultText(value.toString()); connect((CLineEdit*)w, SIGNAL(textChanged(QString)), this, SLOT(changed())); break;
|
||||
case QVariant::Int:
|
||||
w = new QSpinBox(parent);
|
||||
type = 2;
|
||||
((QSpinBox *)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF);
|
||||
connect((QSpinBox *)w, SIGNAL(valueChanged(int)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::UInt:
|
||||
w = new QSpinBox(parent);
|
||||
type = 3;
|
||||
((QSpinBox *)w)->setRange(0, 0xFFFFFFFF);
|
||||
connect((QSpinBox *)w, SIGNAL(valueChanged(int)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::LongLong:
|
||||
w = new QSpinBox(parent);
|
||||
type = 4;
|
||||
((QSpinBox *)w)->setRange(-0x7FFFFFFF, 0x7FFFFFFF);
|
||||
connect((QSpinBox *)w, SIGNAL(valueChanged(int)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::ULongLong:
|
||||
w = new QSpinBox(parent);
|
||||
type = 5;
|
||||
((QSpinBox *)w)->setRange(0, 0xFFFFFFFF);
|
||||
connect((QSpinBox *)w, SIGNAL(valueChanged(int)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::Double:
|
||||
w = new QDoubleSpinBox(parent);
|
||||
type = 6;
|
||||
((QDoubleSpinBox *)w)->setRange(-999999999, 999999999);
|
||||
((QDoubleSpinBox *)w)->setDecimals(3);
|
||||
connect((QDoubleSpinBox *)w, SIGNAL(valueChanged(double)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::Bool:
|
||||
w = new QCheckBox(parent);
|
||||
type = 7;
|
||||
((QCheckBox *)w)->setChecked(value.toBool());
|
||||
connect((QCheckBox *)w, SIGNAL(toggled(bool)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::Color:
|
||||
w = new ColorButton(parent);
|
||||
type = 8;
|
||||
((ColorButton *)w)->setUseAlphaChannel(true);
|
||||
((ColorButton *)w)->setColor(value.value<QColor>());
|
||||
connect((ColorButton *)w, SIGNAL(colorChanged(QColor)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::Point:
|
||||
w = new QPointEdit(parent);
|
||||
type = 9;
|
||||
((QPointEdit *)w)->setDecimals(0);
|
||||
((QPointEdit *)w)->setValue(QPointF(value.toPoint()));
|
||||
connect((QPointEdit *)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::PointF:
|
||||
w = new QPointEdit(parent);
|
||||
type = 10;
|
||||
((QPointEdit *)w)->setDecimals(3);
|
||||
((QPointEdit *)w)->setValue(value.toPointF());
|
||||
connect((QPointEdit *)w, SIGNAL(valueChanged(QPointF)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::Rect:
|
||||
w = new QRectEdit(parent);
|
||||
type = 11;
|
||||
((QRectEdit *)w)->setDecimals(0);
|
||||
((QRectEdit *)w)->setValue(QRectF(value.toRect()));
|
||||
connect((QRectEdit *)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::RectF:
|
||||
w = new QRectEdit(parent);
|
||||
type = 12;
|
||||
((QRectEdit *)w)->setDecimals(3);
|
||||
((QRectEdit *)w)->setValue(value.toRectF());
|
||||
connect((QRectEdit *)w, SIGNAL(valueChanged(QRectF)), this, SLOT(changed()));
|
||||
break;
|
||||
case QVariant::String:
|
||||
default:
|
||||
w = new CLineEdit(parent);
|
||||
type = 1;
|
||||
((CLineEdit *)w)->setDefaultText(value.toString());
|
||||
connect((CLineEdit *)w, SIGNAL(textChanged(QString)), this, SLOT(changed()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,15 +138,18 @@ QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & inde
|
||||
void Delegate::setWidgetProperty(QWidget * w, const QVariant & value) const {
|
||||
if (w == 0) return;
|
||||
switch (w->property("__type").toInt()) {
|
||||
case 1: ((CLineEdit*)w)->setText(value.toString()); break;
|
||||
case 2: case 3: case 4: case 5: ((QSpinBox*)w)->setValue(value.toInt()); break;
|
||||
case 6: ((QDoubleSpinBox*)w)->setValue(value.toDouble()); break;
|
||||
case 7: ((QCheckBox*)w)->setChecked(value.toBool()); break;
|
||||
case 8: ((ColorButton*)w)->setColor(value.value<QColor>()); break;
|
||||
case 9: ((QPointEdit*)w)->setValue(value.value<QPoint>()); break;
|
||||
case 10: ((QPointEdit*)w)->setValue(value.value<QPointF>()); break;
|
||||
case 11: ((QRectEdit*)w)->setValue(value.value<QRect>()); break;
|
||||
case 12: ((QRectEdit*)w)->setValue(value.value<QRectF>()); break;
|
||||
case 1: ((CLineEdit *)w)->setText(value.toString()); break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5: ((QSpinBox *)w)->setValue(value.toInt()); break;
|
||||
case 6: ((QDoubleSpinBox *)w)->setValue(value.toDouble()); break;
|
||||
case 7: ((QCheckBox *)w)->setChecked(value.toBool()); break;
|
||||
case 8: ((ColorButton *)w)->setColor(value.value<QColor>()); break;
|
||||
case 9: ((QPointEdit *)w)->setValue(value.value<QPoint>()); break;
|
||||
case 10: ((QPointEdit *)w)->setValue(value.value<QPointF>()); break;
|
||||
case 11: ((QRectEdit *)w)->setValue(value.value<QRect>()); break;
|
||||
case 12: ((QRectEdit *)w)->setValue(value.value<QRectF>()); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,19 +157,22 @@ void Delegate::setWidgetProperty(QWidget * w, const QVariant & value) const {
|
||||
const QVariant Delegate::widgetProperty(QWidget * w) const {
|
||||
if (w == 0) return QVariant();
|
||||
switch (w->property("__type").toInt()) {
|
||||
case 1: return QVariant::fromValue<QString>(((CLineEdit*)w)->text()); break;
|
||||
case 2: return QVariant::fromValue<int>(((QSpinBox*)w)->value()); break;
|
||||
case 3: return QVariant::fromValue<uint>(((QSpinBox*)w)->value()); break;
|
||||
case 4: return QVariant::fromValue<qlonglong>(((QSpinBox*)w)->value()); break;
|
||||
case 5: return QVariant::fromValue<qulonglong>(((QSpinBox*)w)->value()); break;
|
||||
case 6: return QVariant::fromValue<double>(((QDoubleSpinBox*)w)->value()); break;
|
||||
case 7: return QVariant::fromValue<bool>(((QCheckBox*)w)->isChecked()); break;
|
||||
case 8: return QVariant::fromValue<QColor>(((ColorButton*)w)->color()); break;
|
||||
case 9: return QVariant::fromValue<QPoint>(((QPointEdit*)w)->value().toPoint()); break;
|
||||
case 10: return QVariant::fromValue<QPointF>(((QPointEdit*)w)->value()); break;
|
||||
case 11: return QVariant::fromValue<QRect>(((QRectEdit*)w)->value().toRect()); break;
|
||||
case 12: return QVariant::fromValue<QRectF>(((QRectEdit*)w)->value()); break;
|
||||
case 13: return QVariant::fromValue<PropertyValuePair>(PropertyValuePair(w->property("__prop").value<QMetaProperty>(), ((QComboBox*)w)->itemData(((QComboBox*)w)->currentIndex()))); break;
|
||||
case 1: return QVariant::fromValue<QString>(((CLineEdit *)w)->text()); break;
|
||||
case 2: return QVariant::fromValue<int>(((QSpinBox *)w)->value()); break;
|
||||
case 3: return QVariant::fromValue<uint>(((QSpinBox *)w)->value()); break;
|
||||
case 4: return QVariant::fromValue<qlonglong>(((QSpinBox *)w)->value()); break;
|
||||
case 5: return QVariant::fromValue<qulonglong>(((QSpinBox *)w)->value()); break;
|
||||
case 6: return QVariant::fromValue<double>(((QDoubleSpinBox *)w)->value()); break;
|
||||
case 7: return QVariant::fromValue<bool>(((QCheckBox *)w)->isChecked()); break;
|
||||
case 8: return QVariant::fromValue<QColor>(((ColorButton *)w)->color()); break;
|
||||
case 9: return QVariant::fromValue<QPoint>(((QPointEdit *)w)->value().toPoint()); break;
|
||||
case 10: return QVariant::fromValue<QPointF>(((QPointEdit *)w)->value()); break;
|
||||
case 11: return QVariant::fromValue<QRect>(((QRectEdit *)w)->value().toRect()); break;
|
||||
case 12: return QVariant::fromValue<QRectF>(((QRectEdit *)w)->value()); break;
|
||||
case 13:
|
||||
return QVariant::fromValue<PropertyValuePair>(
|
||||
PropertyValuePair(w->property("__prop").value<QMetaProperty>(), ((QComboBox *)w)->itemData(((QComboBox *)w)->currentIndex())));
|
||||
break;
|
||||
default: return QVariant(); break;
|
||||
}
|
||||
return QVariant();
|
||||
@@ -101,35 +180,44 @@ const QVariant Delegate::widgetProperty(QWidget * w) const {
|
||||
|
||||
|
||||
void Delegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
|
||||
if (index.data(Qt::UserRole + 1).toString() != "__flag")
|
||||
model->setData(index, widgetProperty(editor), Qt::UserRole);
|
||||
if (index.data(Qt::UserRole + 1).toString() != "__flag") model->setData(index, widgetProperty(editor), Qt::UserRole);
|
||||
}
|
||||
|
||||
|
||||
void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
QVariant value = index.data(Qt::UserRole);
|
||||
QStyle * style = QApplication::style();
|
||||
QStyleOption * so = 0;
|
||||
QVariant value = index.data(Qt::UserRole);
|
||||
QStyle * style = QApplication::style();
|
||||
QStyleOption * so = 0;
|
||||
QStyleOptionComplex * soc = 0;
|
||||
QString text;
|
||||
QRect rect;
|
||||
QPalette::ColorRole role = (option.state.testFlag(QStyle::State_Selected) && option.state.testFlag(QStyle::State_Active) ? QPalette::HighlightedText : QPalette::WindowText);
|
||||
QPalette::ColorRole role =
|
||||
(option.state.testFlag(QStyle::State_Selected) && option.state.testFlag(QStyle::State_Active) ? QPalette::HighlightedText
|
||||
: QPalette::WindowText);
|
||||
if (index.data(Qt::UserRole + 2).toString() == "__flags") {
|
||||
text = "0x" + QString::number(value.toInt(), 16).toUpper();
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
return;
|
||||
}
|
||||
if (index.data(Qt::UserRole + 1) == "__flag") {
|
||||
qulonglong key = index.data(Qt::UserRole).toULongLong();
|
||||
value = index.parent().data(Qt::UserRole);
|
||||
so = new QStyleOptionButton();
|
||||
so->rect = option.rect;
|
||||
so->palette = option.palette;
|
||||
qulonglong key = index.data(Qt::UserRole).toULongLong();
|
||||
value = index.parent().data(Qt::UserRole);
|
||||
so = new QStyleOptionButton();
|
||||
so->rect = option.rect;
|
||||
so->palette = option.palette;
|
||||
so->fontMetrics = option.fontMetrics;
|
||||
((QStyleOptionButton*)so)->state = (((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0) ? QStyle::State_On : QStyle::State_Off) | option.state;
|
||||
((QStyleOptionButton*)so)->text = "0x" + QString::number(key, 16).toUpper();
|
||||
((QStyleOptionButton *)so)->state =
|
||||
(((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0) ? QStyle::State_On
|
||||
: QStyle::State_Off) |
|
||||
option.state;
|
||||
((QStyleOptionButton *)so)->text = "0x" + QString::number(key, 16).toUpper();
|
||||
if (option.state.testFlag(QStyle::State_Selected))
|
||||
so->palette.setColor(QPalette::WindowText, so->palette.color(QPalette::HighlightedText));
|
||||
style->drawControl(QStyle::CE_CheckBox, so, painter);
|
||||
@@ -144,126 +232,180 @@ void Delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, co
|
||||
break;
|
||||
}
|
||||
}
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
}
|
||||
} else {
|
||||
switch (value.type()) {
|
||||
switch (value.type()) {
|
||||
case QVariant::Int:
|
||||
text.setNum(value.toInt());
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::UInt:
|
||||
text.setNum(value.toUInt());
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::LongLong:
|
||||
text.setNum(value.toLongLong());
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::ULongLong:
|
||||
text.setNum(value.toULongLong());
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::Double:
|
||||
text.setNum(value.toDouble(), 'f', 3);
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::Bool:
|
||||
so = new QStyleOptionButton();
|
||||
so->rect = option.rect;
|
||||
so->state = option.state;
|
||||
so->palette = option.palette;
|
||||
so->fontMetrics = option.fontMetrics;
|
||||
((QStyleOptionButton*)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off) | option.state;
|
||||
so = new QStyleOptionButton();
|
||||
so->rect = option.rect;
|
||||
so->state = option.state;
|
||||
so->palette = option.palette;
|
||||
so->fontMetrics = option.fontMetrics;
|
||||
((QStyleOptionButton *)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off) | option.state;
|
||||
style->drawControl(QStyle::CE_CheckBox, so, painter);
|
||||
break;
|
||||
case QVariant::Color:
|
||||
rect = option.rect;//style->subElementRect(QStyle::QStyle::SE_FrameContents, so);
|
||||
rect = option.rect; // style->subElementRect(QStyle::QStyle::SE_FrameContents, so);
|
||||
rect.setRect(rect.x() + 3, rect.y() + 3, rect.width() - 6, rect.height() - 6);
|
||||
painter->fillRect(rect, ab);
|
||||
painter->fillRect(rect, value.value<QColor>());
|
||||
break;
|
||||
case QVariant::Point:
|
||||
text = pointString(value.toPoint());
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::PointF:
|
||||
text = pointString(value.toPointF());
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::Rect:
|
||||
text = rectString(value.toRect());
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::RectF:
|
||||
text = rectString(value.toRectF());
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text, role);
|
||||
style->drawItemText(painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, text),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
text,
|
||||
role);
|
||||
break;
|
||||
case QVariant::String: default:
|
||||
style->drawItemText(painter, style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, value.toString()),
|
||||
Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, value.toString(), role);
|
||||
case QVariant::String:
|
||||
default:
|
||||
style->drawItemText(
|
||||
painter,
|
||||
style->itemTextRect(option.fontMetrics, option.rect, Qt::AlignLeft | Qt::AlignVCenter, true, value.toString()),
|
||||
Qt::AlignLeft | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
true,
|
||||
value.toString(),
|
||||
role);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*so = new QStyleOptionFrame();
|
||||
so->rect = option.rect;
|
||||
so->state = option.state;
|
||||
so->palette = option.palette;
|
||||
so->fontMetrics = option.fontMetrics;
|
||||
((QStyleOptionFrame*)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off);
|
||||
style->drawPrimitive(QStyle::PE_PanelLineEdit, so, painter);
|
||||
style->drawPrimitive(QStyle::PE_FrameLineEdit, so, painter);
|
||||
break;*/
|
||||
/*so = new QStyleOptionFrame();
|
||||
so->rect = option.rect;
|
||||
so->state = option.state;
|
||||
so->palette = option.palette;
|
||||
so->fontMetrics = option.fontMetrics;
|
||||
((QStyleOptionFrame*)so)->state = (value.toBool() ? QStyle::State_On : QStyle::State_Off);
|
||||
style->drawPrimitive(QStyle::PE_PanelLineEdit, so, painter);
|
||||
style->drawPrimitive(QStyle::PE_FrameLineEdit, so, painter);
|
||||
break;*/
|
||||
if (so != 0) delete so;
|
||||
if (soc != 0) delete soc;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Delegate::changedFlag() {
|
||||
QAbstractItemModel * model = const_cast<QAbstractItemModel * >(cmi.model());
|
||||
model->setData(cmi, qobject_cast<QCheckBox * >(sender())->isChecked(), Qt::UserRole + 3);
|
||||
QModelIndex p = cmi.parent(), mi;
|
||||
int row = 0;
|
||||
QAbstractItemModel * model = const_cast<QAbstractItemModel *>(cmi.model());
|
||||
model->setData(cmi, qobject_cast<QCheckBox *>(sender())->isChecked(), Qt::UserRole + 3);
|
||||
QModelIndex p = cmi.parent(), mi;
|
||||
int row = 0;
|
||||
qulonglong val = 0;
|
||||
QList<QModelIndex> chldr;
|
||||
mi = model->index(row, 1, p);
|
||||
while (mi.isValid()) {
|
||||
chldr << mi;
|
||||
model->setData(mi, !mi.data(Qt::UserRole + 4).toBool(), Qt::UserRole + 4);
|
||||
mi =model->index(++row, 1, p);
|
||||
mi = model->index(++row, 1, p);
|
||||
}
|
||||
bool cc = cmi.data(Qt::UserRole + 3).toBool();
|
||||
bool cc = cmi.data(Qt::UserRole + 3).toBool();
|
||||
qulonglong cv = cmi.data(Qt::UserRole).toULongLong();
|
||||
//qDebug() << "*****";
|
||||
// qDebug() << "*****";
|
||||
if (cc && cv == 0) {
|
||||
val = 0;
|
||||
//qDebug() << "null" << cv;
|
||||
// qDebug() << "null" << cv;
|
||||
} else {
|
||||
if (!cc && cv != 0) {
|
||||
//qDebug() << "uncheck" << cv;
|
||||
// qDebug() << "uncheck" << cv;
|
||||
for (int i = 0; i < chldr.size(); ++i) {
|
||||
if (chldr[i] == cmi) continue;
|
||||
//qDebug() << (chldr[i].data(Qt::UserRole).toULongLong() & cv);
|
||||
if (chldr[i].data(Qt::UserRole).toULongLong() & cv)
|
||||
model->setData(chldr[i], false, Qt::UserRole + 3);
|
||||
// qDebug() << (chldr[i].data(Qt::UserRole).toULongLong() & cv);
|
||||
if (chldr[i].data(Qt::UserRole).toULongLong() & cv) model->setData(chldr[i], false, Qt::UserRole + 3);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < chldr.size(); ++i) {
|
||||
//qDebug() << chldr[i].data(Qt::UserRole + 3).toBool();
|
||||
if (chldr[i].data(Qt::UserRole + 3).toBool())
|
||||
val |= chldr[i].data(Qt::UserRole).toULongLong();
|
||||
// qDebug() << chldr[i].data(Qt::UserRole + 3).toBool();
|
||||
if (chldr[i].data(Qt::UserRole + 3).toBool()) val |= chldr[i].data(Qt::UserRole).toULongLong();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < chldr.size(); ++i) {
|
||||
@@ -271,25 +413,22 @@ void Delegate::changedFlag() {
|
||||
cv = chldr[i].data(Qt::UserRole).toULongLong();
|
||||
model->setData(chldr[i], ((val & cv) == cv && cv != 0) || (val == 0 && cv == 0), Qt::UserRole + 3);
|
||||
}
|
||||
//qDebug() << val;
|
||||
// qDebug() << val;
|
||||
model->setData(p, val, Qt::UserRole);
|
||||
model->setData(p.sibling(p.row(), 1), val, Qt::UserRole);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PropertyEditor::PropertyEditor(QWidget * parent): QTreeWidget(parent) {
|
||||
object = 0;
|
||||
object = 0;
|
||||
active_ = false;
|
||||
configTree();
|
||||
connect(this, SIGNAL(itemClicked(QTreeWidgetItem * , int)), this, SLOT(itemClicked(QTreeWidgetItem * , int)));
|
||||
connect(this, SIGNAL(itemChanged(QTreeWidgetItem * , int)), this, SLOT(itemChanged(QTreeWidgetItem * , int)));
|
||||
connect(this, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *, int)));
|
||||
connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(itemChanged(QTreeWidgetItem *, int)));
|
||||
}
|
||||
|
||||
|
||||
PropertyEditor::~PropertyEditor() {
|
||||
|
||||
}
|
||||
PropertyEditor::~PropertyEditor() {}
|
||||
|
||||
|
||||
void PropertyEditor::changeEvent(QEvent * e) {
|
||||
@@ -312,7 +451,6 @@ void PropertyEditor::configTree() {
|
||||
setHeaderLabels(lbls);
|
||||
setAlternatingRowColors(true);
|
||||
setItemDelegateForColumn(1, new Delegate());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -341,25 +479,25 @@ void PropertyEditor::rebuild() {
|
||||
clear();
|
||||
configTree();
|
||||
if (object == 0) return;
|
||||
active_ = false;
|
||||
active_ = false;
|
||||
const QMetaObject * mo = object->metaObject();
|
||||
QList<const QMetaObject * > mol;
|
||||
QList<const QMetaObject *> mol;
|
||||
while (mo != 0) {
|
||||
mol.push_front(mo);
|
||||
mo = mo->superClass();
|
||||
}
|
||||
int ps, pe;
|
||||
QTreeWidgetItem * ti, * tli, * tfi;
|
||||
QTreeWidgetItem *ti, *tli, *tfi;
|
||||
QVariant value;
|
||||
// QWidget * pw = 0;
|
||||
// QWidget * pw = 0;
|
||||
int chue = 0;
|
||||
QColor bc;
|
||||
font_b = font();
|
||||
font_b.setBold(true);
|
||||
foreach (const QMetaObject * o, mol) {
|
||||
ps = o->propertyOffset();
|
||||
pe = o->propertyCount();// - ps;
|
||||
//qDebug() << i->className() << ps << pe;
|
||||
foreach(const QMetaObject * o, mol) {
|
||||
ps = o->propertyOffset();
|
||||
pe = o->propertyCount(); // - ps;
|
||||
// qDebug() << i->className() << ps << pe;
|
||||
tli = new QTreeWidgetItem();
|
||||
tli->setText(0, o->className());
|
||||
tli->setFont(0, font_b);
|
||||
@@ -371,7 +509,7 @@ void PropertyEditor::rebuild() {
|
||||
for (int i = ps; i < pe; ++i) {
|
||||
props << o->property(i);
|
||||
value = o->property(i).read(object);
|
||||
ti = new QTreeWidgetItem();
|
||||
ti = new QTreeWidgetItem();
|
||||
ti->setSizeHint(1, QSize(20, 20));
|
||||
bc.setHsv(chue, 60, 245 + (i % 2) * 20 - 10);
|
||||
setItemBackColor(ti, bc);
|
||||
@@ -394,14 +532,13 @@ void PropertyEditor::rebuild() {
|
||||
ti->setData(1, Qt::UserRole, value);
|
||||
ti->setData(1, Qt::UserRole + 2, "__flags");
|
||||
ti->setData(0, Qt::UserRole + 1, QVariant::fromValue<QMetaProperty>(props.back()));
|
||||
}
|
||||
else if (props.back().isEnumType())
|
||||
} else if (props.back().isEnumType())
|
||||
value.setValue<PropertyValuePair>(PropertyValuePair(props.back(), value));
|
||||
//ti->setText(1, value.toString());
|
||||
// ti->setText(1, value.toString());
|
||||
ti->setData(1, Qt::UserRole, value);
|
||||
tli->addChild(ti);
|
||||
//const_cast<QModelIndex & >(indexFromItem(ti, 1)).;
|
||||
//if (pw != 0) setItemWidget(ti, 1, pw);
|
||||
// const_cast<QModelIndex & >(indexFromItem(ti, 1)).;
|
||||
// if (pw != 0) setItemWidget(ti, 1, pw);
|
||||
}
|
||||
chue += 60;
|
||||
chue %= 360;
|
||||
@@ -410,6 +547,4 @@ void PropertyEditor::rebuild() {
|
||||
}
|
||||
|
||||
|
||||
void PropertyEditor::refresh() {
|
||||
|
||||
}
|
||||
void PropertyEditor::refresh() {}
|
||||
|
||||
@@ -1,68 +1,87 @@
|
||||
#ifndef PROPERTYEDITOR_H
|
||||
#define PROPERTYEDITOR_H
|
||||
|
||||
#include <QTreeWidget>
|
||||
#include <QDebug>
|
||||
#include <QEvent>
|
||||
#include <QHeaderView>
|
||||
#include <QMetaProperty>
|
||||
#include <QEvent>
|
||||
#include <QDebug>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QTreeWidget>
|
||||
#include <qpiconfigwidget.h>
|
||||
|
||||
|
||||
class Delegate: public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Delegate(QObject * parent = 0): QStyledItemDelegate() {ab = QBrush(QImage(":/icons/alpha.png"));}
|
||||
|
||||
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {cmi = const_cast<QModelIndex & >(index); return widgetForProperty(parent, index);}
|
||||
void setEditorData(QWidget * editor, const QModelIndex & index) const {setWidgetProperty(editor, index.data(Qt::UserRole));}
|
||||
Delegate(QObject * parent = 0): QStyledItemDelegate() { ab = QBrush(QImage(":/icons/alpha.png")); }
|
||||
|
||||
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||
cmi = const_cast<QModelIndex &>(index);
|
||||
return widgetForProperty(parent, index);
|
||||
}
|
||||
void setEditorData(QWidget * editor, const QModelIndex & index) const { setWidgetProperty(editor, index.data(Qt::UserRole)); }
|
||||
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
|
||||
void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const {editor->setGeometry(option.rect);}
|
||||
void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||
editor->setGeometry(option.rect);
|
||||
}
|
||||
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
||||
|
||||
|
||||
private:
|
||||
QWidget * widgetForProperty(QWidget * parent, const QModelIndex & index) const;
|
||||
void setWidgetProperty(QWidget * w, const QVariant & value) const;
|
||||
const QVariant widgetProperty(QWidget * w) const;
|
||||
QString pointString(const QPoint & p) const {return QString::number(p.x()) + " x " + QString::number(p.y());}
|
||||
QString pointString(const QPointF & p) const {return QString::number(p.x()) + " x " + QString::number(p.y());}
|
||||
QString rectString(const QRect & r) const {return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " +
|
||||
QString::number(r.width()) + " x " + QString::number(r.height());}
|
||||
QString rectString(const QRectF & r) const {return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " +
|
||||
QString::number(r.width()) + " x " + QString::number(r.height());}
|
||||
|
||||
QString pointString(const QPoint & p) const { return QString::number(p.x()) + " x " + QString::number(p.y()); }
|
||||
QString pointString(const QPointF & p) const { return QString::number(p.x()) + " x " + QString::number(p.y()); }
|
||||
QString rectString(const QRect & r) const {
|
||||
return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " + QString::number(r.width()) + " x " +
|
||||
QString::number(r.height());
|
||||
}
|
||||
QString rectString(const QRectF & r) const {
|
||||
return QString::number(r.x()) + " x " + QString::number(r.y()) + " : " + QString::number(r.width()) + " x " +
|
||||
QString::number(r.height());
|
||||
}
|
||||
|
||||
QBrush ab;
|
||||
mutable QModelIndex cmi;
|
||||
|
||||
|
||||
private slots:
|
||||
void changed() {setModelData((QWidget * )sender(), const_cast<QAbstractItemModel * >(cmi.model()), cmi);}
|
||||
void changed() { setModelData((QWidget *)sender(), const_cast<QAbstractItemModel *>(cmi.model()), cmi); }
|
||||
void changedFlag();
|
||||
|
||||
};
|
||||
|
||||
typedef QPair<QMetaProperty, QVariant> PropertyValuePair;
|
||||
Q_DECLARE_METATYPE (PropertyValuePair)
|
||||
Q_DECLARE_METATYPE(PropertyValuePair)
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
Q_DECLARE_METATYPE (QMetaProperty)
|
||||
Q_DECLARE_METATYPE(QMetaProperty)
|
||||
#endif
|
||||
|
||||
|
||||
class PropertyEditor: public QTreeWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PropertyEditor(QWidget * parent = 0);
|
||||
virtual ~PropertyEditor();
|
||||
|
||||
void assignObject(QObject * o) {object = o; rebuild();}
|
||||
void assignObject(QObject * o) {
|
||||
object = o;
|
||||
rebuild();
|
||||
}
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent * e);
|
||||
|
||||
private:
|
||||
void configTree();
|
||||
void setItemBackColor(QTreeWidgetItem * i, const QColor & c) {i->setBackground(0, c); i->setBackground(1, c);}
|
||||
void setItemForeColor(QTreeWidgetItem * i, const QColor & c) {i->setForeground(0, c); i->setForeground(1, c);}
|
||||
void setItemBackColor(QTreeWidgetItem * i, const QColor & c) {
|
||||
i->setBackground(0, c);
|
||||
i->setBackground(1, c);
|
||||
}
|
||||
void setItemForeColor(QTreeWidgetItem * i, const QColor & c) {
|
||||
i->setForeground(0, c);
|
||||
i->setForeground(1, c);
|
||||
}
|
||||
void rebuild();
|
||||
void refresh();
|
||||
|
||||
@@ -74,7 +93,6 @@ private:
|
||||
private slots:
|
||||
void itemClicked(QTreeWidgetItem * item, int column);
|
||||
void itemChanged(QTreeWidgetItem * item, int column);
|
||||
|
||||
};
|
||||
|
||||
#endif // PROPERTYEDITOR_H
|
||||
|
||||
@@ -1,64 +1,64 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
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 Lesser General Public License for more details.
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qglview.h"
|
||||
#include <qad_types.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
#include <qad_types.h>
|
||||
|
||||
|
||||
QGLView::QGLView(): OpenGLWindow(), fbo_selection(3) {
|
||||
// setFrameShape(QFrame::NoFrame);
|
||||
// setViewportUpdateMode(FullViewportUpdate);
|
||||
// setCacheMode(CacheNone);
|
||||
// setMouseTracking(true);
|
||||
// setFocusPolicy(Qt::WheelFocus);
|
||||
// setScene(new QGraphicsScene());
|
||||
// setInteractive(true);
|
||||
// setFrameShape(QFrame::NoFrame);
|
||||
// setViewportUpdateMode(FullViewportUpdate);
|
||||
// setCacheMode(CacheNone);
|
||||
// setMouseTracking(true);
|
||||
// setFocusPolicy(Qt::WheelFocus);
|
||||
// setScene(new QGraphicsScene());
|
||||
// setInteractive(true);
|
||||
setIcon(QIcon("://icons/qglview.png"));
|
||||
deleting_ = false;
|
||||
timer = 0;
|
||||
deleting_ = false;
|
||||
timer = 0;
|
||||
need_init_ = is_first_draw = true;
|
||||
objects_.is_root = true;
|
||||
objects_.view_ = this;
|
||||
backColor_ = Qt::darkGray;
|
||||
hoverHaloColor_ = QColor(195, 140, 255, 96);
|
||||
selectionHaloColor_ = QColor(175, 255, 140);
|
||||
ambientColor_ = QColor(10, 10, 10);
|
||||
lastPos = QPoint(-1, -1);
|
||||
lineWidth_ = 1.;
|
||||
max_anisotropic = 1;
|
||||
max_texture_chanels = 8;
|
||||
objects_.is_root = true;
|
||||
objects_.view_ = this;
|
||||
backColor_ = Qt::darkGray;
|
||||
hoverHaloColor_ = QColor(195, 140, 255, 96);
|
||||
selectionHaloColor_ = QColor(175, 255, 140);
|
||||
ambientColor_ = QColor(10, 10, 10);
|
||||
lastPos = QPoint(-1, -1);
|
||||
lineWidth_ = 1.;
|
||||
max_anisotropic = 1;
|
||||
max_texture_chanels = 8;
|
||||
cameraOrbit_ = lightEnabled_ = true;
|
||||
shaders_supported = selecting_ = customMouseMove_ = false;
|
||||
sel_button = Qt::LeftButton;
|
||||
sel_mod = Qt::NoModifier;
|
||||
renderer_ = nullptr;
|
||||
fps_cnt = 0;
|
||||
sel_button = Qt::LeftButton;
|
||||
sel_mod = Qt::NoModifier;
|
||||
renderer_ = nullptr;
|
||||
fps_cnt = 0;
|
||||
fps_tm = fps_ = 0.;
|
||||
sel_obj = hov_obj = nullptr;
|
||||
fogDensity_ = fogEnd_ = 1.;
|
||||
fogStart_ = 0.;
|
||||
fogMode_ = Exp;
|
||||
hoverHaloFill_ = 0.333f;
|
||||
selectionHaloFill_ = 0.5f;
|
||||
//lmode = Simple;
|
||||
fogStart_ = 0.;
|
||||
fogMode_ = Exp;
|
||||
hoverHaloFill_ = 0.333f;
|
||||
selectionHaloFill_ = 0.5f;
|
||||
// lmode = Simple;
|
||||
shader_select = shader_halo = nullptr;
|
||||
setFeature(qglMSAA, false);
|
||||
setFeature(qglFXAA, false);
|
||||
@@ -88,18 +88,18 @@ QGLView::QGLView(): OpenGLWindow(), fbo_selection(3) {
|
||||
setFeature(qglDepthOfFieldFocus, 1.);
|
||||
setFeature(qglDepthOfFieldDiaphragm, 8.);
|
||||
mouse_first = mouseSelect_ = hoverHalo_ = selectionHalo_ = true;
|
||||
mouseRotate_ = true;
|
||||
mouseRotate_ = true;
|
||||
fogEnabled_ = is_init = grabMouse_ = shaders_bind = changed_ = false;
|
||||
rmode = GLObjectBase::Fill;
|
||||
sel_mode = QGLView::SingleSelection;
|
||||
// sel_pen = QPen(Qt::black, 1, Qt::DashLine);
|
||||
// sel_brush = QBrush(QColor(170, 100, 255, 120));
|
||||
rmode = GLObjectBase::Fill;
|
||||
sel_mode = QGLView::SingleSelection;
|
||||
// sel_pen = QPen(Qt::black, 1, Qt::DashLine);
|
||||
// sel_brush = QBrush(QColor(170, 100, 255, 120));
|
||||
camera()->setAim(QVector3D());
|
||||
camera()->setPos(QVector3D(2, 2, 2));
|
||||
camera()->setName("Camera");
|
||||
addObject(camera());
|
||||
emit cameraPosChanged(camera()->pos());
|
||||
//camera().aim_ = camera().pos_;
|
||||
// camera().aim_ = camera().pos_;
|
||||
ktm_.restart();
|
||||
}
|
||||
|
||||
@@ -139,9 +139,9 @@ void QGLView::addObject(GLObjectBase * o) {
|
||||
objects_.addChild(o);
|
||||
o->setView(this);
|
||||
collectLights();
|
||||
QList<GLObjectBase*> cl = o->children(true);
|
||||
QList<GLObjectBase *> cl = o->children(true);
|
||||
cl << o;
|
||||
foreach (GLObjectBase * i, cl) {
|
||||
foreach(GLObjectBase * i, cl) {
|
||||
emit objectAdded(i);
|
||||
}
|
||||
if (is_init) {
|
||||
@@ -199,7 +199,7 @@ void QGLView::removeLight(int index) {
|
||||
|
||||
|
||||
void QGLView::removeLight(Light * l) {
|
||||
foreach (Light * i, lights_)
|
||||
foreach(Light * i, lights_)
|
||||
if (i == l) removeObject(i);
|
||||
lights_.removeAll(l);
|
||||
}
|
||||
@@ -207,7 +207,8 @@ void QGLView::removeLight(Light * l) {
|
||||
|
||||
void QGLView::clearLights(bool deleteAll) {
|
||||
if (deleteAll)
|
||||
foreach (Light * i, lights_) delete i;
|
||||
foreach(Light * i, lights_)
|
||||
delete i;
|
||||
lights_.clear();
|
||||
}
|
||||
|
||||
@@ -228,7 +229,7 @@ Light * QGLView::light(int index) {
|
||||
|
||||
|
||||
Light * QGLView::light(const QString & name) {
|
||||
foreach (Light * i, lights_)
|
||||
foreach(Light * i, lights_)
|
||||
if (i->name_ == name) return i;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -237,7 +238,7 @@ Light * QGLView::light(const QString & name) {
|
||||
void QGLView::selectObject(GLObjectBase * o) {
|
||||
if (o == sel_obj) return;
|
||||
GLObjectBase * pso = sel_obj;
|
||||
sel_obj = o;
|
||||
sel_obj = o;
|
||||
emit selectionChanged(sel_obj, pso);
|
||||
}
|
||||
|
||||
@@ -250,7 +251,7 @@ void QGLView::timerEvent(QTimerEvent *) {
|
||||
renderNow();
|
||||
if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return;
|
||||
Qt::KeyboardModifiers km = QApplication::keyboardModifiers();
|
||||
foreach (int i, keys_)
|
||||
foreach(int i, keys_)
|
||||
emit keyEvent((Qt::Key)i, km);
|
||||
}
|
||||
|
||||
@@ -260,19 +261,19 @@ void QGLView::render() {
|
||||
resizeGL(width(), height());
|
||||
QRect g_rect(QPoint(), size());
|
||||
emit glBeforePaint();
|
||||
//qDebug() << "paintGL";
|
||||
//QMutexLocker ml_v(&v_mutex);
|
||||
// qDebug() << "paintGL";
|
||||
// QMutexLocker ml_v(&v_mutex);
|
||||
glEnable(GL_CULL_FACE);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
// glDisable(GL_CULL_FACE);
|
||||
camera()->apply(aspect);
|
||||
//objects_.preparePos(camera());
|
||||
// objects_.preparePos(camera());
|
||||
start_rp.cam_offset_matrix = camera()->offsetMatrix();
|
||||
start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
//objects_.buildTransform();
|
||||
start_rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
|
||||
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
// objects_.buildTransform();
|
||||
|
||||
/// Selection detect
|
||||
//glClearFramebuffer(QColor(100, 0, 0, 0));
|
||||
// glClearFramebuffer(QColor(100, 0, 0, 0));
|
||||
if (mouseSelect_) {
|
||||
glReleaseTextures();
|
||||
glEnableDepth();
|
||||
@@ -294,8 +295,8 @@ void QGLView::render() {
|
||||
if (shaders_supported && shader_select->isLinked()) shader_select->bind();
|
||||
renderSelection();
|
||||
if (shaders_supported && shader_select->isLinked()) shader_select->release();
|
||||
uchar cgid[4] = {0, 0, 0, 0};
|
||||
uint iid = 0;
|
||||
uchar cgid[4] = {0, 0, 0, 0};
|
||||
uint iid = 0;
|
||||
GLObjectBase * so = nullptr;
|
||||
if (!g_rect.contains(lastPos)) {
|
||||
if (hov_obj != nullptr) {
|
||||
@@ -305,13 +306,13 @@ void QGLView::render() {
|
||||
} else {
|
||||
glReadPixels(lastPos.x(), height() - lastPos.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, cgid);
|
||||
iid = uint(cgid[0] << 24) | uint(cgid[1] << 16) | uint(cgid[2] << 8) | cgid[3];
|
||||
so = ids.value(iid, nullptr);
|
||||
//qDebug() <<cgid[0]<<cgid[1]<<cgid[2]<<cgid[3]<< iid;
|
||||
so = ids.value(iid, nullptr);
|
||||
// qDebug() <<cgid[0]<<cgid[1]<<cgid[2]<<cgid[3]<< iid;
|
||||
if (so != hov_obj) {
|
||||
emit hoverChanged(so, hov_obj);
|
||||
hov_obj = so;
|
||||
}
|
||||
//if (so != 0) qDebug() << sel_obj->name() << cgid[3];
|
||||
// if (so != 0) qDebug() << sel_obj->name() << cgid[3];
|
||||
}
|
||||
if (selectionHalo_ && sel_obj) {
|
||||
fbo_selection.setWriteBuffer(2);
|
||||
@@ -329,9 +330,9 @@ void QGLView::render() {
|
||||
}
|
||||
|
||||
camera()->apply(aspect);
|
||||
start_rp.cam_offset_matrix = camera()->offsetMatrix();
|
||||
cur_mvpm = start_rp.proj_matrix * start_rp.view_matrix * start_rp.cam_offset_matrix;
|
||||
//objects_.preparePos(camera());
|
||||
start_rp.cam_offset_matrix = camera()->offsetMatrix();
|
||||
cur_mvpm = start_rp.proj_matrix * start_rp.view_matrix * start_rp.cam_offset_matrix;
|
||||
// objects_.preparePos(camera());
|
||||
|
||||
static GLRendererBase * prev_rend = nullptr;
|
||||
glShadeModel(GL_SMOOTH);
|
||||
@@ -355,7 +356,7 @@ void QGLView::render() {
|
||||
glReleaseTextures();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
//glClearFramebuffer(Qt::black, false);
|
||||
// glClearFramebuffer(Qt::black, false);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_BLEND);
|
||||
@@ -365,13 +366,13 @@ void QGLView::render() {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
if (selectionHalo_ && sel_obj) {
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2));
|
||||
//qDebug() << "draw sel";
|
||||
// qDebug() << "draw sel";
|
||||
glDrawQuad();
|
||||
}
|
||||
if (hoverHalo_ && hov_obj) {
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(1));
|
||||
//qDebug() << "draw hover";
|
||||
//glBindTexture(GL_TEXTURE_2D, textures_manager->loadTexture("batt_pn.jpg"));
|
||||
// qDebug() << "draw hover";
|
||||
// glBindTexture(GL_TEXTURE_2D, textures_manager->loadTexture("batt_pn.jpg"));
|
||||
glDrawQuad();
|
||||
}
|
||||
}
|
||||
@@ -380,11 +381,11 @@ void QGLView::render() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glUseProgram(0);
|
||||
|
||||
//glDisable(GL_BLEND);
|
||||
//glDisable(GL_LIGHTING);
|
||||
//glActiveTexture(GL_TEXTURE0);
|
||||
//glBindTexture(GL_TEXTURE_2D, textures_manager->loadTexture("batt_pn.jpg"));
|
||||
//glDrawQuad();
|
||||
// glDisable(GL_BLEND);
|
||||
// glDisable(GL_LIGHTING);
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
// glBindTexture(GL_TEXTURE_2D, textures_manager->loadTexture("batt_pn.jpg"));
|
||||
// glDrawQuad();
|
||||
|
||||
emit glEndPaint();
|
||||
|
||||
@@ -424,14 +425,14 @@ void QGLView::render() {
|
||||
time.restart();
|
||||
fps_cnt++;
|
||||
if (fps_tm < 1000.) return;
|
||||
fps_ = fps_cnt / fps_tm * 1000.;
|
||||
fps_tm = 0.;
|
||||
fps_ = fps_cnt / fps_tm * 1000.;
|
||||
fps_tm = 0.;
|
||||
fps_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::initialize() {
|
||||
//initializeOpenGLFunctions();
|
||||
// initializeOpenGLFunctions();
|
||||
glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glEnableDepth();
|
||||
@@ -458,10 +459,10 @@ void QGLView::initialize() {
|
||||
checkCaps();
|
||||
|
||||
shader_select = new QOpenGLShaderProgram(context());
|
||||
shader_halo = new QOpenGLShaderProgram(context());
|
||||
shader_halo = new QOpenGLShaderProgram(context());
|
||||
reloadThisShaders();
|
||||
is_init = true;
|
||||
//resizeGL(width(), height());
|
||||
is_init = true;
|
||||
// resizeGL(width(), height());
|
||||
need_init_ = false;
|
||||
emit glInitializeDone();
|
||||
}
|
||||
@@ -478,18 +479,19 @@ void QGLView::renderHalo(const GLObjectBase * obj, const uint iid, const QColor
|
||||
shader_halo->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4());
|
||||
shader_halo->setUniformValue("t0", 0);
|
||||
shader_halo->setUniformValue("dt", QVector2D(1.f / width(), 1.f / height()));
|
||||
shader_halo->setUniformValue("selected", QVector4D(float((iid >> 24) & 0xFF) / 255.f,
|
||||
float((iid >> 16) & 0xFF) / 255.f,
|
||||
float((iid >> 8) & 0xFF) / 255.f,
|
||||
float( iid & 0xFF) / 255.f));
|
||||
shader_halo->setUniformValue("selected",
|
||||
QVector4D(float((iid >> 24) & 0xFF) / 255.f,
|
||||
float((iid >> 16) & 0xFF) / 255.f,
|
||||
float((iid >> 8) & 0xFF) / 255.f,
|
||||
float(iid & 0xFF) / 255.f));
|
||||
shader_halo->setUniformValue("color", color);
|
||||
shader_halo->setUniformValue("fill", GLfloat(fill));
|
||||
//qDebug() << "render halo" << iid << shader_halo->log() << shader_halo->programId();
|
||||
// qDebug() << "render halo" << iid << shader_halo->log() << shader_halo->programId();
|
||||
glDisableDepth();
|
||||
//glClearFramebuffer(color);
|
||||
// glClearFramebuffer(color);
|
||||
glDrawQuad(shader_halo);
|
||||
glDepthMask(GL_TRUE);
|
||||
//glFlush();
|
||||
// glFlush();
|
||||
shader_halo->release();
|
||||
} else {
|
||||
glClearFramebuffer(Qt::black, false);
|
||||
@@ -498,7 +500,7 @@ void QGLView::renderHalo(const GLObjectBase * obj, const uint iid, const QColor
|
||||
|
||||
|
||||
void QGLView::renderSelection() {
|
||||
// cid = 1;
|
||||
// cid = 1;
|
||||
ids.clear();
|
||||
if (shaders_supported) {
|
||||
if (shader_select) {
|
||||
@@ -509,7 +511,7 @@ void QGLView::renderSelection() {
|
||||
}
|
||||
}
|
||||
}
|
||||
//qDebug() << sh_id_loc;
|
||||
// qDebug() << sh_id_loc;
|
||||
start_rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
|
||||
glPushMatrix();
|
||||
renderSingleSelection(objects_);
|
||||
@@ -524,32 +526,34 @@ void QGLView::renderSingleSelection(GLObjectBase & o) {
|
||||
}
|
||||
if (!o.visible_ || !o.select_) return;
|
||||
QMatrix4x4 curview = start_rp.view_matrix * start_rp.cam_offset_matrix * o.itransform_;
|
||||
uint id = qHash((quint64)&o);
|
||||
uint id = qHash((quint64)&o);
|
||||
ids.insert(id, &o);
|
||||
glLineWidth(o.line_width > 0.f ? o.line_width : lineWidth_);
|
||||
glPointSize(o.line_width > 0.f ? o.line_width : lineWidth_);
|
||||
if (shaders_supported){
|
||||
if (shaders_supported) {
|
||||
if (shader_select) {
|
||||
if (shader_select->isLinked()) {
|
||||
setUniformMatrices(shader_select, start_rp.proj_matrix, curview);
|
||||
shader_select->setUniformValue(sh_id_loc, QVector4D(float((id >> 24) & 0xFF) / 255.f,
|
||||
float((id >> 16) & 0xFF) / 255.f,
|
||||
float((id >> 8) & 0xFF) / 255.f,
|
||||
float(id & 0xFF) / 255.f));
|
||||
shader_select->setUniformValue(sh_id_loc,
|
||||
QVector4D(float((id >> 24) & 0xFF) / 255.f,
|
||||
float((id >> 16) & 0xFF) / 255.f,
|
||||
float((id >> 8) & 0xFF) / 255.f,
|
||||
float(id & 0xFF) / 255.f));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setGLMatrix(curview);
|
||||
glColor4f(float((id >> 24) & 0xFF) / 255.f,
|
||||
float((id >> 16) & 0xFF) / 255.f,
|
||||
float((id >> 8) & 0xFF) / 255.f,
|
||||
float(id & 0xFF) / 255.f);
|
||||
float((id >> 16) & 0xFF) / 255.f,
|
||||
float((id >> 8) & 0xFF) / 255.f,
|
||||
float(id & 0xFF) / 255.f);
|
||||
}
|
||||
//qDebug() << o.name() << "assign to" << sh_id_loc << cid;
|
||||
//glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) / 255.f);
|
||||
// ++cid;
|
||||
// qDebug() << o.name() << "assign to" << sh_id_loc << cid;
|
||||
// glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) /
|
||||
// 255.f);
|
||||
// ++cid;
|
||||
o.draw(nullptr, true);
|
||||
foreach (GLObjectBase * i, o.children_)
|
||||
foreach(GLObjectBase * i, o.children_)
|
||||
renderSingleSelection(*i);
|
||||
}
|
||||
|
||||
@@ -562,7 +566,7 @@ void QGLView::collectLights() {
|
||||
|
||||
void QGLView::objectDeleted(GLObjectBase * o) {
|
||||
if (deleting_) return;
|
||||
//qDebug() << "del" << o;
|
||||
// qDebug() << "del" << o;
|
||||
if (sel_obj == o) selectObject(nullptr);
|
||||
if (hov_obj == o) hov_obj = nullptr;
|
||||
collectLights();
|
||||
@@ -571,23 +575,23 @@ void QGLView::objectDeleted(GLObjectBase * o) {
|
||||
|
||||
void QGLView::collectObjectLights(GLObjectBase * o) {
|
||||
if (o->type_ == GLObjectBase::glLight) {
|
||||
lights_ << globject_cast<Light * >(o);
|
||||
lights_ << globject_cast<Light *>(o);
|
||||
o->view_ = this;
|
||||
}
|
||||
foreach (GLObjectBase * i, o->children())
|
||||
foreach(GLObjectBase * i, o->children())
|
||||
collectObjectLights(i);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::objectsCountInternal(int * cnt, GLObjectBase * where) {
|
||||
++(*cnt);
|
||||
foreach (GLObjectBase * i, where->children_)
|
||||
foreach(GLObjectBase * i, where->children_)
|
||||
objectsCountInternal(cnt, i);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::removeObjectInternal(GLObjectBase * o, GLObjectBase * where) {
|
||||
foreach (GLObjectBase * i, where->children_) {
|
||||
foreach(GLObjectBase * i, where->children_) {
|
||||
if (o == i)
|
||||
where->removeChild(i);
|
||||
else
|
||||
@@ -599,9 +603,9 @@ void QGLView::removeObjectInternal(GLObjectBase * o, GLObjectBase * where) {
|
||||
|
||||
void QGLView::checkCaps() {
|
||||
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic);
|
||||
//glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_chanels);
|
||||
//qDebug() << max_texture_chanels;
|
||||
//qDebug() << max_texture_chanels;
|
||||
// glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_chanels);
|
||||
// qDebug() << max_texture_chanels;
|
||||
// qDebug() << max_texture_chanels;
|
||||
shaders_supported = QOpenGLShaderProgram::hasOpenGLShaderPrograms();
|
||||
}
|
||||
|
||||
@@ -610,7 +614,7 @@ void QGLView::reloadThisShaders() {
|
||||
if (!shaders_supported) return;
|
||||
loadShaders(shader_select, "selection", "://shaders");
|
||||
loadShaders(shader_halo, "selection_halo", "://shaders");
|
||||
//loadShaders(shader_rope, "rope", "://shaders");
|
||||
// loadShaders(shader_rope, "rope", "://shaders");
|
||||
}
|
||||
|
||||
void QGLView::glReleaseTextures(int channels) {
|
||||
@@ -634,7 +638,8 @@ void QGLView::applyFog() {
|
||||
fog_col[1] = fogColor_.greenF();
|
||||
fog_col[2] = fogColor_.blueF();
|
||||
glFogfv(GL_FOG_COLOR, fog_col);
|
||||
} else glDisable(GL_FOG);
|
||||
} else
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
|
||||
|
||||
@@ -643,10 +648,10 @@ void QGLView::resizeGL(int width, int height) {
|
||||
if (width <= 0 || height <= 0) return;
|
||||
if (prev_size == QSize(width, height)) return;
|
||||
prev_size = QSize(width, height);
|
||||
aspect = float(width) / float(height);
|
||||
aspect = float(width) / float(height);
|
||||
if (renderer_) renderer_->resize(width, height);
|
||||
mouse_first = true;
|
||||
//qDebug() << "resize" << width << height;
|
||||
// qDebug() << "resize" << width << height;
|
||||
fbo_selection.resize(width, height);
|
||||
iaspect = (aspect == 0.f) ? 0. : 1 / aspect;
|
||||
glViewport(0, 0, width, height);
|
||||
@@ -655,14 +660,13 @@ void QGLView::resizeGL(int width, int height) {
|
||||
|
||||
|
||||
void QGLView::mouseReleaseEvent(QMouseEvent * e) {
|
||||
// qDebug() << "mouseReleaseEvent" << e << isActive();
|
||||
// QGraphicsView::mouseReleaseEvent(e);
|
||||
//setCursor(QCursor(Qt::ArrowCursor));
|
||||
// qDebug() << "mouseReleaseEvent" << e << isActive();
|
||||
// QGraphicsView::mouseReleaseEvent(e);
|
||||
// setCursor(QCursor(Qt::ArrowCursor));
|
||||
selecting_ = false;
|
||||
if (mouseSelect_ && e->button() == Qt::LeftButton) {
|
||||
if ((lastPos - downPos).manhattanLength() < 8) {
|
||||
if (sel_obj != hov_obj)
|
||||
selectObject(hov_obj);
|
||||
if (sel_obj != hov_obj) selectObject(hov_obj);
|
||||
}
|
||||
}
|
||||
emit glMouseReleaseEvent(e);
|
||||
@@ -670,38 +674,38 @@ void QGLView::mouseReleaseEvent(QMouseEvent * e) {
|
||||
|
||||
|
||||
void QGLView::mousePressEvent(QMouseEvent * e) {
|
||||
// qDebug() << "mousePressEvent" << e << isActive();
|
||||
// QGraphicsView::mousePressEvent(e);
|
||||
// mouseThis_ = (scene()->itemAt(mapToScene(e->pos()) , QTransform() ) == 0);
|
||||
// qDebug() << "mousePressEvent" << e << isActive();
|
||||
// QGraphicsView::mousePressEvent(e);
|
||||
// mouseThis_ = (scene()->itemAt(mapToScene(e->pos()) , QTransform() ) == 0);
|
||||
selecting_ = false;
|
||||
if (!QRect(QPoint(), size()).contains(e->pos())) return;
|
||||
/// TODO select by rect
|
||||
//if (e->button() == sel_button && e->modifiers() == sel_mod)
|
||||
// if (e->button() == sel_button && e->modifiers() == sel_mod)
|
||||
// selecting_ = true;
|
||||
lastPos = e->pos();
|
||||
downPos = lastPos;
|
||||
//qDebug() << mouseThis_;
|
||||
// qDebug() << mouseThis_;
|
||||
emit glMousePressEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::mouseMoveEvent(QMouseEvent * e) {
|
||||
// qDebug() << "mouseMoveEvent" << e << isActive();
|
||||
// QGraphicsView::mouseMoveEvent(e);
|
||||
//lastPos = e->pos();
|
||||
// qDebug() << "mouseMoveEvent" << e << isActive();
|
||||
// QGraphicsView::mouseMoveEvent(e);
|
||||
// lastPos = e->pos();
|
||||
if (selecting_) {
|
||||
return;
|
||||
}
|
||||
// if (!QRect(QPoint(), size()).contains(e->pos())) return;
|
||||
//if (scene()->itemAt(mapToScene(e->pos())) != 0) return;
|
||||
///qDebug() << e->x() << e->y();
|
||||
// if (!QRect(QPoint(), size()).contains(e->pos())) return;
|
||||
// if (scene()->itemAt(mapToScene(e->pos())) != 0) return;
|
||||
/// qDebug() << e->x() << e->y();
|
||||
QRect g_rect(QPoint(), size());
|
||||
if (mouseRotate_) {
|
||||
float dx = e->x() - lastPos.x();
|
||||
float dy = e->y() - lastPos.y();
|
||||
if (e->buttons() & Qt::LeftButton) {
|
||||
//camera().angle_z += dx / 4.;
|
||||
//camera().angle_xy += dy / 4.;
|
||||
// camera().angle_z += dx / 4.;
|
||||
// camera().angle_xy += dy / 4.;
|
||||
if (cameraOrbit_) {
|
||||
camera()->orbitZ(dx / 4.f);
|
||||
camera()->orbitXY(dy / 4.f);
|
||||
@@ -714,16 +718,16 @@ void QGLView::mouseMoveEvent(QMouseEvent * e) {
|
||||
float ad = camera()->distance();
|
||||
camera()->moveLeft(dx / 1000.f * ad);
|
||||
camera()->moveUp(dy / 1000.f * ad);
|
||||
//camera().pos.setX(camera().pos.x() + camera().pos.z() * dx / 500.);
|
||||
//camera().pos.setY(camera().pos.y() - camera().pos.z() * dy / 500.);
|
||||
// camera().pos.setX(camera().pos.x() + camera().pos.z() * dx / 500.);
|
||||
// camera().pos.setY(camera().pos.y() - camera().pos.z() * dy / 500.);
|
||||
emit cameraPosChanged(camera()->pos());
|
||||
}
|
||||
//lights[0]->pos_ = camera().pos();
|
||||
// lights[0]->pos_ = camera().pos();
|
||||
}
|
||||
if (customMouseMove_) emit customMouseMoveEvent(e->pos(), lastPos, e->buttons());
|
||||
lastPos = e->pos();
|
||||
if (grabMouse_) {
|
||||
//if (!isrunning) return;
|
||||
// if (!isrunning) return;
|
||||
QCursor::setPos(mapToGlobal(QRect(QPoint(), size()).center()));
|
||||
static bool mouse_sec = false;
|
||||
if (mouse_sec) {
|
||||
@@ -732,13 +736,13 @@ void QGLView::mouseMoveEvent(QMouseEvent * e) {
|
||||
}
|
||||
if (mouse_first) {
|
||||
mouse_first = false;
|
||||
mouse_sec = true;
|
||||
//qDebug() << "first" << e->pos();
|
||||
mouse_sec = true;
|
||||
// qDebug() << "first" << e->pos();
|
||||
return;
|
||||
}
|
||||
lastPos = g_rect.center();
|
||||
int dx = e->x() - lastPos.x();
|
||||
int dy = e->y() - lastPos.y();
|
||||
int dx = e->x() - lastPos.x();
|
||||
int dy = e->y() - lastPos.y();
|
||||
emit glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers()));
|
||||
return;
|
||||
}
|
||||
@@ -750,21 +754,21 @@ void QGLView::wheelEvent(QWheelEvent * e) {
|
||||
if (mouseRotate_) {
|
||||
double ang =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
e->delta();
|
||||
e->delta();
|
||||
#else
|
||||
e->angleDelta().y();
|
||||
e->angleDelta().y();
|
||||
#endif
|
||||
if (ang > 0) camera()->flyCloser(0.1f); //camera().pos.setZ(camera().pos.z() - 0.1 * camera().pos.z());
|
||||
if (ang < 0) camera()->flyFarer(0.1f); //camera().pos.setZ(camera().pos.z() + 0.1 * camera().pos.z());
|
||||
if (ang > 0) camera()->flyCloser(0.1f); // camera().pos.setZ(camera().pos.z() - 0.1 * camera().pos.z());
|
||||
if (ang < 0) camera()->flyFarer(0.1f); // camera().pos.setZ(camera().pos.z() + 0.1 * camera().pos.z());
|
||||
emit cameraPosChanged(camera()->pos());
|
||||
}
|
||||
emit glWheelEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::leaveEvent(QEvent * ) {
|
||||
void QGLView::leaveEvent(QEvent *) {
|
||||
lastPos = QPoint(-1, -1);
|
||||
//qDebug() << lastPos;
|
||||
// qDebug() << lastPos;
|
||||
}
|
||||
|
||||
|
||||
@@ -789,8 +793,7 @@ void QGLView::focusOutEvent(QFocusEvent *) {
|
||||
|
||||
|
||||
void QGLView::mouseDoubleClickEvent(QMouseEvent * e) {
|
||||
if (e->buttons().testFlag(QT_MID_BUTTON))
|
||||
emit doubleClick();
|
||||
if (e->buttons().testFlag(QT_MID_BUTTON)) emit doubleClick();
|
||||
}
|
||||
|
||||
|
||||
@@ -811,7 +814,7 @@ QByteArray QGLView::saveCamera() {
|
||||
}
|
||||
|
||||
|
||||
void QGLView::restoreCamera(const QByteArray &ba) {
|
||||
void QGLView::restoreCamera(const QByteArray & ba) {
|
||||
if (ba.isEmpty()) return;
|
||||
ChunkStream cs(ba);
|
||||
QVector3D pos, aim, ang;
|
||||
@@ -850,4 +853,3 @@ void QGLView::restoreFeatures(const QByteArray & ba) {
|
||||
ds >> f;
|
||||
features_ = f;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,71 +1,81 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
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 Lesser General Public License for more details.
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QGLVIEW_H
|
||||
#define QGLVIEW_H
|
||||
|
||||
#include "openglwindow.h"
|
||||
#include "glframebuffer.h"
|
||||
#include "glprimitives.h"
|
||||
#include "glparticles_system.h"
|
||||
#include "glprimitives.h"
|
||||
#include "glrendererbase.h"
|
||||
#include "openglwindow.h"
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QTime>
|
||||
|
||||
|
||||
class QGLView: public OpenGLWindow, public QGLViewBase
|
||||
{
|
||||
class QGLView
|
||||
: public OpenGLWindow
|
||||
, public QGLViewBase {
|
||||
friend class GLRendererBase;
|
||||
friend class GLObjectBase;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY (QColor backColor READ backColor WRITE setBackColor)
|
||||
Q_PROPERTY (float lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY (float FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY (float depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY (float depthEnd READ depthEnd WRITE setDepthEnd)
|
||||
Q_PROPERTY (QColor ambientColor READ ambientColor WRITE setAmbientColor)
|
||||
Q_PROPERTY (QColor fogColor READ fogColor WRITE setFogColor)
|
||||
Q_PROPERTY (float fogDensity READ fogDensity WRITE setFogDensity)
|
||||
Q_PROPERTY (float fogStart READ fogStart WRITE setFogStart)
|
||||
Q_PROPERTY (float fogEnd READ fogEnd WRITE setFogEnd)
|
||||
Q_PROPERTY (FogMode fogMode READ fogMode WRITE setFogMode)
|
||||
Q_PROPERTY (bool fogEnabled READ isFogEnabled WRITE setFogEnabled)
|
||||
Q_PROPERTY (int renderMode READ renderMode WRITE setRenderMode)
|
||||
Q_PROPERTY (bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY (bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY (bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY (bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY (bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY (QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY (float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY (bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY (QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY (float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
Q_PROPERTY (Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton)
|
||||
Q_PROPERTY (Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier)
|
||||
Q_PROPERTY (SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
|
||||
Q_PROPERTY(QColor backColor READ backColor WRITE setBackColor)
|
||||
Q_PROPERTY(float lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY(float FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY(float depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY(float depthEnd READ depthEnd WRITE setDepthEnd)
|
||||
Q_PROPERTY(QColor ambientColor READ ambientColor WRITE setAmbientColor)
|
||||
Q_PROPERTY(QColor fogColor READ fogColor WRITE setFogColor)
|
||||
Q_PROPERTY(float fogDensity READ fogDensity WRITE setFogDensity)
|
||||
Q_PROPERTY(float fogStart READ fogStart WRITE setFogStart)
|
||||
Q_PROPERTY(float fogEnd READ fogEnd WRITE setFogEnd)
|
||||
Q_PROPERTY(FogMode fogMode READ fogMode WRITE setFogMode)
|
||||
Q_PROPERTY(bool fogEnabled READ isFogEnabled WRITE setFogEnabled)
|
||||
Q_PROPERTY(int renderMode READ renderMode WRITE setRenderMode)
|
||||
Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY(bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY(bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY(bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY(bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY(QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY(float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY(bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY(QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY(float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
Q_PROPERTY(Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton)
|
||||
Q_PROPERTY(Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier)
|
||||
Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
|
||||
|
||||
public:
|
||||
QGLView();
|
||||
virtual ~QGLView();
|
||||
|
||||
enum FogMode {Linear = GL_LINEAR, Exp = GL_EXP, Exp2 = GL_EXP2};
|
||||
enum SelectionMode {NoSelection, SingleSelection, MultiSelection};
|
||||
enum FogMode {
|
||||
Linear = GL_LINEAR,
|
||||
Exp = GL_EXP,
|
||||
Exp2 = GL_EXP2
|
||||
};
|
||||
enum SelectionMode {
|
||||
NoSelection,
|
||||
SingleSelection,
|
||||
MultiSelection
|
||||
};
|
||||
enum Feature {
|
||||
qglMSAA,
|
||||
qglFXAA,
|
||||
@@ -96,8 +106,8 @@ public:
|
||||
qglDepthOfFieldDiaphragm
|
||||
};
|
||||
|
||||
Q_ENUMS (FogMode)
|
||||
Q_ENUMS (SelectionMode)
|
||||
Q_ENUMS(FogMode)
|
||||
Q_ENUMS(SelectionMode)
|
||||
|
||||
void stop();
|
||||
void start(float freq = 60.);
|
||||
@@ -105,72 +115,76 @@ public:
|
||||
GLRendererBase * renderer();
|
||||
void setRenderer(GLRendererBase * r, GLRendererBase ** prev = nullptr);
|
||||
|
||||
QColor backColor() const {return backColor_;}
|
||||
float lineWidth() const {return lineWidth_;}
|
||||
float FOV() const {return camera()->fov_;}
|
||||
float depthStart() const {return camera()->depth_start;}
|
||||
float depthEnd() const {return camera()->depth_end;}
|
||||
float currentFPS() const {return fps_;}
|
||||
int maxAnisotropicLevel() const {return max_anisotropic;}
|
||||
QColor backColor() const { return backColor_; }
|
||||
float lineWidth() const { return lineWidth_; }
|
||||
float FOV() const { return camera()->fov_; }
|
||||
float depthStart() const { return camera()->depth_start; }
|
||||
float depthEnd() const { return camera()->depth_end; }
|
||||
float currentFPS() const { return fps_; }
|
||||
int maxAnisotropicLevel() const { return max_anisotropic; }
|
||||
|
||||
QColor ambientColor() const {return ambientColor_;}
|
||||
QColor fogColor() const {return fogColor_;}
|
||||
float fogDensity() const {return fogDensity_;}
|
||||
float fogStart() const {return fogStart_;}
|
||||
float fogEnd() const {return fogEnd_;}
|
||||
FogMode fogMode() const {return fogMode_;}
|
||||
bool isFogEnabled() const {return fogEnabled_;}
|
||||
bool isLightEnabled() const {return lightEnabled_;}
|
||||
bool isGrabMouseEnabled() const {return grabMouse_;}
|
||||
bool isMouseRotateEnabled() const {return mouseRotate_;}
|
||||
bool isMouseSelectionEnabled() const {return mouseSelect_;}
|
||||
bool isCameraOrbit() const {return cameraOrbit_;}
|
||||
bool isHoverHaloEnabled() const {return hoverHalo_;}
|
||||
QColor hoverHaloColor() const {return hoverHaloColor_;}
|
||||
float hoverHaloFillAlpha() const {return hoverHaloFill_;}
|
||||
bool isSelectionHaloEnabled() const {return selectionHalo_;}
|
||||
QColor selectionHaloColor() const {return selectionHaloColor_;}
|
||||
float selectionHaloFillAlpha() const {return selectionHaloFill_;}
|
||||
QColor ambientColor() const { return ambientColor_; }
|
||||
QColor fogColor() const { return fogColor_; }
|
||||
float fogDensity() const { return fogDensity_; }
|
||||
float fogStart() const { return fogStart_; }
|
||||
float fogEnd() const { return fogEnd_; }
|
||||
FogMode fogMode() const { return fogMode_; }
|
||||
bool isFogEnabled() const { return fogEnabled_; }
|
||||
bool isLightEnabled() const { return lightEnabled_; }
|
||||
bool isGrabMouseEnabled() const { return grabMouse_; }
|
||||
bool isMouseRotateEnabled() const { return mouseRotate_; }
|
||||
bool isMouseSelectionEnabled() const { return mouseSelect_; }
|
||||
bool isCameraOrbit() const { return cameraOrbit_; }
|
||||
bool isHoverHaloEnabled() const { return hoverHalo_; }
|
||||
QColor hoverHaloColor() const { return hoverHaloColor_; }
|
||||
float hoverHaloFillAlpha() const { return hoverHaloFill_; }
|
||||
bool isSelectionHaloEnabled() const { return selectionHalo_; }
|
||||
QColor selectionHaloColor() const { return selectionHaloColor_; }
|
||||
float selectionHaloFillAlpha() const { return selectionHaloFill_; }
|
||||
|
||||
QVariant feature(Feature f) const {return features_.value(int(f));}
|
||||
QVariant setFeature(Feature f, const QVariant & value) {QVariant ret = features_.value(int(f)); features_[int(f)] = value; return ret;}
|
||||
bool isFeatureEnabled(Feature f) const {return features_[int(f)].toBool();}
|
||||
QVariant feature(Feature f) const { return features_.value(int(f)); }
|
||||
QVariant setFeature(Feature f, const QVariant & value) {
|
||||
QVariant ret = features_.value(int(f));
|
||||
features_[int(f)] = value;
|
||||
return ret;
|
||||
}
|
||||
bool isFeatureEnabled(Feature f) const { return features_[int(f)].toBool(); }
|
||||
|
||||
int renderMode() const {return (int)rmode;}
|
||||
void setRenderMode(int mode) {rmode = (GLObjectBase::RenderMode)mode;}
|
||||
int renderMode() const { return (int)rmode; }
|
||||
void setRenderMode(int mode) { rmode = (GLObjectBase::RenderMode)mode; }
|
||||
|
||||
void addObject(GLObjectBase * o);
|
||||
// void addObject(GLObjectBase & o) {addObject(&o);}
|
||||
// void addObject(GLObjectBase & o) {addObject(&o);}
|
||||
int objectsCount(bool all = false);
|
||||
void removeObject(GLObjectBase * o, bool inChildren = true);
|
||||
void removeObject(GLObjectBase & o, bool inChildren = true);
|
||||
void clearObjects(bool deleteAll = false);
|
||||
QList<GLObjectBase * > objects(bool all = false);
|
||||
QList<GLObjectBase *> objects(bool all = false);
|
||||
|
||||
int lightsCount() const;
|
||||
void removeLight(int index);
|
||||
void removeLight(Light * l);
|
||||
void clearLights(bool deleteAll = false);
|
||||
QList<Light * > lights() {return lights_;}
|
||||
QList<Light *> lights() { return lights_; }
|
||||
|
||||
void addTexture(const QString & path);
|
||||
void addAnimation(const QString & dir, const QString & name);
|
||||
|
||||
const GLObjectBase & rootObject() {return objects_;}
|
||||
GLObjectBase * object(int index) {return objects_.child(index);}
|
||||
GLObjectBase * object(const QString & name) {return objects_.child(name);}
|
||||
const GLObjectBase & rootObject() { return objects_; }
|
||||
GLObjectBase * object(int index) { return objects_.child(index); }
|
||||
GLObjectBase * object(const QString & name) { return objects_.child(name); }
|
||||
Light * light(int index);
|
||||
Light * light(const QString & name);
|
||||
|
||||
SelectionMode selectionMode() const {return sel_mode;}
|
||||
Qt::MouseButton selectionButton() const {return sel_button;}
|
||||
Qt::KeyboardModifier selectionModifier() const {return sel_mod;}
|
||||
SelectionMode selectionMode() const { return sel_mode; }
|
||||
Qt::MouseButton selectionButton() const { return sel_button; }
|
||||
Qt::KeyboardModifier selectionModifier() const { return sel_mod; }
|
||||
|
||||
void setSelectionMode(SelectionMode v) {sel_mode = v;}
|
||||
void setSelectionButton(Qt::MouseButton v) {sel_button = v;}
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;}
|
||||
void setSelectionMode(SelectionMode v) { sel_mode = v; }
|
||||
void setSelectionButton(Qt::MouseButton v) { sel_button = v; }
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) { sel_mod = v; }
|
||||
void selectObject(GLObjectBase * o);
|
||||
GLObjectBase * selectedObject() const {return sel_obj;}
|
||||
GLObjectBase * selectedObject() const { return sel_obj; }
|
||||
|
||||
void glReleaseTextures(int channels = 8);
|
||||
QByteArray saveCamera();
|
||||
@@ -186,14 +200,14 @@ protected:
|
||||
void render();
|
||||
void resizeEvent(QResizeEvent * e);
|
||||
|
||||
void timerEvent(QTimerEvent * );
|
||||
void timerEvent(QTimerEvent *);
|
||||
void initialize();
|
||||
void resizeGL(int width, int height);
|
||||
void mousePressEvent(QMouseEvent * e);
|
||||
void mouseMoveEvent(QMouseEvent * e);
|
||||
void mouseReleaseEvent(QMouseEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void leaveEvent(QEvent * );
|
||||
void leaveEvent(QEvent *);
|
||||
void mouseDoubleClickEvent(QMouseEvent * e);
|
||||
|
||||
void keyPressEvent(QKeyEvent * e);
|
||||
@@ -212,7 +226,7 @@ private:
|
||||
void objectsCountInternal(int * cnt, GLObjectBase * where);
|
||||
void removeObjectInternal(GLObjectBase * o, GLObjectBase * where);
|
||||
void renderSingleSelection(GLObjectBase & o);
|
||||
//void renderSingleShadow(GLObjectBase & o);
|
||||
// void renderSingleShadow(GLObjectBase & o);
|
||||
void renderHalo(const GLObjectBase * obj, const uint iid, const QColor & color, const float & fill);
|
||||
void reloadThisShaders();
|
||||
void processKeys();
|
||||
@@ -220,18 +234,18 @@ private:
|
||||
|
||||
QPoint lastPos, downPos;
|
||||
GLObjectBase objects_;
|
||||
QList<Light * > lights_;
|
||||
// uint cid;
|
||||
QHash<uint, GLObjectBase * > ids;
|
||||
QList<Light *> lights_;
|
||||
// uint cid;
|
||||
QHash<uint, GLObjectBase *> ids;
|
||||
QSet<int> keys_;
|
||||
FogMode fogMode_;
|
||||
QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_;
|
||||
QElapsedTimer time, ktm_;
|
||||
GLint max_anisotropic, max_texture_chanels;
|
||||
GLObjectBase::RenderMode rmode;
|
||||
GLObjectBase * sel_obj, * hov_obj;
|
||||
GLObjectBase *sel_obj, *hov_obj;
|
||||
GLFramebuffer fbo_selection;
|
||||
QOpenGLShaderProgram * shader_select, * shader_halo;
|
||||
QOpenGLShaderProgram *shader_select, *shader_halo;
|
||||
GLRendererBase * renderer_;
|
||||
SelectionMode sel_mode;
|
||||
Qt::MouseButton sel_button;
|
||||
@@ -247,33 +261,39 @@ private:
|
||||
bool hoverHalo_, selectionHalo_, shaders_bind, selecting_;
|
||||
|
||||
public slots:
|
||||
void setBackColor(const QColor & arg) {backColor_ = arg;}
|
||||
void setLineWidth(const float & arg) {lineWidth_ = arg;}
|
||||
void setFOV(const float & arg) {camera()->fov_ = arg;}
|
||||
void setDepthStart(const float & arg) {camera()->depth_start = arg;}
|
||||
void setDepthEnd(const float & arg) {camera()->depth_end = arg;}
|
||||
void setAmbientColor(const QColor & arg) {ambientColor_ = arg;}
|
||||
void setFogColor(const QColor & arg) {fogColor_ = arg;}
|
||||
void setFogDensity(const float & arg) {fogDensity_ = arg;}
|
||||
void setFogStart(const float & arg) {fogStart_ = arg;}
|
||||
void setFogEnd(const float & arg) {fogEnd_ = arg;}
|
||||
void setFogMode(const FogMode & arg) {fogMode_ = arg;}
|
||||
void setFogEnabled(const bool & arg) {fogEnabled_ = arg;}
|
||||
void setLightEnabled(const bool & arg) {lightEnabled_ = arg;}
|
||||
void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;}
|
||||
void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;}
|
||||
void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;}
|
||||
void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;}
|
||||
void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;}
|
||||
void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;}
|
||||
void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;}
|
||||
void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;}
|
||||
void setSelectionHaloEnabled(const bool & arg) {selectionHalo_ = arg;}
|
||||
void setSelectionHaloColor(const QColor & arg) {selectionHaloColor_ = arg;}
|
||||
void setSelectionHaloFillAlpha(const float & arg) {selectionHaloFill_ = arg;}
|
||||
void setBackColor(const QColor & arg) { backColor_ = arg; }
|
||||
void setLineWidth(const float & arg) { lineWidth_ = arg; }
|
||||
void setFOV(const float & arg) { camera()->fov_ = arg; }
|
||||
void setDepthStart(const float & arg) { camera()->depth_start = arg; }
|
||||
void setDepthEnd(const float & arg) { camera()->depth_end = arg; }
|
||||
void setAmbientColor(const QColor & arg) { ambientColor_ = arg; }
|
||||
void setFogColor(const QColor & arg) { fogColor_ = arg; }
|
||||
void setFogDensity(const float & arg) { fogDensity_ = arg; }
|
||||
void setFogStart(const float & arg) { fogStart_ = arg; }
|
||||
void setFogEnd(const float & arg) { fogEnd_ = arg; }
|
||||
void setFogMode(const FogMode & arg) { fogMode_ = arg; }
|
||||
void setFogEnabled(const bool & arg) { fogEnabled_ = arg; }
|
||||
void setLightEnabled(const bool & arg) { lightEnabled_ = arg; }
|
||||
void setGrabMouseEnabled(const bool & arg) {
|
||||
grabMouse_ = arg;
|
||||
mouse_first = true;
|
||||
}
|
||||
void setMouseRotateEnabled(const bool & arg) { mouseRotate_ = arg; }
|
||||
void setMouseSelectionEnabled(const bool & arg) { mouseSelect_ = arg; }
|
||||
void setCustomMouseMove(const bool & arg) { customMouseMove_ = arg; }
|
||||
void setCameraOrbit(const bool & arg) { cameraOrbit_ = arg; }
|
||||
void setHoverHaloEnabled(const bool & arg) { hoverHalo_ = arg; }
|
||||
void setHoverHaloColor(const QColor & arg) { hoverHaloColor_ = arg; }
|
||||
void setHoverHaloFillAlpha(const float & arg) { hoverHaloFill_ = arg; }
|
||||
void setSelectionHaloEnabled(const bool & arg) { selectionHalo_ = arg; }
|
||||
void setSelectionHaloColor(const QColor & arg) { selectionHaloColor_ = arg; }
|
||||
void setSelectionHaloFillAlpha(const float & arg) { selectionHaloFill_ = arg; }
|
||||
|
||||
void reloadShaders() {if (renderer_ != nullptr) renderer_->reloadShaders(); reloadThisShaders();}
|
||||
void deselect() {sel_obj = nullptr;}
|
||||
void reloadShaders() {
|
||||
if (renderer_ != nullptr) renderer_->reloadShaders();
|
||||
reloadThisShaders();
|
||||
}
|
||||
void deselect() { sel_obj = nullptr; }
|
||||
|
||||
signals:
|
||||
void glBeforePaint();
|
||||
@@ -294,9 +314,8 @@ signals:
|
||||
|
||||
void hoverChanged(GLObjectBase * cur, GLObjectBase * prev);
|
||||
void selectionChanged(GLObjectBase * cur, GLObjectBase * prev);
|
||||
void objectAdded(GLObjectBase * );
|
||||
void objectAdded(GLObjectBase *);
|
||||
void doubleClick();
|
||||
|
||||
};
|
||||
|
||||
#endif // QGLVIEW_H
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qglview_window.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include "qglview_window.h"
|
||||
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
@@ -29,7 +30,7 @@ int main(int argc, char ** argv) {
|
||||
w.show();
|
||||
QStringList al(a.arguments());
|
||||
al.pop_front();
|
||||
foreach (QString s, al)
|
||||
foreach(QString s, al)
|
||||
w.loadFile(s);
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
*/
|
||||
|
||||
#include "qglview_window.h"
|
||||
#include "loader_qgl.h"
|
||||
#include "loader_ase.h"
|
||||
|
||||
#include "loader_3ds.h"
|
||||
#include "loader_obj.h"
|
||||
#include "loader_ase.h"
|
||||
#include "loader_dae.h"
|
||||
#include "loader_obj.h"
|
||||
#include "loader_qgl.h"
|
||||
#include "qad_types.h"
|
||||
|
||||
#include <QGraphicsRectItem>
|
||||
#include <QImageReader>
|
||||
#include <QMessageBox>
|
||||
@@ -32,18 +34,18 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
|
||||
setupUi(this);
|
||||
session.setFile("session_qglview_test.conf");
|
||||
session.addEntry(this);
|
||||
icon_geo = QIcon(":/icons/type-geo.png");
|
||||
icon_geo = QIcon(":/icons/type-geo.png");
|
||||
icon_camera = QIcon(":/icons/type-camera.png");
|
||||
icon_light = QIcon(":/icons/type-light.png");
|
||||
icon_light = QIcon(":/icons/type-light.png");
|
||||
QAction * a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove");
|
||||
connect(a, SIGNAL(triggered()), this, SLOT(removeObjects()));
|
||||
treeObjects->addAction(a);
|
||||
spinViewLineWidth->setValue(lineThickness()*2);
|
||||
|
||||
spinViewLineWidth->setValue(lineThickness() * 2);
|
||||
|
||||
sel_obj = nullptr;
|
||||
view->view()->camera()->setAim(QVector3D());
|
||||
view->view()->camera()->setPos(QVector3D(2, 2, 2));
|
||||
// view->setFrameShape(QFrame::NoFrame);
|
||||
// view->setFrameShape(QFrame::NoFrame);
|
||||
view->view()->setRenderer(new RendererSimple(view->view()));
|
||||
view->view()->setMouseRotateEnabled(true);
|
||||
view->view()->setMouseSelectionEnabled(true);
|
||||
@@ -95,30 +97,36 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
|
||||
|
||||
axis = new GLObjectBase();
|
||||
GLObjectBase * obj;
|
||||
float al = 1.;
|
||||
obj = new GLPrimitiveLine(QVector3D(0, 0, -al), QVector3D(0, 0, al));
|
||||
obj->material().color_diffuse = Qt::darkBlue; obj->setAcceptLight(false);
|
||||
float al = 1.;
|
||||
obj = new GLPrimitiveLine(QVector3D(0, 0, -al), QVector3D(0, 0, al));
|
||||
obj->material().color_diffuse = Qt::darkBlue;
|
||||
obj->setAcceptLight(false);
|
||||
axis->addChild(obj);
|
||||
obj = new GLPrimitiveLine(QVector3D(-al, 0, 0), QVector3D(al, 0, 0));
|
||||
obj->material().color_diffuse = Qt::darkRed; obj->setAcceptLight(false);
|
||||
obj = new GLPrimitiveLine(QVector3D(-al, 0, 0), QVector3D(al, 0, 0));
|
||||
obj->material().color_diffuse = Qt::darkRed;
|
||||
obj->setAcceptLight(false);
|
||||
axis->addChild(obj);
|
||||
obj = new GLPrimitiveLine(QVector3D(0, -al, 0), QVector3D(0, al, 0));
|
||||
obj->material().color_diffuse = Qt::darkGreen; obj->setAcceptLight(false);
|
||||
obj = new GLPrimitiveLine(QVector3D(0, -al, 0), QVector3D(0, al, 0));
|
||||
obj->material().color_diffuse = Qt::darkGreen;
|
||||
obj->setAcceptLight(false);
|
||||
axis->addChild(obj);
|
||||
view->view()->addObject(axis);
|
||||
|
||||
cam_light = new Light();
|
||||
cam_light = new Light();
|
||||
cam_light->intensity = 0.5;
|
||||
cam_light->setName("Camera_Light");
|
||||
view->view()->camera()->addChild(cam_light);
|
||||
view->view()->start(-1);
|
||||
startTimer(1000/60);
|
||||
startTimer(1000 / 60);
|
||||
|
||||
connect(view->view(), SIGNAL(selectionChanged(GLObjectBase*,GLObjectBase*)), this, SLOT(selectionChanged(GLObjectBase*,GLObjectBase*)));
|
||||
connect(view->view(),
|
||||
SIGNAL(selectionChanged(GLObjectBase *, GLObjectBase *)),
|
||||
this,
|
||||
SLOT(selectionChanged(GLObjectBase *, GLObjectBase *)));
|
||||
connect(view->view(), SIGNAL(keyEvent(Qt::Key, Qt::KeyboardModifiers)), this, SLOT(view_keyEvent(Qt::Key, Qt::KeyboardModifiers)));
|
||||
connect(matEditor, SIGNAL(changed()), this, SLOT(materialChanged()));
|
||||
|
||||
//view->view()->addObject(&partsys);
|
||||
// view->view()->addObject(&partsys);
|
||||
partsys.material().color_diffuse = Qt::red;
|
||||
treeProps->assignObject(&partsys);
|
||||
session.load();
|
||||
@@ -127,7 +135,7 @@ QGLViewWindow::QGLViewWindow(QWidget * parent): QMainWindow(parent), Ui::QGLView
|
||||
|
||||
QGLViewWindow::~QGLViewWindow() {
|
||||
session.save();
|
||||
//delete ps;
|
||||
// delete ps;
|
||||
}
|
||||
|
||||
|
||||
@@ -140,9 +148,9 @@ void QGLViewWindow::changeEvent(QEvent * e) {
|
||||
}
|
||||
|
||||
|
||||
void QGLViewWindow::timerEvent(QTimerEvent * ) {
|
||||
//static double t = 0.;
|
||||
//cam_light->intensity = checkCameraLight->isChecked() ? 0.5 : 0.;
|
||||
void QGLViewWindow::timerEvent(QTimerEvent *) {
|
||||
// static double t = 0.;
|
||||
// cam_light->intensity = checkCameraLight->isChecked() ? 0.5 : 0.;
|
||||
cam_light->setVisible(checkCameraLight->isChecked());
|
||||
//((RendererSimple*)(view->view()->renderer()))->mpos = view->view()->mapFromGlobal(QCursor::pos());
|
||||
statusBar()->showMessage(QString("FPS: %1").arg(QString::number(view->view()->currentFPS(), 'f', 2)));
|
||||
@@ -179,7 +187,7 @@ void QGLViewWindow::makeObjetTree(const GLObjectBase * o, QTreeWidgetItem * ti)
|
||||
if (o == axis) return;
|
||||
for (int i = 0; i < o->childCount(); ++i) {
|
||||
const GLObjectBase * co = o->child(i);
|
||||
QTreeWidgetItem * ci = new QTreeWidgetItem(ti);
|
||||
QTreeWidgetItem * ci = new QTreeWidgetItem(ti);
|
||||
ci->setText(0, co->name());
|
||||
ci->setData(0, Qt::UserRole, quintptr(co));
|
||||
switch (co->type()) {
|
||||
@@ -195,22 +203,22 @@ void QGLViewWindow::makeObjetTree(const GLObjectBase * o, QTreeWidgetItem * ti)
|
||||
|
||||
void QGLViewWindow::selectionChanged(GLObjectBase * cur, GLObjectBase *) {
|
||||
sel_obj = cur;
|
||||
//qDebug() << "selected" << (cur != 0 ? cur->name() : "0");
|
||||
// qDebug() << "selected" << (cur != 0 ? cur->name() : "0");
|
||||
labelName->setText(cur != nullptr ? cur->name() : "");
|
||||
/**if (cur == 0) box->hide();
|
||||
else {
|
||||
box->setScale(cur->boundingBox().size());
|
||||
box->setPos(cur->boundingBox().pos());
|
||||
Box3D b = cur->boundingBox().movedTo(-cur->boundingBox().center());
|
||||
b.z = -b.z - b.height;
|
||||
ps->setEmitterRect(b);
|
||||
cur->addChild(box);
|
||||
box->show();
|
||||
box->setScale(cur->boundingBox().size());
|
||||
box->setPos(cur->boundingBox().pos());
|
||||
Box3D b = cur->boundingBox().movedTo(-cur->boundingBox().center());
|
||||
b.z = -b.z - b.height;
|
||||
ps->setEmitterRect(b);
|
||||
cur->addChild(box);
|
||||
box->show();
|
||||
}*/
|
||||
objectEditor->setObject(sel_obj);
|
||||
if (sel_obj == nullptr) return;
|
||||
matEditor->setMaterial(sel_obj->material());
|
||||
//qDebug() << sel_obj->boundingBox();
|
||||
// qDebug() << sel_obj->boundingBox();
|
||||
}
|
||||
|
||||
|
||||
@@ -224,8 +232,10 @@ void QGLViewWindow::on_comboRenderer_currentIndexChanged(int val) {
|
||||
GLRendererBase * pr = nullptr;
|
||||
switch (val) {
|
||||
case 0: view->view()->setRenderer(new RendererSimple(view->view()), &pr); break;
|
||||
case 1: view->view()->setRenderer(new RendererDeferredShading(view->view()), &pr); break;
|
||||
//case 2: view->view()->setRenderer(new RendererRT(view), &pr); break;
|
||||
case 1:
|
||||
view->view()->setRenderer(new RendererDeferredShading(view->view()), &pr);
|
||||
break;
|
||||
// case 2: view->view()->setRenderer(new RendererRT(view), &pr); break;
|
||||
}
|
||||
if (pr != nullptr) delete pr;
|
||||
}
|
||||
@@ -240,15 +250,18 @@ void QGLViewWindow::on_actionReset_triggered() {
|
||||
|
||||
|
||||
void QGLViewWindow::on_actionImport_triggered() {
|
||||
QStringList fl = QFileDialog::getOpenFileNames(this, "Select files", prev_path, "Supported types(*.qgl *.ase *.3ds *.obj *.dae);;"
|
||||
"QGLView(*.qgl);;"
|
||||
"Ascii Scene Export(*.ase);;"
|
||||
"3D Studio(*.3ds);;"
|
||||
"Wavefront OBJ(*.obj);;"
|
||||
"Collada(*.dae)");
|
||||
QStringList fl = QFileDialog::getOpenFileNames(this,
|
||||
"Select files",
|
||||
prev_path,
|
||||
"Supported types(*.qgl *.ase *.3ds *.obj *.dae);;"
|
||||
"QGLView(*.qgl);;"
|
||||
"Ascii Scene Export(*.ase);;"
|
||||
"3D Studio(*.3ds);;"
|
||||
"Wavefront OBJ(*.obj);;"
|
||||
"Collada(*.dae)");
|
||||
if (fl.isEmpty()) return;
|
||||
prev_path = fl.back();
|
||||
foreach (QString f, fl)
|
||||
foreach(QString f, fl)
|
||||
importFile(f);
|
||||
}
|
||||
|
||||
@@ -256,8 +269,7 @@ void QGLViewWindow::on_actionImport_triggered() {
|
||||
void QGLViewWindow::on_actionSave_triggered() {
|
||||
QString f = QFileDialog::getSaveFileName(this, "Select file", prev_path, "QGLView(*.qgl)");
|
||||
if (f.isEmpty()) return;
|
||||
if (f.right(4).toLower() != ".qgl")
|
||||
f += ".qgl";
|
||||
if (f.right(4).toLower() != ".qgl") f += ".qgl";
|
||||
prev_path = f;
|
||||
view->view()->removeObject(axis);
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
@@ -271,8 +283,7 @@ void QGLViewWindow::on_actionSaveSelected_triggered() {
|
||||
if (!sel_obj) return;
|
||||
QString f = QFileDialog::getSaveFileName(this, "Select file", prev_path, "QGLView(*.qgl)");
|
||||
if (f.isEmpty()) return;
|
||||
if (f.right(4).toLower() != ".qgl")
|
||||
f += ".qgl";
|
||||
if (f.right(4).toLower() != ".qgl") f += ".qgl";
|
||||
prev_path = f;
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
saveToQGLFile(f, sel_obj);
|
||||
@@ -281,12 +292,15 @@ void QGLViewWindow::on_actionSaveSelected_triggered() {
|
||||
|
||||
|
||||
void QGLViewWindow::on_actionOpen_triggered() {
|
||||
QString f = QFileDialog::getOpenFileName(this, "Select file", prev_path, "Supported types(*.qgl *.ase *.3ds *.obj *.dae);;"
|
||||
"QGLView(*.qgl);;"
|
||||
"Ascii Scene Export(*.ase);;"
|
||||
"3D Studio(*.3ds);;"
|
||||
"Wavefront OBJ(*.obj);;"
|
||||
"Collada(*.dae)");
|
||||
QString f = QFileDialog::getOpenFileName(this,
|
||||
"Select file",
|
||||
prev_path,
|
||||
"Supported types(*.qgl *.ase *.3ds *.obj *.dae);;"
|
||||
"QGLView(*.qgl);;"
|
||||
"Ascii Scene Export(*.ase);;"
|
||||
"3D Studio(*.3ds);;"
|
||||
"Wavefront OBJ(*.obj);;"
|
||||
"Collada(*.dae)");
|
||||
if (f.isEmpty()) return;
|
||||
prev_path = f;
|
||||
importFile(f);
|
||||
@@ -294,10 +308,9 @@ void QGLViewWindow::on_actionOpen_triggered() {
|
||||
|
||||
|
||||
void QGLViewWindow::view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m) {
|
||||
//qDebug() << k;
|
||||
// qDebug() << k;
|
||||
double spd = 0.2;
|
||||
if (m.testFlag(Qt::ShiftModifier))
|
||||
spd = 0.5;
|
||||
if (m.testFlag(Qt::ShiftModifier)) spd = 0.5;
|
||||
switch (k) {
|
||||
case Qt::Key_W: view->view()->camera()->moveForward(spd); break;
|
||||
case Qt::Key_S: view->view()->camera()->moveBackward(spd); break;
|
||||
@@ -309,17 +322,16 @@ void QGLViewWindow::view_keyEvent(Qt::Key k, Qt::KeyboardModifiers m) {
|
||||
|
||||
|
||||
void QGLViewWindow::on_treeObjects_itemClicked(QTreeWidgetItem * ti, int) {
|
||||
((GLObjectBase*)(ti->data(0, Qt::UserRole).toULongLong()))->select();
|
||||
//qDebug() << ((GLObjectBase*)(ti->data(0, Qt::UserRole).toULongLong()))->type();
|
||||
if (sel_obj->type() == GLObjectBase::glCamera)
|
||||
view->view()->setCamera((Camera*)sel_obj);
|
||||
((GLObjectBase *)(ti->data(0, Qt::UserRole).toULongLong()))->select();
|
||||
// qDebug() << ((GLObjectBase*)(ti->data(0, Qt::UserRole).toULongLong()))->type();
|
||||
if (sel_obj->type() == GLObjectBase::glCamera) view->view()->setCamera((Camera *)sel_obj);
|
||||
}
|
||||
|
||||
|
||||
void QGLViewWindow::removeObjects() {
|
||||
QList<QTreeWidgetItem*> sil = treeObjects->selectedItems();
|
||||
foreach (QTreeWidgetItem * i, sil) {
|
||||
GLObjectBase * o = (GLObjectBase*)(i->data(0, Qt::UserRole).toULongLong());
|
||||
QList<QTreeWidgetItem *> sil = treeObjects->selectedItems();
|
||||
foreach(QTreeWidgetItem * i, sil) {
|
||||
GLObjectBase * o = (GLObjectBase *)(i->data(0, Qt::UserRole).toULongLong());
|
||||
delete o;
|
||||
}
|
||||
qDeleteAll(sil);
|
||||
@@ -334,20 +346,19 @@ void QGLViewWindow::objectsTreeChanged() {
|
||||
|
||||
|
||||
void QGLViewWindow::on_pushButton_clicked() {
|
||||
//view->view()->removeLight(view->view()->lightsCount() - 1);
|
||||
//setWindowTitle(QString::number(view->view()->lightsCount()));
|
||||
// view->view()->removeLight(view->view()->lightsCount() - 1);
|
||||
// setWindowTitle(QString::number(view->view()->lightsCount()));
|
||||
QVector3D wp = view->view()->light(0)->worldPos();
|
||||
view->view()->camera()->setPos(wp);
|
||||
view->view()->camera()->setAim(wp + (view->view()->light(0)->worldTransform() * QVector4D(view->view()->light(0)->direction)).toVector3D()*100);
|
||||
view->view()->camera()->setAim(
|
||||
wp + (view->view()->light(0)->worldTransform() * QVector4D(view->view()->light(0)->direction)).toVector3D() * 100);
|
||||
}
|
||||
|
||||
|
||||
void QGLViewWindow::on_pushButton_3_clicked() {
|
||||
QList<GLObjectBase * > ol = view->view()->objects(true);
|
||||
QList<GLObjectBase *> ol = view->view()->objects(true);
|
||||
qDebug() << ol.size();
|
||||
foreach (GLObjectBase * i, ol) {
|
||||
foreach(GLObjectBase * i, ol) {
|
||||
i->VBO().rebuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,32 +19,35 @@
|
||||
#ifndef QGLVIEWWINDOW_H
|
||||
#define QGLVIEWWINDOW_H
|
||||
|
||||
#include <QTranslator>
|
||||
#include <QInputDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QColorDialog>
|
||||
#include <QCloseEvent>
|
||||
#include <QClipboard>
|
||||
#include <QRadioButton>
|
||||
#include <QUrl>
|
||||
#include <QThread>
|
||||
#include <QTime>
|
||||
#include <QSplitter>
|
||||
#include "ui_qglview_window.h"
|
||||
#include "loader_3ds.h"
|
||||
#include "loader_ase.h"
|
||||
#include "renderer_simple.h"
|
||||
#include "renderer_deferred_shading.h"
|
||||
#include "renderer_simple.h"
|
||||
#include "session_manager.h"
|
||||
//#include "renderer_rt.h"
|
||||
#include "ui_qglview_window.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QCloseEvent>
|
||||
#include <QColorDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QRadioButton>
|
||||
#include <QSplitter>
|
||||
#include <QThread>
|
||||
#include <QTime>
|
||||
#include <QTranslator>
|
||||
#include <QUrl>
|
||||
// #include "renderer_rt.h"
|
||||
#include "glparticles_system.h"
|
||||
#include "qglview.h"
|
||||
#include "ui_qglview_window.h"
|
||||
|
||||
|
||||
class QGLViewWindow: public QMainWindow, public Ui::QGLViewWindow
|
||||
{
|
||||
class QGLViewWindow
|
||||
: public QMainWindow
|
||||
, public Ui::QGLViewWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QGLViewWindow(QWidget * parent = 0);
|
||||
~QGLViewWindow();
|
||||
@@ -54,7 +57,7 @@ public:
|
||||
private:
|
||||
// Qt`s overloaded
|
||||
void changeEvent(QEvent * e);
|
||||
void timerEvent(QTimerEvent * );
|
||||
void timerEvent(QTimerEvent *);
|
||||
|
||||
void importFile(const QString & path);
|
||||
void makeObjetTree(const GLObjectBase * o, QTreeWidgetItem * ti);
|
||||
@@ -62,7 +65,7 @@ private:
|
||||
QTranslator translator;
|
||||
QIcon icon_geo, icon_camera, icon_light;
|
||||
QString prev_path;
|
||||
GLObjectBase * sel_obj, * axis;
|
||||
GLObjectBase *sel_obj, *axis;
|
||||
Light * cam_light;
|
||||
GLPrimitiveCube * box;
|
||||
Material m;
|
||||
@@ -72,48 +75,51 @@ private:
|
||||
GLParticlesSystem partsys;
|
||||
|
||||
private slots:
|
||||
void on_spinFOV_valueChanged(double val) {view->view()->setFOV(val);}
|
||||
void on_spinDepthStart_valueChanged(double val) {view->view()->setDepthStart(val);}
|
||||
void on_spinDepthEnd_valueChanged(double val) {view->view()->setDepthEnd(val);}
|
||||
void on_spinFOV_valueChanged(double val) { view->view()->setFOV(val); }
|
||||
void on_spinDepthStart_valueChanged(double val) { view->view()->setDepthStart(val); }
|
||||
void on_spinDepthEnd_valueChanged(double val) { view->view()->setDepthEnd(val); }
|
||||
void on_comboRenderer_currentIndexChanged(int val);
|
||||
void on_comboViewRenderMode_currentIndexChanged(int val) {static int modes[] = {GL_POINT, GL_LINE, GL_FILL}; view->view()->setRenderMode((GLObjectBase::RenderMode)modes[val]);}
|
||||
void on_groupHoverHalo_clicked(bool val) {view->view()->setHoverHaloEnabled(val);}
|
||||
void on_groupSelectionHalo_clicked(bool val) {view->view()->setSelectionHaloEnabled(val);}
|
||||
void on_spinHoverHaloFill_valueChanged(double val) {view->view()->setHoverHaloFillAlpha(val);}
|
||||
void on_spinSelectionHaloFill_valueChanged(double val) {view->view()->setSelectionHaloFillAlpha(val);}
|
||||
void on_colorHoverHalo_colorChanged(QColor color) {view->view()->setHoverHaloColor(color);}
|
||||
void on_colorSelectionHalo_colorChanged(QColor color) {view->view()->setSelectionHaloColor(color);}
|
||||
void on_checkFXAA_clicked(bool val) {view->view()->setFeature(QGLView::qglFXAA, val);}
|
||||
void on_checkMSAA_clicked(bool val) {view->view()->setFeature(QGLView::qglMSAA, val);}
|
||||
void on_colorBack_colorChanged(QColor color) {view->view()->setBackColor(color);}
|
||||
void on_colorAmbient_colorChanged(QColor color) {view->view()->setAmbientColor(color);}
|
||||
void on_checkCameraOrbit_clicked(bool val) {view->view()->setCameraOrbit(val);}
|
||||
void on_spinViewLineWidth_valueChanged(double val) {view->view()->setLineWidth(val);}
|
||||
void on_comboViewRenderMode_currentIndexChanged(int val) {
|
||||
static int modes[] = {GL_POINT, GL_LINE, GL_FILL};
|
||||
view->view()->setRenderMode((GLObjectBase::RenderMode)modes[val]);
|
||||
}
|
||||
void on_groupHoverHalo_clicked(bool val) { view->view()->setHoverHaloEnabled(val); }
|
||||
void on_groupSelectionHalo_clicked(bool val) { view->view()->setSelectionHaloEnabled(val); }
|
||||
void on_spinHoverHaloFill_valueChanged(double val) { view->view()->setHoverHaloFillAlpha(val); }
|
||||
void on_spinSelectionHaloFill_valueChanged(double val) { view->view()->setSelectionHaloFillAlpha(val); }
|
||||
void on_colorHoverHalo_colorChanged(QColor color) { view->view()->setHoverHaloColor(color); }
|
||||
void on_colorSelectionHalo_colorChanged(QColor color) { view->view()->setSelectionHaloColor(color); }
|
||||
void on_checkFXAA_clicked(bool val) { view->view()->setFeature(QGLView::qglFXAA, val); }
|
||||
void on_checkMSAA_clicked(bool val) { view->view()->setFeature(QGLView::qglMSAA, val); }
|
||||
void on_colorBack_colorChanged(QColor color) { view->view()->setBackColor(color); }
|
||||
void on_colorAmbient_colorChanged(QColor color) { view->view()->setAmbientColor(color); }
|
||||
void on_checkCameraOrbit_clicked(bool val) { view->view()->setCameraOrbit(val); }
|
||||
void on_spinViewLineWidth_valueChanged(double val) { view->view()->setLineWidth(val); }
|
||||
|
||||
void on_groupShadows_clicked(bool val) {view->view()->setFeature(QGLView::qglShadowsEnabled, val);}
|
||||
void on_groupEyeAccomodation_clicked(bool val) {view->view()->setFeature(QGLView::qglEyeAccomodationEnabled, val);}
|
||||
void on_groupBloom_clicked(bool val) {view->view()->setFeature(QGLView::qglBloomEnabled, val);}
|
||||
void on_groupMotionBlur_clicked(bool val) {view->view()->setFeature(QGLView::qglMotionBlurEnabled, val);}
|
||||
void on_groupReflections_clicked(bool val) {view->view()->setFeature(QGLView::qglReflectionsEnabled, val);}
|
||||
void on_checkSoftShadows_clicked(bool val) {view->view()->setFeature(QGLView::qglShadowsSoftEnabled, val);}
|
||||
void on_groupSSAO_clicked(bool val) {view->view()->setFeature(QGLView::qglSSAOEnabled, val);}
|
||||
void on_groupDOF_clicked(bool val) {view->view()->setFeature(QGLView::qglDepthOfFieldEnabled, val);}
|
||||
void on_checkDOFAutoFocus_clicked(bool val) {view->view()->setFeature(QGLView::qglDepthOfFieldAutoFocusEnabled, val);}
|
||||
void on_spinDOFFocus_valueChanged(double val) {view->view()->setFeature(QGLView::qglDepthOfFieldFocus, val);}
|
||||
void on_spinDOFDiaphragm_valueChanged(double val) {view->view()->setFeature(QGLView::qglDepthOfFieldDiaphragm, val);}
|
||||
void on_spinDOFSpeed_valueChanged(double val) {view->view()->setFeature(QGLView::qglDepthOfFieldAutoFocusSpeed, val);}
|
||||
void on_spinAccom_valueChanged(double val) {view->view()->setFeature(QGLView::qglEyeAccomodationTime, val);}
|
||||
void on_spinAccomMS_valueChanged(double val) {view->view()->setFeature(QGLView::qglEyeAccomodationMaxSpeed, val);}
|
||||
void on_checkReflectionsBlur_clicked(bool val) {view->view()->setFeature(QGLView::qglReflectionsBlur, val);}
|
||||
void on_spinShadowmapSize_valueChanged(double val) {view->view()->setFeature(QGLView::qglShadowsMapSize, val);}
|
||||
void on_spinMotionBlurFactor_valueChanged(double val) {view->view()->setFeature(QGLView::qglMotionBlurFactor, val);}
|
||||
void on_spinMotionBlurSteps_valueChanged(int val) {view->view()->setFeature(QGLView::qglMotionBlurSteps, val);}
|
||||
void on_spinBloomFactor_valueChanged(double val) {view->view()->setFeature(QGLView::qglBloomFactor, val);}
|
||||
void on_spinBloomRadius_valueChanged(int val) {view->view()->setFeature(QGLView::qglBloomRadius, val);}
|
||||
void on_spinBloomThreshold_valueChanged(double val) {view->view()->setFeature(QGLView::qglBloomThreshold, val);}
|
||||
void on_spinSSAORadius_valueChanged(int val) {view->view()->setFeature(QGLView::qglSSAORadius, val);}
|
||||
void on_groupShadows_clicked(bool val) { view->view()->setFeature(QGLView::qglShadowsEnabled, val); }
|
||||
void on_groupEyeAccomodation_clicked(bool val) { view->view()->setFeature(QGLView::qglEyeAccomodationEnabled, val); }
|
||||
void on_groupBloom_clicked(bool val) { view->view()->setFeature(QGLView::qglBloomEnabled, val); }
|
||||
void on_groupMotionBlur_clicked(bool val) { view->view()->setFeature(QGLView::qglMotionBlurEnabled, val); }
|
||||
void on_groupReflections_clicked(bool val) { view->view()->setFeature(QGLView::qglReflectionsEnabled, val); }
|
||||
void on_checkSoftShadows_clicked(bool val) { view->view()->setFeature(QGLView::qglShadowsSoftEnabled, val); }
|
||||
void on_groupSSAO_clicked(bool val) { view->view()->setFeature(QGLView::qglSSAOEnabled, val); }
|
||||
void on_groupDOF_clicked(bool val) { view->view()->setFeature(QGLView::qglDepthOfFieldEnabled, val); }
|
||||
void on_checkDOFAutoFocus_clicked(bool val) { view->view()->setFeature(QGLView::qglDepthOfFieldAutoFocusEnabled, val); }
|
||||
void on_spinDOFFocus_valueChanged(double val) { view->view()->setFeature(QGLView::qglDepthOfFieldFocus, val); }
|
||||
void on_spinDOFDiaphragm_valueChanged(double val) { view->view()->setFeature(QGLView::qglDepthOfFieldDiaphragm, val); }
|
||||
void on_spinDOFSpeed_valueChanged(double val) { view->view()->setFeature(QGLView::qglDepthOfFieldAutoFocusSpeed, val); }
|
||||
void on_spinAccom_valueChanged(double val) { view->view()->setFeature(QGLView::qglEyeAccomodationTime, val); }
|
||||
void on_spinAccomMS_valueChanged(double val) { view->view()->setFeature(QGLView::qglEyeAccomodationMaxSpeed, val); }
|
||||
void on_checkReflectionsBlur_clicked(bool val) { view->view()->setFeature(QGLView::qglReflectionsBlur, val); }
|
||||
void on_spinShadowmapSize_valueChanged(double val) { view->view()->setFeature(QGLView::qglShadowsMapSize, val); }
|
||||
void on_spinMotionBlurFactor_valueChanged(double val) { view->view()->setFeature(QGLView::qglMotionBlurFactor, val); }
|
||||
void on_spinMotionBlurSteps_valueChanged(int val) { view->view()->setFeature(QGLView::qglMotionBlurSteps, val); }
|
||||
void on_spinBloomFactor_valueChanged(double val) { view->view()->setFeature(QGLView::qglBloomFactor, val); }
|
||||
void on_spinBloomRadius_valueChanged(int val) { view->view()->setFeature(QGLView::qglBloomRadius, val); }
|
||||
void on_spinBloomThreshold_valueChanged(double val) { view->view()->setFeature(QGLView::qglBloomThreshold, val); }
|
||||
void on_spinSSAORadius_valueChanged(int val) { view->view()->setFeature(QGLView::qglSSAORadius, val); }
|
||||
|
||||
void on_actionExit_triggered() {close();}
|
||||
void on_actionExit_triggered() { close(); }
|
||||
void on_actionReset_triggered();
|
||||
void on_actionImport_triggered();
|
||||
void on_actionSave_triggered();
|
||||
@@ -130,7 +136,7 @@ private slots:
|
||||
void selectionChanged(GLObjectBase * cur, GLObjectBase *);
|
||||
|
||||
void on_pushButton_clicked();
|
||||
void on_pushButton_2_clicked() {view->view()->reloadShaders();}
|
||||
void on_pushButton_2_clicked() { view->view()->reloadShaders(); }
|
||||
void on_pushButton_3_clicked();
|
||||
|
||||
public slots:
|
||||
@@ -139,7 +145,6 @@ signals:
|
||||
|
||||
private:
|
||||
QMatrix4x4 cam_mat;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGLVIEWWINDOW_H
|
||||
|
||||
@@ -17,35 +17,29 @@
|
||||
*/
|
||||
|
||||
#include "renderer_deferred_shading.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
|
||||
|
||||
RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_),
|
||||
fbo_g(5, true, GL_RGBA16F), fbo_out(3, false, GL_RGBA16F), fbo_hsmall(1, false, GL_RGB16F) {
|
||||
shaders << ShaderPair("FXAA", &shader_fxaa)
|
||||
<< ShaderPair("dsl_pass_0", &shader_ds_0)
|
||||
<< ShaderPair("dsl_pass_1", &shader_ds_1)
|
||||
<< ShaderPair("hdr", &shader_hdr)
|
||||
<< ShaderPair("downscale", &shader_small)
|
||||
<< ShaderPair("bloom_pass_0", &shader_bloom_0)
|
||||
<< ShaderPair("bloom_pass_1", &shader_bloom_1)
|
||||
<< ShaderPair("fbo_add", &shader_fbo_add)
|
||||
<< ShaderPair("motion_blur", &shader_motion_blur)
|
||||
<< ShaderPair("shadow", &shader_shadow)
|
||||
<< ShaderPair("ssr", &shader_ssr)
|
||||
<< ShaderPair("ssr_blur", &shader_ssr_blur)
|
||||
<< ShaderPair("ssr_merge", &shader_ssr_merge)
|
||||
<< ShaderPair("ssao_blur", &shader_ssao_blur)
|
||||
<< ShaderPair("ssao_merge", &shader_ssao_merge)
|
||||
<< ShaderPair("dof", &shader_dof);
|
||||
RendererDeferredShading::RendererDeferredShading(QGLView * view_)
|
||||
: GLRendererBase(view_)
|
||||
, fbo_g(5, true, GL_RGBA16F)
|
||||
, fbo_out(3, false, GL_RGBA16F)
|
||||
, fbo_hsmall(1, false, GL_RGB16F) {
|
||||
shaders << ShaderPair("FXAA", &shader_fxaa) << ShaderPair("dsl_pass_0", &shader_ds_0) << ShaderPair("dsl_pass_1", &shader_ds_1)
|
||||
<< ShaderPair("hdr", &shader_hdr) << ShaderPair("downscale", &shader_small) << ShaderPair("bloom_pass_0", &shader_bloom_0)
|
||||
<< ShaderPair("bloom_pass_1", &shader_bloom_1) << ShaderPair("fbo_add", &shader_fbo_add)
|
||||
<< ShaderPair("motion_blur", &shader_motion_blur) << ShaderPair("shadow", &shader_shadow) << ShaderPair("ssr", &shader_ssr)
|
||||
<< ShaderPair("ssr_blur", &shader_ssr_blur) << ShaderPair("ssr_merge", &shader_ssr_merge)
|
||||
<< ShaderPair("ssao_blur", &shader_ssao_blur) << ShaderPair("ssao_merge", &shader_ssao_merge) << ShaderPair("dof", &shader_dof);
|
||||
for (int i = 0; i < shaders.size(); ++i)
|
||||
*(shaders[i].second) = nullptr;
|
||||
lights_per_pass = 8;
|
||||
tnoise = 0;
|
||||
exposure_ = 1.;
|
||||
df = new QWidget();
|
||||
tnoise = 0;
|
||||
exposure_ = 1.;
|
||||
df = new QWidget();
|
||||
df->setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
|
||||
label_exp = new QLabel();
|
||||
label_exp = new QLabel();
|
||||
label_exp_step = new QLabel();
|
||||
df->layout()->addWidget(label_exp);
|
||||
df->layout()->addWidget(label_exp_step);
|
||||
@@ -53,7 +47,7 @@ fbo_g(5, true, GL_RGBA16F), fbo_out(3, false, GL_RGBA16F), fbo_hsmall(1, false,
|
||||
pal.setBrush(QPalette::Window, QColor(255, 255, 255, 192));
|
||||
df->setPalette(pal);
|
||||
if (view_)
|
||||
;//view_->addObject(df);
|
||||
; // view_->addObject(df);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,24 +61,24 @@ RendererDeferredShading::~RendererDeferredShading() {
|
||||
|
||||
|
||||
void RendererDeferredShading::renderScene() {
|
||||
//qDebug() << lights_per_pass;
|
||||
QMatrix4x4 mproj = rp.proj_matrix;
|
||||
QMatrix4x4 mproji = rp.proj_matrix_i;
|
||||
QMatrix4x4 mview = rp.view_matrix;
|
||||
QMatrix4x4 mviewi = rp.view_matrix_i;
|
||||
// qDebug() << lights_per_pass;
|
||||
QMatrix4x4 mproj = rp.proj_matrix;
|
||||
QMatrix4x4 mproji = rp.proj_matrix_i;
|
||||
QMatrix4x4 mview = rp.view_matrix;
|
||||
QMatrix4x4 mviewi = rp.view_matrix_i;
|
||||
QMatrix4x4 mviewproji = (mproj * mview).inverted();
|
||||
QMatrix4x4 moffset = view.camera()->offsetMatrix();
|
||||
QMatrix4x4 moffseti = moffset.inverted();
|
||||
rp.prev_proj_matrix = prev_proj;
|
||||
rp.prev_view_matrix = prev_view;
|
||||
QMatrix4x4 moffset = view.camera()->offsetMatrix();
|
||||
QMatrix4x4 moffseti = moffset.inverted();
|
||||
rp.prev_proj_matrix = prev_proj;
|
||||
rp.prev_view_matrix = prev_view;
|
||||
QMatrix4x4 vc_proji;
|
||||
vc_proji.perspective(90., 1., view.camera()->depthStart(), view.camera()->depthEnd());
|
||||
vc_proji = vc_proji.inverted();
|
||||
vc_proji = vc_proji.inverted();
|
||||
corner_dirs[0] = (mproji * QVector4D(-1, -1, 0, 1));
|
||||
corner_dirs[1] = (mproji * QVector4D( 1, -1, 0, 1));
|
||||
corner_dirs[2] = (mproji * QVector4D(-1, 1, 0, 1));
|
||||
corner_dirs[3] = (mproji * QVector4D( 1, 1, 0, 1));
|
||||
//qDebug() << corner_dirs[0] << corner_dirs[1] << corner_dirs[2] << corner_dirs[3];
|
||||
corner_dirs[1] = (mproji * QVector4D(1, -1, 0, 1));
|
||||
corner_dirs[2] = (mproji * QVector4D(-1, 1, 0, 1));
|
||||
corner_dirs[3] = (mproji * QVector4D(1, 1, 0, 1));
|
||||
// qDebug() << corner_dirs[0] << corner_dirs[1] << corner_dirs[2] << corner_dirs[3];
|
||||
fbo_g.bind();
|
||||
int buffs[] = {0, 1, 2, 3, 4};
|
||||
fbo_g.setWriteBuffers(buffs, 5);
|
||||
@@ -113,10 +107,10 @@ void RendererDeferredShading::renderScene() {
|
||||
shader_ds_0->setUniformValue("t3", 3);
|
||||
shader_ds_0->setUniformValue("t4", 4);
|
||||
shader_ds_0->setUniformValue("dt", QVector2D(1.f / view.width(), 1.f / view.height()));
|
||||
//qDebug() << rp.view_matrix << prev_view;
|
||||
//shader_ds_0->setUniformValue("qgl_ModelViewMatrix", rp.view_matrix);
|
||||
// qDebug() << rp.view_matrix << prev_view;
|
||||
// shader_ds_0->setUniformValue("qgl_ModelViewMatrix", rp.view_matrix);
|
||||
renderObjects(GLObjectBase::Solid, 0, shader_ds_0, true, false, false);
|
||||
//glReleaseShaders();
|
||||
// glReleaseShaders();
|
||||
fbo_g.release();
|
||||
|
||||
if (view.isFeatureEnabled(QGLView::qglShadowsEnabled)) {
|
||||
@@ -133,7 +127,7 @@ void RendererDeferredShading::renderScene() {
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
//qDebug() << "render shadows";
|
||||
// qDebug() << "render shadows";
|
||||
for (int i = 0; i < view.lightsCount(); ++i) {
|
||||
Light * l = view.light(i);
|
||||
if (l->light_type == Light::Omni) continue;
|
||||
@@ -141,26 +135,26 @@ void RendererDeferredShading::renderScene() {
|
||||
l->shadow_map.bind();
|
||||
l->shadow_map.setWriteBuffer(0);
|
||||
glClearFramebuffer();
|
||||
//glClear(GL_DEPTH_BUFFER_BIT);
|
||||
renderShadow(l, shader_shadow, moffseti*mviewi);
|
||||
// glClear(GL_DEPTH_BUFFER_BIT);
|
||||
renderShadow(l, shader_shadow, moffseti * mviewi);
|
||||
l->shadow_map.release();
|
||||
}
|
||||
}
|
||||
// glUseProgram(0);
|
||||
//// fbo_g.bindColorTextures();
|
||||
// glBindTexture(GL_TEXTURE_2D, fbo_g.colorTexture(0));
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
// glDrawQuad();
|
||||
// return;
|
||||
// glUseProgram(0);
|
||||
//// fbo_g.bindColorTextures();
|
||||
// glBindTexture(GL_TEXTURE_2D, fbo_g.colorTexture(0));
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
// glDrawQuad();
|
||||
// return;
|
||||
|
||||
glResetAllTransforms();
|
||||
glSetLightEnabled(false);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
//glBlendFunc(GL_ONE, GL_ONE);
|
||||
// glBlendFunc(GL_ONE, GL_ONE);
|
||||
glDisableDepth();
|
||||
rp.prepare();
|
||||
//qDebug() << rp.view_matrix;
|
||||
// qDebug() << rp.view_matrix;
|
||||
shader_ds_1->bind();
|
||||
shader_ds_1->setUniformValue("z_far", view.depthEnd());
|
||||
shader_ds_1->setUniformValue("z_near", view.depthStart());
|
||||
@@ -183,25 +177,25 @@ void RendererDeferredShading::renderScene() {
|
||||
fbo_out.bind();
|
||||
fbo_out.setWriteBuffer(0);
|
||||
glClearFramebuffer(Qt::black, false);
|
||||
//QVector<QVector4D> lpos;
|
||||
//qDebug() << view_matrix;
|
||||
// QVector<QVector4D> lpos;
|
||||
// qDebug() << view_matrix;
|
||||
shader_ds_1->setUniformValue("t_pp", 6);
|
||||
int passes = (view.lightsCount() - 1) / lights_per_pass + 1;
|
||||
if (passes < 1) passes = 1;
|
||||
//qDebug() << "render in" << passes << "passes (" << lights_per_pass << ")";
|
||||
// qDebug() << "render in" << passes << "passes (" << lights_per_pass << ")";
|
||||
int wi, ri;
|
||||
for (int l = 0; l < passes; ++l) {
|
||||
wi = 1 - l % 2;
|
||||
ri = l % 2;
|
||||
//qDebug() << " pass" << l << "read from" << ri << "write to" << wi;
|
||||
// qDebug() << " pass" << l << "read from" << ri << "write to" << wi;
|
||||
glActiveTexture(GL_TEXTURE0 + 6);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
fbo_out.setWriteBuffer(wi);
|
||||
setupDSLights(l, mview * moffset);
|
||||
glDrawQuad(shader_ds_1, corner_dirs);
|
||||
//break;
|
||||
// break;
|
||||
}
|
||||
//fbo_out.release();
|
||||
// fbo_out.release();
|
||||
wi = 1 - passes % 2;
|
||||
ri = passes % 2;
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -210,16 +204,25 @@ void RendererDeferredShading::renderScene() {
|
||||
if (view.isFeatureEnabled(QGLView::qglSSAOEnabled)) {
|
||||
fbo_out.setWriteBuffer(2);
|
||||
fbo_out.setReadBuffer(ri);
|
||||
glBlitFramebuffer(0, 0, fbo_out.width(), fbo_out.height(), 0, 0, fbo_out.width(), fbo_out.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBlitFramebuffer(0,
|
||||
0,
|
||||
fbo_out.width(),
|
||||
fbo_out.height(),
|
||||
0,
|
||||
0,
|
||||
fbo_out.width(),
|
||||
fbo_out.height(),
|
||||
GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST);
|
||||
glActiveTexture(GL_TEXTURE0 + 1);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(2));
|
||||
glActiveTexture(GL_TEXTURE0 + 2);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_g.colorTexture(1));
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
//glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
//glActiveTextureChannel(1);
|
||||
//glBindTexture(GL_TEXTURE_2D, fbo_g.colorTexture(0));
|
||||
int lri = ri, lwi = wi;//, lms = ri;
|
||||
// glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
// glActiveTextureChannel(1);
|
||||
// glBindTexture(GL_TEXTURE_2D, fbo_g.colorTexture(0));
|
||||
int lri = ri, lwi = wi; //, lms = ri;
|
||||
shader_ssao_blur->bind();
|
||||
shader_ssao_blur->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4());
|
||||
shader_ssao_blur->setUniformValue("dt", QVector2D(1.f / fbo_out.width(), 1.f / fbo_out.height()));
|
||||
@@ -227,7 +230,7 @@ void RendererDeferredShading::renderScene() {
|
||||
shader_ssao_blur->setUniformValue("ts", 1);
|
||||
shader_ssao_blur->setUniformValue("tg1", 2);
|
||||
int passes = view.feature(QGLView::qglSSAORadius).toInt();
|
||||
int crad = 1;
|
||||
int crad = 1;
|
||||
for (int p = 0; p < passes; ++p) {
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(lri));
|
||||
fbo_out.setWriteBuffer(lwi);
|
||||
@@ -236,7 +239,7 @@ void RendererDeferredShading::renderScene() {
|
||||
piSwap<int>(lwi, lri);
|
||||
crad *= 2;
|
||||
}
|
||||
//qDebug() << wi << ri << lms;
|
||||
// qDebug() << wi << ri << lms;
|
||||
/*wi = lri;
|
||||
ri = 1 - lms;*/
|
||||
glEnable(GL_TEXTURE_1D);
|
||||
@@ -244,9 +247,9 @@ void RendererDeferredShading::renderScene() {
|
||||
glGenTextures(1, &tnoise);
|
||||
glBindTexture(GL_TEXTURE_1D, tnoise);
|
||||
QByteArray ba;
|
||||
for (int i = 0; i < 32*3; ++i)
|
||||
for (int i = 0; i < 32 * 3; ++i)
|
||||
ba.push_back(char(random() % 256));
|
||||
//qDebug() << ba;
|
||||
// qDebug() << ba;
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB8, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, ba.constData());
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
@@ -277,11 +280,11 @@ void RendererDeferredShading::renderScene() {
|
||||
glDisable(GL_TEXTURE_1D);
|
||||
wi = lri;
|
||||
ri = lwi;
|
||||
//piSwap<int>(wi, ri);
|
||||
// piSwap<int>(wi, ri);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
//piSwap<int>(wi, ri);
|
||||
// piSwap<int>(wi, ri);
|
||||
}
|
||||
|
||||
if (view.isFeatureEnabled(QGLView::qglReflectionsEnabled)) {
|
||||
@@ -289,8 +292,8 @@ void RendererDeferredShading::renderScene() {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//_MIPMAP_LINEAR);
|
||||
//glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //_MIPMAP_LINEAR);
|
||||
// glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0 + 1);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_g.colorTexture(0));
|
||||
glActiveTexture(GL_TEXTURE0 + 2);
|
||||
@@ -315,11 +318,11 @@ void RendererDeferredShading::renderScene() {
|
||||
shader_ssr_blur->setUniformValue("dt", QVector2D(1.f / fbo_out.width(), 1.f / fbo_out.height()));
|
||||
shader_ssr_blur->setUniformValue("t0", 0);
|
||||
int passes = 5;
|
||||
int crad = 1;
|
||||
int crad = 1;
|
||||
for (int p = 0; p < passes; ++p) {
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(lri));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //_MIPMAP_LINEAR);
|
||||
fbo_out.setWriteBuffer(lwi);
|
||||
shader_ssr_blur->setUniformValue("radius", GLfloat(crad));
|
||||
glDrawQuad(shader_ssr_blur);
|
||||
@@ -327,7 +330,7 @@ void RendererDeferredShading::renderScene() {
|
||||
crad *= 2;
|
||||
}
|
||||
}
|
||||
//qDebug() << wi << ri << lms;
|
||||
// qDebug() << wi << ri << lms;
|
||||
wi = lri;
|
||||
ri = 1 - lms;
|
||||
|
||||
@@ -345,7 +348,7 @@ void RendererDeferredShading::renderScene() {
|
||||
glDrawQuad(shader_ssr_merge);
|
||||
wi = ri;
|
||||
ri = 1 - ri;
|
||||
//piSwap<int>(wi, ri);
|
||||
// piSwap<int>(wi, ri);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(wi));
|
||||
@@ -355,16 +358,16 @@ void RendererDeferredShading::renderScene() {
|
||||
if (view.isFeatureEnabled(QGLView::qglDepthOfFieldEnabled)) {
|
||||
if (view.isFeatureEnabled(QGLView::qglDepthOfFieldAutoFocusEnabled)) {
|
||||
GLfloat cw;
|
||||
//glReadBuffer();
|
||||
// glReadBuffer();
|
||||
fbo_g.bind();
|
||||
glReadPixels(fbo_out.width() / 2, fbo_out.height() / 2, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &cw);
|
||||
fbo_out.bind();
|
||||
const float _pe = 2.4e-7f;
|
||||
float cz = cw + cw - 1;
|
||||
cz = ((_pe - 2.f) * view.depthStart()) / (cz + _pe - 1.f); // infinite depth
|
||||
float z = view.feature(QGLView::qglDepthOfFieldFocus).toFloat(),
|
||||
s = view.feature(QGLView::qglDepthOfFieldAutoFocusSpeed).toFloat();
|
||||
z = z * (1.f - s) + cz * s;
|
||||
float cz = cw + cw - 1;
|
||||
cz = ((_pe - 2.f) * view.depthStart()) / (cz + _pe - 1.f); // infinite depth
|
||||
float z = view.feature(QGLView::qglDepthOfFieldFocus).toFloat(),
|
||||
s = view.feature(QGLView::qglDepthOfFieldAutoFocusSpeed).toFloat();
|
||||
z = z * (1.f - s) + cz * s;
|
||||
view.setFeature(QGLView::qglDepthOfFieldFocus, z);
|
||||
}
|
||||
shader_dof->bind();
|
||||
@@ -408,33 +411,34 @@ void RendererDeferredShading::renderScene() {
|
||||
glDrawQuad(shader_small);
|
||||
hcontent.resize(fbo_hsmall.width() * fbo_hsmall.height());
|
||||
glReadPixels(0, 0, fbo_hsmall.width(), fbo_hsmall.height(), GL_RGB, GL_FLOAT, hcontent.data());
|
||||
GLfloat max[3] = {0.,0.,0.};//min[3] = {10000.,10000.,10000.},;
|
||||
GLfloat max[3] = {0., 0., 0.}; // min[3] = {10000.,10000.,10000.},;
|
||||
for (int i = 0; i < hcontent.size(); ++i) {
|
||||
//if (min[0] > hcontent[i].x) min[0] = hcontent[i].x;
|
||||
// if (min[0] > hcontent[i].x) min[0] = hcontent[i].x;
|
||||
if (max[0] < hcontent[i].x) max[0] = hcontent[i].x;
|
||||
//if (min[1] > hcontent[i].y) min[1] = hcontent[i].y;
|
||||
// if (min[1] > hcontent[i].y) min[1] = hcontent[i].y;
|
||||
if (max[1] < hcontent[i].y) max[1] = hcontent[i].y;
|
||||
//if (min[2] > hcontent[i].z) min[2] = hcontent[i].z;
|
||||
// if (min[2] > hcontent[i].z) min[2] = hcontent[i].z;
|
||||
if (max[2] < hcontent[i].z) max[2] = hcontent[i].z;
|
||||
}
|
||||
GLfloat mluma = (0.299f * max[0]) + (0.587f * max[1]) + (0.114f * max[2]);
|
||||
float nexp = mluma / 16.f, dexp = nexp - exposure_, mestep = exposure_ * view.feature(QGLView::qglEyeAccomodationMaxSpeed).toFloat();
|
||||
float nexp = mluma / 16.f, dexp = nexp - exposure_,
|
||||
mestep = exposure_ * view.feature(QGLView::qglEyeAccomodationMaxSpeed).toFloat();
|
||||
dexp /= view.feature(QGLView::qglEyeAccomodationTime).toFloat();
|
||||
if (dexp > 0.f && dexp > mestep/4) dexp = mestep/4;
|
||||
if (dexp > 0.f && dexp > mestep / 4) dexp = mestep / 4;
|
||||
if (dexp < 0.f && dexp < -mestep) dexp = -mestep;
|
||||
exposure_ += dexp;
|
||||
label_exp->setText(QString("exposure: %1").arg(exposure_));
|
||||
label_exp_step->setText(QString("d_exposure: %1").arg(dexp));
|
||||
//qDebug() << min[0] << max[0] << min[1] << max[1] << min[2] << max[2];
|
||||
// qDebug() << min[0] << max[0] << min[1] << max[1] << min[2] << max[2];
|
||||
fbo_hsmall.release();
|
||||
|
||||
//glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
// glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
fbo_out.bind();
|
||||
fbo_out.setWriteBuffer(wi);
|
||||
shader_hdr->bind();
|
||||
shader_hdr->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4());
|
||||
shader_hdr->setUniformValue("t0", 0);
|
||||
shader_hdr->setUniformValue("exposure", GLfloat(1.f/exposure_));
|
||||
shader_hdr->setUniformValue("exposure", GLfloat(1.f / exposure_));
|
||||
glDrawQuad(shader_hdr);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(wi));
|
||||
piSwap<int>(wi, ri);
|
||||
@@ -460,9 +464,18 @@ void RendererDeferredShading::renderScene() {
|
||||
if (view.isFeatureEnabled(QGLView::qglBloomEnabled)) {
|
||||
fbo_out.setWriteBuffer(2);
|
||||
fbo_out.setReadBuffer(ri);
|
||||
glBlitFramebuffer(0, 0, fbo_out.width(), fbo_out.height(), 0, 0, fbo_out.width(), fbo_out.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
//QTime tm;
|
||||
//tm.restart();
|
||||
glBlitFramebuffer(0,
|
||||
0,
|
||||
fbo_out.width(),
|
||||
fbo_out.height(),
|
||||
0,
|
||||
0,
|
||||
fbo_out.width(),
|
||||
fbo_out.height(),
|
||||
GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST);
|
||||
// QTime tm;
|
||||
// tm.restart();
|
||||
fbo_out.setWriteBuffer(wi);
|
||||
shader_bloom_0->bind();
|
||||
shader_bloom_0->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4());
|
||||
@@ -479,20 +492,19 @@ void RendererDeferredShading::renderScene() {
|
||||
shader_bloom_1->setUniformValue("t0", 0);
|
||||
int radius = view.feature(QGLView::qglBloomRadius).toInt();
|
||||
int passes = qMax<int>(int(ceil(log2(radius))), 1);
|
||||
int crad = 1;
|
||||
int crad = 1;
|
||||
for (int p = 0; p < passes; ++p) {
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
fbo_out.setWriteBuffer(wi);
|
||||
if (p == passes - 1)
|
||||
crad = piMax(1, radius - crad);
|
||||
if (p == passes - 1) crad = piMax(1, radius - crad);
|
||||
shader_bloom_1->setUniformValue("radius", crad);
|
||||
glDrawQuad(shader_bloom_1);
|
||||
piSwap<int>(wi, ri);
|
||||
crad *= 2;
|
||||
}
|
||||
//qDebug() << tm.elapsed();
|
||||
// qDebug() << tm.elapsed();
|
||||
fbo_out.setWriteBuffer(wi);
|
||||
// glActiveTextureChannel(0);
|
||||
// glActiveTextureChannel(0);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
|
||||
glActiveTexture(GL_TEXTURE0 + 1);
|
||||
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(2));
|
||||
@@ -519,8 +531,7 @@ void RendererDeferredShading::renderScene() {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
glDrawQuad();
|
||||
if (view.isFeatureEnabled(QGLView::qglFXAA))
|
||||
shader_fxaa->release();
|
||||
if (view.isFeatureEnabled(QGLView::qglFXAA)) shader_fxaa->release();
|
||||
prev_proj = mproj;
|
||||
prev_view = mview;
|
||||
}
|
||||
@@ -536,8 +547,8 @@ void RendererDeferredShading::resize(int width, int height) {
|
||||
fbo_g.resize(width, height);
|
||||
fbo_out.resize(width, height);
|
||||
fbo_hsmall.resize(width / 16, height / 16);
|
||||
// view.setSceneRect(QRect(0, 0, width, height));
|
||||
//df->move(-width / 2, -height / 2);
|
||||
// view.setSceneRect(QRect(0, 0, width, height));
|
||||
// df->move(-width / 2, -height / 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -561,15 +572,15 @@ void RendererDeferredShading::setupShadersTextures(GLObjectBase & object, GLRend
|
||||
|
||||
void RendererDeferredShading::setupDSLights(int pass, const QMatrix4x4 & view_matrix) {
|
||||
int light_start, light_end, lmax, shadow_start = 7;
|
||||
light_start = pass * lights_per_pass;
|
||||
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights().size());
|
||||
lmax = light_start + lights_per_pass;
|
||||
light_start = pass * lights_per_pass;
|
||||
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights().size());
|
||||
lmax = light_start + lights_per_pass;
|
||||
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");
|
||||
amb_light.intensity = 0.;
|
||||
QVector<Light*> lv;
|
||||
QVector<Light *> lv;
|
||||
for (int i = light_start; i < light_end; ++i) {
|
||||
lv << view.lights()[i];
|
||||
glActiveTexture(GL_TEXTURE0 + shadow_start + i - light_start);
|
||||
@@ -586,12 +597,10 @@ void RendererDeferredShading::setupDSLights(int pass, const QMatrix4x4 & view_ma
|
||||
amb_light.setName("null");
|
||||
for (int i = light_end; i < lmax; ++i)
|
||||
lv << &amb_light;
|
||||
//QStringList lnl; foreach (Light * l, lv) lnl << l->name();
|
||||
//qDebug() << " lights" << light_start << "->" << light_end << ", inactive" << (lmax - light_end) << lnl;
|
||||
// QStringList lnl; foreach (Light * l, lv) lnl << l->name();
|
||||
// qDebug() << " lights" << light_start << "->" << light_end << ", inactive" << (lmax - light_end) << lnl;
|
||||
setUniformLights(shader_ds_1, lv, view_matrix, shadow_start);
|
||||
}
|
||||
|
||||
|
||||
void RendererDeferredShading::setupAmbientLight(const QColor & a, bool first_pass) {
|
||||
|
||||
}
|
||||
void RendererDeferredShading::setupAmbientLight(const QColor & a, bool first_pass) {}
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
#define RENDERER_DEFERRED_SHADING_H
|
||||
|
||||
#include "qglview.h"
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
|
||||
class RendererDeferredShading: public GLRendererBase
|
||||
{
|
||||
class RendererDeferredShading: public GLRendererBase {
|
||||
public:
|
||||
RendererDeferredShading(QGLView * view);
|
||||
virtual ~RendererDeferredShading();
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
|
||||
protected:
|
||||
void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp);
|
||||
void setupShadersLights(int lights_count) {cplc = lights_count;}
|
||||
void setupShadersLights(int lights_count) { cplc = lights_count; }
|
||||
void setupDSLights(int pass, const QMatrix4x4 & view_matrix);
|
||||
void setupAmbientLight(const QColor & a, bool first_pass);
|
||||
|
||||
@@ -46,10 +46,10 @@ private:
|
||||
int cplc, lights_per_pass;
|
||||
float exposure_;
|
||||
GLFramebuffer fbo_g, fbo_out, fbo_hsmall;
|
||||
QOpenGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1, * shader_hdr, * shader_small;
|
||||
QOpenGLShaderProgram * shader_bloom_0, * shader_bloom_1, * shader_motion_blur, * shader_fbo_add;
|
||||
QOpenGLShaderProgram * shader_shadow, * shader_ssr, * shader_ssr_blur, * shader_ssr_merge;
|
||||
QOpenGLShaderProgram * shader_ssao_blur, * shader_ssao_merge, * shader_dof;
|
||||
QOpenGLShaderProgram *shader_fxaa, *shader_ds_0, *shader_ds_1, *shader_hdr, *shader_small;
|
||||
QOpenGLShaderProgram *shader_bloom_0, *shader_bloom_1, *shader_motion_blur, *shader_fbo_add;
|
||||
QOpenGLShaderProgram *shader_shadow, *shader_ssr, *shader_ssr_blur, *shader_ssr_merge;
|
||||
QOpenGLShaderProgram *shader_ssao_blur, *shader_ssao_merge, *shader_dof;
|
||||
GLuint tnoise;
|
||||
QVector<ShaderPair> shaders;
|
||||
|
||||
@@ -60,8 +60,7 @@ private:
|
||||
Light amb_light;
|
||||
|
||||
QWidget * df;
|
||||
QLabel * label_exp, * label_exp_step;
|
||||
|
||||
QLabel *label_exp, *label_exp_step;
|
||||
};
|
||||
|
||||
#endif // RENDERER_DEFERRED_SHADING_H
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
#include "renderer_simple.h"
|
||||
|
||||
|
||||
RendererSimple::RendererSimple(QGLView * view_): GLRendererBase(view_), fbo(2)
|
||||
, fbo_c(1, true, GL_RGBA32F) /// WARNING
|
||||
RendererSimple::RendererSimple(QGLView * view_)
|
||||
: GLRendererBase(view_)
|
||||
, fbo(2)
|
||||
, fbo_c(1, true, GL_RGBA32F) /// WARNING
|
||||
{
|
||||
shader_fxaa = 0;
|
||||
shader = 0; /// WARNING
|
||||
shader = 0; /// WARNING
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +35,8 @@ void RendererSimple::reloadShaders() {
|
||||
loadShaders(shader_fxaa, "FXAA", "://shaders");
|
||||
}
|
||||
/*if (shader == 0) {
|
||||
shader = new QOpenGLShaderProgram(view.context()); /// WARNING
|
||||
loadShaders(shader, "test", "shaders"); /// WARNING
|
||||
shader = new QOpenGLShaderProgram(view.context()); /// WARNING
|
||||
loadShaders(shader, "test", "shaders"); /// WARNING
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -48,12 +50,12 @@ void RendererSimple::resizeFBO(int w, int h) {
|
||||
|
||||
void RendererSimple::renderScene() {
|
||||
int passes = (view.lightsCount() - 1) / 8 + 1;
|
||||
//QMatrix4x4 pm = getGLMatrix(GL_PROJECTION_MATRIX), mvm = getGLMatrix(GL_MODELVIEW_MATRIX), pmvm = pm * mvm, lpm, lmvm, lpmvm;
|
||||
//glSetCapEnabled(GL_MULTISAMPLE, view.isFeatureEnabled(QGLView::qglMSAA));
|
||||
// QMatrix4x4 pm = getGLMatrix(GL_PROJECTION_MATRIX), mvm = getGLMatrix(GL_MODELVIEW_MATRIX), pmvm = pm * mvm, lpm, lmvm, lpmvm;
|
||||
// glSetCapEnabled(GL_MULTISAMPLE, view.isFeatureEnabled(QGLView::qglMSAA));
|
||||
if (passes < 1) passes = 1;
|
||||
//glEnable(GL_FOG);
|
||||
//if (view.isFeatureEnabled(QGLView::qglFXAA)) fbo.bind();
|
||||
//glEnable(GL_TEXTURE_2D);
|
||||
// glEnable(GL_FOG);
|
||||
// if (view.isFeatureEnabled(QGLView::qglFXAA)) fbo.bind();
|
||||
// glEnable(GL_TEXTURE_2D);
|
||||
if (passes > 1 || view.isFeatureEnabled(QGLView::qglFXAA)) {
|
||||
fbo.bind();
|
||||
fbo.setWriteBuffer(0);
|
||||
@@ -73,8 +75,8 @@ void RendererSimple::renderScene() {
|
||||
glClearFramebuffer(Qt::black, false);
|
||||
view.camera()->apply(view.aspect);
|
||||
}
|
||||
//rp.cam_offset_matrix = view.camera()->offsetMatrix();
|
||||
//rp.prepare();
|
||||
// rp.cam_offset_matrix = view.camera()->offsetMatrix();
|
||||
// rp.prepare();
|
||||
setupLights(l, 8);
|
||||
renderObjects(GLObjectBase::Solid, l, nullptr, true, view.isLightEnabled(), view.isFogEnabled());
|
||||
renderObjects(GLObjectBase::Transparent, l, nullptr, true, true, view.isFogEnabled());
|
||||
|
||||
@@ -21,16 +21,17 @@
|
||||
|
||||
#include "qglview.h"
|
||||
|
||||
class RendererSimple: public GLRendererBase
|
||||
{
|
||||
class RendererSimple: public GLRendererBase {
|
||||
public:
|
||||
RendererSimple(QGLView * view);
|
||||
virtual ~RendererSimple() {if (shader_fxaa != 0) delete shader_fxaa;}
|
||||
virtual ~RendererSimple() {
|
||||
if (shader_fxaa != 0) delete shader_fxaa;
|
||||
}
|
||||
|
||||
virtual void renderScene();
|
||||
virtual void reloadShaders();
|
||||
virtual void init(int width, int height) {resizeFBO(width, height);}
|
||||
virtual void resize(int width, int height) {resizeFBO(width, height);}
|
||||
virtual void init(int width, int height) { resizeFBO(width, height); }
|
||||
virtual void resize(int width, int height) { resizeFBO(width, height); }
|
||||
|
||||
QPoint mpos;
|
||||
|
||||
@@ -38,10 +39,9 @@ protected:
|
||||
|
||||
private:
|
||||
void resizeFBO(int w, int h);
|
||||
|
||||
GLFramebuffer fbo, fbo_c;
|
||||
QOpenGLShaderProgram * shader_fxaa, * shader;
|
||||
|
||||
GLFramebuffer fbo, fbo_c;
|
||||
QOpenGLShaderProgram *shader_fxaa, *shader;
|
||||
};
|
||||
|
||||
#endif // RENDERER_SIMPLE_H
|
||||
|
||||
@@ -34,11 +34,11 @@ Example,
|
||||
Or,
|
||||
|
||||
#define FXAA_360 1
|
||||
|
||||
|
||||
Or,
|
||||
|
||||
#define FXAA_PS3 1
|
||||
|
||||
|
||||
Etc.
|
||||
|
||||
(2.)
|
||||
@@ -49,7 +49,7 @@ Then include this file,
|
||||
(3.)
|
||||
Then call the FXAA pixel shader from within your desired shader.
|
||||
Look at the FXAA Quality FxaaPixelShader() for docs on inputs.
|
||||
As for FXAA 3.11 all inputs for all shaders are the same
|
||||
As for FXAA 3.11 all inputs for all shaders are the same
|
||||
to enable easy porting between platforms.
|
||||
|
||||
return FxaaPixelShader(...);
|
||||
@@ -80,7 +80,7 @@ Look at the FXAA Quality FxaaPixelShader() for docs on inputs.
|
||||
|
||||
(6.)
|
||||
Have FXAA vertex shader run as a full screen triangle,
|
||||
and output "pos" and "fxaaConsolePosPos"
|
||||
and output "pos" and "fxaaConsolePosPos"
|
||||
such that inputs in the pixel shader provide,
|
||||
|
||||
// {xy} = center of pixel
|
||||
@@ -97,7 +97,7 @@ Insure the texture sampler(s) used by FXAA are set to bilinear filtering.
|
||||
------------------------------------------------------------------------------
|
||||
INTEGRATION - RGBL AND COLORSPACE
|
||||
------------------------------------------------------------------------------
|
||||
FXAA3 requires RGBL as input unless the following is set,
|
||||
FXAA3 requires RGBL as input unless the following is set,
|
||||
|
||||
#define FXAA_GREEN_AS_LUMA 1
|
||||
|
||||
@@ -150,7 +150,7 @@ Getting luma correct is required for the algorithm to work correctly.
|
||||
------------------------------------------------------------------------------
|
||||
Applying FXAA to a framebuffer with linear RGB color will look worse.
|
||||
This is very counter intuitive, but happends to be true in this case.
|
||||
The reason is because dithering artifacts will be more visiable
|
||||
The reason is because dithering artifacts will be more visiable
|
||||
in a linear colorspace.
|
||||
|
||||
|
||||
@@ -184,191 +184,191 @@ A. Or use FXAA_GREEN_AS_LUMA.
|
||||
//
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_PS3
|
||||
#define FXAA_PS3 0
|
||||
# define FXAA_PS3 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_360
|
||||
#define FXAA_360 0
|
||||
# define FXAA_360 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_360_OPT
|
||||
#define FXAA_360_OPT 0
|
||||
# define FXAA_360_OPT 0
|
||||
#endif
|
||||
/*==========================================================================*/
|
||||
#ifndef FXAA_PC
|
||||
//
|
||||
// FXAA Quality
|
||||
// The high quality PC algorithm.
|
||||
//
|
||||
#define FXAA_PC 0
|
||||
//
|
||||
// FXAA Quality
|
||||
// The high quality PC algorithm.
|
||||
//
|
||||
# define FXAA_PC 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_PC_CONSOLE
|
||||
//
|
||||
// The console algorithm for PC is included
|
||||
// for developers targeting really low spec machines.
|
||||
// Likely better to just run FXAA_PC, and use a really low preset.
|
||||
//
|
||||
#define FXAA_PC_CONSOLE 0
|
||||
//
|
||||
// The console algorithm for PC is included
|
||||
// for developers targeting really low spec machines.
|
||||
// Likely better to just run FXAA_PC, and use a really low preset.
|
||||
//
|
||||
# define FXAA_PC_CONSOLE 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_GLSL_120
|
||||
#define FXAA_GLSL_120 0
|
||||
# define FXAA_GLSL_120 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_GLSL_130
|
||||
#define FXAA_GLSL_130 0
|
||||
# define FXAA_GLSL_130 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_HLSL_3
|
||||
#define FXAA_HLSL_3 0
|
||||
# define FXAA_HLSL_3 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_HLSL_4
|
||||
#define FXAA_HLSL_4 0
|
||||
# define FXAA_HLSL_4 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_HLSL_5
|
||||
#define FXAA_HLSL_5 0
|
||||
# define FXAA_HLSL_5 0
|
||||
#endif
|
||||
/*==========================================================================*/
|
||||
#ifndef FXAA_GREEN_AS_LUMA
|
||||
//
|
||||
// For those using non-linear color,
|
||||
// and either not able to get luma in alpha, or not wanting to,
|
||||
// this enables FXAA to run using green as a proxy for luma.
|
||||
// So with this enabled, no need to pack luma in alpha.
|
||||
//
|
||||
// This will turn off AA on anything which lacks some amount of green.
|
||||
// Pure red and blue or combination of only R and B, will get no AA.
|
||||
//
|
||||
// Might want to lower the settings for both,
|
||||
// fxaaConsoleEdgeThresholdMin
|
||||
// fxaaQualityEdgeThresholdMin
|
||||
// In order to insure AA does not get turned off on colors
|
||||
// which contain a minor amount of green.
|
||||
//
|
||||
// 1 = On.
|
||||
// 0 = Off.
|
||||
//
|
||||
#define FXAA_GREEN_AS_LUMA 0
|
||||
//
|
||||
// For those using non-linear color,
|
||||
// and either not able to get luma in alpha, or not wanting to,
|
||||
// this enables FXAA to run using green as a proxy for luma.
|
||||
// So with this enabled, no need to pack luma in alpha.
|
||||
//
|
||||
// This will turn off AA on anything which lacks some amount of green.
|
||||
// Pure red and blue or combination of only R and B, will get no AA.
|
||||
//
|
||||
// Might want to lower the settings for both,
|
||||
// fxaaConsoleEdgeThresholdMin
|
||||
// fxaaQualityEdgeThresholdMin
|
||||
// In order to insure AA does not get turned off on colors
|
||||
// which contain a minor amount of green.
|
||||
//
|
||||
// 1 = On.
|
||||
// 0 = Off.
|
||||
//
|
||||
# define FXAA_GREEN_AS_LUMA 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_EARLY_EXIT
|
||||
//
|
||||
// Controls algorithm's early exit path.
|
||||
// On PS3 turning this ON adds 2 cycles to the shader.
|
||||
// On 360 turning this OFF adds 10ths of a millisecond to the shader.
|
||||
// Turning this off on console will result in a more blurry image.
|
||||
// So this defaults to on.
|
||||
//
|
||||
// 1 = On.
|
||||
// 0 = Off.
|
||||
//
|
||||
#define FXAA_EARLY_EXIT 1
|
||||
//
|
||||
// Controls algorithm's early exit path.
|
||||
// On PS3 turning this ON adds 2 cycles to the shader.
|
||||
// On 360 turning this OFF adds 10ths of a millisecond to the shader.
|
||||
// Turning this off on console will result in a more blurry image.
|
||||
// So this defaults to on.
|
||||
//
|
||||
// 1 = On.
|
||||
// 0 = Off.
|
||||
//
|
||||
# define FXAA_EARLY_EXIT 1
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_DISCARD
|
||||
//
|
||||
// Only valid for PC OpenGL currently.
|
||||
// Probably will not work when FXAA_GREEN_AS_LUMA = 1.
|
||||
//
|
||||
// 1 = Use discard on pixels which don't need AA.
|
||||
// For APIs which enable concurrent TEX+ROP from same surface.
|
||||
// 0 = Return unchanged color on pixels which don't need AA.
|
||||
//
|
||||
#define FXAA_DISCARD 0
|
||||
//
|
||||
// Only valid for PC OpenGL currently.
|
||||
// Probably will not work when FXAA_GREEN_AS_LUMA = 1.
|
||||
//
|
||||
// 1 = Use discard on pixels which don't need AA.
|
||||
// For APIs which enable concurrent TEX+ROP from same surface.
|
||||
// 0 = Return unchanged color on pixels which don't need AA.
|
||||
//
|
||||
# define FXAA_DISCARD 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_FAST_PIXEL_OFFSET
|
||||
//
|
||||
// Used for GLSL 120 only.
|
||||
//
|
||||
// 1 = GL API supports fast pixel offsets
|
||||
// 0 = do not use fast pixel offsets
|
||||
//
|
||||
#ifdef GL_EXT_gpu_shader4
|
||||
#define FXAA_FAST_PIXEL_OFFSET 1
|
||||
#endif
|
||||
#ifdef GL_NV_gpu_shader5
|
||||
#define FXAA_FAST_PIXEL_OFFSET 1
|
||||
#endif
|
||||
#ifdef GL_ARB_gpu_shader5
|
||||
#define FXAA_FAST_PIXEL_OFFSET 1
|
||||
#endif
|
||||
#ifndef FXAA_FAST_PIXEL_OFFSET
|
||||
#define FXAA_FAST_PIXEL_OFFSET 0
|
||||
#endif
|
||||
//
|
||||
// Used for GLSL 120 only.
|
||||
//
|
||||
// 1 = GL API supports fast pixel offsets
|
||||
// 0 = do not use fast pixel offsets
|
||||
//
|
||||
# ifdef GL_EXT_gpu_shader4
|
||||
# define FXAA_FAST_PIXEL_OFFSET 1
|
||||
# endif
|
||||
# ifdef GL_NV_gpu_shader5
|
||||
# define FXAA_FAST_PIXEL_OFFSET 1
|
||||
# endif
|
||||
# ifdef GL_ARB_gpu_shader5
|
||||
# define FXAA_FAST_PIXEL_OFFSET 1
|
||||
# endif
|
||||
# ifndef FXAA_FAST_PIXEL_OFFSET
|
||||
# define FXAA_FAST_PIXEL_OFFSET 0
|
||||
# endif
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_GATHER4_ALPHA
|
||||
//
|
||||
// 1 = API supports gather4 on alpha channel.
|
||||
// 0 = API does not support gather4 on alpha channel.
|
||||
//
|
||||
#if (FXAA_HLSL_5 == 1)
|
||||
#define FXAA_GATHER4_ALPHA 1
|
||||
#endif
|
||||
#ifdef GL_ARB_gpu_shader5
|
||||
#define FXAA_GATHER4_ALPHA 1
|
||||
#endif
|
||||
#ifdef GL_NV_gpu_shader5
|
||||
#define FXAA_GATHER4_ALPHA 1
|
||||
#endif
|
||||
#ifndef FXAA_GATHER4_ALPHA
|
||||
#define FXAA_GATHER4_ALPHA 0
|
||||
#endif
|
||||
//
|
||||
// 1 = API supports gather4 on alpha channel.
|
||||
// 0 = API does not support gather4 on alpha channel.
|
||||
//
|
||||
# if (FXAA_HLSL_5 == 1)
|
||||
# define FXAA_GATHER4_ALPHA 1
|
||||
# endif
|
||||
# ifdef GL_ARB_gpu_shader5
|
||||
# define FXAA_GATHER4_ALPHA 1
|
||||
# endif
|
||||
# ifdef GL_NV_gpu_shader5
|
||||
# define FXAA_GATHER4_ALPHA 1
|
||||
# endif
|
||||
# ifndef FXAA_GATHER4_ALPHA
|
||||
# define FXAA_GATHER4_ALPHA 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*============================================================================
|
||||
FXAA CONSOLE PS3 - TUNING KNOBS
|
||||
============================================================================*/
|
||||
#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS
|
||||
//
|
||||
// Consoles the sharpness of edges on PS3 only.
|
||||
// Non-PS3 tuning is done with shader input.
|
||||
//
|
||||
// Due to the PS3 being ALU bound,
|
||||
// there are only two safe values here: 4 and 8.
|
||||
// These options use the shaders ability to a free *|/ by 2|4|8.
|
||||
//
|
||||
// 8.0 is sharper
|
||||
// 4.0 is softer
|
||||
// 2.0 is really soft (good for vector graphics inputs)
|
||||
//
|
||||
#if 1
|
||||
#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0
|
||||
#endif
|
||||
#if 0
|
||||
#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0
|
||||
#endif
|
||||
#if 0
|
||||
#define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0
|
||||
#endif
|
||||
//
|
||||
// Consoles the sharpness of edges on PS3 only.
|
||||
// Non-PS3 tuning is done with shader input.
|
||||
//
|
||||
// Due to the PS3 being ALU bound,
|
||||
// there are only two safe values here: 4 and 8.
|
||||
// These options use the shaders ability to a free *|/ by 2|4|8.
|
||||
//
|
||||
// 8.0 is sharper
|
||||
// 4.0 is softer
|
||||
// 2.0 is really soft (good for vector graphics inputs)
|
||||
//
|
||||
# if 1
|
||||
# define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0
|
||||
# endif
|
||||
# if 0
|
||||
# define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0
|
||||
# endif
|
||||
# if 0
|
||||
# define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0
|
||||
# endif
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD
|
||||
//
|
||||
// Only effects PS3.
|
||||
// Non-PS3 tuning is done with shader input.
|
||||
//
|
||||
// The minimum amount of local contrast required to apply algorithm.
|
||||
// The console setting has a different mapping than the quality setting.
|
||||
//
|
||||
// This only applies when FXAA_EARLY_EXIT is 1.
|
||||
//
|
||||
// Due to the PS3 being ALU bound,
|
||||
// there are only two safe values here: 0.25 and 0.125.
|
||||
// These options use the shaders ability to a free *|/ by 2|4|8.
|
||||
//
|
||||
// 0.125 leaves less aliasing, but is softer
|
||||
// 0.25 leaves more aliasing, and is sharper
|
||||
//
|
||||
#if 1
|
||||
#define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125
|
||||
#else
|
||||
#define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25
|
||||
#endif
|
||||
//
|
||||
// Only effects PS3.
|
||||
// Non-PS3 tuning is done with shader input.
|
||||
//
|
||||
// The minimum amount of local contrast required to apply algorithm.
|
||||
// The console setting has a different mapping than the quality setting.
|
||||
//
|
||||
// This only applies when FXAA_EARLY_EXIT is 1.
|
||||
//
|
||||
// Due to the PS3 being ALU bound,
|
||||
// there are only two safe values here: 0.25 and 0.125.
|
||||
// These options use the shaders ability to a free *|/ by 2|4|8.
|
||||
//
|
||||
// 0.125 leaves less aliasing, but is softer
|
||||
// 0.25 leaves more aliasing, and is sharper
|
||||
//
|
||||
# if 1
|
||||
# define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125
|
||||
# else
|
||||
# define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*============================================================================
|
||||
@@ -377,27 +377,27 @@ A. Or use FXAA_GREEN_AS_LUMA.
|
||||
NOTE the other tuning knobs are now in the shader function inputs!
|
||||
============================================================================*/
|
||||
#ifndef FXAA_QUALITY__PRESET
|
||||
//
|
||||
// Choose the quality preset.
|
||||
// This needs to be compiled into the shader as it effects code.
|
||||
// Best option to include multiple presets is to
|
||||
// in each shader define the preset, then include this file.
|
||||
//
|
||||
// OPTIONS
|
||||
// -----------------------------------------------------------------------
|
||||
// 10 to 15 - default medium dither (10=fastest, 15=highest quality)
|
||||
// 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
|
||||
// 39 - no dither, very expensive
|
||||
//
|
||||
// NOTES
|
||||
// -----------------------------------------------------------------------
|
||||
// 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
|
||||
// 13 = about same speed as FXAA 3.9 and better than 12
|
||||
// 23 = closest to FXAA 3.9 visually and performance wise
|
||||
// _ = the lowest digit is directly related to performance
|
||||
// _ = the highest digit is directly related to style
|
||||
//
|
||||
#define FXAA_QUALITY__PRESET 12
|
||||
//
|
||||
// Choose the quality preset.
|
||||
// This needs to be compiled into the shader as it effects code.
|
||||
// Best option to include multiple presets is to
|
||||
// in each shader define the preset, then include this file.
|
||||
//
|
||||
// OPTIONS
|
||||
// -----------------------------------------------------------------------
|
||||
// 10 to 15 - default medium dither (10=fastest, 15=highest quality)
|
||||
// 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
|
||||
// 39 - no dither, very expensive
|
||||
//
|
||||
// NOTES
|
||||
// -----------------------------------------------------------------------
|
||||
// 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
|
||||
// 13 = about same speed as FXAA 3.9 and better than 12
|
||||
// 23 = closest to FXAA 3.9 visually and performance wise
|
||||
// _ = the lowest digit is directly related to performance
|
||||
// _ = the highest digit is directly related to style
|
||||
//
|
||||
# define FXAA_QUALITY__PRESET 12
|
||||
#endif
|
||||
|
||||
|
||||
@@ -411,291 +411,296 @@ NOTE the other tuning knobs are now in the shader function inputs!
|
||||
FXAA QUALITY - MEDIUM DITHER PRESETS
|
||||
============================================================================*/
|
||||
#if (FXAA_QUALITY__PRESET == 10)
|
||||
#define FXAA_QUALITY__PS 3
|
||||
#define FXAA_QUALITY__P0 1.5
|
||||
#define FXAA_QUALITY__P1 3.0
|
||||
#define FXAA_QUALITY__P2 12.0
|
||||
# define FXAA_QUALITY__PS 3
|
||||
# define FXAA_QUALITY__P0 1.5
|
||||
# define FXAA_QUALITY__P1 3.0
|
||||
# define FXAA_QUALITY__P2 12.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 11)
|
||||
#define FXAA_QUALITY__PS 4
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 3.0
|
||||
#define FXAA_QUALITY__P3 12.0
|
||||
# define FXAA_QUALITY__PS 4
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 3.0
|
||||
# define FXAA_QUALITY__P3 12.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 12)
|
||||
#define FXAA_QUALITY__PS 5
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 4.0
|
||||
#define FXAA_QUALITY__P4 12.0
|
||||
# define FXAA_QUALITY__PS 5
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 4.0
|
||||
# define FXAA_QUALITY__P4 12.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 13)
|
||||
#define FXAA_QUALITY__PS 6
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 4.0
|
||||
#define FXAA_QUALITY__P5 12.0
|
||||
# define FXAA_QUALITY__PS 6
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 4.0
|
||||
# define FXAA_QUALITY__P5 12.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 14)
|
||||
#define FXAA_QUALITY__PS 7
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 4.0
|
||||
#define FXAA_QUALITY__P6 12.0
|
||||
# define FXAA_QUALITY__PS 7
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 4.0
|
||||
# define FXAA_QUALITY__P6 12.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 15)
|
||||
#define FXAA_QUALITY__PS 8
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 4.0
|
||||
#define FXAA_QUALITY__P7 12.0
|
||||
# define FXAA_QUALITY__PS 8
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 2.0
|
||||
# define FXAA_QUALITY__P6 4.0
|
||||
# define FXAA_QUALITY__P7 12.0
|
||||
#endif
|
||||
|
||||
/*============================================================================
|
||||
FXAA QUALITY - LOW DITHER PRESETS
|
||||
============================================================================*/
|
||||
#if (FXAA_QUALITY__PRESET == 20)
|
||||
#define FXAA_QUALITY__PS 3
|
||||
#define FXAA_QUALITY__P0 1.5
|
||||
#define FXAA_QUALITY__P1 2.0
|
||||
#define FXAA_QUALITY__P2 8.0
|
||||
# define FXAA_QUALITY__PS 3
|
||||
# define FXAA_QUALITY__P0 1.5
|
||||
# define FXAA_QUALITY__P1 2.0
|
||||
# define FXAA_QUALITY__P2 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 21)
|
||||
#define FXAA_QUALITY__PS 4
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 8.0
|
||||
# define FXAA_QUALITY__PS 4
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 22)
|
||||
#define FXAA_QUALITY__PS 5
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 8.0
|
||||
# define FXAA_QUALITY__PS 5
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 23)
|
||||
#define FXAA_QUALITY__PS 6
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 8.0
|
||||
# define FXAA_QUALITY__PS 6
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 24)
|
||||
#define FXAA_QUALITY__PS 7
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 3.0
|
||||
#define FXAA_QUALITY__P6 8.0
|
||||
# define FXAA_QUALITY__PS 7
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 3.0
|
||||
# define FXAA_QUALITY__P6 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 25)
|
||||
#define FXAA_QUALITY__PS 8
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 4.0
|
||||
#define FXAA_QUALITY__P7 8.0
|
||||
# define FXAA_QUALITY__PS 8
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 2.0
|
||||
# define FXAA_QUALITY__P6 4.0
|
||||
# define FXAA_QUALITY__P7 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 26)
|
||||
#define FXAA_QUALITY__PS 9
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 4.0
|
||||
#define FXAA_QUALITY__P8 8.0
|
||||
# define FXAA_QUALITY__PS 9
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 2.0
|
||||
# define FXAA_QUALITY__P6 2.0
|
||||
# define FXAA_QUALITY__P7 4.0
|
||||
# define FXAA_QUALITY__P8 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 27)
|
||||
#define FXAA_QUALITY__PS 10
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 2.0
|
||||
#define FXAA_QUALITY__P8 4.0
|
||||
#define FXAA_QUALITY__P9 8.0
|
||||
# define FXAA_QUALITY__PS 10
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 2.0
|
||||
# define FXAA_QUALITY__P6 2.0
|
||||
# define FXAA_QUALITY__P7 2.0
|
||||
# define FXAA_QUALITY__P8 4.0
|
||||
# define FXAA_QUALITY__P9 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 28)
|
||||
#define FXAA_QUALITY__PS 11
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 2.0
|
||||
#define FXAA_QUALITY__P8 2.0
|
||||
#define FXAA_QUALITY__P9 4.0
|
||||
#define FXAA_QUALITY__P10 8.0
|
||||
# define FXAA_QUALITY__PS 11
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 2.0
|
||||
# define FXAA_QUALITY__P6 2.0
|
||||
# define FXAA_QUALITY__P7 2.0
|
||||
# define FXAA_QUALITY__P8 2.0
|
||||
# define FXAA_QUALITY__P9 4.0
|
||||
# define FXAA_QUALITY__P10 8.0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PRESET == 29)
|
||||
#define FXAA_QUALITY__PS 12
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 2.0
|
||||
#define FXAA_QUALITY__P8 2.0
|
||||
#define FXAA_QUALITY__P9 2.0
|
||||
#define FXAA_QUALITY__P10 4.0
|
||||
#define FXAA_QUALITY__P11 8.0
|
||||
# define FXAA_QUALITY__PS 12
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.5
|
||||
# define FXAA_QUALITY__P2 2.0
|
||||
# define FXAA_QUALITY__P3 2.0
|
||||
# define FXAA_QUALITY__P4 2.0
|
||||
# define FXAA_QUALITY__P5 2.0
|
||||
# define FXAA_QUALITY__P6 2.0
|
||||
# define FXAA_QUALITY__P7 2.0
|
||||
# define FXAA_QUALITY__P8 2.0
|
||||
# define FXAA_QUALITY__P9 2.0
|
||||
# define FXAA_QUALITY__P10 4.0
|
||||
# define FXAA_QUALITY__P11 8.0
|
||||
#endif
|
||||
|
||||
/*============================================================================
|
||||
FXAA QUALITY - EXTREME QUALITY
|
||||
============================================================================*/
|
||||
#if (FXAA_QUALITY__PRESET == 39)
|
||||
#define FXAA_QUALITY__PS 12
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.0
|
||||
#define FXAA_QUALITY__P2 1.0
|
||||
#define FXAA_QUALITY__P3 1.0
|
||||
#define FXAA_QUALITY__P4 1.0
|
||||
#define FXAA_QUALITY__P5 1.5
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 2.0
|
||||
#define FXAA_QUALITY__P8 2.0
|
||||
#define FXAA_QUALITY__P9 2.0
|
||||
#define FXAA_QUALITY__P10 4.0
|
||||
#define FXAA_QUALITY__P11 8.0
|
||||
# define FXAA_QUALITY__PS 12
|
||||
# define FXAA_QUALITY__P0 1.0
|
||||
# define FXAA_QUALITY__P1 1.0
|
||||
# define FXAA_QUALITY__P2 1.0
|
||||
# define FXAA_QUALITY__P3 1.0
|
||||
# define FXAA_QUALITY__P4 1.0
|
||||
# define FXAA_QUALITY__P5 1.5
|
||||
# define FXAA_QUALITY__P6 2.0
|
||||
# define FXAA_QUALITY__P7 2.0
|
||||
# define FXAA_QUALITY__P8 2.0
|
||||
# define FXAA_QUALITY__P9 2.0
|
||||
# define FXAA_QUALITY__P10 4.0
|
||||
# define FXAA_QUALITY__P11 8.0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*============================================================================
|
||||
|
||||
API PORTING
|
||||
|
||||
============================================================================*/
|
||||
#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)
|
||||
#define FxaaBool bool
|
||||
#define FxaaDiscard discard
|
||||
#define FxaaFloat float
|
||||
#define FxaaFloat2 vec2
|
||||
#define FxaaFloat3 vec3
|
||||
#define FxaaFloat4 vec4
|
||||
#define FxaaHalf float
|
||||
#define FxaaHalf2 vec2
|
||||
#define FxaaHalf3 vec3
|
||||
#define FxaaHalf4 vec4
|
||||
#define FxaaInt2 ivec2
|
||||
#define FxaaSat(x) clamp(x, 0.0, 1.0)
|
||||
#define FxaaTex sampler2D
|
||||
# define FxaaBool bool
|
||||
# define FxaaDiscard discard
|
||||
# define FxaaFloat float
|
||||
# define FxaaFloat2 vec2
|
||||
# define FxaaFloat3 vec3
|
||||
# define FxaaFloat4 vec4
|
||||
# define FxaaHalf float
|
||||
# define FxaaHalf2 vec2
|
||||
# define FxaaHalf3 vec3
|
||||
# define FxaaHalf4 vec4
|
||||
# define FxaaInt2 ivec2
|
||||
# define FxaaSat(x) clamp(x, 0.0, 1.0)
|
||||
# define FxaaTex sampler2D
|
||||
#else
|
||||
#define FxaaBool bool
|
||||
#define FxaaDiscard clip(-1)
|
||||
#define FxaaFloat float
|
||||
#define FxaaFloat2 float2
|
||||
#define FxaaFloat3 float3
|
||||
#define FxaaFloat4 float4
|
||||
#define FxaaHalf half
|
||||
#define FxaaHalf2 half2
|
||||
#define FxaaHalf3 half3
|
||||
#define FxaaHalf4 half4
|
||||
#define FxaaSat(x) saturate(x)
|
||||
# define FxaaBool bool
|
||||
# define FxaaDiscard clip(-1)
|
||||
# define FxaaFloat float
|
||||
# define FxaaFloat2 float2
|
||||
# define FxaaFloat3 float3
|
||||
# define FxaaFloat4 float4
|
||||
# define FxaaHalf half
|
||||
# define FxaaHalf2 half2
|
||||
# define FxaaHalf3 half3
|
||||
# define FxaaHalf4 half4
|
||||
# define FxaaSat(x) saturate(x)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_GLSL_120 == 1)
|
||||
// Requires,
|
||||
// #version 120
|
||||
// And at least,
|
||||
// #extension GL_EXT_gpu_shader4 : enable
|
||||
// (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
|
||||
#define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
|
||||
#if (FXAA_FAST_PIXEL_OFFSET == 1)
|
||||
#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
|
||||
#else
|
||||
#define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)
|
||||
#endif
|
||||
#if (FXAA_GATHER4_ALPHA == 1)
|
||||
// use #extension GL_ARB_gpu_shader5 : enable
|
||||
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
|
||||
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
|
||||
#define FxaaTexGreen4(t, p) textureGather(t, p, 1)
|
||||
#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
|
||||
#endif
|
||||
// Requires,
|
||||
// #version 120
|
||||
// And at least,
|
||||
// #extension GL_EXT_gpu_shader4 : enable
|
||||
// (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
|
||||
# define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
|
||||
# if (FXAA_FAST_PIXEL_OFFSET == 1)
|
||||
# define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
|
||||
# else
|
||||
# define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)
|
||||
# endif
|
||||
# if (FXAA_GATHER4_ALPHA == 1)
|
||||
// use #extension GL_ARB_gpu_shader5 : enable
|
||||
# define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
|
||||
# define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
|
||||
# define FxaaTexGreen4(t, p) textureGather(t, p, 1)
|
||||
# define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
|
||||
# endif
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_GLSL_130 == 1)
|
||||
// Requires "#version 130" or better
|
||||
#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
|
||||
#if (FXAA_GATHER4_ALPHA == 1)
|
||||
// use #extension GL_ARB_gpu_shader5 : enable
|
||||
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
|
||||
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
|
||||
#define FxaaTexGreen4(t, p) textureGather(t, p, 1)
|
||||
#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
|
||||
#endif
|
||||
// Requires "#version 130" or better
|
||||
# define FxaaTexTop(t, p) textureLod(t, p, 0.0)
|
||||
# define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
|
||||
# if (FXAA_GATHER4_ALPHA == 1)
|
||||
// use #extension GL_ARB_gpu_shader5 : enable
|
||||
# define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
|
||||
# define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
|
||||
# define FxaaTexGreen4(t, p) textureGather(t, p, 1)
|
||||
# define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
|
||||
# endif
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1)
|
||||
#define FxaaInt2 float2
|
||||
#define FxaaTex sampler2D
|
||||
#define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
|
||||
#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
|
||||
# define FxaaInt2 float2
|
||||
# define FxaaTex sampler2D
|
||||
# define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
|
||||
# define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_HLSL_4 == 1)
|
||||
#define FxaaInt2 int2
|
||||
struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
|
||||
# define FxaaInt2 int2
|
||||
struct FxaaTex {
|
||||
SamplerState smpl;
|
||||
Texture2D tex;
|
||||
};
|
||||
# define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
|
||||
# define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_HLSL_5 == 1)
|
||||
#define FxaaInt2 int2
|
||||
struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
|
||||
#define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)
|
||||
#define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)
|
||||
#define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)
|
||||
#define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)
|
||||
# define FxaaInt2 int2
|
||||
struct FxaaTex {
|
||||
SamplerState smpl;
|
||||
Texture2D tex;
|
||||
};
|
||||
# define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
|
||||
# define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
|
||||
# define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)
|
||||
# define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)
|
||||
# define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)
|
||||
# define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -703,13 +708,15 @@ NOTE the other tuning knobs are now in the shader function inputs!
|
||||
GREEN AS LUMA OPTION SUPPORT FUNCTION
|
||||
============================================================================*/
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
//FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
|
||||
FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return dot(rgba.rgb, FxaaFloat3(0.299, 0.587, 0.114)); }
|
||||
// FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
|
||||
FxaaFloat FxaaLuma(FxaaFloat4 rgba) {
|
||||
return dot(rgba.rgb, FxaaFloat3(0.299, 0.587, 0.114));
|
||||
}
|
||||
#else
|
||||
FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }
|
||||
#endif
|
||||
|
||||
|
||||
FxaaFloat FxaaLuma(FxaaFloat4 rgba) {
|
||||
return rgba.y;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*============================================================================
|
||||
@@ -720,71 +727,71 @@ NOTE the other tuning knobs are now in the shader function inputs!
|
||||
#if (FXAA_PC == 1)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat4 FxaaPixelShader(
|
||||
//
|
||||
//
|
||||
// Use noperspective interpolation here (turn off perspective interpolation).
|
||||
// {xy} = center of pixel
|
||||
FxaaFloat2 pos,
|
||||
//
|
||||
FxaaFloat2 pos,
|
||||
//
|
||||
// Used only for FXAA Console, and not used on the 360 version.
|
||||
// Use noperspective interpolation here (turn off perspective interpolation).
|
||||
// {xy__} = upper left of pixel
|
||||
// {__zw} = lower right of pixel
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
//
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
//
|
||||
// Input color texture.
|
||||
// {rgb_} = color in linear or perceptual color space
|
||||
// if (FXAA_GREEN_AS_LUMA == 0)
|
||||
// {___a} = luma in perceptual color space (not linear)
|
||||
FxaaTex tex,
|
||||
//
|
||||
FxaaTex tex,
|
||||
//
|
||||
// Only used on the optimized 360 version of FXAA Console.
|
||||
// For everything but 360, just use the same input here as for "tex".
|
||||
// For 360, same texture, just alias with a 2nd sampler.
|
||||
// This sampler needs to have an exponent bias of -1.
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
//
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
//
|
||||
// Only used on the optimized 360 version of FXAA Console.
|
||||
// For everything but 360, just use the same input here as for "tex".
|
||||
// For 360, same texture, just alias with a 3nd sampler.
|
||||
// This sampler needs to have an exponent bias of -2.
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
//
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
//
|
||||
// Only used on FXAA Quality.
|
||||
// This must be from a constant/uniform.
|
||||
// {x_} = 1.0/screenWidthInPixels
|
||||
// {_y} = 1.0/screenHeightInPixels
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
//
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
//
|
||||
// Only used on FXAA Console.
|
||||
// This must be from a constant/uniform.
|
||||
// This effects sub-pixel AA quality and inversely sharpness.
|
||||
// Where N ranges between,
|
||||
// N = 0.50 (default)
|
||||
// N = 0.33 (sharper)
|
||||
// {x___} = -N/screenWidthInPixels
|
||||
// {x___} = -N/screenWidthInPixels
|
||||
// {_y__} = -N/screenHeightInPixels
|
||||
// {__z_} = N/screenWidthInPixels
|
||||
// {___w} = N/screenHeightInPixels
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
//
|
||||
// {__z_} = N/screenWidthInPixels
|
||||
// {___w} = N/screenHeightInPixels
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
//
|
||||
// Only used on FXAA Console.
|
||||
// Not used on 360, but used on PS3 and PC.
|
||||
// This must be from a constant/uniform.
|
||||
// {x___} = -2.0/screenWidthInPixels
|
||||
// {x___} = -2.0/screenWidthInPixels
|
||||
// {_y__} = -2.0/screenHeightInPixels
|
||||
// {__z_} = 2.0/screenWidthInPixels
|
||||
// {___w} = 2.0/screenHeightInPixels
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
//
|
||||
// {__z_} = 2.0/screenWidthInPixels
|
||||
// {___w} = 2.0/screenHeightInPixels
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
//
|
||||
// Only used on FXAA Console.
|
||||
// Only used on 360 in place of fxaaConsoleRcpFrameOpt2.
|
||||
// This must be from a constant/uniform.
|
||||
// {x___} = 8.0/screenWidthInPixels
|
||||
// {x___} = 8.0/screenWidthInPixels
|
||||
// {_y__} = 8.0/screenHeightInPixels
|
||||
// {__z_} = -4.0/screenWidthInPixels
|
||||
// {___w} = -4.0/screenHeightInPixels
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
//
|
||||
// {__z_} = -4.0/screenWidthInPixels
|
||||
// {___w} = -4.0/screenHeightInPixels
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
//
|
||||
// Only used on FXAA Quality.
|
||||
// This used to be the FXAA_QUALITY__SUBPIX define.
|
||||
// It is here now to allow easier tuning.
|
||||
@@ -795,8 +802,8 @@ FxaaFloat4 FxaaPixelShader(
|
||||
// 0.50 - lower limit (sharper, less sub-pixel aliasing removal)
|
||||
// 0.25 - almost off
|
||||
// 0.00 - completely off
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
//
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
//
|
||||
// Only used on FXAA Quality.
|
||||
// This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.
|
||||
// It is here now to allow easier tuning.
|
||||
@@ -804,10 +811,10 @@ FxaaFloat4 FxaaPixelShader(
|
||||
// 0.333 - too little (faster)
|
||||
// 0.250 - low quality
|
||||
// 0.166 - default
|
||||
// 0.125 - high quality
|
||||
// 0.125 - high quality
|
||||
// 0.063 - overkill (slower)
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
//
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
//
|
||||
// Only used on FXAA Quality.
|
||||
// This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.
|
||||
// It is here now to allow easier tuning.
|
||||
@@ -821,8 +828,8 @@ FxaaFloat4 FxaaPixelShader(
|
||||
// will appear very dark in the green channel!
|
||||
// Tune by looking at mostly non-green content,
|
||||
// then start at zero and increase until aliasing is a problem.
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
//
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
//
|
||||
// Only used on FXAA Console.
|
||||
// This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define.
|
||||
// It is here now to allow easier tuning.
|
||||
@@ -835,8 +842,8 @@ FxaaFloat4 FxaaPixelShader(
|
||||
// 8.0 is sharper (default!!!)
|
||||
// 4.0 is softer
|
||||
// 2.0 is really soft (good only for vector graphics inputs)
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
//
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
//
|
||||
// Only used on FXAA Console.
|
||||
// This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define.
|
||||
// It is here now to allow easier tuning.
|
||||
@@ -849,15 +856,15 @@ FxaaFloat4 FxaaPixelShader(
|
||||
// Other platforms can use other values.
|
||||
// 0.125 leaves less aliasing, but is softer (default!!!)
|
||||
// 0.25 leaves more aliasing, and is sharper
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
//
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
//
|
||||
// Only used on FXAA Console.
|
||||
// This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define.
|
||||
// It is here now to allow easier tuning.
|
||||
// Trims the algorithm from processing darks.
|
||||
// The console setting has a different mapping than the quality setting.
|
||||
// This only applies when FXAA_EARLY_EXIT is 1.
|
||||
// This does not apply to PS3,
|
||||
// This does not apply to PS3,
|
||||
// PS3 was simplified to avoid more shader instructions.
|
||||
// 0.06 - faster but more aliasing in darks
|
||||
// 0.05 - default
|
||||
@@ -868,478 +875,474 @@ FxaaFloat4 FxaaPixelShader(
|
||||
// will appear very dark in the green channel!
|
||||
// Tune by looking at mostly non-green content,
|
||||
// then start at zero and increase until aliasing is a problem.
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
//
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
//
|
||||
// Extra constants for 360 FXAA Console only.
|
||||
// Use zeros or anything else for other platforms.
|
||||
// These must be in physical constant registers and NOT immedates.
|
||||
// Immedates will result in compiler un-optimizing.
|
||||
// {xyzw} = float4(1.0, -1.0, 0.25, -0.25)
|
||||
FxaaFloat4 fxaaConsole360ConstDir
|
||||
) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 posM;
|
||||
posM.x = pos.x;
|
||||
posM.y = pos.y;
|
||||
#if (FXAA_GATHER4_ALPHA == 1)
|
||||
#if (FXAA_DISCARD == 0)
|
||||
FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
#define lumaM rgbyM.w
|
||||
#else
|
||||
#define lumaM rgbyM.y
|
||||
#endif
|
||||
#endif
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
|
||||
FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
|
||||
#else
|
||||
FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
|
||||
FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
|
||||
#endif
|
||||
#if (FXAA_DISCARD == 1)
|
||||
#define lumaM luma4A.w
|
||||
#endif
|
||||
#define lumaE luma4A.z
|
||||
#define lumaS luma4A.x
|
||||
#define lumaSE luma4A.y
|
||||
#define lumaNW luma4B.w
|
||||
#define lumaN luma4B.z
|
||||
#define lumaW luma4B.x
|
||||
#else
|
||||
FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
#define lumaM rgbyM.w
|
||||
#else
|
||||
#define lumaM rgbyM.y
|
||||
#endif
|
||||
FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat maxSM = max(lumaS, lumaM);
|
||||
FxaaFloat minSM = min(lumaS, lumaM);
|
||||
FxaaFloat maxESM = max(lumaE, maxSM);
|
||||
FxaaFloat minESM = min(lumaE, minSM);
|
||||
FxaaFloat maxWN = max(lumaN, lumaW);
|
||||
FxaaFloat minWN = min(lumaN, lumaW);
|
||||
FxaaFloat rangeMax = max(maxWN, maxESM);
|
||||
FxaaFloat rangeMin = min(minWN, minESM);
|
||||
FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
|
||||
FxaaFloat range = rangeMax - rangeMin;
|
||||
FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
|
||||
FxaaBool earlyExit = range < rangeMaxClamped;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if(earlyExit)
|
||||
#if (FXAA_DISCARD == 1)
|
||||
FxaaDiscard;
|
||||
#else
|
||||
return rgbyM;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_GATHER4_ALPHA == 0)
|
||||
FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
|
||||
#else
|
||||
FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNS = lumaN + lumaS;
|
||||
FxaaFloat lumaWE = lumaW + lumaE;
|
||||
FxaaFloat subpixRcpRange = 1.0/range;
|
||||
FxaaFloat subpixNSWE = lumaNS + lumaWE;
|
||||
FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
|
||||
FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNESE = lumaNE + lumaSE;
|
||||
FxaaFloat lumaNWNE = lumaNW + lumaNE;
|
||||
FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
|
||||
FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNWSW = lumaNW + lumaSW;
|
||||
FxaaFloat lumaSWSE = lumaSW + lumaSE;
|
||||
FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
|
||||
FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
|
||||
FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
|
||||
FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
|
||||
FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
|
||||
FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
|
||||
FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
|
||||
FxaaBool horzSpan = edgeHorz >= edgeVert;
|
||||
FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if(!horzSpan) lumaN = lumaW;
|
||||
if(!horzSpan) lumaS = lumaE;
|
||||
if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
|
||||
FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat gradientN = lumaN - lumaM;
|
||||
FxaaFloat gradientS = lumaS - lumaM;
|
||||
FxaaFloat lumaNN = lumaN + lumaM;
|
||||
FxaaFloat lumaSS = lumaS + lumaM;
|
||||
FxaaBool pairN = abs(gradientN) >= abs(gradientS);
|
||||
FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
|
||||
if(pairN) lengthSign = -lengthSign;
|
||||
FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 posB;
|
||||
posB.x = posM.x;
|
||||
posB.y = posM.y;
|
||||
FxaaFloat2 offNP;
|
||||
offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
|
||||
offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
|
||||
if(!horzSpan) posB.x += lengthSign * 0.5;
|
||||
if( horzSpan) posB.y += lengthSign * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 posN;
|
||||
posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
|
||||
posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
|
||||
FxaaFloat2 posP;
|
||||
posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
|
||||
posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
|
||||
FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;
|
||||
FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
|
||||
FxaaFloat subpixE = subpixC * subpixC;
|
||||
FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if(!pairN) lumaNN = lumaSS;
|
||||
FxaaFloat gradientScaled = gradient * 1.0/4.0;
|
||||
FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
|
||||
FxaaFloat subpixF = subpixD * subpixE;
|
||||
FxaaBool lumaMLTZero = lumaMM < 0.0;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
lumaEndN -= lumaNN * 0.5;
|
||||
lumaEndP -= lumaNN * 0.5;
|
||||
FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
|
||||
FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
|
||||
FxaaBool doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 3)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 4)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 5)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 6)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 7)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 8)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 9)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 10)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 11)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 12)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat dstN = posM.x - posN.x;
|
||||
FxaaFloat dstP = posP.x - posM.x;
|
||||
if(!horzSpan) dstN = posM.y - posN.y;
|
||||
if(!horzSpan) dstP = posP.y - posM.y;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
|
||||
FxaaFloat spanLength = (dstP + dstN);
|
||||
FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
|
||||
FxaaFloat spanLengthRcp = 1.0/spanLength;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaBool directionN = dstN < dstP;
|
||||
FxaaFloat dst = min(dstN, dstP);
|
||||
FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
|
||||
FxaaFloat subpixG = subpixF * subpixF;
|
||||
FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
|
||||
FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
|
||||
FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
|
||||
if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
|
||||
if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
|
||||
#if (FXAA_DISCARD == 1)
|
||||
return FxaaTexTop(tex, posM);
|
||||
#else
|
||||
return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
|
||||
#endif
|
||||
FxaaFloat4 fxaaConsole360ConstDir) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 posM;
|
||||
posM.x = pos.x;
|
||||
posM.y = pos.y;
|
||||
# if (FXAA_GATHER4_ALPHA == 1)
|
||||
# if (FXAA_DISCARD == 0)
|
||||
FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
# define lumaM rgbyM.w
|
||||
# else
|
||||
# define lumaM rgbyM.y
|
||||
# endif
|
||||
# endif
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
|
||||
FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
|
||||
# else
|
||||
FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
|
||||
FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
|
||||
# endif
|
||||
# if (FXAA_DISCARD == 1)
|
||||
# define lumaM luma4A.w
|
||||
# endif
|
||||
# define lumaE luma4A.z
|
||||
# define lumaS luma4A.x
|
||||
# define lumaSE luma4A.y
|
||||
# define lumaNW luma4B.w
|
||||
# define lumaN luma4B.z
|
||||
# define lumaW luma4B.x
|
||||
# else
|
||||
FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
# define lumaM rgbyM.w
|
||||
# else
|
||||
# define lumaM rgbyM.y
|
||||
# endif
|
||||
FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(0, 1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, 0), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(0, -1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat maxSM = max(lumaS, lumaM);
|
||||
FxaaFloat minSM = min(lumaS, lumaM);
|
||||
FxaaFloat maxESM = max(lumaE, maxSM);
|
||||
FxaaFloat minESM = min(lumaE, minSM);
|
||||
FxaaFloat maxWN = max(lumaN, lumaW);
|
||||
FxaaFloat minWN = min(lumaN, lumaW);
|
||||
FxaaFloat rangeMax = max(maxWN, maxESM);
|
||||
FxaaFloat rangeMin = min(minWN, minESM);
|
||||
FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
|
||||
FxaaFloat range = rangeMax - rangeMin;
|
||||
FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
|
||||
FxaaBool earlyExit = range < rangeMaxClamped;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if (earlyExit)
|
||||
# if (FXAA_DISCARD == 1)
|
||||
FxaaDiscard;
|
||||
# else
|
||||
return rgbyM;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_GATHER4_ALPHA == 0)
|
||||
FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, -1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, 1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
|
||||
# else
|
||||
FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNS = lumaN + lumaS;
|
||||
FxaaFloat lumaWE = lumaW + lumaE;
|
||||
FxaaFloat subpixRcpRange = 1.0 / range;
|
||||
FxaaFloat subpixNSWE = lumaNS + lumaWE;
|
||||
FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
|
||||
FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNESE = lumaNE + lumaSE;
|
||||
FxaaFloat lumaNWNE = lumaNW + lumaNE;
|
||||
FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
|
||||
FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNWSW = lumaNW + lumaSW;
|
||||
FxaaFloat lumaSWSE = lumaSW + lumaSE;
|
||||
FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
|
||||
FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
|
||||
FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
|
||||
FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
|
||||
FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
|
||||
FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
|
||||
FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
|
||||
FxaaBool horzSpan = edgeHorz >= edgeVert;
|
||||
FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if (!horzSpan) lumaN = lumaW;
|
||||
if (!horzSpan) lumaS = lumaE;
|
||||
if (horzSpan) lengthSign = fxaaQualityRcpFrame.y;
|
||||
FxaaFloat subpixB = (subpixA * (1.0 / 12.0)) - lumaM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat gradientN = lumaN - lumaM;
|
||||
FxaaFloat gradientS = lumaS - lumaM;
|
||||
FxaaFloat lumaNN = lumaN + lumaM;
|
||||
FxaaFloat lumaSS = lumaS + lumaM;
|
||||
FxaaBool pairN = abs(gradientN) >= abs(gradientS);
|
||||
FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
|
||||
if (pairN) lengthSign = -lengthSign;
|
||||
FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 posB;
|
||||
posB.x = posM.x;
|
||||
posB.y = posM.y;
|
||||
FxaaFloat2 offNP;
|
||||
offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
|
||||
offNP.y = (horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
|
||||
if (!horzSpan) posB.x += lengthSign * 0.5;
|
||||
if (horzSpan) posB.y += lengthSign * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 posN;
|
||||
posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
|
||||
posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
|
||||
FxaaFloat2 posP;
|
||||
posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
|
||||
posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
|
||||
FxaaFloat subpixD = ((-2.0) * subpixC) + 3.0;
|
||||
FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
|
||||
FxaaFloat subpixE = subpixC * subpixC;
|
||||
FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if (!pairN) lumaNN = lumaSS;
|
||||
FxaaFloat gradientScaled = gradient * 1.0 / 4.0;
|
||||
FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
|
||||
FxaaFloat subpixF = subpixD * subpixE;
|
||||
FxaaBool lumaMLTZero = lumaMM < 0.0;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
lumaEndN -= lumaNN * 0.5;
|
||||
lumaEndP -= lumaNN * 0.5;
|
||||
FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
|
||||
FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
|
||||
FxaaBool doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 3)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 4)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 5)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 6)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 7)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 8)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 9)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 10)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 11)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_QUALITY__PS > 12)
|
||||
if (doneNP) {
|
||||
if (!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if (!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if (!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
|
||||
if (!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if (!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
|
||||
if (!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat dstN = posM.x - posN.x;
|
||||
FxaaFloat dstP = posP.x - posM.x;
|
||||
if (!horzSpan) dstN = posM.y - posN.y;
|
||||
if (!horzSpan) dstP = posP.y - posM.y;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
|
||||
FxaaFloat spanLength = (dstP + dstN);
|
||||
FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
|
||||
FxaaFloat spanLengthRcp = 1.0 / spanLength;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaBool directionN = dstN < dstP;
|
||||
FxaaFloat dst = min(dstN, dstP);
|
||||
FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
|
||||
FxaaFloat subpixG = subpixF * subpixF;
|
||||
FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
|
||||
FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
|
||||
FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
|
||||
if (!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
|
||||
if (horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
|
||||
# if (FXAA_DISCARD == 1)
|
||||
return FxaaTexTop(tex, posM);
|
||||
# else
|
||||
return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
|
||||
# endif
|
||||
}
|
||||
/*==========================================================================*/
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*============================================================================
|
||||
|
||||
FXAA3 CONSOLE - PC VERSION
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Instead of using this on PC, I'd suggest just using FXAA Quality with
|
||||
#define FXAA_QUALITY__PRESET 10
|
||||
Or
|
||||
Or
|
||||
#define FXAA_QUALITY__PRESET 20
|
||||
Either are higher qualilty and almost as fast as this on modern PC GPUs.
|
||||
============================================================================*/
|
||||
#if (FXAA_PC_CONSOLE == 1)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat4 FxaaPixelShader(
|
||||
// See FXAA Quality FxaaPixelShader() source for docs on Inputs!
|
||||
FxaaFloat2 pos,
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
FxaaTex tex,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
FxaaFloat4 fxaaConsole360ConstDir
|
||||
) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy));
|
||||
FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw));
|
||||
FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy));
|
||||
FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy);
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
FxaaFloat lumaM = rgbyM.w;
|
||||
#else
|
||||
FxaaFloat lumaM = rgbyM.y;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw);
|
||||
lumaNe += 1.0/384.0;
|
||||
FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe);
|
||||
FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw);
|
||||
FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMinM = min(lumaMin, lumaM);
|
||||
FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled);
|
||||
FxaaFloat lumaMaxM = max(lumaMax, lumaM);
|
||||
FxaaFloat dirSwMinusNe = lumaSw - lumaNe;
|
||||
FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM;
|
||||
FxaaFloat dirSeMinusNw = lumaSe - lumaNw;
|
||||
if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 dir;
|
||||
dir.x = dirSwMinusNe + dirSeMinusNw;
|
||||
dir.y = dirSwMinusNe - dirSeMinusNw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 dir1 = normalize(dir.xy);
|
||||
FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw);
|
||||
FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness;
|
||||
FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw);
|
||||
FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat4 rgbyA = rgbyN1 + rgbyP1;
|
||||
FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax);
|
||||
#else
|
||||
FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax);
|
||||
#endif
|
||||
if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5;
|
||||
return rgbyB; }
|
||||
// See FXAA Quality FxaaPixelShader() source for docs on Inputs!
|
||||
FxaaFloat2 pos,
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
FxaaTex tex,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
FxaaFloat4 fxaaConsole360ConstDir) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy));
|
||||
FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw));
|
||||
FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy));
|
||||
FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy);
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
FxaaFloat lumaM = rgbyM.w;
|
||||
# else
|
||||
FxaaFloat lumaM = rgbyM.y;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw);
|
||||
lumaNe += 1.0 / 384.0;
|
||||
FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe);
|
||||
FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw);
|
||||
FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaMinM = min(lumaMin, lumaM);
|
||||
FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled);
|
||||
FxaaFloat lumaMaxM = max(lumaMax, lumaM);
|
||||
FxaaFloat dirSwMinusNe = lumaSw - lumaNe;
|
||||
FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM;
|
||||
FxaaFloat dirSeMinusNw = lumaSe - lumaNw;
|
||||
if (lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 dir;
|
||||
dir.x = dirSwMinusNe + dirSeMinusNw;
|
||||
dir.y = dirSwMinusNe - dirSeMinusNw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 dir1 = normalize(dir.xy);
|
||||
FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw);
|
||||
FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness;
|
||||
FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw);
|
||||
FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat4 rgbyA = rgbyN1 + rgbyP1;
|
||||
FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax);
|
||||
# else
|
||||
FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax);
|
||||
# endif
|
||||
if (twoTap) rgbyB.xyz = rgbyA.xyz * 0.5;
|
||||
return rgbyB;
|
||||
}
|
||||
/*==========================================================================*/
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*============================================================================
|
||||
|
||||
FXAA3 CONSOLE - 360 PIXEL SHADER
|
||||
FXAA3 CONSOLE - 360 PIXEL SHADER
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
This optimized version thanks to suggestions from Andy Luedke.
|
||||
@@ -1351,88 +1354,88 @@ If it does not work, please let me know so I can fix it.
|
||||
============================================================================*/
|
||||
#if (FXAA_360 == 1)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
[reduceTempRegUsage(4)]
|
||||
float4 FxaaPixelShader(
|
||||
// See FXAA Quality FxaaPixelShader() source for docs on Inputs!
|
||||
FxaaFloat2 pos,
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
FxaaTex tex,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
FxaaFloat4 fxaaConsole360ConstDir
|
||||
) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 lumaNwNeSwSe;
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
asm {
|
||||
[reduceTempRegUsage(4)] float4 FxaaPixelShader(
|
||||
// See FXAA Quality FxaaPixelShader() source for docs on Inputs!
|
||||
FxaaFloat2 pos,
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
FxaaTex tex,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
FxaaFloat4 fxaaConsole360ConstDir) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 lumaNwNeSwSe;
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
asm {
|
||||
tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
|
||||
tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false
|
||||
tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false
|
||||
tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false
|
||||
};
|
||||
#else
|
||||
asm {
|
||||
}
|
||||
;
|
||||
# else
|
||||
asm {
|
||||
tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
|
||||
tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false
|
||||
tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false
|
||||
tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false
|
||||
};
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
lumaNwNeSwSe.y += 1.0/384.0;
|
||||
float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
|
||||
float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
|
||||
float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y);
|
||||
float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
float lumaMinM = min(lumaMin, rgbyM.w);
|
||||
float lumaMaxM = max(lumaMax, rgbyM.w);
|
||||
#else
|
||||
float lumaMinM = min(lumaMin, rgbyM.y);
|
||||
float lumaMaxM = max(lumaMax, rgbyM.y);
|
||||
#endif
|
||||
if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float2 dir;
|
||||
dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx);
|
||||
dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy);
|
||||
dir = normalize(dir);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 dir2;
|
||||
float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness;
|
||||
dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5);
|
||||
dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0));
|
||||
float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0));
|
||||
float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0));
|
||||
float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 rgbyA = rgbyN1 + rgbyP1;
|
||||
float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB;
|
||||
rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA;
|
||||
return rgbyR; }
|
||||
}
|
||||
;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
lumaNwNeSwSe.y += 1.0 / 384.0;
|
||||
float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
|
||||
float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
|
||||
float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y);
|
||||
float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
float lumaMinM = min(lumaMin, rgbyM.w);
|
||||
float lumaMaxM = max(lumaMax, rgbyM.w);
|
||||
# else
|
||||
float lumaMinM = min(lumaMin, rgbyM.y);
|
||||
float lumaMaxM = max(lumaMax, rgbyM.y);
|
||||
# endif
|
||||
if ((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float2 dir;
|
||||
dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx);
|
||||
dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy);
|
||||
dir = normalize(dir);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 dir2;
|
||||
float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness;
|
||||
dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5);
|
||||
dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0));
|
||||
float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0));
|
||||
float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0));
|
||||
float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 rgbyA = rgbyN1 + rgbyP1;
|
||||
float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB;
|
||||
rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA;
|
||||
return rgbyR;
|
||||
}
|
||||
/*==========================================================================*/
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*============================================================================
|
||||
|
||||
FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT)
|
||||
@@ -1551,7 +1554,7 @@ Pass | Unit | uOp | PC: Op
|
||||
| | |
|
||||
13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---;
|
||||
| SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1;
|
||||
|
||||
|
||||
Pass SCT TEX SCB
|
||||
1: 0% 100% 25%
|
||||
2: 0% 100% 25%
|
||||
@@ -1590,137 +1593,136 @@ Results 13 cycles, 3 r regs, 923,076,923 pixels/s
|
||||
============================================================================*/
|
||||
#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#pragma regcount 7
|
||||
#pragma disablepc all
|
||||
#pragma option O3
|
||||
#pragma option OutColorPrec=fp16
|
||||
#pragma texformat default RGBA8
|
||||
# pragma regcount 7
|
||||
# pragma disablepc all
|
||||
# pragma option O3
|
||||
# pragma option OutColorPrec =fp16
|
||||
# pragma texformat default RGBA8
|
||||
/*==========================================================================*/
|
||||
half4 FxaaPixelShader(
|
||||
// See FXAA Quality FxaaPixelShader() source for docs on Inputs!
|
||||
FxaaFloat2 pos,
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
FxaaTex tex,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
FxaaFloat4 fxaaConsole360ConstDir
|
||||
) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (1)
|
||||
half4 dir;
|
||||
half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
lumaNe.w += half(1.0/512.0);
|
||||
dir.x = -lumaNe.w;
|
||||
dir.z = -lumaNe.w;
|
||||
#else
|
||||
lumaNe.y += half(1.0/512.0);
|
||||
dir.x = -lumaNe.y;
|
||||
dir.z = -lumaNe.y;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (2)
|
||||
half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
dir.x += lumaSw.w;
|
||||
dir.z += lumaSw.w;
|
||||
#else
|
||||
dir.x += lumaSw.y;
|
||||
dir.z += lumaSw.y;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (3)
|
||||
half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
dir.x -= lumaNw.w;
|
||||
dir.z += lumaNw.w;
|
||||
#else
|
||||
dir.x -= lumaNw.y;
|
||||
dir.z += lumaNw.y;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (4)
|
||||
half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
dir.x += lumaSe.w;
|
||||
dir.z -= lumaSe.w;
|
||||
#else
|
||||
dir.x += lumaSe.y;
|
||||
dir.z -= lumaSe.y;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (5)
|
||||
half4 dir1_pos;
|
||||
dir1_pos.xy = normalize(dir.xyz).xz;
|
||||
half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (6)
|
||||
half4 dir2_pos;
|
||||
dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0));
|
||||
dir1_pos.zw = pos.xy;
|
||||
dir2_pos.zw = pos.xy;
|
||||
half4 temp1N;
|
||||
temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (7)
|
||||
temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
|
||||
half4 rgby1;
|
||||
rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (8)
|
||||
rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
|
||||
rgby1 = (temp1N + rgby1) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (9)
|
||||
half4 temp2N;
|
||||
temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
|
||||
temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (10)
|
||||
half4 rgby2;
|
||||
rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
|
||||
rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
|
||||
rgby2 = (temp2N + rgby2) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (11)
|
||||
// compilier moves these scalar ops up to other cycles
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w));
|
||||
half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w));
|
||||
#else
|
||||
half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y));
|
||||
half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y));
|
||||
#endif
|
||||
rgby2 = (rgby2 + rgby1) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (12)
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
bool twoTapLt = rgby2.w < lumaMin;
|
||||
bool twoTapGt = rgby2.w > lumaMax;
|
||||
#else
|
||||
bool twoTapLt = rgby2.y < lumaMin;
|
||||
bool twoTapGt = rgby2.y > lumaMax;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (13)
|
||||
if(twoTapLt || twoTapGt) rgby2 = rgby1;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
return rgby2; }
|
||||
// See FXAA Quality FxaaPixelShader() source for docs on Inputs!
|
||||
FxaaFloat2 pos,
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
FxaaTex tex,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
FxaaFloat4 fxaaConsole360ConstDir) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (1)
|
||||
half4 dir;
|
||||
half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
lumaNe.w += half(1.0 / 512.0);
|
||||
dir.x = -lumaNe.w;
|
||||
dir.z = -lumaNe.w;
|
||||
# else
|
||||
lumaNe.y += half(1.0 / 512.0);
|
||||
dir.x = -lumaNe.y;
|
||||
dir.z = -lumaNe.y;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (2)
|
||||
half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
dir.x += lumaSw.w;
|
||||
dir.z += lumaSw.w;
|
||||
# else
|
||||
dir.x += lumaSw.y;
|
||||
dir.z += lumaSw.y;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (3)
|
||||
half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
dir.x -= lumaNw.w;
|
||||
dir.z += lumaNw.w;
|
||||
# else
|
||||
dir.x -= lumaNw.y;
|
||||
dir.z += lumaNw.y;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (4)
|
||||
half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
dir.x += lumaSe.w;
|
||||
dir.z -= lumaSe.w;
|
||||
# else
|
||||
dir.x += lumaSe.y;
|
||||
dir.z -= lumaSe.y;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (5)
|
||||
half4 dir1_pos;
|
||||
dir1_pos.xy = normalize(dir.xyz).xz;
|
||||
half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (6)
|
||||
half4 dir2_pos;
|
||||
dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0));
|
||||
dir1_pos.zw = pos.xy;
|
||||
dir2_pos.zw = pos.xy;
|
||||
half4 temp1N;
|
||||
temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (7)
|
||||
temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
|
||||
half4 rgby1;
|
||||
rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (8)
|
||||
rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
|
||||
rgby1 = (temp1N + rgby1) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (9)
|
||||
half4 temp2N;
|
||||
temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
|
||||
temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (10)
|
||||
half4 rgby2;
|
||||
rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
|
||||
rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
|
||||
rgby2 = (temp2N + rgby2) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (11)
|
||||
// compilier moves these scalar ops up to other cycles
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w));
|
||||
half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w));
|
||||
# else
|
||||
half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y));
|
||||
half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y));
|
||||
# endif
|
||||
rgby2 = (rgby2 + rgby1) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (12)
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
bool twoTapLt = rgby2.w < lumaMin;
|
||||
bool twoTapGt = rgby2.w > lumaMax;
|
||||
# else
|
||||
bool twoTapLt = rgby2.y < lumaMin;
|
||||
bool twoTapGt = rgby2.y > lumaMax;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (13)
|
||||
if (twoTapLt || twoTapGt) rgby2 = rgby1;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
return rgby2;
|
||||
}
|
||||
/*==========================================================================*/
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*============================================================================
|
||||
|
||||
FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT)
|
||||
@@ -1856,7 +1858,7 @@ Pass | Unit | uOp | PC: Op
|
||||
| | |
|
||||
15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2;
|
||||
| SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1;
|
||||
|
||||
|
||||
Pass SCT TEX SCB
|
||||
1: 0% 100% 25%
|
||||
2: 0% 100% 25%
|
||||
@@ -1899,150 +1901,150 @@ Results 15 cycles, 3 r regs, 800,000,000 pixels/s
|
||||
============================================================================*/
|
||||
#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#pragma regcount 7
|
||||
#pragma disablepc all
|
||||
#pragma option O2
|
||||
#pragma option OutColorPrec=fp16
|
||||
#pragma texformat default RGBA8
|
||||
# pragma regcount 7
|
||||
# pragma disablepc all
|
||||
# pragma option O2
|
||||
# pragma option OutColorPrec =fp16
|
||||
# pragma texformat default RGBA8
|
||||
/*==========================================================================*/
|
||||
half4 FxaaPixelShader(
|
||||
// See FXAA Quality FxaaPixelShader() source for docs on Inputs!
|
||||
FxaaFloat2 pos,
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
FxaaTex tex,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
FxaaFloat4 fxaaConsole360ConstDir
|
||||
) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (1)
|
||||
half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaNe = rgbyNe.w + half(1.0/512.0);
|
||||
#else
|
||||
half lumaNe = rgbyNe.y + half(1.0/512.0);
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (2)
|
||||
half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaSwNegNe = lumaSw.w - lumaNe;
|
||||
#else
|
||||
half lumaSwNegNe = lumaSw.y - lumaNe;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (3)
|
||||
half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaMaxNwSw = max(lumaNw.w, lumaSw.w);
|
||||
half lumaMinNwSw = min(lumaNw.w, lumaSw.w);
|
||||
#else
|
||||
half lumaMaxNwSw = max(lumaNw.y, lumaSw.y);
|
||||
half lumaMinNwSw = min(lumaNw.y, lumaSw.y);
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (4)
|
||||
half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half dirZ = lumaNw.w + lumaSwNegNe;
|
||||
half dirX = -lumaNw.w + lumaSwNegNe;
|
||||
#else
|
||||
half dirZ = lumaNw.y + lumaSwNegNe;
|
||||
half dirX = -lumaNw.y + lumaSwNegNe;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (5)
|
||||
half3 dir;
|
||||
dir.y = 0.0;
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
dir.x = lumaSe.w + dirX;
|
||||
dir.z = -lumaSe.w + dirZ;
|
||||
half lumaMinNeSe = min(lumaNe, lumaSe.w);
|
||||
#else
|
||||
dir.x = lumaSe.y + dirX;
|
||||
dir.z = -lumaSe.y + dirZ;
|
||||
half lumaMinNeSe = min(lumaNe, lumaSe.y);
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (6)
|
||||
half4 dir1_pos;
|
||||
dir1_pos.xy = normalize(dir).xz;
|
||||
half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (7)
|
||||
half4 dir2_pos;
|
||||
dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0));
|
||||
dir1_pos.zw = pos.xy;
|
||||
dir2_pos.zw = pos.xy;
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaMaxNeSe = max(lumaNe, lumaSe.w);
|
||||
#else
|
||||
half lumaMaxNeSe = max(lumaNe, lumaSe.y);
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (8)
|
||||
half4 temp1N;
|
||||
temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
|
||||
temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
|
||||
half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe);
|
||||
half lumaMin = min(lumaMinNwSw, lumaMinNeSe);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (9)
|
||||
half4 rgby1;
|
||||
rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
|
||||
rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
|
||||
rgby1 = (temp1N + rgby1) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (10)
|
||||
half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0));
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaMaxM = max(lumaMax, rgbyM.w);
|
||||
half lumaMinM = min(lumaMin, rgbyM.w);
|
||||
#else
|
||||
half lumaMaxM = max(lumaMax, rgbyM.y);
|
||||
half lumaMinM = min(lumaMin, rgbyM.y);
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (11)
|
||||
half4 temp2N;
|
||||
temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
|
||||
temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
|
||||
half4 rgby2;
|
||||
rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
|
||||
half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (12)
|
||||
rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
|
||||
rgby2 = (temp2N + rgby2) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (13)
|
||||
rgby2 = (rgby2 + rgby1) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (14)
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
bool twoTapLt = rgby2.w < lumaMin;
|
||||
bool twoTapGt = rgby2.w > lumaMax;
|
||||
#else
|
||||
bool twoTapLt = rgby2.y < lumaMin;
|
||||
bool twoTapGt = rgby2.y > lumaMax;
|
||||
#endif
|
||||
bool earlyExit = lumaRangeM < lumaMax;
|
||||
bool twoTap = twoTapLt || twoTapGt;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (15)
|
||||
if(twoTap) rgby2 = rgby1;
|
||||
if(earlyExit) rgby2 = rgbyM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
return rgby2; }
|
||||
// See FXAA Quality FxaaPixelShader() source for docs on Inputs!
|
||||
FxaaFloat2 pos,
|
||||
FxaaFloat4 fxaaConsolePosPos,
|
||||
FxaaTex tex,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegOne,
|
||||
FxaaTex fxaaConsole360TexExpBiasNegTwo,
|
||||
FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt,
|
||||
FxaaFloat4 fxaaConsoleRcpFrameOpt2,
|
||||
FxaaFloat4 fxaaConsole360RcpFrameOpt2,
|
||||
FxaaFloat fxaaQualitySubpix,
|
||||
FxaaFloat fxaaQualityEdgeThreshold,
|
||||
FxaaFloat fxaaQualityEdgeThresholdMin,
|
||||
FxaaFloat fxaaConsoleEdgeSharpness,
|
||||
FxaaFloat fxaaConsoleEdgeThreshold,
|
||||
FxaaFloat fxaaConsoleEdgeThresholdMin,
|
||||
FxaaFloat4 fxaaConsole360ConstDir) {
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (1)
|
||||
half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaNe = rgbyNe.w + half(1.0 / 512.0);
|
||||
# else
|
||||
half lumaNe = rgbyNe.y + half(1.0 / 512.0);
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (2)
|
||||
half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaSwNegNe = lumaSw.w - lumaNe;
|
||||
# else
|
||||
half lumaSwNegNe = lumaSw.y - lumaNe;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (3)
|
||||
half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaMaxNwSw = max(lumaNw.w, lumaSw.w);
|
||||
half lumaMinNwSw = min(lumaNw.w, lumaSw.w);
|
||||
# else
|
||||
half lumaMaxNwSw = max(lumaNw.y, lumaSw.y);
|
||||
half lumaMinNwSw = min(lumaNw.y, lumaSw.y);
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (4)
|
||||
half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half dirZ = lumaNw.w + lumaSwNegNe;
|
||||
half dirX = -lumaNw.w + lumaSwNegNe;
|
||||
# else
|
||||
half dirZ = lumaNw.y + lumaSwNegNe;
|
||||
half dirX = -lumaNw.y + lumaSwNegNe;
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (5)
|
||||
half3 dir;
|
||||
dir.y = 0.0;
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
dir.x = lumaSe.w + dirX;
|
||||
dir.z = -lumaSe.w + dirZ;
|
||||
half lumaMinNeSe = min(lumaNe, lumaSe.w);
|
||||
# else
|
||||
dir.x = lumaSe.y + dirX;
|
||||
dir.z = -lumaSe.y + dirZ;
|
||||
half lumaMinNeSe = min(lumaNe, lumaSe.y);
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (6)
|
||||
half4 dir1_pos;
|
||||
dir1_pos.xy = normalize(dir).xz;
|
||||
half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (7)
|
||||
half4 dir2_pos;
|
||||
dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0));
|
||||
dir1_pos.zw = pos.xy;
|
||||
dir2_pos.zw = pos.xy;
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaMaxNeSe = max(lumaNe, lumaSe.w);
|
||||
# else
|
||||
half lumaMaxNeSe = max(lumaNe, lumaSe.y);
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (8)
|
||||
half4 temp1N;
|
||||
temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
|
||||
temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
|
||||
half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe);
|
||||
half lumaMin = min(lumaMinNwSw, lumaMinNeSe);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (9)
|
||||
half4 rgby1;
|
||||
rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
|
||||
rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
|
||||
rgby1 = (temp1N + rgby1) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (10)
|
||||
half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0));
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
half lumaMaxM = max(lumaMax, rgbyM.w);
|
||||
half lumaMinM = min(lumaMin, rgbyM.w);
|
||||
# else
|
||||
half lumaMaxM = max(lumaMax, rgbyM.y);
|
||||
half lumaMinM = min(lumaMin, rgbyM.y);
|
||||
# endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (11)
|
||||
half4 temp2N;
|
||||
temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
|
||||
temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
|
||||
half4 rgby2;
|
||||
rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
|
||||
half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (12)
|
||||
rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
|
||||
rgby2 = (temp2N + rgby2) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (13)
|
||||
rgby2 = (rgby2 + rgby1) * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (14)
|
||||
# if (FXAA_GREEN_AS_LUMA == 0)
|
||||
bool twoTapLt = rgby2.w < lumaMin;
|
||||
bool twoTapGt = rgby2.w > lumaMax;
|
||||
# else
|
||||
bool twoTapLt = rgby2.y < lumaMin;
|
||||
bool twoTapGt = rgby2.y > lumaMax;
|
||||
# endif
|
||||
bool earlyExit = lumaRangeM < lumaMax;
|
||||
bool twoTap = twoTapLt || twoTapGt;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// (15)
|
||||
if (twoTap) rgby2 = rgby1;
|
||||
if (earlyExit) rgby2 = rgbyM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
return rgby2;
|
||||
}
|
||||
/*==========================================================================*/
|
||||
#endif
|
||||
Reference in New Issue
Block a user