added open file ability from the old project to Qt,
texture seams not to open, texture display does not work
This commit is contained in:
parent
1cc4f1ca90
commit
481256e8ea
|
@ -0,0 +1,72 @@
|
|||
#pragma once
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <QMatrix4x4>
|
||||
|
||||
//TODO: shouldn't be here
|
||||
enum ModelTyp {
|
||||
null,
|
||||
dynamicMesh,
|
||||
cloth,
|
||||
bone,
|
||||
staticMesh,
|
||||
shadowMesh = 6
|
||||
};
|
||||
|
||||
struct BoundingBox {
|
||||
float quaternion[4];
|
||||
float center[3];
|
||||
float extents[3];
|
||||
};
|
||||
|
||||
struct Segment {
|
||||
std::uint32_t textureIndex = 0;
|
||||
float* vertex = nullptr;
|
||||
float* uv = nullptr;
|
||||
std::vector<std::vector<std::uint32_t>> polyIndices; // indices into vertex array
|
||||
};
|
||||
|
||||
struct Model {
|
||||
std::string name = "";
|
||||
std::string parent = "";
|
||||
ModelTyp type = null; //TODO: should be removed
|
||||
std::int32_t renderFlags = -1; //TODO: should be removed
|
||||
QMatrix4x4 m4x4Translation;
|
||||
std::vector<Segment*> segmList;
|
||||
};
|
||||
|
||||
class FileInterface
|
||||
{
|
||||
public:
|
||||
FileInterface(const char* path)
|
||||
: m_vModels(new std::vector<Model*>)
|
||||
{
|
||||
//open file
|
||||
m_fsMesh.open(path, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!m_fsMesh.is_open())
|
||||
throw std::invalid_argument(std::string("file not found: ") += path);
|
||||
};
|
||||
|
||||
virtual ~FileInterface()
|
||||
{
|
||||
// close file
|
||||
m_fsMesh.close();
|
||||
|
||||
//clean up
|
||||
m_vTextureNames.clear();
|
||||
};
|
||||
|
||||
protected:
|
||||
std::vector<Model*>* m_vModels;
|
||||
std::fstream m_fsMesh;
|
||||
std::vector<std::string> m_vTextureNames;
|
||||
BoundingBox m_sceneBbox;
|
||||
|
||||
virtual void import() = 0;
|
||||
|
||||
public:
|
||||
virtual std::vector<Model*>* getModels() const { return m_vModels; };
|
||||
virtual std::vector<std::string> getTextureNames() const { return m_vTextureNames; };
|
||||
virtual BoundingBox getBoundingBox() const { return m_sceneBbox; };
|
||||
};
|
|
@ -18,6 +18,7 @@ private:
|
|||
// Functions
|
||||
private:
|
||||
void setupWindow();
|
||||
void import(const char* path);
|
||||
|
||||
// Slots
|
||||
private slots:
|
||||
|
|
|
@ -1,22 +1,6 @@
|
|||
#pragma once
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <QMatrix4x4>
|
||||
#include "FileInterface.h"
|
||||
|
||||
enum ModelTyp {
|
||||
null,
|
||||
dynamicMesh,
|
||||
cloth,
|
||||
bone,
|
||||
staticMesh,
|
||||
shadowMesh = 6
|
||||
};
|
||||
|
||||
struct BoundingBox {
|
||||
float quaternion[4];
|
||||
float center[3];
|
||||
float extents[3];
|
||||
};
|
||||
|
||||
struct ChunkHeader {
|
||||
char name[5];
|
||||
|
@ -24,36 +8,16 @@ struct ChunkHeader {
|
|||
std::streampos position;
|
||||
};
|
||||
|
||||
struct Segment {
|
||||
std::uint32_t textureIndex = 0;
|
||||
float* vertex = nullptr;
|
||||
float* uv = nullptr;
|
||||
std::vector<std::vector<std::uint32_t>> polyIndices; // indices into vertex array
|
||||
};
|
||||
|
||||
struct Model {
|
||||
std::string name = "";
|
||||
std::string parent = "";
|
||||
ModelTyp type = null;
|
||||
std::int32_t renderFlags = -1;
|
||||
QMatrix4x4 m4x4Translation;
|
||||
std::vector<Segment*> segmList;
|
||||
};
|
||||
|
||||
|
||||
class MshFile
|
||||
class MshFile : public FileInterface
|
||||
{
|
||||
public:
|
||||
MshFile(const char* path);
|
||||
~MshFile();
|
||||
|
||||
private:
|
||||
std::vector<Model*>* m_vModels;
|
||||
std::fstream m_fsMesh;
|
||||
std::vector<std::string> m_vTextureNames;
|
||||
BoundingBox m_sceneBbox;
|
||||
virtual void import() override final;
|
||||
|
||||
private:
|
||||
void loadChunks(std::list<ChunkHeader*> &destination, std::streampos start, const std::uint32_t length);
|
||||
|
||||
void analyseMsh2Chunks(std::list<ChunkHeader*> &chunkList);
|
||||
|
@ -67,9 +31,4 @@ private:
|
|||
|
||||
void readVertex(Segment* dataDestination, std::streampos position);
|
||||
void readUV(Segment* dataDestination, std::streampos position);
|
||||
|
||||
public:
|
||||
std::vector<Model*>* getModels() const;
|
||||
std::vector<std::string> getTextureNames() const;
|
||||
BoundingBox getBoundingBox() const;
|
||||
};
|
|
@ -6,7 +6,7 @@
|
|||
#include <QOpenGlShaderProgram>
|
||||
#include <QOpenGlTexture>
|
||||
#include <QImage>
|
||||
#include "..\Header\MshFile.h"
|
||||
#include "..\Header\FileInterface.h"
|
||||
|
||||
struct Vertex {
|
||||
GLfloat position[3];
|
||||
|
@ -30,8 +30,8 @@ private:
|
|||
QOpenGLShaderProgram* m_program = nullptr;
|
||||
|
||||
// Data ========================================
|
||||
std::vector<Model*>* m_vModels = nullptr;
|
||||
std::vector<QImage*> m_vTextures;
|
||||
std::vector<Model*>* m_vModels = nullptr;
|
||||
std::vector<QImage*>* m_vTextures = nullptr;
|
||||
BoundingBox m_sceneBoundings;
|
||||
|
||||
// Transformation ==============================
|
||||
|
@ -49,13 +49,13 @@ private:
|
|||
|
||||
private:
|
||||
virtual void initializeGL() override final;
|
||||
virtual void resizeGL(int w, int h) override final;
|
||||
virtual void paintGL() override final;
|
||||
|
||||
void printContextInformation();
|
||||
QMatrix4x4 getModelMatrix(unsigned int index) const;
|
||||
QMatrix4x4 getMVPMatrix(unsigned int index) const;
|
||||
void deleteData();
|
||||
|
||||
public:
|
||||
void setData(std::vector<Model*>* models, std::vector<QImage*> textures);
|
||||
void setData(std::vector<Model*>* models, std::vector<QImage*>* textures, BoundingBox bbox);
|
||||
};
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#include "..\Header\MainWindow.h"
|
||||
#include "..\Header\OpenGlViewer.h"
|
||||
#include "..\Header\MshFile.h"
|
||||
#include "..\Header\defines.h"
|
||||
#include <QKeyEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
@ -34,18 +36,85 @@ void MainWindow::setupWindow()
|
|||
|
||||
this->setCentralWidget(new OpenGlViewer(this));
|
||||
|
||||
ui->mainToolBar->addAction("Open File", this, &MainWindow::openFile);
|
||||
ui->mainToolBar->addAction("File Info", this, &MainWindow::aboutFile);
|
||||
|
||||
ui->statusBar->showMessage(DEFAULT_STATUS_MESSAGE);
|
||||
}
|
||||
|
||||
void MainWindow::import(const char * path)
|
||||
{
|
||||
try
|
||||
{
|
||||
MshFile file(path);
|
||||
|
||||
// Models
|
||||
std::vector<Model*>* tmp_models = file.getModels();
|
||||
|
||||
// Textures
|
||||
std::vector<std::string> tmp_texNames = file.getTextureNames();
|
||||
std::vector<QImage*>* tmp_textures = new std::vector<QImage*>;
|
||||
|
||||
std::string tmp_path = path;
|
||||
|
||||
while (tmp_path.back() != '/' && tmp_path.back() != '\\')
|
||||
tmp_path.pop_back();
|
||||
|
||||
for (auto& it : tmp_texNames)
|
||||
{
|
||||
QImage* tmp_image = new QImage;
|
||||
|
||||
std::string test = tmp_path + it;
|
||||
QString test2 = "D:\\workspaces\\Visual Studio 2015\\Projects\\OpenGL\\Release\\Msh\\texture32R.tga";
|
||||
|
||||
if (tmp_image->load(test2))
|
||||
tmp_textures->push_back(tmp_image);
|
||||
else
|
||||
{
|
||||
delete tmp_image;
|
||||
tmp_image = new QImage(1, 1, QImage::Format_RGB32);
|
||||
tmp_image->fill(Qt::red);
|
||||
tmp_textures->push_back(tmp_image);
|
||||
}
|
||||
}
|
||||
|
||||
// add a solid default color at the end (maybe there is an invalid index later)
|
||||
QImage* tmp_image = new QImage(1, 1, QImage::Format_RGB16);
|
||||
tmp_image->fill(Qt::red);
|
||||
tmp_textures->push_back(tmp_image);
|
||||
|
||||
tmp_texNames.clear();
|
||||
|
||||
// Bounding Box
|
||||
BoundingBox tmp_bbox = file.getBoundingBox();
|
||||
|
||||
OpenGlViewer* tmp_viewer = dynamic_cast<OpenGlViewer*>(centralWidget());
|
||||
|
||||
tmp_viewer->setData(tmp_models, tmp_textures, tmp_bbox);
|
||||
|
||||
}
|
||||
catch (std::invalid_argument e)
|
||||
{
|
||||
//TODO:
|
||||
QMessageBox msg(this);
|
||||
msg.addButton(QMessageBox::Ok);
|
||||
msg.setText(QString::fromStdString(e.what()));
|
||||
msg.setIcon(QMessageBox::Critical);
|
||||
msg.setWindowTitle("Open File Error");
|
||||
|
||||
msg.exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// private slots
|
||||
|
||||
void MainWindow::openFile()
|
||||
{
|
||||
//TODO: Open file
|
||||
QString fileName = QFileDialog::getOpenFileName(this, "Open File", "../Release/Msh", "Mesh (*.msh)");
|
||||
|
||||
import(fileName.toStdString().c_str());
|
||||
}
|
||||
|
||||
void MainWindow::aboutFile()
|
||||
|
|
|
@ -10,14 +10,21 @@
|
|||
// public constructor/destructor
|
||||
|
||||
MshFile::MshFile(const char * path)
|
||||
: m_vModels(new std::vector<Model*>)
|
||||
: FileInterface(path)
|
||||
{
|
||||
//open file
|
||||
m_fsMesh.open(path, std::ios::in | std::ios::binary);
|
||||
import();
|
||||
}
|
||||
|
||||
if (!m_fsMesh.is_open())
|
||||
throw std::invalid_argument(std::string("file not found: ") += path);
|
||||
MshFile::~MshFile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// private functions
|
||||
|
||||
void MshFile::import()
|
||||
{
|
||||
// go to file size information
|
||||
m_fsMesh.seekg(4);
|
||||
|
||||
|
@ -57,20 +64,8 @@ MshFile::MshFile(const char * path)
|
|||
tmp_mainChunks.pop_front();
|
||||
delete cur;
|
||||
}
|
||||
|
||||
// close file
|
||||
m_fsMesh.close();
|
||||
}
|
||||
|
||||
MshFile::~MshFile()
|
||||
{
|
||||
m_vTextureNames.clear();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// private functions
|
||||
|
||||
void MshFile::loadChunks(std::list<ChunkHeader*>& destination, std::streampos start, const std::uint32_t length)
|
||||
{
|
||||
// jump to first chunk
|
||||
|
@ -572,22 +567,3 @@ void MshFile::readUV(Segment * dataDestination, std::streampos position)
|
|||
for (unsigned int i = 0; i < tmp_size * 2; i++)
|
||||
m_fsMesh.read(F2V(dataDestination->uv[i]), sizeof(float));
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// public getter
|
||||
|
||||
std::vector<Model*>* MshFile::getModels() const
|
||||
{
|
||||
return m_vModels;
|
||||
}
|
||||
|
||||
std::vector<std::string> MshFile::getTextureNames() const
|
||||
{
|
||||
return m_vTextureNames;
|
||||
}
|
||||
|
||||
BoundingBox MshFile::getBoundingBox() const
|
||||
{
|
||||
return m_sceneBbox;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "..\Header\OpenGlViewer.h"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
@ -104,11 +106,6 @@ void OpenGlViewer::initializeGL()
|
|||
|
||||
}
|
||||
|
||||
void OpenGlViewer::resizeGL(int w, int h)
|
||||
{
|
||||
//TODO: change perspective
|
||||
}
|
||||
|
||||
void OpenGlViewer::paintGL()
|
||||
{
|
||||
//TODO: paint here
|
||||
|
@ -134,8 +131,8 @@ void OpenGlViewer::paintGL()
|
|||
for (auto& segmentIterator : m_vModels->at(modelIndex)->segmList)
|
||||
{
|
||||
// set the texture
|
||||
std::uint32_t tmp_textureIndex = segmentIterator->textureIndex >= m_vTextures.size() ? m_vTextures.size() - 1 : segmentIterator->textureIndex;
|
||||
m_oglTexture->setData(*m_vTextures.at(tmp_textureIndex));
|
||||
std::uint32_t tmp_textureIndex = segmentIterator->textureIndex >= m_vTextures->size() ? m_vTextures->size() - 1 : segmentIterator->textureIndex;
|
||||
m_oglTexture->setData(*m_vTextures->at(tmp_textureIndex));
|
||||
|
||||
// give the MVP to the shader
|
||||
m_program->setUniformValue(m_uniformMVP, getMVPMatrix(modelIndex));
|
||||
|
@ -152,7 +149,7 @@ void OpenGlViewer::paintGL()
|
|||
}
|
||||
}
|
||||
}
|
||||
//glDrawArrays(GL_TRIANGLES, 0, sizeof(sg_vertexes) / sizeof(sg_vertexes[0]));
|
||||
|
||||
m_oglTexture->release();
|
||||
m_vertexArray.release();
|
||||
m_program->release();
|
||||
|
@ -179,14 +176,50 @@ void OpenGlViewer::printContextInformation()
|
|||
std::cout << glType.toStdString() << " - " << glVersion.toStdString() << " (" << glProfile.toStdString() << ")";
|
||||
}
|
||||
|
||||
QMatrix4x4 OpenGlViewer::getModelMatrix(unsigned int index) const
|
||||
{
|
||||
QMatrix4x4 tmp_parent;
|
||||
|
||||
for (unsigned int loop = 0; loop < m_vModels->size(); loop++)
|
||||
{
|
||||
if (!strcmp(m_vModels->at(index)->parent.c_str(), m_vModels->at(loop)->name.c_str()))
|
||||
{
|
||||
tmp_parent = getModelMatrix(loop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tmp_parent * m_vModels->at(index)->m4x4Translation;
|
||||
}
|
||||
|
||||
QMatrix4x4 OpenGlViewer::getMVPMatrix(unsigned int index) const
|
||||
{
|
||||
return QMatrix4x4();
|
||||
QMatrix4x4 tmp_mvp;
|
||||
|
||||
// projection
|
||||
tmp_mvp.perspective(m_fFOV, float(QWidget::width()) / float(QWidget::height()), m_fMinView, m_fMaxView);
|
||||
|
||||
// view
|
||||
tmp_mvp.lookAt(QVector3D(m_fTranX, m_fTranY, m_fTranZ), QVector3D(m_fTranX, m_fTranY, m_fTranZ - 1), QVector3D(0, 0, 1));
|
||||
|
||||
// user controlled rotation
|
||||
tmp_mvp.rotate(m_fRotX, QVector3D(1, 0, 0));
|
||||
tmp_mvp.rotate(m_fRotY, QVector3D(0, 1, 0));
|
||||
tmp_mvp.rotate(m_fRotZ, QVector3D(0, 0, 1));
|
||||
|
||||
//scale to 1
|
||||
float maxExtent = std::max(std::max(m_sceneBoundings.extents[0], m_sceneBoundings.extents[1]), m_sceneBoundings.extents[2]);
|
||||
tmp_mvp.scale(1 / maxExtent);
|
||||
|
||||
// move to center
|
||||
tmp_mvp.translate(-m_sceneBoundings.center[0], -m_sceneBoundings.center[1], -m_sceneBoundings.center[2]);
|
||||
|
||||
return tmp_mvp * getModelMatrix(index);
|
||||
}
|
||||
|
||||
void OpenGlViewer::deleteData()
|
||||
{
|
||||
if (m_vModels != NULL)
|
||||
if (m_vModels != nullptr)
|
||||
{
|
||||
while (!m_vModels->empty())
|
||||
{
|
||||
|
@ -223,17 +256,19 @@ void OpenGlViewer::deleteData()
|
|||
delete m_vModels;
|
||||
}
|
||||
|
||||
while (!m_vTextures.empty())
|
||||
if (m_vTextures != nullptr)
|
||||
{
|
||||
// remove the last texture
|
||||
QImage* cursor = m_vTextures.back();
|
||||
m_vTextures.pop_back();
|
||||
while (!m_vTextures->empty())
|
||||
{
|
||||
// remove the last texture
|
||||
QImage* cursor = m_vTextures->back();
|
||||
m_vTextures->pop_back();
|
||||
|
||||
//delete image
|
||||
delete cursor;
|
||||
|
||||
//delete the texture
|
||||
delete cursor;
|
||||
//delete image
|
||||
delete cursor;
|
||||
}
|
||||
// delete the Textrue's Vector
|
||||
delete m_vTextures;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,9 +276,73 @@ void OpenGlViewer::deleteData()
|
|||
/////////////////////////////////////////////////////////////////////////
|
||||
// public functions
|
||||
|
||||
void OpenGlViewer::setData(std::vector<Model*>* models, std::vector<QImage*> textures)
|
||||
void OpenGlViewer::setData(std::vector<Model*>* models, std::vector<QImage*>* textures, BoundingBox bbox)
|
||||
{
|
||||
// new Data, so clean up the old things
|
||||
deleteData();
|
||||
|
||||
// save the variables
|
||||
m_vModels = models;
|
||||
m_vTextures = textures;
|
||||
}
|
||||
m_sceneBoundings = bbox;
|
||||
|
||||
// collect vertex data of all models
|
||||
std::vector<Vertex> tmp_bufferData;
|
||||
|
||||
for (auto& modIt : *m_vModels) // for every model chunk
|
||||
{
|
||||
for (auto& segIt : modIt->segmList) // for every cluster
|
||||
{
|
||||
for (auto& mshIt : segIt->polyIndices) // for every polygon
|
||||
{
|
||||
if (mshIt.size() >= 3) // multipoly
|
||||
{
|
||||
// for every triangle of the multi polygon
|
||||
for (unsigned int tri = 0; tri < mshIt.size() - 2; tri++)
|
||||
{
|
||||
// for every edge of the triangle
|
||||
for (int triEdge = 0; triEdge < 3; triEdge++)
|
||||
{
|
||||
Vertex tempVertex;
|
||||
// every edge has 3 coordinates
|
||||
for (int j = 0; j < 3; j++)
|
||||
tempVertex.position[j] = (GLfloat)segIt->vertex[mshIt[tri + triEdge - ((tri % 2) * (triEdge - 1) * 2)] * 3 + j];
|
||||
|
||||
// and 2 UV
|
||||
if (segIt->uv == NULL)
|
||||
{
|
||||
tempVertex.uv[0] = 1.0;
|
||||
tempVertex.uv[1] = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
tempVertex.uv[j] = (GLfloat)segIt->uv[mshIt[tri + triEdge - ((tri % 2) * (triEdge - 1) * 2)] * 2 + j];
|
||||
}
|
||||
tmp_bufferData.push_back(tempVertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // this shouldn't happen (polygon with less then 3 vertex)
|
||||
{
|
||||
deleteData();
|
||||
|
||||
QMessageBox msg(this);
|
||||
msg.addButton(QMessageBox::Ok);
|
||||
msg.setText("You have polygons with less then 3 vertices!");
|
||||
msg.setIcon(QMessageBox::Critical);
|
||||
msg.setWindowTitle("Open File Error");
|
||||
msg.exec();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_vertexBuffer.bind();
|
||||
m_vertexBuffer.allocate(tmp_bufferData.data(), sizeof(Vertex) * tmp_bufferData.size());
|
||||
m_vertexBuffer.release();
|
||||
|
||||
tmp_bufferData.clear();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue