Files
qad/libs/qglview/globject.h
2022-12-14 14:14:33 +03:00

394 lines
10 KiB
C++

/*
GLObjectBase & Light
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 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/>.
*/
#ifndef GLOBJECT_H
#define GLOBJECT_H
#include "glframebuffer.h"
#include "glmaterial.h"
#include "glvbo.h"
class Camera;
class QGLView;
class GLObjectBase {
friend class QGLView;
friend class GLRendererBase;
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
};
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;}
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_; }
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; }
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(); }
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);
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; }
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 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);
void setRotationX(GLfloat a);
void setRotationY(GLfloat a);
void setRotationZ(GLfloat a);
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_; }
void setTransform(const QMatrix4x4 & t);
bool isRawMatrix() { return raw_matrix; }
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 isSelected() const { return selected_; }
void setSelected(bool yes) { selected_ = yes; }
void select();
void deselect() { selected_ = false; }
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();
}
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_; }
const Box3D & boundingBox(bool withChildren = true) const { return bound; }
GLVBO & VBO() { return vbo; }
void calculateBoundingBox();
void setProperty(const QString & pn, const QVariant & v);
QVariant property(const QString & pn, bool * exists = 0) const;
bool hasProperty(const QString & pn) const;
void removeProperty(const QString & pn);
QVector3D pos_h;
QVector<Vector3d> points, puvws;
QVector<Vector3i> faces, uvws, norms;
QVector<Vector3d> normals;
// QVector<GLfloat> d_vertices, d_normals, d_uvs;
protected:
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 buildTransform();
void initInternal();
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_root;
float line_width;
Type type_;
GeomPrimitives geom_prim;
RenderMode render_mode;
Material material_;
Box3D bound;
QVector3D pos_, angles_, scale_;
QList<GLObjectBase *> children_;
QList<GLuint> textures;
QMatrix4x4 itransform_, mat_;
// 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();
}
class Light: public GLObjectBase {
friend class QGLView;
friend class GLRendererBase;
public:
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 draw(QOpenGLShaderProgram * prog, bool simplest = false);
QVector3D direction, dir0, dir1;
float angle_start;
float angle_end;
float intensity;
float decay_const;
float decay_linear;
float decay_quadratic;
float decay_start;
float decay_end;
Type light_type;
GLFramebuffer shadow_map;
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(const GLObjectBase * object) {
return reinterpret_cast<T>(object);
}
QDataStream & operator<<(QDataStream & s, const GLObjectBase * p);
QDataStream & operator>>(QDataStream & s, GLObjectBase *& p);
#endif // GLOBJECT_H