diff --git a/qglengine/CMakeLists.txt b/qglengine/CMakeLists.txt
index 45080bf..a84d4fc 100644
--- a/qglengine/CMakeLists.txt
+++ b/qglengine/CMakeLists.txt
@@ -30,6 +30,8 @@ list(APPEND SRC ${FSRC})
qt_sources(FSRC DIR "core")
list(APPEND SRC ${FSRC})
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
+file(GLOB PHS "*_p.h" "formats/*_p.h" "core/*_p.h")
+list(REMOVE_ITEM out_HDR "${PHS}")
qt_add_library(qglengine_core SHARED out_CPP)
qt_target_link_libraries(qglengine_core qad_utils qad_widgets assimp ${OPENGL_LIBRARIES})
message(STATUS "Building qglengine_core")
diff --git a/qglengine/core/glcubemap.cpp b/qglengine/core/glcubemap.cpp
new file mode 100644
index 0000000..49bfee3
--- /dev/null
+++ b/qglengine/core/glcubemap.cpp
@@ -0,0 +1,274 @@
+/*
+ QGLView
+ Copyright (C) 2019 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 .
+*/
+
+#include "gltypes.h"
+#include "glcubemap.h"
+#include "hdr_p.h"
+
+using namespace QGLEngineShaders;
+
+
+QVector loadFileHDR(const QString & path, QSize * size) {
+ if (size) *size = QSize();
+ QVector ret;
+ QFile f(path);
+ if (!f.open(QIODevice::ReadOnly)) {
+ qDebug() << "[QGLEngine] Can`t open" << path;
+ return ret;
+ }
+ QTextStream ts(&f);
+ QString line = ts.readLine(256);
+ if (line != "#?RADIANCE") return ret;
+ QSize sz;
+ while (!ts.atEnd()) {
+ line = ts.readLine(256);
+ if (line.startsWith("FORMAT")) {
+ line.remove(0, 7);
+ if (!line.startsWith("32-bit")) {
+ qDebug() << "[QGLEngine] File" << path << "has unknown format!";
+ return ret;
+ }
+ }
+ if (line.mid(1, 2) == "Y ") {
+ QStringList sl = line.trimmed().split(" ");
+ sl.removeAll("");
+ if (sl.size() != 4) {
+ qDebug() << "[QGLEngine] File" << path << "has unknown size!";
+ return ret;
+ }
+ sz.setWidth (sl[3].toInt());
+ sz.setHeight(sl[1].toInt());
+ //qDebug() << "found size" << sz;
+ break;
+ }
+ }
+ if (sz.isEmpty()) return ret;
+ f.seek(ts.pos());
+ QDataStream ds(&f);
+ int count = sz.width() * sz.height();
+ QVector data(count*3);
+ if (!RGBE_ReadPixels_RLE(&ds, data.data(), sz.width(), sz.height()))
+ return ret;
+
+ if (size) *size = sz;
+ ret.resize(count);
+ //QColor col;
+ //QImage im(sz, QImage::Format_ARGB32);
+ //QRgb * imdata = (QRgb*)im.bits();
+ for (int i = 0; i < count; ++i) {
+ QVector3D p(pow(data[i*3 + 2], 1. / 2.2),
+ pow(data[i*3 + 1], 1. / 2.2),
+ pow(data[i*3 + 0], 1. / 2.2));
+ ret[i] = p;
+ //col = QColor::fromRgbF(piClamp(p[0], 0.f, 1.f),
+ // piClamp(p[1], 0.f, 1.f),
+ // piClamp(p[2], 0.f, 1.f));
+ //imdata[i] = col.rgb();
+ }
+ //im.save("_hdr.png");
+
+ return ret;
+}
+
+
+//#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+//#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+//#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+QVector faceHDR(const QVector & data, QSize sz, QSize & fsz, int face) {
+ QVector ret;
+ if (data.isEmpty() || sz.isNull()) return ret;
+ QRect fr;
+ int fw = sz.width () / 4;
+ int fh = sz.height() / 3;
+ fsz = QSize(fw, fh);
+ ret.reserve(fw * fh);
+ switch (face) {
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ fr.setRect(fw, fh, fw, fh);
+ for (int x = fr.left(); x <= fr.right(); ++x) {
+ for (int y = fr.top(); y <= fr.bottom(); ++y) {
+ ret << data[y*sz.width() + x];
+ }
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ fr.setRect(fw*3, fh, fw, fh);
+ for (int x = fr.right(); x >= fr.left(); --x) {
+ for (int y = fr.bottom(); y >= fr.top(); --y) {
+ ret << data[y*sz.width() + x];
+ }
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ fr.setRect( 0, fh, fw, fh);
+ for (int y = fr.bottom(); y >= fr.top(); --y) {
+ for (int x = fr.left(); x <= fr.right(); ++x) {
+ ret << data[y*sz.width() + x];
+ }
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ fr.setRect(fw*2, fh, fw, fh);
+ for (int y = fr.top(); y <= fr.bottom(); ++y) {
+ for (int x = fr.right(); x >= fr.left(); --x) {
+ ret << data[y*sz.width() + x];
+ }
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ fr.setRect(fw, 0, fw, fh);
+ for (int x = fr.left(); x <= fr.right(); ++x) {
+ for (int y = fr.top(); y <= fr.bottom(); ++y) {
+ ret << data[y*sz.width() + x];
+ }
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ fr.setRect(fw, fh*2, fw, fh);
+ for (int x = fr.left(); x <= fr.right(); ++x) {
+ for (int y = fr.top(); y <= fr.bottom(); ++y) {
+ ret << data[y*sz.width() + x];
+ }
+ }
+ break;
+ default: break;
+ }
+ if (fr.isEmpty()) return ret;
+ //qDebug() << ret.size() << fr;
+ return ret;
+}
+
+
+
+CubeTexture::CubeTexture(QOpenGLExtraFunctions * f_, int _size, const GLenum & _format): f(f_) {
+ size = _size;
+ format_ = _format;
+ id_ = 0;
+ changed_ = false;
+}
+
+
+bool CubeTexture::init() {
+ if (isInit()) return true;
+ f->glGenTextures(1, &id_);
+ f->glBindTexture(GL_TEXTURE_CUBE_MAP, id_);
+ f->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ f->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ f->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ f->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ f->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+ //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);
+ changed_ = false;
+ return id_ > 0;
+}
+
+
+void CubeTexture::destroy() {
+ if (!isInit()) return;
+ f->glDeleteTextures(1, &id_);
+ id_ = 0;
+}
+
+
+void CubeTexture::bind(int channel) {
+ init();
+ f->glActiveTexture(GL_TEXTURE0 + channel);
+ f->glBindTexture(GL_TEXTURE_CUBE_MAP, id_);
+}
+
+
+void CubeTexture::release() {
+ f->glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+}
+
+
+void CubeTexture::loadHDR(const QVector & data, QSize sz) {
+ bind();
+ QSize fsz;
+ QVector fd;
+ for (int i = 0; i < 6; ++i) {
+ fd = faceHDR(data, sz, fsz, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
+ //qDebug() << "load cube" << fd[0];
+ //f->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ f->glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format_, fsz.width(), fsz.height(), 0, GL_RGB, GL_FLOAT, fd.isEmpty() ? 0 : fd.constData());
+ //qDebug() << QString::number(GetLastError(), 16);
+ }
+ f->glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+}
+
+
+void CubeTexture::setFileHDR(const QString & path) {
+ hdr_path = path;
+ changed_ = true;
+}
+
+
+void CubeTexture::load() {
+ if (!changed_) return;
+ init();
+ if (!hdr_path.isEmpty()) {
+ QSize sz;
+ QVector data = loadFileHDR(hdr_path, &sz);
+ loadHDR(data, sz);
+ }
+ changed_ = false;
+}
+
+/*
+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();
+}
+*/
diff --git a/qglengine/core/glcubemap.h b/qglengine/core/glcubemap.h
new file mode 100644
index 0000000..65d6042
--- /dev/null
+++ b/qglengine/core/glcubemap.h
@@ -0,0 +1,67 @@
+/*
+ QGLView
+ Copyright (C) 2019 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 GLCUBEMAP_H
+#define GLCUBEMAP_H
+
+#include "glshaders_types.h"
+#include "chunkstream.h"
+
+QVector loadFileHDR(const QString & path, QSize * size = 0);
+
+class CubeTexture {
+public:
+ CubeTexture(QOpenGLExtraFunctions * f_, int _size, const GLenum & _format = GL_RGB16F);
+ bool init();
+ void destroy();
+ void bind(int channel = 0);
+ void release();
+ void resize(int _size) {size = _size; changed_ = true;}
+ void loadHDR(const QVector & data, QSize sz);
+ void setFileHDR(const QString & path);
+ QString fileHDR() const {return hdr_path;}
+ //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_;}
+ bool isInit() const {return id_ != 0;}
+ //const QString & path(int side) const {return pathes[side];}
+ //void setPath(int side, const QString & p) {pathes[side] = p;}
+ //void loadPathesFromDirectory(const QString & dir);
+ void load();
+private:
+
+ QOpenGLExtraFunctions * f;
+ bool changed_;
+ int size;
+ GLenum format_;
+ GLuint id_;
+ QString hdr_path;
+ //QVector pathes;
+};
+
+
+#endif // GLCUBEMAP_H
diff --git a/qglengine/core/glmaterial.cpp b/qglengine/core/glmaterial.cpp
index b2c28ee..86caa69 100644
--- a/qglengine/core/glmaterial.cpp
+++ b/qglengine/core/glmaterial.cpp
@@ -199,3 +199,13 @@ void Material::setTypes() {
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();
+}
diff --git a/qglengine/core/glmaterial.h b/qglengine/core/glmaterial.h
index 90a3143..2e6d311 100644
--- a/qglengine/core/glmaterial.h
+++ b/qglengine/core/glmaterial.h
@@ -104,6 +104,7 @@ public:
void load(TextureManager * tm);
void setMapsChanged();
void setTypes();
+ void detectMaps();
QString name;
QColor color_diffuse;
QColor color_emission;
diff --git a/qglengine/core/hdr.cpp b/qglengine/core/hdr.cpp
new file mode 100644
index 0000000..f2b01d6
--- /dev/null
+++ b/qglengine/core/hdr.cpp
@@ -0,0 +1,125 @@
+/*
+ QGLView
+ Copyright (C) 2019 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 .
+*/
+
+#include "hdr_p.h"
+#include "qmath.h"
+
+#define RGBE_DATA_RED 2
+#define RGBE_DATA_GREEN 1
+#define RGBE_DATA_BLUE 0
+/* number of floats per pixel */
+#define RGBE_DATA_SIZE 3
+
+
+void rgbe2float(float *red, float *green, float *blue, uchar rgbe[4]) {
+ float f;
+ if (rgbe[3]) {
+ f = static_cast(ldexp(1.0,rgbe[3]-(int)(128+8)));
+ *red = rgbe[0] * f;
+ *green = rgbe[1] * f;
+ *blue = rgbe[2] * f;
+ }
+ else
+ *red = *green = *blue = 0.0;
+}
+
+
+/* simple read routine. will not correctly handle run length encoding */
+bool RGBE_ReadPixels(QDataStream * fp, float * data, int numpixels) {
+ uchar rgbe[4];
+ while(numpixels-- > 0) {
+ if (fp->readRawData((char*)rgbe, sizeof(rgbe)) < 1)
+ return false;
+ rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE],rgbe);
+ data += RGBE_DATA_SIZE;
+ }
+ return true;
+}
+
+
+bool RGBE_ReadPixels_RLE(QDataStream * fp, float * data, int scanline_width, int num_scanlines) {
+ uchar rgbe[4], *ptr, *ptr_end;
+ int i, count;
+ uchar buf[2];
+ QByteArray scanline_buffer;
+
+ if ((scanline_width < 8)||(scanline_width > 0x7fff))
+ /* run length encoding is not allowed so read flat*/
+ return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines);
+ scanline_buffer.resize(4*scanline_width);
+ /* read in each successive scanline */
+ while(num_scanlines > 0) {
+ if (fp->readRawData((char*)rgbe,sizeof(rgbe)) < 1) {
+ return false;
+ }
+ if ((rgbe[0] != 2)||(rgbe[1] != 2)||(rgbe[2] & 0x80)) {
+ /* this file is not run length encoded */
+ rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN],&data[RGBE_DATA_BLUE],rgbe);
+ data += RGBE_DATA_SIZE;
+ return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines-1);
+ }
+ if ((((int)rgbe[2])<<8 | rgbe[3]) != scanline_width) {
+ return false;
+ }
+ ptr = (uchar*)scanline_buffer.data();
+ /* read each of the four channels for the scanline into the buffer */
+ for(i=0;i<4;i++) {
+ ptr_end = (uchar*)scanline_buffer.data() + ((i+1)*scanline_width);
+ while(ptr < ptr_end) {
+ if (fp->readRawData((char*)buf,sizeof(buf[0])*2) < 1) {
+ return false;
+ }
+ if (buf[0] > 128) {
+ /* a run of the same value */
+ count = buf[0]-128;
+ if ((count == 0)||(count > ptr_end - ptr)) {
+ return false;
+ }
+ while(count-- > 0)
+ *ptr++ = buf[1];
+ }
+ else {
+ /* a non-run */
+ count = buf[0];
+ if ((count == 0)||(count > ptr_end - ptr)) {
+ return false;
+ }
+ *ptr++ = buf[1];
+ if (--count > 0) {
+ if (fp->readRawData((char*)ptr,sizeof(*ptr)*count) < 1) {
+ return false;
+ }
+ ptr += count;
+ }
+ }
+ }
+ }
+ /* now convert data from buffer into floats */
+ for(i=0;i.
+*/
+
+#ifndef HDR_P_H
+#define HDR_P_H
+
+#include
+
+bool RGBE_ReadPixels_RLE(QDataStream * fp, float * data, int scanline_width, int num_scanlines);
+
+#endif // HDR_P_H
diff --git a/qglengine/formats/loader_assimp.cpp b/qglengine/formats/loader_assimp.cpp
index d848a06..9a07077 100644
--- a/qglengine/formats/loader_assimp.cpp
+++ b/qglengine/formats/loader_assimp.cpp
@@ -124,6 +124,7 @@ Material * assimpMaterial(const aiMaterial * m) {
ret->map_roughness.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_SHININESS(0));
ret->map_emission .bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_EMISSIVE(0));
ret->transparency = 1.f - aiMatFloat(m, AI_MATKEY_OPACITY, 1.f);
+ ret->detectMaps();
ret->setTypes();
return ret;
}
diff --git a/qglengine/qglview.cpp b/qglengine/qglview.cpp
index efcb5f6..f4c05dc 100644
--- a/qglengine/qglview.cpp
+++ b/qglengine/qglview.cpp
@@ -90,8 +90,9 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
//camera().aim_ = camera().pos_;
ktm_.restart();
- Mesh * m = Primitive::torus(100, 40, 1., 0.4, 360);
- //Mesh * m = Primitive::coneFrame(10, 1, 1., 2.);
+ //Mesh * m = Primitive::torus(100, 40, 1., 0.4, 360);
+ Mesh * m = Primitive::cube(10, 10, 10);
+ m->flipNormals();
//QMatrix4x4 mat;
//mat.rotate(90, 0,1,0);
//mat.translate(0, 0, 2);
@@ -178,17 +179,19 @@ void QGLView::render() {
void QGLView::initialize() {
checkCaps();
- renderer_.reloadShaders();
- renderer_.init(width(), height());
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_MULTISAMPLE);
glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
+ glEnable(GL_TEXTURE_CUBE_MAP);
glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT);
glEnable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
glCullFace(GL_BACK);
+ renderer_.reloadShaders();
+ renderer_.init(width(), height());
is_init = true;
need_init_ = false;
emit glInitializeDone();
diff --git a/qglengine/qglview.h b/qglengine/qglview.h
index 45c31b1..8f5f014 100644
--- a/qglengine/qglview.h
+++ b/qglengine/qglview.h
@@ -75,6 +75,12 @@ public:
QGLView();
virtual ~QGLView();
+ enum CameraLightMode {
+ clmOff,
+ clmAuto,
+ clmOn,
+ };
+
enum Feature {
qglFXAA,
qglAnisotropicLevel,
@@ -102,6 +108,7 @@ public:
qglDepthOfFieldDiaphragm
};
+ Q_ENUM(CameraLightMode)
void stop();
void start(float freq = 60.);
@@ -114,6 +121,7 @@ public:
float gamma() const {return renderer_.gamma_;}
bool autoExposure() const {return renderer_.tone_proc.enabled;}
int maxAnisotropicLevel() const {return max_anisotropic;}
+ QString environmentMapFile() const {return renderer_.tex_env.fileHDR();}
QColor ambientColor() const {return ambientColor_;}
QColor fogColor() const {return fogColor_;}
@@ -164,8 +172,8 @@ public:
Scene * scene() {return scene_;}
void focusOn(const Box3D & bb);
- void setCameraLightOn(bool on) {renderer_.setCameraLightOn(on);}
- bool isCameraLightOn() const {return renderer_.isCameraLightOn();}
+ void setCameraLightMode(CameraLightMode m) {renderer_.setCameraLightMode(m);}
+ CameraLightMode cameraLightMode() const {return (CameraLightMode)renderer_.cameraLightMode();}
Camera * camera() {return camera_;}
const Camera * camera() const {return camera_;}
@@ -238,6 +246,7 @@ public slots:
void setGamma(const float & arg) {renderer_.gamma_ = arg;}
void setAutoExposure(bool arg) {renderer_.tone_proc.enabled = arg;}
void setAmbientColor(const QColor & arg) {ambientColor_ = arg;}
+ void setEnvironmentMapFile(QString file) {renderer_.tex_env.setFileHDR(file);}
void setFogColor(const QColor & arg) {fogColor_ = arg;}
void setFogDensity(const float & arg) {fogDensity_ = arg;}
void setFogDecay(const float & arg) {fogDecay_ = arg;}
diff --git a/qglengine/qglview_test/qglview_window.cpp b/qglengine/qglview_test/qglview_window.cpp
index 5d9291a..5d9d37e 100644
--- a/qglengine/qglview_test/qglview_window.cpp
+++ b/qglengine/qglview_test/qglview_window.cpp
@@ -242,3 +242,10 @@ void QGLViewWindow::on_actionScale_triggered(bool on) {
actionScale ->setChecked(true);
view->view()->setCurrentAction(RendererService::haScale);
}
+
+
+#include "glcubemap.h"
+void QGLViewWindow::on_pushButton_3_clicked() {
+ QString f = QFileDialog::getOpenFileName(this, "Select file", "", "*");
+ if (f.isEmpty()) return;
+}
diff --git a/qglengine/qglview_test/qglview_window.h b/qglengine/qglview_test/qglview_window.h
index c96687c..aebb7c3 100644
--- a/qglengine/qglview_test/qglview_window.h
+++ b/qglengine/qglview_test/qglview_window.h
@@ -105,6 +105,8 @@ private slots:
void on_spinFogDensity_valueChanged(double v) {view->view()->setFogDensity(v);}
void on_spinFogDecay_valueChanged(double v) {view->view()->setFogDecay(v);}
+ void on_pushButton_3_clicked();
+
public slots:
signals:
diff --git a/qglengine/qglview_test/qglview_window.ui b/qglengine/qglview_test/qglview_window.ui
index 91eaaa2..a9bde08 100644
--- a/qglengine/qglview_test/qglview_window.ui
+++ b/qglengine/qglview_test/qglview_window.ui
@@ -80,8 +80,8 @@
0
0
- 945
- 636
+ 934
+ 737
@@ -635,6 +635,13 @@
+ -
+
+
+ load HDR
+
+
+
-
@@ -741,7 +748,7 @@
0
0
1107
- 21
+ 24
+ -
+
+
+ Gamma:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ 0.010000000000000
+
+
+ 5.000000000000000
+
+
+ 1.000000000000000
+
+
+ 2
+
+
+
+ -
+
+
+ Env HDR:
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+ -
+
+
+
+ :/icons/edit-delete.png:/icons/edit-delete.png
+
+
+
+ -
+
+
+
+ :/icons/document-open.png:/icons/document-open.png
+
+
+
+
+
@@ -90,9 +149,6 @@
Auto exposure
-
- true
-
-
@@ -105,6 +161,16 @@
+ -
+
+
+ Camera light
+
+
+ true
+
+
+
-
@@ -112,117 +178,86 @@
Camera
-
-
-
-
-
- Gamma:
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
+
+
-
+
+
-
+
+
+ Orbit
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 1
+
+
+
+
+ -
+
+
+ FOV:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ 0.100000000000000
+
+
+ 179.900000000000006
+
+
+ 60.000000000000000
+
+
+
+
- -
-
-
- 0.010000000000000
-
-
- 5.000000000000000
-
-
- 1.000000000000000
-
-
- 2
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Preferred
-
-
-
- 20
- 1
-
-
-
-
- -
-
-
- FOV:
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- CamLight
-
-
- true
-
-
-
- -
-
-
- 0.100000000000000
-
-
- 179.900000000000006
-
-
- 60.000000000000000
-
-
-
- -
-
-
- Orbit
-
-
- true
-
-
-
- -
-
-
- Depth start:
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
- 3
-
-
- 999999999.000000000000000
-
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
-
- 1.000000000000000
-
-
+
-
+
+
-
+
+
+ Depth start:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ 3
+
+
+ 999999999.000000000000000
+
+
+ QAbstractSpinBox::AdaptiveDecimalStepType
+
+
+ 1.000000000000000
+
+
+
+
@@ -468,6 +503,9 @@
-
+
+
+
+