save more material information,

hold default material in geometry separated,
load diffuse color if texture cannot be opened,
fixed gamma correction on the texture,
This commit is contained in:
Anakin 2017-01-20 16:26:58 +01:00
parent abd9070e90
commit 9808cd03c0
5 changed files with 77 additions and 59 deletions

View File

@ -42,12 +42,14 @@ struct Model {
struct Material { struct Material {
QString name; QString name;
QString textureName;
QOpenGLTexture* texture = Q_NULLPTR; 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; 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 class FileInterface : public QObject
@ -110,8 +112,8 @@ public:
virtual QVector<Material>* getMaterials() const { return m_materials; }; virtual QVector<Material>* getMaterials() const { return m_materials; };
virtual BoundingBox getBoundingBox() const { return m_sceneBbox; }; virtual BoundingBox getBoundingBox() const { return m_sceneBbox; };
static Material getDefaultMaterial() { static Material* getDefaultMaterial() {
Material defMaterial; Material* defMaterial = new Material;
QImage img(1, 1, QImage::Format_RGB32); QImage img(1, 1, QImage::Format_RGB32);
img.fill(Qt::red); img.fill(Qt::red);
@ -128,7 +130,8 @@ public:
// f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2) // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2)
new_texture->setWrapMode(QOpenGLTexture::Repeat); new_texture->setWrapMode(QOpenGLTexture::Repeat);
defMaterial.texture = new_texture; defMaterial->texture = new_texture;
defMaterial->name = "Default Material";
return defMaterial; return defMaterial;
}; };

View File

@ -28,6 +28,7 @@ private:
QVector<Material>* m_materials = Q_NULLPTR; QVector<Material>* m_materials = Q_NULLPTR;
QVector<DrawInformation> m_drawList; QVector<DrawInformation> m_drawList;
BoundingBox m_boundings; BoundingBox m_boundings;
Material* m_defaultMaterial;
void clearData(); void clearData();

View File

@ -61,7 +61,6 @@ void main()
// final color after gama correction // final color after gama correction
vec3 gamma = vec3(1.0/2.2); vec3 gamma = vec3(1.0/2.2);
gl_FragColor = vec4(pow(linearColor, gamma), surfaceColor.a); gl_FragColor = vec4(pow(linearColor, gamma), surfaceColor.a);
//gl_FragColor = vec4(linearColor, surfaceColor.a);
} }
else else
{ {

View File

@ -14,11 +14,15 @@ GeometryEngine::GeometryEngine(QObject *parent)
, m_indexBuf(QOpenGLBuffer::IndexBuffer) , m_indexBuf(QOpenGLBuffer::IndexBuffer)
{ {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
m_defaultMaterial = FileInterface::getDefaultMaterial();
} }
GeometryEngine::~GeometryEngine() GeometryEngine::~GeometryEngine()
{ {
clearData(); clearData();
delete m_defaultMaterial->texture;
delete m_defaultMaterial;
} }
@ -113,9 +117,6 @@ void GeometryEngine::loadFile(QString filePath)
m_indexBuf.bind(); m_indexBuf.bind();
m_indexBuf.allocate(indexData.data(), indexData.size() * sizeof(GLuint)); m_indexBuf.allocate(indexData.data(), indexData.size() * sizeof(GLuint));
//pushback a default material
m_materials->push_back(FileInterface::getDefaultMaterial());
emit requestUpdate(); emit requestUpdate();
emit sendMessage("done..", 0); emit sendMessage("done..", 0);
emit sendFileInfo(filePath.right(filePath.size() - filePath.lastIndexOf(QRegExp("/|\\\\")) - 1), m_materials, vertexData.size(), indexData.size() / 3); 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(); m_materials->at(it.textureIndex).texture->bind();
tmp_transparent = m_materials->at(it.textureIndex).transparent; tmp_transparent = m_materials->at(it.textureIndex).transparent;
shininess = m_materials->at(it.textureIndex).shininess; shininess = m_materials->at(it.textureIndex).shininess;
specularColor = m_materials->at(it.textureIndex).specularColor; specularColor = m_materials->at(it.textureIndex).specularColor.toVector3D();
} }
else else
{ {
m_materials->last().texture->bind(); m_defaultMaterial->texture->bind();
tmp_transparent = m_materials->last().transparent; tmp_transparent = m_defaultMaterial->transparent;
} }
// Set model matrix // Set model matrix
program->setUniformValue("m_matrix", it.modelMatrix); program->setUniformValue("m_matrix", it.modelMatrix);

View File

@ -1,5 +1,6 @@
#include "..\Header\MshFile.h" #include "..\Header\MshFile.h"
#include "..\Header\tga.h" #include "..\Header\tga.h"
#include <QColor>
// helper function to save data from file to any variable type // helper function to save data from file to any variable type
#define F2V(variableName) reinterpret_cast<char*>(&variableName) #define F2V(variableName) reinterpret_cast<char*>(&variableName)
@ -160,7 +161,6 @@ void MshFile::analyseMsh2Chunks(std::list<ChunkHeader*>& chunkList)
std::list<ChunkHeader*> tmp_matdChunks; std::list<ChunkHeader*> tmp_matdChunks;
loadChunks(tmp_matdChunks, it->position, it->size); loadChunks(tmp_matdChunks, it->position, it->size);
//TODO: materialy without texture have null pointer need to fix that
m_materials->push_back(Material()); m_materials->push_back(Material());
// analyse MATD subchunks // analyse MATD subchunks
@ -227,17 +227,31 @@ void MshFile::analyseMatdChunks(std::list<ChunkHeader*>& chunkList)
m_materials->back().name = buffer; m_materials->back().name = buffer;
delete[] buffer; delete[] buffer;
} }
// TODO: read the data information
// data // data
else if(!strcmp("DATA", it->name)) 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: use diffuse color instead of default texture
//TODO: get information from flags // TODO: evaluate specular, gloss,.. and save values
// attributes // attributes
if (!strcmp("ATRB", it->name)) else if (!strcmp("ATRB", it->name))
{ {
// read the attributes // read the attributes
m_file.seekg(it->position); m_file.seekg(it->position);
@ -247,31 +261,21 @@ void MshFile::analyseMatdChunks(std::list<ChunkHeader*>& chunkList)
m_file.read(F2V(data[0]), sizeof(data[0])); m_file.read(F2V(data[0]), sizeof(data[0]));
m_file.read(F2V(data[1]), sizeof(data[1])); m_file.read(F2V(data[1]), sizeof(data[1]));
// specular // flags
if (flag >> 7) // 0: emissive
{ // 1: glow
std::cout << "specular" << std::endl; // 2: single-sided transparency
} // 3: double-sided transparency
// additive transparency || hard edged transparency || double-sided transparency || single-sided transparency // 4: hard-edged transparency
if ((flag << 1) >> 7 || (flag << 3) >> 7 || (flag << 4) >> 7 || (flag << 5) >> 7) // 5: per-pixel lighting
{ // 6: additive transparency
m_materials->back().transparent = true; // 7: specular
}
// per-pixel lighting for (unsigned int i = 0; i < 8; i++)
if ((flag << 2) >> 7) m_materials->back().flags[i] = (flag << (7 - i)) >> 7;
{
std::cout << "per-pixel lighting" << std::endl; m_materials->back().transparent = m_materials->back().flags[2] || m_materials->back().flags[3] || m_materials->back().flags[4] || m_materials->back().flags[6];
}
// glow
if ((flag << 6) >> 7)
{
std::cout << "glow" << std::endl;
}
// emissive
if ((flag << 7) >> 7)
{
std::cout << "emissive" << std::endl;
}
} }
// texture zero // texture zero
@ -282,13 +286,12 @@ void MshFile::analyseMatdChunks(std::list<ChunkHeader*>& chunkList)
char* buffer = new char[it->size + 1]; char* buffer = new char[it->size + 1];
*buffer = { 0 }; *buffer = { 0 };
m_file.read(buffer, it->size); m_file.read(buffer, it->size);
QString texName(buffer); m_materials->back().textureName = buffer;
delete[] buffer; delete[] buffer;
// load the texture if the name is not empty // load the texture if the name is not empty
// TODO: save filename for the output if (!m_materials->back().textureName.isEmpty())
if (!texName.isEmpty()) loadTexture(m_materials->back().texture, m_filepath + "/" + m_materials->back().textureName);
loadTexture(m_materials->back().texture, m_filepath + "/" + texName);
} }
} }
} }
@ -684,10 +687,21 @@ void MshFile::loadTexture(QOpenGLTexture *& destination, QString filepath)
bool loadSuccess(false); bool loadSuccess(false);
QImage img = loadTga(filepath, loadSuccess); 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) if (!loadSuccess)
{ {
emit sendMessage("WARNING: texture not found or corrupted: " + m_materials->back().name, 1); 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 // Load image to OglTexture