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 <QOPenGLVertexArrayObject>
#include <QOpenGlShaderProgram>
#include <QOpenGlTexture>
#include <QImage>
#include "..\Header\Texture.h"
#include "..\Header\FileInterface.h"
struct Vertex {
@ -13,6 +12,13 @@ struct Vertex {
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
{
Q_OBJECT
@ -24,14 +30,14 @@ public:
private:
// OpenGL ======================================
int m_uniformMVP;
QOpenGLTexture* m_oglTexture;
QOpenGLBuffer m_vertexBuffer;
GLuint m_oglTexture;
GLuint m_vertexBuffer;
QOpenGLVertexArrayObject m_vertexArray;
QOpenGLShaderProgram* m_program = nullptr;
// Data ========================================
std::vector<Model*>* m_vModels = nullptr;
std::vector<QImage*>* m_vTextures = nullptr;
std::vector<TextureData*>* m_vTextures = nullptr;
BoundingBox m_sceneBoundings;
// Transformation ==============================
@ -57,5 +63,5 @@ private:
void deleteData();
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
in vec2 UV;
@ -8,5 +8,5 @@ out vec4 color;
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
layout(location = 0) in vec3 vertexPosition;

View File

@ -44,58 +44,22 @@ void MainWindow::setupWindow()
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
{
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);
tmp_models = file.getModels();
tmp_texNames = file.getTextureNames();
tmp_bbox = file.getBoundingBox();
}
catch (std::invalid_argument e)
{
//TODO:
QMessageBox msg(this);
msg.addButton(QMessageBox::Ok);
msg.setText(QString::fromStdString(e.what()));
@ -103,7 +67,52 @@ void MainWindow::import(const char * path)
msg.setWindowTitle("Open File Error");
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;
format.setRenderableType(QSurfaceFormat::OpenGL);
format.setSamples(4);
format.setProfile(QSurfaceFormat::CompatibilityProfile);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
setFormat(format);
@ -44,9 +44,9 @@ OpenGlViewer::OpenGlViewer(QWidget *parent)
OpenGlViewer::~OpenGlViewer()
{
m_oglTexture->destroy();
glDeleteTextures(1, &m_oglTexture);
glDeleteBuffers(1, &m_vertexBuffer);
m_vertexArray.destroy();
m_vertexBuffer.destroy();
delete m_program;
deleteData();
@ -70,10 +70,12 @@ void OpenGlViewer::initializeGL()
glEnable(GL_CULL_FACE);
// Create texture
m_oglTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
m_oglTexture->setWrapMode(QOpenGLTexture::Repeat);
m_oglTexture->setMagnificationFilter(QOpenGLTexture::Linear);
m_oglTexture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
glGenTextures(1, &m_oglTexture);
glBindTexture(GL_TEXTURE_2D, m_oglTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
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
m_program = new QOpenGLShaderProgram();
@ -87,9 +89,8 @@ void OpenGlViewer::initializeGL()
m_uniformMVP = m_program->uniformLocation("MVP");
// Create Vertex Buffer
m_vertexBuffer.create();
m_vertexBuffer.bind();
m_vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
// Create Vertex Array Object
m_vertexArray.create();
@ -101,7 +102,7 @@ void OpenGlViewer::initializeGL()
// unbind everything
m_vertexArray.release();
m_vertexBuffer.release();
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_program->release();
}
@ -112,8 +113,11 @@ void OpenGlViewer::paintGL()
glClear(GL_COLOR_BUFFER_BIT);
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)
{
@ -133,15 +137,19 @@ void OpenGlViewer::paintGL()
// set the texture
std::uint32_t tmp_textureIndex = segmentIterator->textureIndex >= m_vTextures->size() ? m_vTextures->size() - 1 : segmentIterator->textureIndex;
if (m_oglTexture->isCreated())
{
m_oglTexture->destroy();
m_oglTexture->create();
m_oglTexture->setSize(m_vTextures->at(tmp_textureIndex)->width(), m_vTextures->at(tmp_textureIndex)->height());
m_oglTexture->setData(*m_vTextures->at(tmp_textureIndex));
}
glTexImage2D(
GL_TEXTURE_2D,
0,
m_vTextures->at(tmp_textureIndex)->alpha ? GL_RGBA : GL_RGB,
m_vTextures->at(tmp_textureIndex)->width,
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
m_program->setUniformValue(m_uniformMVP, getMVPMatrix(modelIndex));
@ -159,9 +167,9 @@ void OpenGlViewer::paintGL()
}
}
m_oglTexture->release();
m_vertexArray.release();
m_program->release();
this->frameSwapped();
}
void OpenGlViewer::printContextInformation()
@ -270,9 +278,12 @@ void OpenGlViewer::deleteData()
while (!m_vTextures->empty())
{
// remove the last texture
QImage* cursor = m_vTextures->back();
TextureData* cursor = m_vTextures->back();
m_vTextures->pop_back();
cursor->data->clear();
delete cursor->data;
//delete image
delete cursor;
}
@ -285,7 +296,7 @@ void OpenGlViewer::deleteData()
/////////////////////////////////////////////////////////////////////////
// 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
deleteData();
@ -348,10 +359,14 @@ void OpenGlViewer::setData(std::vector<Model*>* models, std::vector<QImage*>* te
}
}
m_vertexBuffer.bind();
m_vertexBuffer.allocate(tmp_bufferData.data(), sizeof(Vertex) * tmp_bufferData.size());
m_vertexBuffer.release();
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(Vertex) * tmp_bufferData.size(),
tmp_bufferData.data(),
GL_STATIC_DRAW
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
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;
}