From 9808cd03c0531c5f8e85b417292bc0a01ded2616 Mon Sep 17 00:00:00 2001 From: Anakin Date: Fri, 20 Jan 2017 16:26:58 +0100 Subject: [PATCH] save more material information, hold default material in geometry separated, load diffuse color if texture cannot be opened, fixed gamma correction on the texture, --- QtMeshViewer/Header/FileInterface.h | 17 ++-- QtMeshViewer/Header/GeometryEngine.h | 1 + QtMeshViewer/Resources/fshader.glsl | 1 - QtMeshViewer/Source/GeometryEngine.cpp | 13 ++-- QtMeshViewer/Source/MshFile.cpp | 104 ++++++++++++++----------- 5 files changed, 77 insertions(+), 59 deletions(-) diff --git a/QtMeshViewer/Header/FileInterface.h b/QtMeshViewer/Header/FileInterface.h index 0d254ca..ba7c12f 100644 --- a/QtMeshViewer/Header/FileInterface.h +++ b/QtMeshViewer/Header/FileInterface.h @@ -42,12 +42,14 @@ struct Model { struct Material { QString name; + QString textureName; QOpenGLTexture* texture = Q_NULLPTR; + QVector4D specularColor = { 1.0, 1.0, 1.0, 1.0 }; + QVector4D diffuseColor = { 1.0, 0.0, 0.0, 1.0 }; + QVector4D ambientColor = { 1.0, 1.0, 1.0, 1.0 }; + float shininess = 80; + bool flags[8] = { false }; bool transparent = false; - float shininess = 80; //TODO: read from file - QVector4D specularColor = {1.0,1.0,1.0, 1.0}; //TODO: read from file, change to 4D - QVector4D diffuseColor; - QVector4D ambientColor; }; class FileInterface : public QObject @@ -110,8 +112,8 @@ public: virtual QVector* getMaterials() const { return m_materials; }; virtual BoundingBox getBoundingBox() const { return m_sceneBbox; }; - static Material getDefaultMaterial() { - Material defMaterial; + static Material* getDefaultMaterial() { + Material* defMaterial = new Material; QImage img(1, 1, QImage::Format_RGB32); img.fill(Qt::red); @@ -128,7 +130,8 @@ public: // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2) new_texture->setWrapMode(QOpenGLTexture::Repeat); - defMaterial.texture = new_texture; + defMaterial->texture = new_texture; + defMaterial->name = "Default Material"; return defMaterial; }; diff --git a/QtMeshViewer/Header/GeometryEngine.h b/QtMeshViewer/Header/GeometryEngine.h index 3a44ac3..9cd09b2 100644 --- a/QtMeshViewer/Header/GeometryEngine.h +++ b/QtMeshViewer/Header/GeometryEngine.h @@ -28,6 +28,7 @@ private: QVector* m_materials = Q_NULLPTR; QVector m_drawList; BoundingBox m_boundings; + Material* m_defaultMaterial; void clearData(); diff --git a/QtMeshViewer/Resources/fshader.glsl b/QtMeshViewer/Resources/fshader.glsl index 202dc0c..c3abb84 100644 --- a/QtMeshViewer/Resources/fshader.glsl +++ b/QtMeshViewer/Resources/fshader.glsl @@ -61,7 +61,6 @@ void main() // final color after gama correction vec3 gamma = vec3(1.0/2.2); gl_FragColor = vec4(pow(linearColor, gamma), surfaceColor.a); - //gl_FragColor = vec4(linearColor, surfaceColor.a); } else { diff --git a/QtMeshViewer/Source/GeometryEngine.cpp b/QtMeshViewer/Source/GeometryEngine.cpp index fd79dad..75835db 100644 --- a/QtMeshViewer/Source/GeometryEngine.cpp +++ b/QtMeshViewer/Source/GeometryEngine.cpp @@ -14,11 +14,15 @@ GeometryEngine::GeometryEngine(QObject *parent) , m_indexBuf(QOpenGLBuffer::IndexBuffer) { initializeOpenGLFunctions(); + + m_defaultMaterial = FileInterface::getDefaultMaterial(); } GeometryEngine::~GeometryEngine() { clearData(); + delete m_defaultMaterial->texture; + delete m_defaultMaterial; } @@ -113,9 +117,6 @@ void GeometryEngine::loadFile(QString filePath) m_indexBuf.bind(); m_indexBuf.allocate(indexData.data(), indexData.size() * sizeof(GLuint)); - //pushback a default material - m_materials->push_back(FileInterface::getDefaultMaterial()); - emit requestUpdate(); emit sendMessage("done..", 0); emit sendFileInfo(filePath.right(filePath.size() - filePath.lastIndexOf(QRegExp("/|\\\\")) - 1), m_materials, vertexData.size(), indexData.size() / 3); @@ -185,12 +186,12 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program, bool wireframe) m_materials->at(it.textureIndex).texture->bind(); tmp_transparent = m_materials->at(it.textureIndex).transparent; shininess = m_materials->at(it.textureIndex).shininess; - specularColor = m_materials->at(it.textureIndex).specularColor; + specularColor = m_materials->at(it.textureIndex).specularColor.toVector3D(); } else { - m_materials->last().texture->bind(); - tmp_transparent = m_materials->last().transparent; + m_defaultMaterial->texture->bind(); + tmp_transparent = m_defaultMaterial->transparent; } // Set model matrix program->setUniformValue("m_matrix", it.modelMatrix); diff --git a/QtMeshViewer/Source/MshFile.cpp b/QtMeshViewer/Source/MshFile.cpp index 906e083..b654c5c 100644 --- a/QtMeshViewer/Source/MshFile.cpp +++ b/QtMeshViewer/Source/MshFile.cpp @@ -1,5 +1,6 @@ #include "..\Header\MshFile.h" #include "..\Header\tga.h" +#include // helper function to save data from file to any variable type #define F2V(variableName) reinterpret_cast(&variableName) @@ -160,7 +161,6 @@ void MshFile::analyseMsh2Chunks(std::list& chunkList) std::list tmp_matdChunks; loadChunks(tmp_matdChunks, it->position, it->size); - //TODO: materialy without texture have null pointer need to fix that m_materials->push_back(Material()); // analyse MATD subchunks @@ -217,27 +217,41 @@ void MshFile::analyseMatdChunks(std::list& chunkList) { for (auto& it : chunkList) { - // name - if (!strcmp("NAME", it->name)) - { + // name + if (!strcmp("NAME", it->name)) + { m_file.seekg(it->position); char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); m_materials->back().name = buffer; delete[] buffer; - } - // TODO: read the data information - // data - else if(!strcmp("DATA", it->name)) - { - - - } - // TODO: use diffuse color instead of default texture - //TODO: get information from flags + } + + // data + else if(!strcmp("DATA", it->name)) + { + m_file.seekg(it->position); + + // diffuse + for (unsigned int i = 0; i < 4; i++) + m_file.read(F2V(m_materials->back().diffuseColor[i]), sizeof(float)); + + // specular + for (unsigned int i = 0; i < 4; i++) + m_file.read(F2V(m_materials->back().specularColor[i]), sizeof(float)); + + // ambient + for (unsigned int i = 0; i < 4; i++) + m_file.read(F2V(m_materials->back().ambientColor[i]), sizeof(float)); + + // shininess + m_file.read(F2V(m_materials->back().shininess), sizeof(float)); + } + + // TODO: evaluate specular, gloss,.. and save values // attributes - if (!strcmp("ATRB", it->name)) + else if (!strcmp("ATRB", it->name)) { // read the attributes m_file.seekg(it->position); @@ -247,31 +261,21 @@ void MshFile::analyseMatdChunks(std::list& chunkList) m_file.read(F2V(data[0]), sizeof(data[0])); m_file.read(F2V(data[1]), sizeof(data[1])); - // specular - if (flag >> 7) - { - std::cout << "specular" << std::endl; - } - // additive transparency || hard edged transparency || double-sided transparency || single-sided transparency - if ((flag << 1) >> 7 || (flag << 3) >> 7 || (flag << 4) >> 7 || (flag << 5) >> 7) - { - m_materials->back().transparent = true; - } - // per-pixel lighting - if ((flag << 2) >> 7) - { - std::cout << "per-pixel lighting" << std::endl; - } - // glow - if ((flag << 6) >> 7) - { - std::cout << "glow" << std::endl; - } - // emissive - if ((flag << 7) >> 7) - { - std::cout << "emissive" << std::endl; - } + // flags + // 0: emissive + // 1: glow + // 2: single-sided transparency + // 3: double-sided transparency + // 4: hard-edged transparency + // 5: per-pixel lighting + // 6: additive transparency + // 7: specular + + for (unsigned int i = 0; i < 8; i++) + m_materials->back().flags[i] = (flag << (7 - i)) >> 7; + + m_materials->back().transparent = m_materials->back().flags[2] || m_materials->back().flags[3] || m_materials->back().flags[4] || m_materials->back().flags[6]; + } // texture zero @@ -282,13 +286,12 @@ void MshFile::analyseMatdChunks(std::list& chunkList) char* buffer = new char[it->size + 1]; *buffer = { 0 }; m_file.read(buffer, it->size); - QString texName(buffer); + m_materials->back().textureName = buffer; delete[] buffer; // load the texture if the name is not empty - // TODO: save filename for the output - if (!texName.isEmpty()) - loadTexture(m_materials->back().texture, m_filepath + "/" + texName); + if (!m_materials->back().textureName.isEmpty()) + loadTexture(m_materials->back().texture, m_filepath + "/" + m_materials->back().textureName); } } } @@ -684,10 +687,21 @@ void MshFile::loadTexture(QOpenGLTexture *& destination, QString filepath) bool loadSuccess(false); QImage img = loadTga(filepath, loadSuccess); + if (filepath.isEmpty()) + { + loadSuccess = true; + img = QImage(1, 1, QImage::Format_RGB32); + img.fill(Qt::red); + } + else + img = loadTga(filepath, loadSuccess); + if (!loadSuccess) { emit sendMessage("WARNING: texture not found or corrupted: " + m_materials->back().name, 1); - return; + + img = QImage(1, 1, QImage::Format_RGB32); + img.fill(QColor(m_materials->back().diffuseColor[0] * 255, m_materials->back().diffuseColor[1] * 255, m_materials->back().diffuseColor[2] * 255)); } // Load image to OglTexture