|
|
|
@ -9,7 +9,7 @@
|
|
|
|
|
#include <GL/glu.h>
|
|
|
|
|
|
|
|
|
|
// Header files, DevIL.
|
|
|
|
|
#include <IL/il.h>
|
|
|
|
|
#include <il.h>
|
|
|
|
|
|
|
|
|
|
// Header files, Assimp.
|
|
|
|
|
#include <assimp/DefaultLogger.hpp>
|
|
|
|
@ -56,15 +56,15 @@ void CGLView::SHelper_Camera::SetDefault()
|
|
|
|
|
|
|
|
|
|
void CGLView::Material_Apply(const aiMaterial* pMaterial)
|
|
|
|
|
{
|
|
|
|
|
GLfloat tcol[4];
|
|
|
|
|
aiColor4D taicol;
|
|
|
|
|
unsigned int max;
|
|
|
|
|
int ret1, ret2;
|
|
|
|
|
int texture_index = 0;
|
|
|
|
|
aiString texture_path;
|
|
|
|
|
GLfloat tcol[4];
|
|
|
|
|
aiColor4D taicol;
|
|
|
|
|
unsigned int max;
|
|
|
|
|
int ret1, ret2;
|
|
|
|
|
int texture_index = 0;
|
|
|
|
|
aiString texture_path;
|
|
|
|
|
|
|
|
|
|
auto set_float4 = [](float f[4], float a, float b, float c, float d) { f[0] = a, f[1] = b, f[2] = c, f[3] = d; };
|
|
|
|
|
auto color4_to_float4 = [](const aiColor4D *c, float f[4]) { f[0] = c->r, f[1] = c->g, f[2] = c->b, f[3] = c->a; };
|
|
|
|
|
auto set_float4 = [](float f[4], float a, float b, float c, float d) { f[0] = a, f[1] = b, f[2] = c, f[3] = d; };
|
|
|
|
|
auto color4_to_float4 = [](const aiColor4D *c, float f[4]) { f[0] = c->r, f[1] = c->g, f[2] = c->b, f[3] = c->a; };
|
|
|
|
|
|
|
|
|
|
///TODO: cache materials
|
|
|
|
|
// Disable color material because glMaterial is used.
|
|
|
|
@ -158,124 +158,127 @@ std::list<aiMatrix4x4> mat_list;
|
|
|
|
|
} while(node_cur != nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// multiplicate all matrices in reverse order
|
|
|
|
|
for(std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); rit++) pOutMatrix = pOutMatrix * (*rit);
|
|
|
|
|
// multiply all matrices in reverse order
|
|
|
|
|
for ( std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); rit++)
|
|
|
|
|
{
|
|
|
|
|
pOutMatrix = pOutMatrix * (*rit);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CGLView::ImportTextures(const QString& pScenePath)
|
|
|
|
|
{
|
|
|
|
|
auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation.
|
|
|
|
|
{
|
|
|
|
|
ILboolean success;
|
|
|
|
|
GLuint id_ogl_texture;// OpenGL texture ID.
|
|
|
|
|
auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation.
|
|
|
|
|
{
|
|
|
|
|
ILboolean success;
|
|
|
|
|
GLuint id_ogl_texture;// OpenGL texture ID.
|
|
|
|
|
|
|
|
|
|
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
|
|
|
|
|
{
|
|
|
|
|
ILuint id_image;// DevIL image ID.
|
|
|
|
|
QString basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
|
|
|
|
|
QString fileloc = (basepath + pFileName);
|
|
|
|
|
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
|
|
|
|
|
{
|
|
|
|
|
ILuint id_image;// DevIL image ID.
|
|
|
|
|
QString basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
|
|
|
|
|
QString fileloc = (basepath + pFileName);
|
|
|
|
|
|
|
|
|
|
fileloc.replace('\\', "/");
|
|
|
|
|
ilGenImages(1, &id_image);// Generate DevIL image ID.
|
|
|
|
|
ilBindImage(id_image);
|
|
|
|
|
success = ilLoadImage(fileloc.toLocal8Bit());
|
|
|
|
|
if(!success)
|
|
|
|
|
{
|
|
|
|
|
LogError(QString("Couldn't load Image: %1").arg(fileloc));
|
|
|
|
|
fileloc.replace('\\', "/");
|
|
|
|
|
ilGenImages(1, &id_image);// Generate DevIL image ID.
|
|
|
|
|
ilBindImage(id_image);
|
|
|
|
|
success = ilLoadImage(fileloc.toLocal8Bit());
|
|
|
|
|
if(!success)
|
|
|
|
|
{
|
|
|
|
|
LogError(QString("Couldn't load Image: %1").arg(fileloc));
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA.
|
|
|
|
|
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
|
|
|
|
|
if(!success)
|
|
|
|
|
{
|
|
|
|
|
LogError("Couldn't convert image.");
|
|
|
|
|
// Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA.
|
|
|
|
|
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
|
|
|
|
|
if(!success)
|
|
|
|
|
{
|
|
|
|
|
LogError("Couldn't convert image.");
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glGenTextures(1, &id_ogl_texture);// Texture ID generation.
|
|
|
|
|
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
|
|
|
|
|
// Redefine standard texture values
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0,
|
|
|
|
|
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
|
|
|
|
|
glGenTextures(1, &id_ogl_texture);// Texture ID generation.
|
|
|
|
|
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
|
|
|
|
|
// Redefine standard texture values
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0,
|
|
|
|
|
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
|
|
|
|
|
|
|
|
|
|
//Cleanup
|
|
|
|
|
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
struct SPixel_Description
|
|
|
|
|
{
|
|
|
|
|
const char* FormatHint;
|
|
|
|
|
const GLint Image_InternalFormat;
|
|
|
|
|
const GLint Pixel_Format;
|
|
|
|
|
};
|
|
|
|
|
//Cleanup
|
|
|
|
|
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
struct SPixel_Description
|
|
|
|
|
{
|
|
|
|
|
const char* FormatHint;
|
|
|
|
|
const GLint Image_InternalFormat;
|
|
|
|
|
const GLint Pixel_Format;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr SPixel_Description Pixel_Description[] = {
|
|
|
|
|
{"rgba8880", GL_RGB, GL_RGB},
|
|
|
|
|
{"rgba8888", GL_RGBA, GL_RGBA}
|
|
|
|
|
};
|
|
|
|
|
constexpr SPixel_Description Pixel_Description[] = {
|
|
|
|
|
{"rgba8880", GL_RGB, GL_RGB},
|
|
|
|
|
{"rgba8888", GL_RGBA, GL_RGBA}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr size_t Pixel_Description_Count = sizeof(Pixel_Description) / sizeof(SPixel_Description);
|
|
|
|
|
constexpr size_t Pixel_Description_Count = sizeof(Pixel_Description) / sizeof(SPixel_Description);
|
|
|
|
|
|
|
|
|
|
size_t idx_description;
|
|
|
|
|
// Get texture index.
|
|
|
|
|
bool ok;
|
|
|
|
|
size_t idx_texture = pFileName.right(strlen(AI_EMBEDDED_TEXNAME_PREFIX)).toULong(&ok);
|
|
|
|
|
size_t idx_description;
|
|
|
|
|
// Get texture index.
|
|
|
|
|
bool ok;
|
|
|
|
|
size_t idx_texture = pFileName.right(strlen(AI_EMBEDDED_TEXNAME_PREFIX)).toULong(&ok);
|
|
|
|
|
|
|
|
|
|
if(!ok)
|
|
|
|
|
{
|
|
|
|
|
LogError("Can not get index of the embedded texture from path in material.");
|
|
|
|
|
if(!ok)
|
|
|
|
|
{
|
|
|
|
|
LogError("Can not get index of the embedded texture from path in material.");
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create alias for conveniance.
|
|
|
|
|
const aiTexture& als = *mScene->mTextures[idx_texture];
|
|
|
|
|
// Create alias for conveniance.
|
|
|
|
|
const aiTexture& als = *mScene->mTextures[idx_texture];
|
|
|
|
|
|
|
|
|
|
if(als.mHeight == 0)// Compressed texture.
|
|
|
|
|
{
|
|
|
|
|
LogError("IME: compressed embedded textures are not implemented.");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ok = false;
|
|
|
|
|
for(size_t idx = 0; idx < Pixel_Description_Count; idx++)
|
|
|
|
|
{
|
|
|
|
|
if(als.CheckFormat(Pixel_Description[idx].FormatHint))
|
|
|
|
|
{
|
|
|
|
|
idx_description = idx;
|
|
|
|
|
ok = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(als.mHeight == 0)// Compressed texture.
|
|
|
|
|
{
|
|
|
|
|
LogError("IME: compressed embedded textures are not implemented.");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ok = false;
|
|
|
|
|
for(size_t idx = 0; idx < Pixel_Description_Count; idx++)
|
|
|
|
|
{
|
|
|
|
|
if(als.CheckFormat(Pixel_Description[idx].FormatHint))
|
|
|
|
|
{
|
|
|
|
|
idx_description = idx;
|
|
|
|
|
ok = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!ok)
|
|
|
|
|
{
|
|
|
|
|
LogError(QString("Unsupported format hint for embedded texture: [%1]").arg(als.achFormatHint));
|
|
|
|
|
if(!ok)
|
|
|
|
|
{
|
|
|
|
|
LogError(QString("Unsupported format hint for embedded texture: [%1]").arg(als.achFormatHint));
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glGenTextures(1, &id_ogl_texture);// Texture ID generation.
|
|
|
|
|
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
|
|
|
|
|
// Redefine standard texture values
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
|
|
|
|
|
// Texture specification.
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, Pixel_Description[idx_description].Image_InternalFormat, als.mWidth, als.mHeight, 0,
|
|
|
|
|
Pixel_Description[idx_description].Pixel_Format, GL_UNSIGNED_BYTE, (uint8_t*)als.pcData);
|
|
|
|
|
}// if(als.mHeight == 0) else
|
|
|
|
|
}// if(!filename.startsWith(AI_EMBEDDED_TEXNAME_PREFIX)) else
|
|
|
|
|
glGenTextures(1, &id_ogl_texture);// Texture ID generation.
|
|
|
|
|
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
|
|
|
|
|
// Redefine standard texture values
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
|
|
|
|
|
// Texture specification.
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, Pixel_Description[idx_description].Image_InternalFormat, als.mWidth, als.mHeight, 0,
|
|
|
|
|
Pixel_Description[idx_description].Pixel_Format, GL_UNSIGNED_BYTE, (uint8_t*)als.pcData);
|
|
|
|
|
}// if(als.mHeight == 0) else
|
|
|
|
|
}// if(!filename.startsWith(AI_EMBEDDED_TEXNAME_PREFIX)) else
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
};// auto LoadTexture = [&](const aiString& pPath)
|
|
|
|
|
return true;
|
|
|
|
|
};// auto LoadTexture = [&](const aiString& pPath)
|
|
|
|
|
|
|
|
|
|
if(mScene == nullptr)
|
|
|
|
|
{
|
|
|
|
|