Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL + Qt using CMake

Tags:

c++

cmake

qt

opengl

I have a Qt project created with a *.pro file that I need to migrate it to a CMakeLists. This project uses a simple OpenGL animation to show a 3D model of a hand. I already change it to use CMake, but I encounter 2 problems. (The program compiles but it doesn't run properly)

  1. The memory consumption of the program passes from being 20-50MB using the *.pro file, to 1.3GB using CMake (Maybe some library being loaded completely or something??)
  2. The program runs incredibly slow (like 1 frame every 5-10 seconds) in contrast with the speed from using the *.pro file (approx. 3 frames per second)

The question is, what I am doing wrong and how can I fix it?

Here is the *.pro file:

QT += core gui opengl

TARGET   = RGBD_3D_Viewer
TEMPLATE = app


SOURCES +=  main.cpp\
            mainwindow.cpp \
            glwidget.cpp \
            glwidget_Camera.cpp \
            glwidget_Comm.cpp \
            glwidget_Extractors.cpp \
            glwidget_Rendering.cpp \
            glwidget_Video.cpp \
            glwidget_UI_Mouse.cpp \
            glwidget_OpenGL.cpp \
            mainwindow_Comm.cpp \
            mainwindow_GUI.cpp \
            model.cpp \
            cameraSet.cpp \
            model_Mesh.cpp \
            model_Skeleton.cpp \
            model_Skin.cpp \
            model_Extra_SkinningStuff.cpp \
            animation.cpp \
            animation_Transform.cpp \
            videoSequence.cpp \
            sequence.cpp \
            mainwindow_UI_Keyboard_Mouse.cpp \
            tracker.cpp \
            mainwindow_FrameNumber.cpp \
            model_Limits.cpp \
            animation_Files_CompleteSequence.cpp \
            mainwindow_MODELS_INFO.cpp \
            modelSET.cpp \
            animation_0_RotAxes_Limits.cpp \
            myMATH.cpp \
            types_Background.cpp \
            model_Extra_VOI.cpp \
            fingertipSet.cpp \
            tracker_OnIndexChange.cpp \
            tracker_wFeatureSet.cpp

HEADERS  += mainwindow.h \
            glwidget.h \
            model.h \
            cameraSet.h \
            animation.h \
            videoSequence.h \
            sequence.h \
            tracker.h \
            mymath.h \
            modelSET.h \
            ui_mainwindow.h \
            featureSet.h \
            typesBackground.h \
            fingertipSet.h

FORMS    += mainwindow.ui



INCLUDEPATH += /usr/include/eigen3/

INCLUDEPATH += /home/cvg11/projects/development/RGBD_3D_Viewer/glm


LIBS += -L/usr/local/lib/
LIBS += -lopencv_core
LIBS += -lopencv_highgui


QMAKE_CXXFLAGS += -O3
QMAKE_CXXFLAGS += -frounding-math
#QMAKE_CXXFLAGS += -std=c++0x

Here is the CMakeLists.txt file:

project(3d_viewer)
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)

include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories( ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/glm)

find_package( PkgConfig )
pkg_check_modules( EIGEN3 REQUIRED eigen3 )
include_directories( ${EIGEN3_INCLUDE_DIRS} )

# Opencv required
find_package(OpenCV COMPONENTS core highgui REQUIRED)
include_directories(${OPENCV_INCLUDE_DIRS})
link_directories(${OPENCV_LIBRARY_DIRS})
add_definitions(${OPENCV_DEFINITIONS})

message("\n\nFound OpenCV\n\n")


# QT4 required
find_package(Qt4 COMPONENTS QtCore QtGui QtOpenGL REQUIRED)
set(QT_USE_QTOPENGL TRUE)
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})

message("\n\nFound QT4\n\n")


INCLUDE_DIRECTORIES(${QT_QTOPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} )

#set the default path for built executables to the "bin" directory
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#set the default path for built libraries to the "lib" directory
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)


file(GLOB VIEWER_SOURCES src/*.cpp)

file(GLOB VIEWER_INCLUDES include/*.h)


# set QT headers
SET(QT_HEADERS
    include/mainwindow.h
    include/glwidget.h
    )

#set QT forms
SET(QT_FORMS
    ui/mainwindow.ui
)

# create moc for QT
QT4_WRAP_CPP(QT_MOC ${QT_HEADERS})

# process ui
QT4_WRAP_UI(QT_FORMS_HEADERS ${QT_FORMS})

ADD_EXECUTABLE(3d_viewer ${VIEWER_SOURCES} ${VIEWER_INCLUDES}
    ${QT_HEADERS}
    ${QT_MOC}
    ${QT_FORMS})

TARGET_LINK_LIBRARIES(3d_viewer ${QT_LIBRARIES} ${OpenCV_LIBS} )
set_property(TARGET 3d_viewer PROPERTY COMPILE_DEFINITIONS QT_SHARED)

EDIT:

Here are the two outputs of make VERBOSE=1 (I just show the last link and one of the files since the rest of the files are the same)

CMake:

[100%] Building CXX object CMakeFiles/3d_viewer.dir/include/moc_glwidget.cxx.o
/usr/bin/c++   -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_SHARED -O3 -DNDEBUG -I/home/cvg11/projects/development/RGBD_3D_Viewer/build -I/home/cvg11/projects/development/RGBD_3D_Viewer/include -I/home/cvg11/projects/development/RGBD_3D_Viewer/glm -I/usr/include/eigen3 -I/usr/local/include/opencv -I/usr/local/include -isystem /usr/include/qt4 -isystem /usr/include/qt4/QtOpenGL -isystem /usr/include/qt4/QtGui -isystem /usr/include/qt4/QtCore    -o CMakeFiles/3d_viewer.dir/include/moc_glwidget.cxx.o -c /home/cvg11/projects/development/RGBD_3D_Viewer/build/include/moc_glwidget.cxx
Linking CXX executable ../bin/3d_viewer
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/3d_viewer.dir/link.txt --verbose=1
/usr/bin/c++   -O3 -DNDEBUG    CMakeFiles/3d_viewer.dir/src/mainwindow_FrameNumber.cpp.o CMakeFiles/3d_viewer.dir/src/animation.cpp.o CMakeFiles/3d_viewer.dir/src/glwidget_OpenGL.cpp.o CMakeFiles/3d_viewer.dir/src/main.cpp.o CMakeFiles/3d_viewer.dir/src/mainwindow_Comm.cpp.o CMakeFiles/3d_viewer.dir/src/glwidget_Comm.cpp.o CMakeFiles/3d_viewer.dir/src/myMATH.cpp.o CMakeFiles/3d_viewer.dir/src/model.cpp.o CMakeFiles/3d_viewer.dir/src/glwidget_Rendering.cpp.o CMakeFiles/3d_viewer.dir/src/model_Extra_VOI.cpp.o CMakeFiles/3d_viewer.dir/src/videoSequence.cpp.o CMakeFiles/3d_viewer.dir/src/cameraSet.cpp.o CMakeFiles/3d_viewer.dir/src/model_Extra_SkinningStuff.cpp.o CMakeFiles/3d_viewer.dir/src/mainwindow_MODELS_INFO.cpp.o CMakeFiles/3d_viewer.dir/src/animation_0_RotAxes_Limits.cpp.o CMakeFiles/3d_viewer.dir/src/modelSET.cpp.o CMakeFiles/3d_viewer.dir/src/glwidget_Video.cpp.o CMakeFiles/3d_viewer.dir/src/animation_Transform.cpp.o CMakeFiles/3d_viewer.dir/src/glwidget_Camera.cpp.o CMakeFiles/3d_viewer.dir/src/sequence.cpp.o CMakeFiles/3d_viewer.dir/src/animation_Files_CompleteSequence.cpp.o CMakeFiles/3d_viewer.dir/src/glwidget_UI_Mouse.cpp.o CMakeFiles/3d_viewer.dir/src/model_Skin.cpp.o CMakeFiles/3d_viewer.dir/src/tracker_wFeatureSet.cpp.o CMakeFiles/3d_viewer.dir/src/tracker_OnIndexChange.cpp.o CMakeFiles/3d_viewer.dir/src/mainwindow.cpp.o CMakeFiles/3d_viewer.dir/src/types_Background.cpp.o CMakeFiles/3d_viewer.dir/src/glwidget_Extractors.cpp.o CMakeFiles/3d_viewer.dir/src/model_Limits.cpp.o CMakeFiles/3d_viewer.dir/src/model_Skeleton.cpp.o CMakeFiles/3d_viewer.dir/src/tracker.cpp.o CMakeFiles/3d_viewer.dir/src/model_Mesh.cpp.o CMakeFiles/3d_viewer.dir/src/mainwindow_UI_Keyboard_Mouse.cpp.o CMakeFiles/3d_viewer.dir/src/fingertipSet.cpp.o CMakeFiles/3d_viewer.dir/src/mainwindow_GUI.cpp.o CMakeFiles/3d_viewer.dir/src/glwidget.cpp.o CMakeFiles/3d_viewer.dir/include/moc_mainwindow.cxx.o CMakeFiles/3d_viewer.dir/include/moc_glwidget.cxx.o  -o ../bin/3d_viewer  -L/usr/local/cuda/lib64 -rdynamic -lglut -lXmu -lXi -lQtOpenGL -lQtGui -lQtCore /usr/local/lib/libopencv_core.so.2.4.9 /usr/local/lib/libopencv_highgui.so.2.4.9 /usr/local/lib/libopencv_core.so.2.4.9 -Wl,-rpath,/usr/local/cuda/lib64:/usr/local/lib -Wl,-rpath-link,/usr/local/lib 
make[2]: Leaving directory `/home/cvg11/projects/development/RGBD_3D_Viewer/build'
/usr/local/bin/cmake -E cmake_progress_report /home/cvg11/projects/development/RGBD_3D_Viewer/build/CMakeFiles  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
[100%] Built target 3d_viewer

*.pro project:

g++ -c -pipe -frounding-math -O3 -O2 -w -D_REENTRANT -DQT_WEBKIT -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I/usr/include/eigen3 -I../../projects/development/RGBD_3D_Viewer/glm -I/usr/X11R6/include -I. -I. -o moc_mainwindow.o moc_mainwindow.cpp
/usr/bin/moc-qt4 -DQT_WEBKIT -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I/usr/include/eigen3 -I../../projects/development/RGBD_3D_Viewer/glm -I/usr/X11R6/include -I. -I. glwidget.h -o moc_glwidget.cpp
g++ -c -pipe -frounding-math -O3 -O2 -w -D_REENTRANT -DQT_WEBKIT -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4 -I/usr/include/eigen3 -I../../projects/development/RGBD_3D_Viewer/glm -I/usr/X11R6/include -I. -I. -o moc_glwidget.o moc_glwidget.cpp
g++ -Wl,-O1 -o RGBD_3D_Viewer main.o mainwindow.o glwidget.o glwidget_Camera.o glwidget_Comm.o glwidget_Extractors.o glwidget_Rendering.o glwidget_Video.o glwidget_UI_Mouse.o glwidget_OpenGL.o mainwindow_Comm.o mainwindow_GUI.o model.o cameraSet.o model_Mesh.o model_Skeleton.o model_Skin.o model_Extra_SkinningStuff.o animation.o animation_Transform.o videoSequence.o sequence.o mainwindow_UI_Keyboard_Mouse.o tracker.o mainwindow_FrameNumber.o model_Limits.o animation_Files_CompleteSequence.o mainwindow_MODELS_INFO.o modelSET.o animation_0_RotAxes_Limits.o myMATH.o types_Background.o model_Extra_VOI.o fingertipSet.o tracker_OnIndexChange.o tracker_wFeatureSet.o moc_mainwindow.o moc_glwidget.o    -L/usr/lib/x86_64-linux-gnu -L/usr/X11R6/lib -L/usr/local/lib/ -lopencv_core -lopencv_highgui -lQtOpenGL -lQtGui -lQtCore -lGL -lpthread 

I tried adding/removing the -frounding-math flag without having any appreciable difference...

like image 556
api55 Avatar asked Nov 21 '14 15:11

api55


People also ask

Does Qt use OpenGL?

The Qt OpenGL module makes it easy to use OpenGL in Qt applications. It provides an OpenGL widget class that can be used just like any other Qt widget, except that it opens an OpenGL display buffer where you can use the OpenGL API to render the contents.

What is CMake Qt?

CMake is a tool to simplify the build process for development projects across different platforms. CMake automatically generates build systems, such as Makefiles and Ninja files. CMake is a third-party tool with its own documentation. This manual focuses on how to use CMake to build Qt applications and libraries.

What is CMake and Qmake?

CMake is an alternative to qmake for automating the generation of build configurations. Setting Up Qbs. Qbs is an all-in-one build tool that generates a build graph from a high-level project description (like qmake or CMake do) and executes the commands in the low-level build graph (like make does).

What is an OpenGL widget?

QOpenGLWidget provides functionality for displaying OpenGL graphics integrated into a Qt application. It is very simple to use: Make your class inherit from it and use the subclass like any other QWidget, except that you have the choice between using QPainter and standard OpenGL rendering commands.


2 Answers

You seem to be trying to change the optimization level value with qmake in the wrong way in here:

QMAKE_CXXFLAGS += -O3

The problem with this line is that g++ will use -O2 for the compiling phase and -O1 for the linking phase by default. You seem to want to change only the compiler phase as you do not specify the linker flags. However, += means addition with qmake, not override. The proper way to achieve your original goal would be this:

QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE += -O3

and the following line to override the linker stage, too:

QMAKE_LFLAGS_RELEASE -= -O1

You will naturally need to rerun qmake after this change. Now, -O3 means that it will optimize for performance and not space. Therefore, your former concern about space may be due to this. The second part is still questionable, however, without concrete details.

The default optimization level for cmake is different to qmake; it is -O3. You can easily check that by running the following short cmake snippet:

message("CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")

You need to sync these up to bring them inline. For instance, if you want to use -O2 everywhere, overriding the cmake, too, you will need to apply something this:

set(CMAKE_CXX_FLAGS_RELEASE "-O2")

If you would like to use -O3, see the aforementioned logic for changing that in the qmake project file. If you would like to use something else like -Os, you will need to apply both types of changes. I think, that is pretty much about it.

As for debugging, you may want to completely turn out optimization in both cases to have a nicer debugging experience, however!

In general, you need to decide about the performance versus space trait. You seem to be complaining about both, but you inherently will not get perfectionism at both. If you want to fully optimize for space, use -Os, if for performance, use -O3, if you want a compromised solution, use something in-between, etc.

like image 199
lpapp Avatar answered Sep 28 '22 16:09

lpapp


After fighting for days with this problem, I found out that it was the -O3 flag. Apparently, Qt is using -O3 -O2 and it is taking the last one, and for the final linking it is using -O1. I changed the flags to use -O2 and everything started to work as fast as it should be and using a normal amount of RAM.

like image 24
api55 Avatar answered Sep 28 '22 17:09

api55