Files
qad/qglengine/core/glmaterial.cpp

212 lines
7.1 KiB
C++

/*
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 <http://www.gnu.org/licenses/>.
*/
#include "gltypes.h"
#include "gltexture_manager.h"
#include "qglview.h"
using namespace QGLEngineShaders;
/*
bool CubeTexture::create() {
//qDebug("create");
destroy();
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_CUBE_MAP, id_);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
//glClearError();
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format_, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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();
changed_ = false;
return id_ > 0;
}
void CubeTexture::load() {
if (isEmpty()) return;
create();
if (!path(0).isEmpty()) loadFront(path(0));
if (!path(1).isEmpty()) loadBack(path(1));
if (!path(2).isEmpty()) loadLeft(path(2));
if (!path(3).isEmpty()) loadRight(path(3));
if (!path(4).isEmpty()) loadTop(path(4));
if (!path(5).isEmpty()) loadBottom(path(5));
}
void CubeTexture::loadFromDirectory(const QString & dir) {
QDir d(dir); QFileInfoList sl;
sl = d.entryInfoList(QStringList("front.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadFront(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("back.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBack(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("left.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadLeft(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("right.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadRight(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("top.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadTop(sl[0].absoluteFilePath());
sl = d.entryInfoList(QStringList("bottom.*"), QDir::Files | QDir::NoDotAndDotDot); if (!sl.isEmpty()) loadBottom(sl[0].absoluteFilePath());
}
void CubeTexture::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();
}
*/
Map::Map() {
bitmap_id = 0;
color_amount = 1.f;
color_offset = 0.f;
bitmap_scale = QPointF(1., 1.);
use_bitmap = false;
_changed = true;
_layer = 0;
}
void Map::setBitmapPath(const QString & p) {
bitmap_path = p;
_changed = true;
}
void Map::load(TextureManager * tm) {
if (bitmap_id == 0)
bitmap_id = tm->loadTexture(bitmap_path, true, _type == mtNormal);
}
void Map::copyToQGLMap(QGLMap & m) const {
m.amount = color_amount;
m.offset = color_offset;
m.scale = QVector2D(bitmap_scale);
if (hasBitmap() && use_bitmap) {
m.array_index = tarMaps;
m.map_index = _layer;
} else {
m.array_index = tarEmpty;
m.map_index = (_type == mtNormal ? emrBlue : emrWhite);
}
}
Material::Material(const QString _name)/*: map_reflection(512)*/ {
setTypes();
name = _name;
color_diffuse = Qt::white;
color_emission = Qt::black;
glass = false;
transparency = reflectivity = 0.f;
map_roughness.color_amount = 0.75f;
map_metalness.color_amount = 0.25f;
iof = 1.f;
dispersion = 0.05f;
_changed = true;
_index = 0;
}
uint Material::hash() {
return qHash(name);
}
bool Material::hasTransparency() const {
return float(color_diffuse.alphaF()) * (1.f - transparency) < 1.f;
}
bool Material::isMapsChanged() const {
return map_diffuse ._changed ||
map_normal ._changed ||
map_metalness._changed ||
map_roughness._changed ||
map_emission ._changed ||
map_relief ._changed;
}
bool Material::isMapChanged(int type) const {
switch (type) {
case mtDiffuse : return map_diffuse ._changed;
case mtNormal : return map_normal ._changed;
case mtMetalness: return map_metalness._changed;
case mtRoughness: return map_roughness._changed;
case mtEmission : return map_emission ._changed;
case mtRelief : return map_relief ._changed;
}
return false;
}
void Material::load(TextureManager * tm) {
map_diffuse .load(tm);
map_normal .load(tm);
map_metalness.load(tm);
map_roughness.load(tm);
map_emission .load(tm);
map_relief .load(tm);
}
void Material::setMapsChanged() {
map_diffuse ._changed = true;
map_normal ._changed = true;
map_metalness._changed = true;
map_roughness._changed = true;
map_emission ._changed = true;
map_relief ._changed = true;
}
void Material::setTypes() {
map_diffuse ._type = mtDiffuse ;
map_normal ._type = mtNormal ;
map_metalness._type = mtMetalness;
map_roughness._type = mtRoughness;
map_emission ._type = mtEmission ;
map_relief ._type = mtRelief ;
}
void Material::detectMaps() {
map_diffuse .use_bitmap = !map_diffuse .bitmap_path.isEmpty();
map_normal .use_bitmap = !map_normal .bitmap_path.isEmpty();
map_metalness.use_bitmap = !map_metalness.bitmap_path.isEmpty();
map_roughness.use_bitmap = !map_roughness.bitmap_path.isEmpty();
map_emission .use_bitmap = !map_emission .bitmap_path.isEmpty();
map_relief .use_bitmap = !map_relief .bitmap_path.isEmpty();
}