still trying to fix the problem

This commit is contained in:
Anakin 2016-12-14 17:20:20 +01:00
parent 96379a9afb
commit b6ef34f988
7 changed files with 255 additions and 84 deletions

View File

@ -4,8 +4,7 @@
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QOPenGLVertexArrayObject> #include <QOPenGLVertexArrayObject>
#include <QOpenGlShaderProgram> #include <QOpenGlShaderProgram>
#include <QOpenGlTexture> #include "..\Header\Texture.h"
#include <QImage>
#include "..\Header\FileInterface.h" #include "..\Header\FileInterface.h"
struct Vertex { struct Vertex {
@ -13,6 +12,13 @@ struct Vertex {
GLfloat uv[2]; GLfloat uv[2];
}; };
struct TextureData {
bool alpha;
std::uint32_t width;
std::uint32_t height;
std::vector<std::uint8_t>* data;
};
class OpenGlViewer : public QOpenGLWidget, protected QOpenGLFunctions class OpenGlViewer : public QOpenGLWidget, protected QOpenGLFunctions
{ {
Q_OBJECT Q_OBJECT
@ -24,14 +30,14 @@ public:
private: private:
// OpenGL ====================================== // OpenGL ======================================
int m_uniformMVP; int m_uniformMVP;
QOpenGLTexture* m_oglTexture; GLuint m_oglTexture;
QOpenGLBuffer m_vertexBuffer; GLuint m_vertexBuffer;
QOpenGLVertexArrayObject m_vertexArray; QOpenGLVertexArrayObject m_vertexArray;
QOpenGLShaderProgram* m_program = nullptr; QOpenGLShaderProgram* m_program = nullptr;
// Data ======================================== // Data ========================================
std::vector<Model*>* m_vModels = nullptr; std::vector<Model*>* m_vModels = nullptr;
std::vector<QImage*>* m_vTextures = nullptr; std::vector<TextureData*>* m_vTextures = nullptr;
BoundingBox m_sceneBoundings; BoundingBox m_sceneBoundings;
// Transformation ============================== // Transformation ==============================
@ -57,5 +63,5 @@ private:
void deleteData(); void deleteData();
public: public:
void setData(std::vector<Model*>* models, std::vector<QImage*>* textures, BoundingBox bbox); void setData(std::vector<Model*>* models, std::vector<TextureData*>* textures, BoundingBox bbox);
}; };

View File

@ -0,0 +1,22 @@
#pragma once
#include <vector>
class TextureTGA
{
public:
TextureTGA(const char* filePath);
~TextureTGA();
private:
std::vector<std::uint8_t>* vui8Pixels;
std::uint32_t ui32BpP;
std::uint32_t ui32Width;
std::uint32_t ui32Height;
public:
std::vector<std::uint8_t>* getData() const;
bool hasAlpha() const;
std::uint32_t getWidth() const;
std::uint32_t getHeight() const;
};

View File

@ -1,4 +1,4 @@
#version 450 #version 330
// Input // Input
in vec2 UV; in vec2 UV;
@ -8,5 +8,5 @@ out vec4 color;
void main() void main()
{ {
color = texture(textureSampler, UV).rgb; color = {255,0,0};//texture(textureSampler, UV).rgb;
} }

View File

@ -1,4 +1,4 @@
#version 450 #version 330
// Input vertex data, different for all executions of this shader // Input vertex data, different for all executions of this shader
layout(location = 0) in vec3 vertexPosition; layout(location = 0) in vec3 vertexPosition;

View File

@ -44,58 +44,22 @@ void MainWindow::setupWindow()
void MainWindow::import(const char * path) void MainWindow::import(const char * path)
{ {
// variables
std::vector<Model*>* tmp_models = nullptr;
std::vector<TextureData*>* tmp_textures = new std::vector<TextureData*>;
std::vector<std::string> tmp_texNames;
BoundingBox tmp_bbox;
// model file
try try
{ {
MshFile file(path); MshFile file(path);
tmp_models = file.getModels();
// Models tmp_texNames = file.getTextureNames();
std::vector<Model*>* tmp_models = file.getModels(); tmp_bbox = file.getBoundingBox();
// 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) catch (std::invalid_argument e)
{ {
//TODO:
QMessageBox msg(this); QMessageBox msg(this);
msg.addButton(QMessageBox::Ok); msg.addButton(QMessageBox::Ok);
msg.setText(QString::fromStdString(e.what())); msg.setText(QString::fromStdString(e.what()));
@ -103,7 +67,52 @@ void MainWindow::import(const char * path)
msg.setWindowTitle("Open File Error"); msg.setWindowTitle("Open File Error");
msg.exec(); msg.exec();
return;
} }
// parth to texture
std::string tmp_path = path;
while (tmp_path.back() != '/' && tmp_path.back() != '\\')
tmp_path.pop_back();
// load all textures
for (auto& texIt : tmp_texNames)
{
TextureData* new_data = new TextureData;
try
{
TextureTGA tmp_texFile(std::string(tmp_path + texIt).c_str());
new_data->alpha = tmp_texFile.hasAlpha();
new_data->width = tmp_texFile.getWidth();
new_data->height = tmp_texFile.getHeight();
new_data->data = tmp_texFile.getData();
}
catch (std::invalid_argument e)
{
new_data->alpha = true;
new_data->width = 1;
new_data->height = 1;
new_data->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 });
}
tmp_textures->push_back(new_data);
}
// add a solid default color at the end (maybe there is an invalid index later)
TextureData* new_data = new TextureData;
new_data->alpha = true;
new_data->width = 1;
new_data->height = 1;
new_data->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 });
tmp_textures->push_back(new_data);
// clean up texture name list
tmp_texNames.clear();
// give the data to the viewer
OpenGlViewer* tmp_viewer = dynamic_cast<OpenGlViewer*>(centralWidget());
tmp_viewer->setData(tmp_models, tmp_textures, tmp_bbox);
} }

View File

@ -35,7 +35,7 @@ OpenGlViewer::OpenGlViewer(QWidget *parent)
QSurfaceFormat format; QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGL); format.setRenderableType(QSurfaceFormat::OpenGL);
format.setSamples(4); format.setSamples(4);
format.setProfile(QSurfaceFormat::CompatibilityProfile); format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION); format.setVersion(DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
setFormat(format); setFormat(format);
@ -44,9 +44,9 @@ OpenGlViewer::OpenGlViewer(QWidget *parent)
OpenGlViewer::~OpenGlViewer() OpenGlViewer::~OpenGlViewer()
{ {
m_oglTexture->destroy(); glDeleteTextures(1, &m_oglTexture);
glDeleteBuffers(1, &m_vertexBuffer);
m_vertexArray.destroy(); m_vertexArray.destroy();
m_vertexBuffer.destroy();
delete m_program; delete m_program;
deleteData(); deleteData();
@ -70,10 +70,12 @@ void OpenGlViewer::initializeGL()
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
// Create texture // Create texture
m_oglTexture = new QOpenGLTexture(QOpenGLTexture::Target2D); glGenTextures(1, &m_oglTexture);
m_oglTexture->setWrapMode(QOpenGLTexture::Repeat); glBindTexture(GL_TEXTURE_2D, m_oglTexture);
m_oglTexture->setMagnificationFilter(QOpenGLTexture::Linear); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
m_oglTexture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
// Create Shader // Create Shader
m_program = new QOpenGLShaderProgram(); m_program = new QOpenGLShaderProgram();
@ -87,9 +89,8 @@ void OpenGlViewer::initializeGL()
m_uniformMVP = m_program->uniformLocation("MVP"); m_uniformMVP = m_program->uniformLocation("MVP");
// Create Vertex Buffer // Create Vertex Buffer
m_vertexBuffer.create(); glGenBuffers(1, &m_vertexBuffer);
m_vertexBuffer.bind(); glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
m_vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
// Create Vertex Array Object // Create Vertex Array Object
m_vertexArray.create(); m_vertexArray.create();
@ -101,7 +102,7 @@ void OpenGlViewer::initializeGL()
// unbind everything // unbind everything
m_vertexArray.release(); m_vertexArray.release();
m_vertexBuffer.release(); glBindBuffer(GL_ARRAY_BUFFER, 0);
m_program->release(); m_program->release();
} }
@ -112,8 +113,11 @@ void OpenGlViewer::paintGL()
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
m_program->bind(); m_program->bind();
m_vertexArray.bind();
m_oglTexture->bind(); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_oglTexture);
m_program->setUniformValue("textureSampler", 0);
if (m_vModels != nullptr) if (m_vModels != nullptr)
{ {
@ -133,15 +137,19 @@ void OpenGlViewer::paintGL()
// set the texture // set the texture
std::uint32_t tmp_textureIndex = segmentIterator->textureIndex >= m_vTextures->size() ? m_vTextures->size() - 1 : segmentIterator->textureIndex; std::uint32_t tmp_textureIndex = segmentIterator->textureIndex >= m_vTextures->size() ? m_vTextures->size() - 1 : segmentIterator->textureIndex;
if (m_oglTexture->isCreated()) glTexImage2D(
{ GL_TEXTURE_2D,
m_oglTexture->destroy(); 0,
m_oglTexture->create(); m_vTextures->at(tmp_textureIndex)->alpha ? GL_RGBA : GL_RGB,
m_oglTexture->setSize(m_vTextures->at(tmp_textureIndex)->width(), m_vTextures->at(tmp_textureIndex)->height()); m_vTextures->at(tmp_textureIndex)->width,
m_oglTexture->setData(*m_vTextures->at(tmp_textureIndex)); m_vTextures->at(tmp_textureIndex)->height,
} 0,
m_vTextures->at(tmp_textureIndex)->alpha ? GL_BGRA : GL_BGR,
GL_UNSIGNED_BYTE,
m_vTextures->at(tmp_textureIndex)->data->data()
);
glGenerateMipmap(GL_TEXTURE_2D);
// give the MVP to the shader // give the MVP to the shader
m_program->setUniformValue(m_uniformMVP, getMVPMatrix(modelIndex)); m_program->setUniformValue(m_uniformMVP, getMVPMatrix(modelIndex));
@ -159,9 +167,9 @@ void OpenGlViewer::paintGL()
} }
} }
m_oglTexture->release();
m_vertexArray.release();
m_program->release(); m_program->release();
this->frameSwapped();
} }
void OpenGlViewer::printContextInformation() void OpenGlViewer::printContextInformation()
@ -270,9 +278,12 @@ void OpenGlViewer::deleteData()
while (!m_vTextures->empty()) while (!m_vTextures->empty())
{ {
// remove the last texture // remove the last texture
QImage* cursor = m_vTextures->back(); TextureData* cursor = m_vTextures->back();
m_vTextures->pop_back(); m_vTextures->pop_back();
cursor->data->clear();
delete cursor->data;
//delete image //delete image
delete cursor; delete cursor;
} }
@ -285,7 +296,7 @@ void OpenGlViewer::deleteData()
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// public functions // public functions
void OpenGlViewer::setData(std::vector<Model*>* models, std::vector<QImage*>* textures, BoundingBox bbox) void OpenGlViewer::setData(std::vector<Model*>* models, std::vector<TextureData*>* textures, BoundingBox bbox)
{ {
// new Data, so clean up the old things // new Data, so clean up the old things
deleteData(); deleteData();
@ -348,10 +359,14 @@ void OpenGlViewer::setData(std::vector<Model*>* models, std::vector<QImage*>* te
} }
} }
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
m_vertexBuffer.bind(); glBufferData(
m_vertexBuffer.allocate(tmp_bufferData.data(), sizeof(Vertex) * tmp_bufferData.size()); GL_ARRAY_BUFFER,
m_vertexBuffer.release(); sizeof(Vertex) * tmp_bufferData.size(),
tmp_bufferData.data(),
GL_STATIC_DRAW
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
tmp_bufferData.clear(); tmp_bufferData.clear();
} }

View File

@ -0,0 +1,119 @@
#include "Texture.h"
#include <fstream>
TextureTGA::TextureTGA(const char * filePath)
{
// open the file
std::fstream fsPicture(filePath, std::ios::in | std::ios::binary);
if (!fsPicture.is_open())
throw std::invalid_argument(std::string("file not found: ") += filePath);
// read in the header
std::uint8_t ui8x18Header[19] = { 0 };
fsPicture.read(reinterpret_cast<char*>(&ui8x18Header), sizeof(ui8x18Header)-1);
//get variables
vui8Pixels = new std::vector<std::uint8_t>;
bool bCompressed;
std::uint32_t ui32IDLength;
std::uint32_t ui32PicType;
std::uint32_t ui32PaletteLength;
std::uint32_t ui32Size;
// extract all information from header
ui32IDLength = ui8x18Header[0];
ui32PicType = ui8x18Header[2];
ui32PaletteLength = ui8x18Header[6] * 0x100 + ui8x18Header[5];
ui32Width = ui8x18Header[13] * 0x100 + ui8x18Header[12];
ui32Height = ui8x18Header[15] * 0x100 + ui8x18Header[14];
ui32BpP = ui8x18Header[16];
// calculate some more information
ui32Size = ui32Width * ui32Height * ui32BpP/8;
bCompressed = ui32PicType == 9 || ui32PicType == 10;
vui8Pixels->resize(ui32Size);
// jump to the data block
fsPicture.seekg(ui32IDLength + ui32PaletteLength, std::ios_base::cur);
// If not compressed 24 or 32 bit
if (ui32PicType == 2 && (ui32BpP == 24 || ui32BpP == 32))
{
fsPicture.read(reinterpret_cast<char*>(vui8Pixels->data()), ui32Size);
}
// else if compressed 24 or 32 bit
else if (ui32PicType == 10 && (ui32BpP == 24 || ui32BpP == 32)) // compressed
{
std::uint8_t tempChunkHeader;
std::uint8_t tempData[5];
unsigned int tempByteIndex = 0;
do {
fsPicture.read(reinterpret_cast<char*>(&tempChunkHeader), sizeof(tempChunkHeader));
if (tempChunkHeader >> 7) // repeat count
{
// just use the first 7 bits
tempChunkHeader = (uint8_t(tempChunkHeader << 1) >> 1);
fsPicture.read(reinterpret_cast<char*>(&tempData), ui32BpP/8);
for (int i = 0; i <= tempChunkHeader; i++)
{
vui8Pixels->at(tempByteIndex++) = tempData[0];
vui8Pixels->at(tempByteIndex++) = tempData[1];
vui8Pixels->at(tempByteIndex++) = tempData[2];
if(ui32BpP == 32) vui8Pixels->at(tempByteIndex++) = tempData[3];
}
}
else // data count
{
// just use the first 7 bits
tempChunkHeader = (uint8_t(tempChunkHeader << 1) >> 1);
for (int i = 0; i <= tempChunkHeader; i++)
{
fsPicture.read(reinterpret_cast<char*>(&tempData), ui32BpP/8);
vui8Pixels->at(tempByteIndex++) = tempData[0];
vui8Pixels->at(tempByteIndex++) = tempData[1];
vui8Pixels->at(tempByteIndex++) = tempData[2];
if (ui32BpP == 32) vui8Pixels->at(tempByteIndex++) = tempData[3];
}
}
} while (tempByteIndex < ui32Size);
}
// not useable format
else
{
fsPicture.close();
throw std::invalid_argument("Invaild File Format! Required 24 or 31 Bit Image.");
}
fsPicture.close();
}
TextureTGA::~TextureTGA()
{
}
std::vector<std::uint8_t>* TextureTGA::getData() const
{
return vui8Pixels;
}
bool TextureTGA::hasAlpha() const
{
return ui32BpP == 32;
}
std::uint32_t TextureTGA::getWidth() const
{
return ui32Width;
}
std::uint32_t TextureTGA::getHeight() const
{
return ui32Height;
}