From 67eff10d8f3197dea997039cdeb63de59825861b Mon Sep 17 00:00:00 2001 From: smalcom Date: Fri, 25 May 2018 21:19:06 +0300 Subject: [PATCH] [*] qt_assimp_viewer can be built with Qt4 or Qt5. [F] Working in doule precision. --- CMakeLists.txt | 27 +-- tools/assimp_qt_viewer/CMakeLists.txt | 127 ++++++++++---- tools/assimp_qt_viewer/glview.cpp | 233 ++++++++++++++++++++++++-- tools/assimp_qt_viewer/glview.hpp | 16 +- tools/assimp_qt_viewer/mainwindow.cpp | 41 ++++- tools/assimp_qt_viewer/mainwindow.hpp | 6 +- 6 files changed, 370 insertions(+), 80 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb407c4b1..d5a7bc278 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -412,32 +412,7 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY ) ADD_SUBDIRECTORY( tools/assimp_cmd/ ) - - # Check dependencies for assimp_qt_viewer. - # Why here? Maybe user do not want Qt viewer and have no Qt. - # Why assimp_qt_viewer/CMakeLists.txt still contain similar check? - # Because viewer can be build independently of Assimp. - FIND_PACKAGE(Qt5Widgets QUIET) - FIND_PACKAGE(DevIL QUIET) - FIND_PACKAGE(OpenGL QUIET) - IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND) - ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ ) - ELSE() - SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "") - IF (NOT Qt5_FOUND) - SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5") - ENDIF (NOT Qt5_FOUND) - - IF (NOT IL_FOUND) - SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL") - ENDIF (NOT IL_FOUND) - - IF (NOT OPENGL_FOUND) - SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL") - ENDIF (NOT OPENGL_FOUND) - - MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}") - ENDIF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND) + ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ ) ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS ) IF ( ASSIMP_BUILD_SAMPLES) diff --git a/tools/assimp_qt_viewer/CMakeLists.txt b/tools/assimp_qt_viewer/CMakeLists.txt index b41291e3d..51a4efad8 100644 --- a/tools/assimp_qt_viewer/CMakeLists.txt +++ b/tools/assimp_qt_viewer/CMakeLists.txt @@ -3,44 +3,103 @@ project(assimp_qt_viewer) cmake_minimum_required(VERSION 2.6) -find_package(Qt5 COMPONENTS Gui Widgets OpenGL REQUIRED) -find_package(DevIL REQUIRED) -find_package(OpenGL REQUIRED) - -include_directories( - ${Qt5Widgets_INCLUDES} - ${Assimp_SOURCE_DIR}/include - ${Assimp_SOURCE_DIR}/code - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_SOURCE_DIR} - ${OPENGL_INCLUDE_DIR} - ${IL_INCLUDE_DIR} +OPTION( ASSIMP_QT4_VIEWER + "Set to ON to enable Qt4 against Qt5 for assimp_qt_viewer" + OFF ) -link_directories(${Assimp_BINARY_DIR}) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall") +FIND_PACKAGE(DevIL QUIET) +FIND_PACKAGE(OpenGL QUIET) -set(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp) -qt5_wrap_ui(UISrcs mainwindow.ui) -qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp) +IF(ASSIMP_QT4_VIEWER) + # Qt4 version + FIND_PACKAGE(Qt4 QUIET) +ELSE(ASSIMP_QT4_VIEWER) + # Qt5 version + FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET) +ENDIF(ASSIMP_QT4_VIEWER) -add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs}) -target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp) +SET(VIEWER_BUILD:BOOL FALSE) -if(WIN32) # Check if we are on Windows - if(MSVC) # Check if we are using the Visual Studio compiler - #set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS") - elseif(CMAKE_COMPILER_IS_GNUCXX) - # SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested - else() - message(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)") - endif() -elseif(UNIX) - # Nothing special required -else() - message(SEND_ERROR "You are on an unsupported platform! (Not Win32 or Unix)") -endif() +IF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) + SET(VIEWER_BUILD TRUE) -set_property(TARGET ${PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) +ELSE((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) + SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "") -install(TARGETS assimp_qt_viewer DESTINATION "${ASSIMP_BIN_INSTALL_DIR}") + IF(ASSIMP_QT4_VIEWER) + IF (NOT Qt4_FOUND) + SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt4") + ENDIF (NOT Qt4_FOUND) + + ELSE(ASSIMP_QT4_VIEWER) + IF (NOT Qt5_FOUND) + SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5") + ENDIF (NOT Qt5_FOUND) + + 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) + SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL") + ENDIF (NOT OPENGL_FOUND) + + 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) + +IF(VIEWER_BUILD) + INCLUDE_DIRECTORIES( + ${Assimp_SOURCE_DIR}/include + ${Assimp_SOURCE_DIR}/code + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR} + ${OPENGL_INCLUDE_DIR} + ${IL_INCLUDE_DIR} + ) + + LINK_DIRECTORIES(${Assimp_BINARY_DIR}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall") + + SET(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp) + + IF(ASSIMP_QT4_VIEWER) + MESSAGE("assimp_qt_viewer use Qt4") + ADD_DEFINITIONS( -DASSIMP_QT4_VIEWER ) + INCLUDE_DIRECTORIES(${QT_INCLUDES}) + qt4_wrap_ui(UISrcs mainwindow.ui) + qt4_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp) + ELSE() + MESSAGE("assimp_qt_viewer use Qt5") + INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES}) + qt5_wrap_ui(UISrcs mainwindow.ui) + qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp) + ENDIF() + + add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs}) + + IF(ASSIMP_QT4_VIEWER) + target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp) + ELSE() + target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp) + ENDIF() + + IF(WIN32) # Check if we are on Windows + IF(MSVC) # Check if we are using the Visual Studio compiler + #set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS") + ELSEIF(CMAKE_COMPILER_IS_GNUCXX) + # SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested + ELSE() + MESSAGE(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)") + ENDIF() + ELSEIF(UNIX) + # Nothing special required + ELSE() + MESSAGE(SEND_ERROR "You are on an unsupported platform! (Not Win32 or Unix)") + ENDIF() + + SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) + INSTALL(TARGETS assimp_qt_viewer DESTINATION "${ASSIMP_BIN_INSTALL_DIR}") +ENDIF(VIEWER_BUILD) diff --git a/tools/assimp_qt_viewer/glview.cpp b/tools/assimp_qt_viewer/glview.cpp index 833400c46..c67420c06 100644 --- a/tools/assimp_qt_viewer/glview.cpp +++ b/tools/assimp_qt_viewer/glview.cpp @@ -5,6 +5,9 @@ #include "glview.hpp" +// Header files, Qt. +#include + // Header files, OpenGL. #if defined(__APPLE__) # include @@ -58,6 +61,33 @@ void CGLView::SHelper_Camera::SetDefault() /************ CGLView *************/ /**********************************/ +#if !ASSIMP_QT4_VIEWER +# define ConditionalContextControl_Begin \ + bool ContextEnabledHere; \ + \ + if(mGLContext_Current) \ + { \ + ContextEnabledHere = false; \ + } \ + else \ + { \ + makeCurrent(); \ + mGLContext_Current = true; \ + ContextEnabledHere = true; \ + } \ + \ + do {} while(false) + +# define ConditionalContextControl_End \ + if(ContextEnabledHere) \ + { \ + doneCurrent(); \ + mGLContext_Current = false; \ + } \ + \ + do {} while(false) +#endif // ASSIMP_QT4_VIEWER + void CGLView::Material_Apply(const aiMaterial* pMaterial) { GLfloat tcol[4]; @@ -105,7 +135,7 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial) glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, tcol); // Shininess - float shininess, strength; + ai_real shininess, strength; max = 1; ret1 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS, &shininess, &max); @@ -406,10 +436,11 @@ void CGLView::BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVe for(size_t idx_vert = 1; idx_vert < pVerticesQuantity; idx_vert++) { - const GLfloat x = pVertices[idx_vert].x; - const GLfloat y = pVertices[idx_vert].y; - const GLfloat z = pVertices[idx_vert].z; + const ai_real x = pVertices[idx_vert].x; + const ai_real y = pVertices[idx_vert].y; + const ai_real z = pVertices[idx_vert].z; + printf("vert[%lu]=%g,%g,%g\r\n", idx_vert, x, y, z);///TODO: dbg // search minimal... AssignIfLesser(&pBBox.Minimum.x, x); AssignIfLesser(&pBBox.Minimum.y, y); @@ -439,14 +470,29 @@ void CGLView::LogError(const QString& pMessage) /************************** Draw functions **************************/ /********************************************************************/ +static void print_matrix(const aiMatrix4x4 pMatrix)///TODO: dbg +{ + printf("Matrix:\r\n"); + printf("\t%g,%g,%g%g\r\n", pMatrix.a1, pMatrix.a2, pMatrix.a3, pMatrix.a4); + printf("\t%g,%g,%g%g\r\n", pMatrix.b1, pMatrix.b2, pMatrix.b3, pMatrix.b4); + printf("\t%g,%g,%g%g\r\n", pMatrix.c1, pMatrix.c2, pMatrix.c3, pMatrix.c4); + printf("\t%g,%g,%g%g\r\n", pMatrix.d1, pMatrix.d2, pMatrix.d3, pMatrix.d4); +} + void CGLView::Draw_Node(const aiNode* pNode) { aiMatrix4x4 mat_node = pNode->mTransformation; // Apply node transformation matrix. mat_node.Transpose(); + print_matrix(mat_node); glPushMatrix(); +#if ASSIMP_DOUBLE_PRECISION + glMultMatrixd((GLdouble*)mat_node[0]); +#else glMultMatrixf((GLfloat*)&mat_node); +#endif // ASSIMP_DOUBLE_PRECISION + // Draw all meshes assigned to this node for(size_t idx_mesh_arr = 0; idx_mesh_arr < pNode->mNumMeshes; idx_mesh_arr++) Draw_Mesh(pNode->mMeshes[idx_mesh_arr]); @@ -473,13 +519,21 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index) // Vertices array // glEnableClientState(GL_VERTEX_ARRAY); +#if ASSIMP_DOUBLE_PRECISION + glVertexPointer(3, GL_DOUBLE, 0, mesh_cur.mVertices); +#else glVertexPointer(3, GL_FLOAT, 0, mesh_cur.mVertices); +#endif // ASSIMP_DOUBLE_PRECISION if(mesh_cur.HasVertexColors(0)) { glEnable(GL_COLOR_MATERIAL);///TODO: cache glEnableClientState(GL_COLOR_ARRAY); +#if ASSIMP_DOUBLE_PRECISION + glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]); +#else glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]); +#endif // ASSIMP_DOUBLE_PRECISION } // @@ -488,7 +542,11 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index) if(mesh_cur.HasTextureCoords(0)) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); +#if ASSIMP_DOUBLE_PRECISION + glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]); +#else glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]); +#endif // ASSIMP_DOUBLE_PRECISION } // @@ -497,7 +555,11 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index) if(mesh_cur.HasNormals()) { glEnableClientState(GL_NORMAL_ARRAY); +#if ASSIMP_DOUBLE_PRECISION + glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals); +#else glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals); +#endif // ASSIMP_DOUBLE_PRECISION } // @@ -530,22 +592,46 @@ void CGLView::Draw_BBox(const SBBox& pBBox) glBindTexture(GL_TEXTURE_1D, 0); glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_3D, 0); +#if ASSIMP_QT4_VIEWER qglColor(QColor(Qt::white)); +#else + const QColor c_w(Qt::white); + + glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF()); +#endif // ASSIMP_QT4_VIEWER + glBegin(GL_LINE_STRIP); +# if 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[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side. +# else glVertex3fv(&vertex[0][0]), glVertex3fv(&vertex[1][0]), glVertex3fv(&vertex[2][0]), glVertex3fv(&vertex[3][0]), glVertex3fv(&vertex[0][0]);// "Minimum" side. glVertex3fv(&vertex[4][0]), glVertex3fv(&vertex[5][0]), glVertex3fv(&vertex[6][0]), glVertex3fv(&vertex[7][0]), glVertex3fv(&vertex[4][0]);// Edge and "maximum" side. +# endif // ASSIMP_DOUBLE_PRECISION glEnd(); + glBegin(GL_LINES); +# if ASSIMP_DOUBLE_PRECISION + glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]); + glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]); + glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]); +# else glVertex3fv(&vertex[1][0]), glVertex3fv(&vertex[5][0]); glVertex3fv(&vertex[2][0]), glVertex3fv(&vertex[6][0]); glVertex3fv(&vertex[3][0]), glVertex3fv(&vertex[7][0]); +# endif // ASSIMP_DOUBLE_PRECISION glEnd(); glDisable(GL_COLOR_MATERIAL); if(mLightingEnabled) glEnable(GL_LIGHTING); + } void CGLView::Enable_Textures(const bool pEnable) { +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_Begin; +#endif // ASSIMP_QT4_VIEWER + if(pEnable) { glEnable(GL_TEXTURE_1D); @@ -558,6 +644,10 @@ void CGLView::Enable_Textures(const bool pEnable) glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_3D); } + +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_End; +#endif // ASSIMP_QT4_VIEWER } /********************************************************************/ @@ -566,7 +656,13 @@ void CGLView::Enable_Textures(const bool pEnable) void CGLView::initializeGL() { +#if ASSIMP_QT4_VIEWER qglClearColor(Qt::gray); +#else + mGLContext_Current = true; + initializeOpenGLFunctions(); + glClearColor(0.5f, 0.5f, 0.5f, 1.0f); +#endif // ASSIMP_QT4_VIEWER glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); @@ -583,15 +679,25 @@ void CGLView::initializeGL() glCullFace(GL_BACK); glFrontFace(GL_CCW); + +#if !ASSIMP_QT4_VIEWER + mGLContext_Current = false; +#endif // ASSIMP_QT4_VIEWER } void CGLView::resizeGL(int pWidth, int pHeight) { +#if !ASSIMP_QT4_VIEWER + mGLContext_Current = true; +#endif // ASSIMP_QT4_VIEWER mCamera_Viewport_AspectRatio = (GLdouble)pWidth / pHeight; glViewport(0, 0, pWidth, pHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(mCamera_FOVY, mCamera_Viewport_AspectRatio, 1.0, 100000.0);///TODO: znear/zfar depend on scene size. +#if !ASSIMP_QT4_VIEWER + mGLContext_Current = false; +#endif // ASSIMP_QT4_VIEWER } void CGLView::drawCoordSystem() { @@ -604,7 +710,8 @@ void CGLView::drawCoordSystem() { glBindTexture(GL_TEXTURE_3D, 0); glEnable(GL_COLOR_MATERIAL); glBegin(GL_LINES); - // X, -X +#if ASSIMP_QT4_VIEWER + // X, -X qglColor(QColor(Qt::red)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0); qglColor(QColor(Qt::cyan)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0); // Y, -Y @@ -614,14 +721,31 @@ void CGLView::drawCoordSystem() { qglColor(QColor(Qt::blue)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0); qglColor(QColor(Qt::yellow)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0); qglColor(QColor(Qt::white)); - glEnd(); +#else + // X, -X + glColor3f(1.0f, 0.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0); + glColor3f(0.5f, 0.5f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0); + // Y, -Y + glColor3f(0.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 100000.0, 0.0); + glColor3f(1.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, -100000.0, 0.0); + // Z, -Z + glColor3f(0.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0); + glColor3f(1.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0); + glColor3f(1.0f, 1.0f, 1.0f); +#endif // ASSIMP_QT4_VIEWER + glEnd(); // Restore previous state of lighting. if(mLightingEnabled) glEnable(GL_LIGHTING); + } void CGLView::paintGL() { - QTime time_paintbegin; +#if !ASSIMP_QT4_VIEWER + mGLContext_Current = true; +#endif // ASSIMP_QT4_VIEWER + + QTime time_paintbegin; time_paintbegin = QTime::currentTime(); @@ -629,9 +753,16 @@ void CGLView::paintGL() glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Apply current camera transformations. +#if ASSIMP_DOUBLE_PRECISION + glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera); + glTranslated(-mHelper_Camera.Translation_ToScene.x, -mHelper_Camera.Translation_ToScene.y, -mHelper_Camera.Translation_ToScene.z); + glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_Scene); +#else glMultMatrixf((GLfloat*)&mHelper_Camera.Rotation_AroundCamera); glTranslatef(-mHelper_Camera.Translation_ToScene.x, -mHelper_Camera.Translation_ToScene.y, -mHelper_Camera.Translation_ToScene.z); glMultMatrixf((GLfloat*)&mHelper_Camera.Rotation_Scene); +#endif // ASSIMP_DOUBLE_PRECISION + // Coordinate system if (mScene_AxesEnabled == true) { @@ -645,9 +776,13 @@ void CGLView::paintGL() Draw_Node(mScene->mRootNode); // Scene BBox if(mScene_DrawBBox) Draw_BBox(mScene_BBox); + } emit Paint_Finished((size_t)time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length()); +#if !ASSIMP_QT4_VIEWER + mGLContext_Current = false; +#endif // ASSIMP_QT4_VIEWER } /********************************************************************/ @@ -655,10 +790,12 @@ void CGLView::paintGL() /********************************************************************/ CGLView::CGLView(QWidget *pParent) +#if ASSIMP_QT4_VIEWER : QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer), pParent) +#else + : QOpenGLWidget(pParent), mGLContext_Current(false) +#endif // ASSIMP_QT4_VIEWER { - static_assert(sizeof(GLfloat) == sizeof(ai_real), "ai_real in Assimp must be equal to GLfloat/float.");///TODO: may be templates can be used. - // set initial view mHelper_CameraDefault.SetDefault(); Camera_Set(0); @@ -675,6 +812,10 @@ CGLView::~CGLView() void CGLView::FreeScene() { +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_Begin; +#endif // ASSIMP_QT4_VIEWER + // Set scene to null and after that \ref paintGL will not try to render it. mScene = nullptr; // Clean helper objects. @@ -704,10 +845,18 @@ void CGLView::FreeScene() mTexture_IDMap.clear(); delete [] id_tex; } + +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_End; +#endif // ASSIMP_QT4_VIEWER } void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) { +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_Begin; +#endif // ASSIMP_QT4_VIEWER + FreeScene();// Clear old data // Why checking here, not at begin of function. Because old scene may not exist at know. So, need cleanup. if(pScene == nullptr) return; @@ -934,6 +1083,10 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str()); } }// if(!mScene->HasCameras()) else + +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_End; +#endif // ASSIMP_QT4_VIEWER } /********************************************************************/ @@ -942,39 +1095,65 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) void CGLView::Lighting_Enable() { +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_Begin; +#endif // ASSIMP_QT4_VIEWER + mLightingEnabled = true; glEnable(GL_LIGHTING); + +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_End; +#endif // ASSIMP_QT4_VIEWER } void CGLView::Lighting_Disable() { +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_Begin; +#endif // ASSIMP_QT4_VIEWER + glDisable(GL_LIGHTING); mLightingEnabled = false; + +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_End; +#endif // ASSIMP_QT4_VIEWER } void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters) { +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_Begin; +#endif // ASSIMP_QT4_VIEWER + const size_t light_num = GL_LIGHT0 + pLightNumber; GLfloat farr[4]; if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; - glLightfv(light_num, GL_AMBIENT, &pLightParameters.Ambient.r);// Ambient color - glLightfv(light_num, GL_DIFFUSE, &pLightParameters.Diffuse.r);// Diffuse color - glLightfv(light_num, GL_SPECULAR, &pLightParameters.Specular.r);// Specular color + // Ambient color + 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); + // 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); + // 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); // Other parameters switch(pLightParameters.Type) { case aiLightSource_DIRECTIONAL: // Direction - farr[0] = pLightParameters.For.Directional.Direction.x, farr[2] = pLightParameters.For.Directional.Direction.y; + farr[0] = pLightParameters.For.Directional.Direction.x, farr[1] = pLightParameters.For.Directional.Direction.y; farr[2] = pLightParameters.For.Directional.Direction.z; farr[3] = 0; glLightfv(light_num, GL_POSITION, farr); break; case aiLightSource_POINT: // Position - farr[0] = pLightParameters.For.Point.Position.x, farr[2] = pLightParameters.For.Point.Position.y; + farr[0] = pLightParameters.For.Point.Position.x, farr[1] = pLightParameters.For.Point.Position.y; farr[2] = pLightParameters.For.Point.Position.z; farr[3] = 1; glLightfv(light_num, GL_POSITION, farr); // Attenuation @@ -985,20 +1164,20 @@ GLfloat farr[4]; break; case aiLightSource_SPOT: // Position - farr[0] = pLightParameters.For.Spot.Position.x, farr[2] = pLightParameters.For.Spot.Position.y, farr[2] = pLightParameters.For.Spot.Position.z; farr[3] = 1; + farr[0] = pLightParameters.For.Spot.Position.x, farr[1] = pLightParameters.For.Spot.Position.y, farr[2] = pLightParameters.For.Spot.Position.z; farr[3] = 1; glLightfv(light_num, GL_POSITION, farr); // Attenuation glLightf(light_num, GL_CONSTANT_ATTENUATION, pLightParameters.For.Spot.Attenuation_Constant); glLightf(light_num, GL_LINEAR_ATTENUATION, pLightParameters.For.Spot.Attenuation_Linear); glLightf(light_num, GL_QUADRATIC_ATTENUATION, pLightParameters.For.Spot.Attenuation_Quadratic); // Spot specific - farr[0] = pLightParameters.For.Spot.Direction.x, farr[2] = pLightParameters.For.Spot.Direction.y, farr[2] = pLightParameters.For.Spot.Direction.z; farr[3] = 0; + farr[0] = pLightParameters.For.Spot.Direction.x, farr[1] = pLightParameters.For.Spot.Direction.y, farr[2] = pLightParameters.For.Spot.Direction.z; farr[3] = 0; glLightfv(light_num, GL_SPOT_DIRECTION, farr); glLightf(light_num, GL_SPOT_CUTOFF, pLightParameters.For.Spot.CutOff); break; default:// For unknown light source types use point source. // Position - farr[0] = pLightParameters.For.Point.Position.x, farr[2] = pLightParameters.For.Point.Position.y; + farr[0] = pLightParameters.For.Point.Position.x, farr[1] = pLightParameters.For.Point.Position.y; farr[2] = pLightParameters.For.Point.Position.z; farr[3] = 1; glLightfv(light_num, GL_POSITION, farr); // Attenuation @@ -1008,20 +1187,40 @@ GLfloat farr[4]; glLightf(light_num, GL_SPOT_CUTOFF, 180.0); break; }// switch(pLightParameters.Type) + +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_End; +#endif // ASSIMP_QT4_VIEWER } void CGLView::Lighting_EnableSource(const size_t pLightNumber) { +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_Begin; +#endif // ASSIMP_QT4_VIEWER + if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; glEnable(GL_LIGHT0 + pLightNumber); + +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_End; +#endif // ASSIMP_QT4_VIEWER } void CGLView::Lighting_DisableSource(const size_t pLightNumber) { +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_Begin; +#endif // ASSIMP_QT4_VIEWER + if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; glDisable(GL_LIGHT0 + pLightNumber); + +#if !ASSIMP_QT4_VIEWER + ConditionalContextControl_End; +#endif // ASSIMP_QT4_VIEWER } /********************************************************************/ diff --git a/tools/assimp_qt_viewer/glview.hpp b/tools/assimp_qt_viewer/glview.hpp index 2d8614e21..6068e1448 100644 --- a/tools/assimp_qt_viewer/glview.hpp +++ b/tools/assimp_qt_viewer/glview.hpp @@ -6,14 +6,24 @@ #pragma once // Header files, Qt. -#include +#include +#if ASSIMP_QT4_VIEWER +# include +#else +# include +# include +#endif // ASSIMP_QT4_VIEWER // Header files Assimp #include /// \class CGLView /// Class which hold and render scene. +#if ASSIMP_QT4_VIEWER class CGLView : public QGLWidget +#else +class CGLView : public QOpenGLWidget, protected QOpenGLFunctions +#endif // ASSIMP_QT4_VIEWER { Q_OBJECT @@ -139,6 +149,10 @@ public: private: +#if !ASSIMP_QT4_VIEWER + // Qt5 widget has another behavior, so you must to know that you already made context are current. Yes, its a dirty hack. Better decision are welcome. + bool mGLContext_Current;///< Widget's GL-context made current. +#endif // ASSIMP_QT4_VIEWER // Scene const aiScene* mScene = nullptr;///< Copy of pointer to scene (\ref aiScene). SBBox mScene_BBox;///< Bounding box of scene. diff --git a/tools/assimp_qt_viewer/mainwindow.cpp b/tools/assimp_qt_viewer/mainwindow.cpp index c17188472..85a70ba6b 100644 --- a/tools/assimp_qt_viewer/mainwindow.cpp +++ b/tools/assimp_qt_viewer/mainwindow.cpp @@ -84,7 +84,11 @@ QTime time_begin = QTime::currentTime(); mGLView->Camera_Set(0); // Scene is loaded, do first rendering. LogInfo("Scene is ready for rendering."); +#if ASSIMP_QT4_VIEWER mGLView->updateGL(); +#else + mGLView->update(); +#endif // ASSIMP_QT4_VIEWER } else { @@ -173,7 +177,11 @@ void MainWindow::mouseMoveEvent(QMouseEvent* pEvent) else mGLView->Camera_RotateScene(dy, dx, 0, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oY axises. + #if ASSIMP_QT4_VIEWER mGLView->updateGL(); + #else + mGLView->update(); + #endif // ASSIMP_QT4_VIEWER } if(pEvent->buttons() & Qt::RightButton) @@ -186,7 +194,11 @@ void MainWindow::mouseMoveEvent(QMouseEvent* pEvent) else mGLView->Camera_Rotate(dy, dx, 0, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oY axises. + #if ASSIMP_QT4_VIEWER mGLView->updateGL(); + #else + mGLView->update(); + #endif // ASSIMP_QT4_VIEWER } } } @@ -215,7 +227,11 @@ GLfloat step; else if(pEvent->key() == Qt::Key_Down) mGLView->Camera_Translate(0, 0, step); +#if ASSIMP_QT4_VIEWER mGLView->updateGL(); +#else + mGLView->update(); +#endif // ASSIMP_QT4_VIEWER } /********************************************************************/ @@ -303,7 +319,6 @@ QString filename, filter; if(!filename.isEmpty()) ImportFile(filename); } - void MainWindow::on_butExport_clicked() { using namespace Assimp; @@ -367,7 +382,11 @@ void MainWindow::on_cbxLighting_clicked(bool pChecked) else mGLView->Lighting_Disable(); +#if ASSIMP_QT4_VIEWER mGLView->updateGL(); +#else + mGLView->update(); +#endif // ASSIMP_QT4_VIEWER } void MainWindow::on_lstLight_itemSelectionChanged() @@ -379,29 +398,49 @@ bool selected = ui->lstLight->isItemSelected(ui->lstLight->currentItem()); else mGLView->Lighting_DisableSource(ui->lstLight->currentRow()); +#if ASSIMP_QT4_VIEWER mGLView->updateGL(); +#else + mGLView->update(); +#endif // ASSIMP_QT4_VIEWER } void MainWindow::on_lstCamera_clicked( const QModelIndex &) { mGLView->Camera_Set(ui->lstLight->currentRow()); +#if ASSIMP_QT4_VIEWER mGLView->updateGL(); +#else + mGLView->update(); +#endif // ASSIMP_QT4_VIEWER } void MainWindow::on_cbxBBox_clicked(bool checked) { mGLView->Enable_SceneBBox(checked); +#if ASSIMP_QT4_VIEWER mGLView->updateGL(); +#else + mGLView->update(); +#endif // ASSIMP_QT4_VIEWER } void MainWindow::on_cbxDrawAxes_clicked(bool checked) { mGLView->Enable_Axes(checked); +#if ASSIMP_QT4_VIEWER mGLView->updateGL(); +#else + mGLView->update(); +#endif // ASSIMP_QT4_VIEWER } void MainWindow::on_cbxTextures_clicked(bool checked) { mGLView->Enable_Textures(checked); +#if ASSIMP_QT4_VIEWER mGLView->updateGL(); +#else + mGLView->update(); +#endif // ASSIMP_QT4_VIEWER } diff --git a/tools/assimp_qt_viewer/mainwindow.hpp b/tools/assimp_qt_viewer/mainwindow.hpp index 2eedf18f2..e0d17181d 100644 --- a/tools/assimp_qt_viewer/mainwindow.hpp +++ b/tools/assimp_qt_viewer/mainwindow.hpp @@ -6,7 +6,11 @@ #pragma once // Header files, Qt. -#include +#if ASSIMP_QT4_VIEWER +# include +#else +# include +#endif // Header files, project. #include "glview.hpp"