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:
Anakin 2016-12-12 16:47:38 +01:00
parent 1cc4f1ca90
commit 481256e8ea
7 changed files with 283 additions and 107 deletions

View File

@ -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; };
};

View File

@ -18,6 +18,7 @@ private:
// Functions
private:
void setupWindow();
void import(const char* path);
// Slots
private slots:

View File

@ -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;
};

View File

@ -6,7 +6,7 @@
#include <QOpenGlShaderProgram>
#include <QOpenGlTexture>
#include <QImage>
#include "..\Header\MshFile.h"
#include "..\Header\FileInterface.h"
struct Vertex {
GLfloat position[3];
@ -31,7 +31,7 @@ private:
// Data ========================================
std::vector<Model*>* m_vModels = nullptr;
std::vector<QImage*> m_vTextures;
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);
};

View File

@ -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()

View File

@ -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;
}

View File

@ -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)
{
while (!m_vTextures->empty())
{
// remove the last texture
QImage* cursor = m_vTextures.back();
m_vTextures.pop_back();
QImage* cursor = m_vTextures->back();
m_vTextures->pop_back();
//delete image
delete cursor;
//delete the texture
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();
}