code format

This commit is contained in:
2022-12-14 14:14:33 +03:00
parent 09e5342956
commit cdb02fc9be
278 changed files with 15371 additions and 12176 deletions

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);
};

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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_;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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!";
}

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 ")) {

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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());

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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() {}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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) {}

View File

@@ -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

View File

@@ -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());

View File

@@ -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

View File

@@ -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