Introduce header-only imagelib to make install of qt-viewer simpler.

pull/2100/head
Kim Kulling 2018-08-18 11:07:12 +02:00
parent 847573b9ed
commit 5a23810d82
4 changed files with 7530 additions and 69 deletions

View File

@ -227,8 +227,8 @@ ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" ) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
ELSEIF( CMAKE_COMPILER_IS_MINGW ) ELSEIF( CMAKE_COMPILER_IS_MINGW )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" ) SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11 -Wa,-mbig-obj" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC ")
ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF() ENDIF()

View File

@ -8,7 +8,6 @@ OPTION( ASSIMP_QT4_VIEWER
OFF OFF
) )
FIND_PACKAGE(DevIL QUIET)
FIND_PACKAGE(OpenGL QUIET) FIND_PACKAGE(OpenGL QUIET)
IF(ASSIMP_QT4_VIEWER) IF(ASSIMP_QT4_VIEWER)
@ -21,10 +20,10 @@ ENDIF(ASSIMP_QT4_VIEWER)
SET(VIEWER_BUILD:BOOL FALSE) SET(VIEWER_BUILD:BOOL FALSE)
IF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) IF((Qt4_FOUND OR Qt5Widgets_FOUND) AND OPENGL_FOUND)
SET(VIEWER_BUILD TRUE) SET(VIEWER_BUILD TRUE)
ELSE((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) ELSE((QT4_FOUND OR Qt5Widgets_FOUND) AND OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "") SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
IF(ASSIMP_QT4_VIEWER) IF(ASSIMP_QT4_VIEWER)
@ -39,16 +38,12 @@ ELSE((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND)
ENDIF(ASSIMP_QT4_VIEWER) ENDIF(ASSIMP_QT4_VIEWER)
IF (NOT IL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL")
ENDIF (NOT IL_FOUND)
IF (NOT OPENGL_FOUND) IF (NOT OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL") SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
ENDIF (NOT OPENGL_FOUND) ENDIF (NOT OPENGL_FOUND)
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}") MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
ENDIF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) ENDIF((Qt4_FOUND OR Qt5Widgets_FOUND) AND OPENGL_FOUND)
IF(VIEWER_BUILD) IF(VIEWER_BUILD)
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(

View File

@ -3,6 +3,7 @@
/// \author smal.root@gmail.com /// \author smal.root@gmail.com
/// \date 2016 /// \date 2016
#include "glview.hpp" #include "glview.hpp"
// Header files, Qt. // Header files, Qt.
@ -16,22 +17,26 @@
#endif #endif
// Header files, DevIL. // Header files, DevIL.
#include <il.h>
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
/*
#ifndef __unused #ifndef __unused
#define __unused __attribute__((unused)) #define __unused __attribute__((unused))
#endif // __unused #endif // __unused
*/
/**********************************/ /**********************************/
/********** SHelper_Mesh **********/ /********** SHelper_Mesh **********/
/**********************************/ /**********************************/
CGLView::SHelper_Mesh::SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox) CGLView::SHelper_Mesh::SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox)
: Quantity_Point(pQuantity_Point), Quantity_Line(pQuantity_Line), Quantity_Triangle(pQuantity_Triangle), BBox(pBBox) : Quantity_Point(pQuantity_Point)
{ , Quantity_Line(pQuantity_Line)
, Quantity_Triangle(pQuantity_Triangle)
, BBox(pBBox) {
Index_Point = pQuantity_Point ? new GLuint[pQuantity_Point * 1] : nullptr; Index_Point = pQuantity_Point ? new GLuint[pQuantity_Point * 1] : nullptr;
Index_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr; Index_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr;
Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr; Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr;
@ -88,6 +93,20 @@ void CGLView::SHelper_Camera::SetDefault()
do {} while(false) do {} while(false)
#endif // ASSIMP_QT4_VIEWER #endif // ASSIMP_QT4_VIEWER
static void 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;
}
static void 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;
}
void CGLView::Material_Apply(const aiMaterial* pMaterial) void CGLView::Material_Apply(const aiMaterial* pMaterial)
{ {
GLfloat tcol[4]; GLfloat tcol[4];
@ -97,9 +116,6 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
int texture_index = 0; int texture_index = 0;
aiString texture_path; 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; };
///TODO: cache materials ///TODO: cache materials
// Disable color material because glMaterial is used. // Disable color material because glMaterial is used.
glDisable(GL_COLOR_MATERIAL);///TODO: cache glDisable(GL_COLOR_MATERIAL);///TODO: cache
@ -203,20 +219,17 @@ void CGLView::ImportTextures(const QString& pScenePath)
{ {
auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation. auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation.
{ {
ILboolean success;
GLuint id_ogl_texture;// OpenGL texture ID. GLuint id_ogl_texture;// OpenGL texture ID.
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX)) 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 basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString fileloc = (basepath + pFileName); QString fileloc = (basepath + pFileName);
fileloc.replace('\\', "/"); fileloc.replace('\\', "/");
ilGenImages(1, &id_image);// Generate DevIL image ID. int x, y, n;
ilBindImage(id_image); unsigned char *data = stbi_load(fileloc.toLocal8Bit(), &x, &y, &n, STBI_rgb_alpha );
success = ilLoadImage(fileloc.toLocal8Bit()); if(nullptr==data)
if(!success)
{ {
LogError(QString("Couldn't load Image: %1").arg(fileloc)); LogError(QString("Couldn't load Image: %1").arg(fileloc));
@ -224,13 +237,6 @@ void CGLView::ImportTextures(const QString& pScenePath)
} }
// Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA. // 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;
}
glGenTextures(1, &id_ogl_texture);// Texture ID generation. glGenTextures(1, &id_ogl_texture);// Texture ID generation.
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
@ -238,11 +244,9 @@ void CGLView::ImportTextures(const QString& pScenePath)
// Redefine standard texture values // 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_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. 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, glTexImage2D(GL_TEXTURE_2D, 0, n, x, y, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, data );// Texture specification.
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
//Cleanup // Cleanup
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
} }
else else
{ {
@ -321,27 +325,18 @@ void CGLView::ImportTextures(const QString& pScenePath)
return; return;
} }
// Before calling ilInit() version should be checked.
if(ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
{
LogError("Wrong DevIL version.");
return;
}
ilInit();// Initialization of DevIL.
// //
// Load textures. // Load textures.
// //
// Get textures file names and number of textures. // Get textures file names and number of textures.
for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) {
{
int idx_texture = 0; int idx_texture = 0;
aiString path; aiString path;
do do {
{ if (mScene->mMaterials[ idx_material ]->GetTexture( aiTextureType_DIFFUSE, idx_texture, &path ) != AI_SUCCESS) {
if(mScene->mMaterials[idx_material]->GetTexture(aiTextureType_DIFFUSE, idx_texture, &path) != AI_SUCCESS) break; break;
}
LoadTexture(QString(path.C_Str())); LoadTexture(QString(path.C_Str()));
idx_texture++; idx_texture++;
@ -349,11 +344,8 @@ void CGLView::ImportTextures(const QString& pScenePath)
}// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) }// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++)
// Textures list is empty, exit. // Textures list is empty, exit.
if(mTexture_IDMap.size() == 0) if(mTexture_IDMap.empty()) {
{
LogInfo("No textures for import."); LogInfo("No textures for import.");
return;
} }
} }
@ -476,7 +468,7 @@ void CGLView::Draw_Node(const aiNode* pNode)
// Apply node transformation matrix. // Apply node transformation matrix.
mat_node.Transpose(); mat_node.Transpose();
glPushMatrix(); glPushMatrix();
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)mat_node[0]); glMultMatrixd((GLdouble*)mat_node[0]);
#else #else
glMultMatrixf((GLfloat*)&mat_node); glMultMatrixf((GLfloat*)&mat_node);
@ -518,7 +510,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
{ {
glEnable(GL_COLOR_MATERIAL);///TODO: cache glEnable(GL_COLOR_MATERIAL);///TODO: cache
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]); glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]);
#else #else
glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]); glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]);
@ -531,7 +523,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
if(mesh_cur.HasTextureCoords(0)) if(mesh_cur.HasTextureCoords(0))
{ {
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]); glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
#else #else
glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]); glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
@ -544,7 +536,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
if(mesh_cur.HasNormals()) if(mesh_cur.HasNormals())
{ {
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals); glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals);
#else #else
glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals); glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals);
@ -590,7 +582,7 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
#endif // ASSIMP_QT4_VIEWER #endif // ASSIMP_QT4_VIEWER
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
# if ASSIMP_DOUBLE_PRECISION # ifdef ASSIMP_DOUBLE_PRECISION
glVertex3dv(&vertex[0][0]), glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[0][0]);// "Minimum" side. glVertex3dv(&vertex[0][0]), glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[0][0]);// "Minimum" side.
glVertex3dv(&vertex[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side. glVertex3dv(&vertex[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side.
# else # else
@ -600,7 +592,7 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
glEnd(); glEnd();
glBegin(GL_LINES); glBegin(GL_LINES);
# if ASSIMP_DOUBLE_PRECISION # ifdef ASSIMP_DOUBLE_PRECISION
glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]); glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]);
glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]); glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]);
glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]); glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]);
@ -1113,25 +1105,37 @@ void CGLView::Lighting_Disable()
void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters) void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
{ {
#if !ASSIMP_QT4_VIEWER #if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin; ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER #endif // ASSIMP_QT4_VIEWER
const size_t light_num = GL_LIGHT0 + pLightNumber; const size_t light_num = GL_LIGHT0 + pLightNumber;
GLfloat farr[4]; GLfloat farr[4];
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
// Ambient color // Ambient color
farr[0] = pLightParameters.Ambient.r, farr[1] = pLightParameters.Ambient.g; farr[2] = pLightParameters.Ambient.b; farr[3] = pLightParameters.Ambient.a; farr[0] = pLightParameters.Ambient.r;
farr[1] = pLightParameters.Ambient.g;
farr[2] = pLightParameters.Ambient.b;
farr[3] = pLightParameters.Ambient.a;
glLightfv(light_num, GL_AMBIENT, farr); glLightfv(light_num, GL_AMBIENT, farr);
// Diffuse color
farr[0] = pLightParameters.Diffuse.r, farr[1] = pLightParameters.Diffuse.g; farr[2] = pLightParameters.Diffuse.b; farr[3] = pLightParameters.Diffuse.a; // Diffuse color
farr[0] = pLightParameters.Diffuse.r;
farr[1] = pLightParameters.Diffuse.g;
farr[2] = pLightParameters.Diffuse.b;
farr[3] = pLightParameters.Diffuse.a;
glLightfv(light_num, GL_DIFFUSE, farr); glLightfv(light_num, GL_DIFFUSE, farr);
// Specular color
farr[0] = pLightParameters.Specular.r, farr[1] = pLightParameters.Specular.g; farr[2] = pLightParameters.Specular.b; farr[3] = pLightParameters.Specular.a; // Specular color
farr[0] = pLightParameters.Specular.r;
farr[1] = pLightParameters.Specular.g;
farr[2] = pLightParameters.Specular.b;
farr[3] = pLightParameters.Specular.a;
glLightfv(light_num, GL_SPECULAR, farr); glLightfv(light_num, GL_SPECULAR, farr);
// Other parameters
// Other parameters
switch(pLightParameters.Type) switch(pLightParameters.Type)
{ {
case aiLightSource_DIRECTIONAL: case aiLightSource_DIRECTIONAL:
@ -1193,7 +1197,7 @@ void CGLView::Lighting_EnableSource(const size_t pLightNumber)
glEnable(GL_LIGHT0 + pLightNumber); glEnable(GL_LIGHT0 + pLightNumber);
#if !ASSIMP_QT4_VIEWER #if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End; ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER #endif // ASSIMP_QT4_VIEWER
} }
@ -1263,7 +1267,7 @@ void CGLView::Camera_Set(const size_t pCameraNumber)
void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) { void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) {
auto deg2rad = [](const GLfloat pDegree) -> GLfloat { auto deg2rad = [](const GLfloat pDegree) -> GLfloat {
return pDegree * AI_MATH_PI / 180.0; return pDegree * AI_MATH_PI / 180.0f;
}; };
aiMatrix4x4 mat_rot; aiMatrix4x4 mat_rot;

File diff suppressed because it is too large Load Diff