still trying to fix the problem
This commit is contained in:
parent
96379a9afb
commit
b6ef34f988
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#version 450
|
||||
#version 330
|
||||
|
||||
// Input vertex data, different for all executions of this shader
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue