/* QGLView Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef GLMATERIAL_H #define GLMATERIAL_H #include "glshaders_types.h" #include "chunkstream.h" /* class Texture { public: Texture(int _width, int _height, const GLenum & _format = GL_RGBA8, const GLenum & _target = GL_TEXTURE_2D) {wid = _width; hei = _height; format_ = _format; target_ = _target; id_ = 0;} bool create() {destroy(); createGLTexture(id_, wid, hei, format_, target_); return id_ > 0;} void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;} void bind() {if (id_ > 0) glBindTexture(target_, id_);} void release() {glBindTexture(target_, 0);} int width() const {return wid;} int height() const {return hei;} GLenum format() const {return format_;} GLenum target() const {return target_;} GLuint id() const {return id_;} private: int wid, hei; GLenum format_, target_; GLuint id_; }; class CubeTexture { public: CubeTexture(int _size, const GLenum & _format = GL_RGBA8) {size = _size; format_ = _format; id_ = 0; changed_ = false; pathes.resize(6);} bool create(); void destroy() {if (id_ > 0) glDeleteTextures(1, &id_); id_ = 0;} void bind() {if (changed_) {changed_ = false; create();} if (id_ > 0) glBindTexture(GL_TEXTURE_CUBE_MAP, id_);} void release() {glBindTexture(GL_TEXTURE_CUBE_MAP, 0);} void resize(int _size) {size = _size; changed_ = true;} void loadFromDirectory(const QString & dir); void loadFront(const QString & path) {bind(); pathes[0] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_X);} void loadBack(const QString & path) {bind(); pathes[1] = path; createGLTexture(id_, rotateQImageRight(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_X);} void loadLeft(const QString & path) {bind(); pathes[2] = path; createGLTexture(id_, QImage(path).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);} void loadRight(const QString & path) {bind(); pathes[3] = path; createGLTexture(id_, rotateQImage180(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Y);} void loadTop(const QString & path) {bind(); pathes[4] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);} void loadBottom(const QString & path) {bind(); pathes[5] = path; createGLTexture(id_, rotateQImageLeft(QImage(path)).scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), format_, GL_TEXTURE_CUBE_MAP_POSITIVE_Z);} void load(); bool isEmpty() const {foreach (const QString & i, pathes) if (!i.isEmpty()) return false; return true;} GLenum format() const {return format_;} void setFormat(GLenum f) {format_ = f; changed_ = true;} GLuint id() const {return id_;} const QString & path(int side) const {return pathes[side];} void setPath(int side, const QString & p) {pathes[side] = p;} void loadPathesFromDirectory(const QString & dir); private: bool changed_; int size; GLenum format_; GLuint id_; QVector pathes; }; */ class Map { public: Map(); void setBitmapPath(const QString & p); void clearBitmap() {setBitmapPath(QString());} bool hasBitmap() const {return !bitmap_path.isEmpty();} void load(TextureManager * tm); void copyToQGLMap(QGLEngineShaders::QGLMap & m) const; QString bitmap_path; GLuint bitmap_id; QPointF bitmap_offset; QPointF bitmap_scale; float color_amount; float color_offset; bool use_bitmap; bool _changed; int _type, _layer; }; class Material { public: Material(const QString _name = QString()); uint hash(); bool hasTransparency() const; bool isMapsChanged() const; bool isMapChanged(int type) const; void load(TextureManager * tm); void setMapsChanged(); void setTypes(); void detectMaps(); QString name; QColor color_diffuse; QColor color_emission; bool glass; float transparency; float reflectivity; float iof; float dispersion; Map map_diffuse ; Map map_normal ; Map map_metalness; Map map_roughness; Map map_emission ; Map map_relief ; bool _changed; int _index; //GLCubeTexture map_reflection; }; 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(6, m.bitmap_scale) .add(7, m.use_bitmap); s << cs.data(); return s; } inline QDataStream & operator >>(QDataStream & s, Map & m) { ChunkStream cs(s); cs.readAll(); cs.get(1, m.bitmap_path).get(2, m.color_amount).get(3, m.color_offset).get(6, m.bitmap_scale) .get(7, m.use_bitmap); return s; } inline QDataStream & operator <<(QDataStream & s, const Material * m) { ChunkStream cs; cs.add(1, m->name).add(2, m->color_diffuse).add(4, m->color_emission) .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_metalness).add(12, m->map_roughness).add(13, m->map_emission); s << /*qCompress*/(cs.data()); return s; } inline QDataStream & operator >>(QDataStream & s, Material *& m) { m = new Material(); //QByteArray ba; //s >> ba; //ba = qUncompres(ba); ChunkStream cs(s); while (!cs.atEnd()) { switch (cs.read()) { case 1: cs.get(m->name); break; case 2: cs.get(m->color_diffuse); break; case 4: cs.get(m->color_emission); break; case 5: cs.get(m->transparency); break; case 6: cs.get(m->reflectivity); break; case 7: cs.get(m->glass); break; case 8: cs.get(m->map_diffuse); break; case 9: cs.get(m->map_normal); break; case 10: cs.get(m->map_relief); break; case 11: cs.get(m->map_metalness); break; case 12: cs.get(m->map_roughness); break; case 13: cs.get(m->map_emission); break; } } m->setTypes(); return s; } #endif // GLMATERIAL_H