refactor texture loading, maps invert channels works
This commit is contained in:
@@ -17,8 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gltexture_manager.h"
|
#include "gltexture_manager.h"
|
||||||
#include "gltypes.h"
|
|
||||||
#include "qglview.h"
|
|
||||||
|
|
||||||
using namespace QGLEngineShaders;
|
using namespace QGLEngineShaders;
|
||||||
|
|
||||||
@@ -31,17 +29,28 @@ Map::Map() {
|
|||||||
use_bitmap = false;
|
use_bitmap = false;
|
||||||
_changed = true;
|
_changed = true;
|
||||||
_layer = 0;
|
_layer = 0;
|
||||||
|
_bitmap_hash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Map::setBitmapPath(const QString & p) {
|
void Map::setBitmapPath(const QString & p) {
|
||||||
bitmap_path = p;
|
bitmap_path = p;
|
||||||
_changed = true;
|
_changed = true;
|
||||||
|
_bitmap_hash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Map::load(TextureManager * tm) {
|
void Map::load(TextureManager * tm) {
|
||||||
if (bitmap_id == 0) bitmap_id = tm->loadTexture(bitmap_path, true, _type == mtNormal);
|
_bitmap_hash = 0;
|
||||||
|
if (!bitmap_path.isEmpty()) tm->loadTextureImage(bitmap_path, _type == mtNormal, bake_options, &_bitmap_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Map::setMapLayer(TextureManager * tm) {
|
||||||
|
if (loadedBitmap())
|
||||||
|
_layer = tm->textureLayer(_bitmap_hash);
|
||||||
|
else
|
||||||
|
_layer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -49,7 +58,7 @@ void Map::copyToQGLMap(QGLMap & m) const {
|
|||||||
m.amount = color_amount;
|
m.amount = color_amount;
|
||||||
m.offset = color_offset;
|
m.offset = color_offset;
|
||||||
m.scale = QVector2D(bitmap_scale);
|
m.scale = QVector2D(bitmap_scale);
|
||||||
if (hasBitmap() && use_bitmap) {
|
if (loadedBitmap() && use_bitmap) {
|
||||||
m.array_index = tarMaps;
|
m.array_index = tarMaps;
|
||||||
m.map_index = _layer;
|
m.map_index = _layer;
|
||||||
} else {
|
} else {
|
||||||
@@ -114,6 +123,16 @@ void Material::load(TextureManager * tm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Material::setMapsLayers(TextureManager * tm) {
|
||||||
|
map_diffuse.setMapLayer(tm);
|
||||||
|
map_normal.setMapLayer(tm);
|
||||||
|
map_metalness.setMapLayer(tm);
|
||||||
|
map_roughness.setMapLayer(tm);
|
||||||
|
map_emission.setMapLayer(tm);
|
||||||
|
map_relief.setMapLayer(tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Material::setMapsChanged() {
|
void Material::setMapsChanged() {
|
||||||
map_diffuse._changed = true;
|
map_diffuse._changed = true;
|
||||||
map_normal._changed = true;
|
map_normal._changed = true;
|
||||||
|
|||||||
@@ -19,9 +19,10 @@
|
|||||||
#ifndef GLMATERIAL_H
|
#ifndef GLMATERIAL_H
|
||||||
#define GLMATERIAL_H
|
#define GLMATERIAL_H
|
||||||
|
|
||||||
#include "chunkstream.h"
|
|
||||||
#include "glshaders_types.h"
|
#include "glshaders_types.h"
|
||||||
|
|
||||||
|
#include <chunkstream.h>
|
||||||
|
|
||||||
|
|
||||||
struct QGLENGINE_CORE_EXPORT MapBakeOptions {
|
struct QGLENGINE_CORE_EXPORT MapBakeOptions {
|
||||||
uint hash() const;
|
uint hash() const;
|
||||||
@@ -37,7 +38,9 @@ public:
|
|||||||
void setBitmapPath(const QString & p);
|
void setBitmapPath(const QString & p);
|
||||||
void clearBitmap() { setBitmapPath(QString()); }
|
void clearBitmap() { setBitmapPath(QString()); }
|
||||||
bool hasBitmap() const { return !bitmap_path.isEmpty(); }
|
bool hasBitmap() const { return !bitmap_path.isEmpty(); }
|
||||||
|
bool loadedBitmap() const { return _bitmap_hash != 0; }
|
||||||
void load(TextureManager * tm);
|
void load(TextureManager * tm);
|
||||||
|
void setMapLayer(TextureManager * tm);
|
||||||
void copyToQGLMap(QGLEngineShaders::QGLMap & m) const;
|
void copyToQGLMap(QGLEngineShaders::QGLMap & m) const;
|
||||||
QString bitmap_path;
|
QString bitmap_path;
|
||||||
GLuint bitmap_id;
|
GLuint bitmap_id;
|
||||||
@@ -50,6 +53,7 @@ public:
|
|||||||
|
|
||||||
bool _changed;
|
bool _changed;
|
||||||
int _type, _layer;
|
int _type, _layer;
|
||||||
|
uint _bitmap_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QGLENGINE_CORE_EXPORT Material {
|
class QGLENGINE_CORE_EXPORT Material {
|
||||||
@@ -60,6 +64,7 @@ public:
|
|||||||
bool isMapsChanged() const;
|
bool isMapsChanged() const;
|
||||||
bool isMapChanged(int type) const;
|
bool isMapChanged(int type) const;
|
||||||
void load(TextureManager * tm);
|
void load(TextureManager * tm);
|
||||||
|
void setMapsLayers(TextureManager * tm);
|
||||||
void setMapsChanged();
|
void setMapsChanged();
|
||||||
void setTypes();
|
void setTypes();
|
||||||
void detectMaps();
|
void detectMaps();
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public:
|
|||||||
|
|
||||||
GLuint ID() const { return texture_; }
|
GLuint ID() const { return texture_; }
|
||||||
bool isInit() const { return texture_ != 0; }
|
bool isInit() const { return texture_ != 0; }
|
||||||
|
int layersCount() const { return layers_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLenum target_;
|
GLenum target_;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "gltexture_manager.h"
|
#include "gltexture_manager.h"
|
||||||
|
|
||||||
|
#include "gltexturearray.h"
|
||||||
#include "gltypes.h"
|
#include "gltypes.h"
|
||||||
|
|
||||||
QStringList TextureManager::search_pathes(".");
|
QStringList TextureManager::search_pathes(".");
|
||||||
@@ -37,18 +38,20 @@ QString TextureManager::findFile(const QString & path) {
|
|||||||
return ::findFile(path, search_pathes);
|
return ::findFile(path, search_pathes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
GLuint TextureManager::loadTexture(const QString & path, bool ownership, bool bump) {
|
GLuint TextureManager::loadTexture(const QString & path, bool is_normal, MapBakeOptions opts) {
|
||||||
QString p = findFile(path);
|
QString p = findFile(path);
|
||||||
if (p.isEmpty()) return 0;
|
if (p.isEmpty()) return 0;
|
||||||
int tid = textureID(p, bump);
|
uint hash = mapHash(p, is_normal, opts);
|
||||||
|
int tid = cache_loaded.value(hash, 0);
|
||||||
if (tid > 0) {
|
if (tid > 0) {
|
||||||
qDebug() << "[TextureManager] Found" << path << "as" << tid;
|
qDebug() << "[TextureManager] Found" << path << "as" << tid;
|
||||||
return tid;
|
return tid;
|
||||||
}
|
}
|
||||||
QImage image(p);
|
QImage image(p);
|
||||||
if (bump) convertToNormal(image);
|
if (is_normal) convertToNormal(image);
|
||||||
// qDebug() << p << image.width() << image.height() << image.format() << bump;
|
applyBakeOption(image, opts);
|
||||||
|
// qDebug() << p << image.width() << image.height() << image.format() << is_normal;
|
||||||
GLuint tid_ = tid;
|
GLuint tid_ = tid;
|
||||||
createGLTexture(f, tid_, image);
|
createGLTexture(f, tid_, image);
|
||||||
tid = tid_;
|
tid = tid_;
|
||||||
@@ -57,18 +60,37 @@ GLuint TextureManager::loadTexture(const QString & path, bool ownership, bool bu
|
|||||||
return tid;
|
return tid;
|
||||||
}
|
}
|
||||||
qDebug() << "[TextureManager] Loaded" << p << "as" << tid;
|
qDebug() << "[TextureManager] Loaded" << p << "as" << tid;
|
||||||
if (ownership) {
|
tex_ids[is_normal ? 1 : 0].insert(p, tid);
|
||||||
tex_ids[bump ? 1 : 0].insert(p, tid);
|
tex_im[is_normal ? 1 : 0].insert(p, image);
|
||||||
tex_im[bump ? 1 : 0].insert(p, image);
|
|
||||||
}
|
|
||||||
return tid;
|
return tid;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
QImage TextureManager::loadTextureImage(const QString & path, bool is_normal, MapBakeOptions opts, uint * result_hash) {
|
||||||
|
if (result_hash) *result_hash = 0;
|
||||||
|
QString p = findFile(path);
|
||||||
|
if (p.isEmpty()) return QImage();
|
||||||
|
uint hash = mapHash(p, is_normal, opts);
|
||||||
|
QImage image = cache_image.value(hash);
|
||||||
|
if (!image.isNull()) {
|
||||||
|
if (result_hash) *result_hash = hash;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
image = QImage(p).convertToFormat(QImage::Format_ARGB32);
|
||||||
|
if (image.isNull()) return image;
|
||||||
|
if (is_normal) convertToNormal(image);
|
||||||
|
applyBakeOption(image, opts);
|
||||||
|
cache_image[hash] = image;
|
||||||
|
if (result_hash) *result_hash = hash;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
GLuint TextureManager::loadTexture(const QImage & im, bool ownership, bool bump) {
|
/*
|
||||||
|
GLuint TextureManager::loadTexture(const QImage & im, bool ownership, bool is_normal, MapBakeOptions opts) {
|
||||||
if (im.isNull()) return 0;
|
if (im.isNull()) return 0;
|
||||||
QImage image(im);
|
QImage image(im);
|
||||||
if (bump) convertToNormal(image);
|
if (is_normal) convertToNormal(image);
|
||||||
|
applyBakeOption(image, opts);
|
||||||
GLuint tid = 0;
|
GLuint tid = 0;
|
||||||
createGLTexture(f, tid, im);
|
createGLTexture(f, tid, im);
|
||||||
if (tid == 0) {
|
if (tid == 0) {
|
||||||
@@ -80,18 +102,6 @@ GLuint TextureManager::loadTexture(const QImage & im, bool ownership, bool bump)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QImage TextureManager::loadTextureImage(const QString & path, bool bump) {
|
|
||||||
QString p = findFile(path);
|
|
||||||
if (p.isEmpty()) return QImage();
|
|
||||||
QImage ret = tex_im[bump ? 1 : 0].value(p);
|
|
||||||
if (!ret.isNull()) return ret;
|
|
||||||
ret = QImage(p);
|
|
||||||
if (bump) convertToNormal(ret);
|
|
||||||
tex_im[bump ? 1 : 0].insert(p, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TextureManager::reloadTexture(GLuint tid, const QString & path) {
|
void TextureManager::reloadTexture(GLuint tid, const QString & path) {
|
||||||
QString p = findFile(path);
|
QString p = findFile(path);
|
||||||
if (p.isEmpty() || (tid == 0)) return;
|
if (p.isEmpty() || (tid == 0)) return;
|
||||||
@@ -111,16 +121,25 @@ void TextureManager::reloadTexture(GLuint tid, const QImage & im) {
|
|||||||
createGLTexture(f, tid, image);
|
createGLTexture(f, tid, image);
|
||||||
qDebug() << "[TextureManager] Reloaded" << tid;
|
qDebug() << "[TextureManager] Reloaded" << tid;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int TextureManager::textureID(const QString & path, bool is_normal, MapBakeOptions opts) {
|
||||||
|
return cache_loaded.value(mapHash(findFile(path), is_normal, opts), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QImage TextureManager::textureImage(const QString & path, bool is_normal, MapBakeOptions opts) {
|
||||||
|
return cache_image.value(mapHash(findFile(path), is_normal, opts));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextureManager::convertToNormal(QImage & im) {
|
void TextureManager::convertToNormal(QImage & im) {
|
||||||
if (im.isNull()) return;
|
if (im.isNull()) return;
|
||||||
QImage sim = im.convertToFormat(QImage::Format_ARGB32);
|
|
||||||
float sum[3] = {0., 0., 0.};
|
float sum[3] = {0., 0., 0.};
|
||||||
llong a = 0;
|
llong a = 0;
|
||||||
const uchar * sd = sim.constBits();
|
const uchar * sd = im.constBits();
|
||||||
for (int i = 0; i < sim.height(); i++) {
|
for (int i = 0; i < im.height(); i++) {
|
||||||
for (int j = 0; j < sim.width(); j++) {
|
for (int j = 0; j < im.width(); j++) {
|
||||||
sum[2] += sd[a] / 255.f - 0.5f;
|
sum[2] += sd[a] / 255.f - 0.5f;
|
||||||
++a;
|
++a;
|
||||||
sum[1] += sd[a] / 255.f - 0.5f;
|
sum[1] += sd[a] / 255.f - 0.5f;
|
||||||
@@ -130,7 +149,7 @@ void TextureManager::convertToNormal(QImage & im) {
|
|||||||
++a;
|
++a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float wh = sim.width() * sim.height();
|
float wh = im.width() * im.height();
|
||||||
sum[0] /= wh;
|
sum[0] /= wh;
|
||||||
sum[1] /= wh;
|
sum[1] /= wh;
|
||||||
sum[2] /= wh;
|
sum[2] /= wh;
|
||||||
@@ -138,26 +157,26 @@ void TextureManager::convertToNormal(QImage & im) {
|
|||||||
if ((qAbs(sum[0]) <= 0.05f) && (qAbs(sum[1]) <= 0.05f) && (sum[2] >= 0.25f)) /// already normal
|
if ((qAbs(sum[0]) <= 0.05f) && (qAbs(sum[1]) <= 0.05f) && (sum[2] >= 0.25f)) /// already normal
|
||||||
return;
|
return;
|
||||||
// qDebug() << "convert to normal";
|
// qDebug() << "convert to normal";
|
||||||
QImage dim = QImage(sim.width(), sim.height(), QImage::Format_ARGB32);
|
QImage dim = QImage(im.width(), im.height(), QImage::Format_ARGB32);
|
||||||
int tx, ty, w = sim.width(), h = sim.height();
|
int tx, ty, w = im.width(), h = im.height();
|
||||||
a = 0;
|
a = 0;
|
||||||
uchar * dd = dim.bits();
|
uchar * dd = dim.bits();
|
||||||
for (int i = 0; i < sim.height(); i++) {
|
for (int i = 0; i < im.height(); i++) {
|
||||||
for (int j = 0; j < sim.width(); j++) {
|
for (int j = 0; j < im.width(); j++) {
|
||||||
tx = j - 1;
|
tx = j - 1;
|
||||||
tx = tx < 0 ? w + tx : tx % w;
|
tx = tx < 0 ? w + tx : tx % w;
|
||||||
ty = i - 1;
|
ty = i - 1;
|
||||||
ty = ty < 0 ? h + ty : ty % h;
|
ty = ty < 0 ? h + ty : ty % h;
|
||||||
QVector3D p[3], res;
|
QVector3D p[3], res;
|
||||||
p[0] = colorVector(sim.pixel(j, i));
|
p[0] = colorVector(im.pixel(j, i));
|
||||||
p[1] = colorVector(sim.pixel(j, ty));
|
p[1] = colorVector(im.pixel(j, ty));
|
||||||
p[2] = colorVector(sim.pixel(tx, i));
|
p[2] = colorVector(im.pixel(tx, i));
|
||||||
res.setY(piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f));
|
res.setY(piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f));
|
||||||
res.setX(piClamp(0.5f - (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f));
|
res.setX(piClamp(0.5f - (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f));
|
||||||
tx = (j + 1) % w;
|
tx = (j + 1) % w;
|
||||||
ty = (i + 1) % h;
|
ty = (i + 1) % h;
|
||||||
p[1] = colorVector(sim.pixel(j, ty));
|
p[1] = colorVector(im.pixel(j, ty));
|
||||||
p[2] = colorVector(sim.pixel(tx, i));
|
p[2] = colorVector(im.pixel(tx, i));
|
||||||
res.setY(piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f));
|
res.setY(piClamp(0.5f + (p[0].length() - p[1].length()) / 2.f, 0.f, 1.f));
|
||||||
res.setX(piClamp(0.5f - (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f));
|
res.setX(piClamp(0.5f - (p[0].length() - p[2].length()) / 2.f, 0.f, 1.f));
|
||||||
res.setZ(1.f);
|
res.setZ(1.f);
|
||||||
@@ -176,6 +195,25 @@ void TextureManager::convertToNormal(QImage & im) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TextureManager::applyBakeOption(QImage & im, MapBakeOptions opts) {
|
||||||
|
if (im.isNull()) return;
|
||||||
|
if (!opts.invert_R && !opts.invert_G && !opts.invert_B) return;
|
||||||
|
QRgb * data = (QRgb *)im.bits();
|
||||||
|
uint pixels = im.width() * im.height();
|
||||||
|
for (uint i = 0; i < pixels; ++i) {
|
||||||
|
uchar * p = (uchar *)&(data[i]);
|
||||||
|
if (opts.invert_B) p[0] = 255 - p[0];
|
||||||
|
if (opts.invert_G) p[1] = 255 - p[1];
|
||||||
|
if (opts.invert_R) p[2] = 255 - p[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint TextureManager::mapHash(const QString & path, bool is_normal, MapBakeOptions opts) {
|
||||||
|
return qHash(path) ^ ((uint)is_normal << 8) ^ opts.hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
bool TextureManager::loadTextures() {
|
bool TextureManager::loadTextures() {
|
||||||
QFileInfoList fil;
|
QFileInfoList fil;
|
||||||
foreach(const QString & i, tex_pathes)
|
foreach(const QString & i, tex_pathes)
|
||||||
@@ -206,9 +244,22 @@ void TextureManager::deleteTexture(const QString & name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void TextureManager::clearImageCache() {
|
void TextureManager::clearImageCache() {
|
||||||
tex_im[0].clear();
|
cache_image.clear();
|
||||||
tex_im[1].clear();
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TextureManager::loadToTexture2DArray(Texture2DArray * array, QSize map_size) {
|
||||||
|
array->resize(f, map_size, texturesCount());
|
||||||
|
array_layers.clear();
|
||||||
|
QMapIterator<uint, QImage> it(cache_image);
|
||||||
|
int cl = -1;
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
array->load(f, it.value(), ++cl);
|
||||||
|
array_layers[it.key()] = cl;
|
||||||
|
}
|
||||||
|
array->mipmaps(f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#ifndef GLTEXTUREMANAGER_H
|
#ifndef GLTEXTUREMANAGER_H
|
||||||
#define GLTEXTUREMANAGER_H
|
#define GLTEXTUREMANAGER_H
|
||||||
|
|
||||||
|
#include "glmaterial.h"
|
||||||
#include "qglengine_core_export.h"
|
#include "qglengine_core_export.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -33,32 +34,42 @@ public:
|
|||||||
TextureManager(QOpenGLExtraFunctions * f_): f(f_) {}
|
TextureManager(QOpenGLExtraFunctions * f_): f(f_) {}
|
||||||
virtual ~TextureManager() {}
|
virtual ~TextureManager() {}
|
||||||
|
|
||||||
|
// GLuint loadTexture(const QString & path, bool is_normal = false, MapBakeOptions opts = {});
|
||||||
|
// GLuint loadTexture(const QImage & image, bool ownership = true, bool is_normal = false, MapBakeOptions opts = {});
|
||||||
|
QImage loadTextureImage(const QString & path, bool is_normal = false, MapBakeOptions opts = {}, uint * result_hash = nullptr);
|
||||||
|
// void reloadTexture(GLuint tid, const QString & path);
|
||||||
|
// void reloadTexture(GLuint tid, const QImage & image);
|
||||||
|
int textureID(const QString & path, bool is_normal = false, MapBakeOptions opts = {});
|
||||||
|
QImage textureImage(const QString & path, bool is_normal = false, MapBakeOptions opts = {});
|
||||||
|
QImage textureImage(uint hash) const { return cache_image.value(hash); }
|
||||||
|
int textureLayer(uint hash) const { return array_layers.value(hash); }
|
||||||
|
// void addTexture(const QString & path) { tex_pathes << path; }
|
||||||
|
// bool loadTextures();
|
||||||
|
// void deleteTextures();
|
||||||
|
// void deleteTexture(const QString & name);
|
||||||
|
int texturesCount() const { return cache_image.size(); }
|
||||||
|
uint texturesHash() const { return qHash(cache_image.keys()); }
|
||||||
|
void clearImageCache();
|
||||||
|
|
||||||
|
void loadToTexture2DArray(Texture2DArray * array, QSize map_size);
|
||||||
|
|
||||||
static void addSearchPath(const QString & path);
|
static void addSearchPath(const QString & path);
|
||||||
static void clearSearchPathes() { search_pathes.clear(); }
|
static void clearSearchPathes() { search_pathes.clear(); }
|
||||||
static QStringList searchPathes() { return search_pathes; }
|
static QStringList searchPathes() { return search_pathes; }
|
||||||
static QString findFile(const QString & path);
|
static 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);
|
|
||||||
QImage loadTextureImage(const QString & path, 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]; }
|
|
||||||
QImage textureImage(const QString & path, bool bump = false) { return tex_im[bump ? 1 : 0][path]; }
|
|
||||||
void addTexture(const QString & path) { tex_pathes << path; }
|
|
||||||
bool loadTextures();
|
|
||||||
void deleteTextures();
|
|
||||||
void deleteTexture(const QString & name);
|
|
||||||
void clearImageCache();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void convertToNormal(QImage & im);
|
static void convertToNormal(QImage & im);
|
||||||
|
static void applyBakeOption(QImage & im, MapBakeOptions opts);
|
||||||
|
static uint mapHash(const QString & path, bool is_normal, MapBakeOptions opts);
|
||||||
|
|
||||||
static QStringList search_pathes;
|
static QStringList search_pathes;
|
||||||
|
|
||||||
QMap<QString, GLuint> tex_ids[2];
|
|
||||||
QMap<QString, QImage> tex_im[2];
|
|
||||||
QStringList tex_pathes;
|
|
||||||
QOpenGLExtraFunctions * f;
|
QOpenGLExtraFunctions * f;
|
||||||
|
QMap<uint, GLuint> cache_loaded;
|
||||||
|
QMap<uint, QImage> cache_image;
|
||||||
|
QMap<uint, int> array_layers;
|
||||||
|
QStringList tex_pathes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ RendererBase::RendererBase(QGLView * view_)
|
|||||||
, textures_empty(false)
|
, textures_empty(false)
|
||||||
, textures_maps(true) {
|
, textures_maps(true) {
|
||||||
textures_manager = new TextureManager(view);
|
textures_manager = new TextureManager(view);
|
||||||
maps_size = QSize(512, 512);
|
maps_size = QSize(1024, 1024);
|
||||||
maps_hash = 0;
|
maps_hash = 0;
|
||||||
tex_coeff[0] = tex_coeff[1] = 0;
|
tex_coeff[0] = tex_coeff[1] = 0;
|
||||||
}
|
}
|
||||||
@@ -147,41 +147,21 @@ void RendererBase::fillSelectionsBuffer(QVector<uchar> & buffer, bool yes, int s
|
|||||||
|
|
||||||
void RendererBase::reloadMaterials(Scene & scene) {
|
void RendererBase::reloadMaterials(Scene & scene) {
|
||||||
// qDebug() << "reloadMaterias";
|
// qDebug() << "reloadMaterias";
|
||||||
QList<Map *> maps[2];
|
QList<Map *> maps;
|
||||||
QMap<QString, int> tex_layers[2];
|
QMap<QString, int> tex_layers[2];
|
||||||
foreach(Material * m, scene.materials) {
|
for (Material * m: scene.materials) {
|
||||||
if (m->map_diffuse.hasBitmap()) maps[0] << &(m->map_diffuse);
|
m->load(textures_manager);
|
||||||
if (m->map_normal.hasBitmap()) maps[1] << &(m->map_normal);
|
|
||||||
if (m->map_metalness.hasBitmap()) maps[0] << &(m->map_metalness);
|
|
||||||
if (m->map_roughness.hasBitmap()) maps[0] << &(m->map_roughness);
|
|
||||||
if (m->map_emission.hasBitmap()) maps[0] << &(m->map_emission);
|
|
||||||
if (m->map_relief.hasBitmap()) maps[0] << &(m->map_relief);
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 2; ++i) {
|
uint cur_maps_hash = textures_manager->texturesHash();
|
||||||
foreach(Map * m, maps[i])
|
|
||||||
tex_layers[i][m->bitmap_path] = 0;
|
|
||||||
}
|
|
||||||
int layers_count = tex_layers[0].size() + tex_layers[1].size(), cl = -1;
|
|
||||||
uint cur_maps_hash = qHash(tex_layers[0].keys()) ^ (qHash(tex_layers[1].keys()) + 0xF00FF00F);
|
|
||||||
if (maps_hash != cur_maps_hash) {
|
if (maps_hash != cur_maps_hash) {
|
||||||
maps_hash = cur_maps_hash;
|
maps_hash = cur_maps_hash;
|
||||||
textures_maps.resize(view, maps_size, layers_count);
|
// textures_maps.resize(view, maps_size, textures_manager->texturesCount());
|
||||||
textures_maps.bind(view);
|
textures_maps.bind(view);
|
||||||
for (int i = 0; i < 2; ++i) {
|
textures_manager->loadToTexture2DArray(&textures_maps, maps_size);
|
||||||
QMutableMapIterator<QString, int> it(tex_layers[i]);
|
qDebug() << "loaded" << textures_maps.layersCount() << "bitmaps";
|
||||||
while (it.hasNext()) {
|
|
||||||
it.next();
|
|
||||||
QImage im = textures_manager->loadTextureImage(it.key(), i == 1);
|
|
||||||
textures_maps.load(view, im, ++cl);
|
|
||||||
it.value() = cl;
|
|
||||||
}
|
}
|
||||||
foreach(Map * m, maps[i]) {
|
for (Material * m: scene.materials) {
|
||||||
m->_layer = tex_layers[i].value(m->bitmap_path);
|
m->setMapsLayers(textures_manager);
|
||||||
// qDebug() << "assign" << m->bitmap_path << "layer" << m->_layer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
textures_maps.mipmaps(view);
|
|
||||||
// qDebug() << "load" << (cl+1) << "bitmaps";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QGLMaterial glm;
|
QGLMaterial glm;
|
||||||
|
|||||||
Reference in New Issue
Block a user