├── .gitignore ├── CMakeLists.txt ├── README.md └── sources ├── CMakeLists.txt ├── main.cpp ├── maingui.cpp ├── maingui.h ├── opengl_widget.cpp └── opengl_widget.h /.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.0) 2 | project(QtOpenGLMousePick) 3 | 4 | # ------------------------------------------------------------------------------ 5 | # Qt path settings 6 | # ------------------------------------------------------------------------------ 7 | set(QT5_ROOT ${QT5_ROOT} CACHE PATH "QT5-NOT_FOUND") 8 | if (NOT EXISTS "${QT5_ROOT}/lib/cmake") 9 | message(FATAL_ERROR "[ERROR] Qt libraries not found!!") 10 | else() 11 | message(STATUS "Qt5: ${QT5_ROOT}") 12 | set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT5_ROOT}) 13 | endif() 14 | 15 | 16 | # ------------------------------------------------------------------------------ 17 | # Set output path 18 | # ------------------------------------------------------------------------------ 19 | set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) 20 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 21 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 22 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 23 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 24 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 25 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) 26 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) 27 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) 28 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) 29 | 30 | # ------------------------------------------------------------------------------ 31 | # Find packages 32 | # ------------------------------------------------------------------------------ 33 | find_package(OpenGL REQUIRED) 34 | find_package(Qt5Widgets REQUIRED) 35 | find_package(Qt5OpenGL REQUIRED) 36 | 37 | add_subdirectory(sources) 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QtOpenGLMousePick 2 | === 3 | 4 | > Sample program of OpenGL mouse picking with Qt5. 5 | 6 | ## Build 7 | 8 | Please use ```CMake``` to build this project :smiley: 9 | 10 | ```sh 11 | $ mkdir build 12 | $ cd build 13 | $ cmake .. 14 | $ cmake --build .. 15 | ``` 16 | 17 | #### Dependencies 18 | 19 | * OpenGL 20 | * Qt 5.5 21 | 22 | ## License 23 | 24 | MIT License (c) Tatsuya Yatagawa (tatsy) 25 | -------------------------------------------------------------------------------- /sources/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(BUILD_TARGET program) 2 | 3 | set(CMAKE_AUTOMOC ON) 4 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 5 | 6 | set(SOURCES ${SOURCES} 7 | main.cpp 8 | maingui.h 9 | maingui.cpp 10 | opengl_widget.h 11 | opengl_widget.cpp) 12 | 13 | add_executable(${BUILD_TARGET} ${SOURCES}) 14 | qt5_use_modules(${BUILD_TARGET} Widgets OpenGL) 15 | target_link_libraries(${BUILD_TARGET} ${OPENGL_LIBRARIES}) 16 | 17 | # ------------------------------------------------------------------------------ 18 | # Enable degugging and profiling 19 | # ------------------------------------------------------------------------------ 20 | if (MSVC) 21 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi") 22 | set_property(TARGET ${libname} APPEND PROPERTY LINK_FLAGS "/DEBUG /PROFILE") 23 | endif() 24 | 25 | # ------------------------------------------------------------------------------ 26 | # Copy Qt DLLs 27 | # ------------------------------------------------------------------------------ 28 | set(QT_LIB_LIST Qt5Widgets 29 | Qt5Widgetsd 30 | Qt5Core 31 | Qt5Cored 32 | Qt5Gui 33 | Qt5Guid 34 | Qt5Xml 35 | Qt5Xmld 36 | Qt5OpenGL 37 | Qt5OpenGLd 38 | Qt5Test 39 | Qt5Testd 40 | icuin54 41 | icuuc54 42 | icudt54) 43 | 44 | # ------------------------------------------------------------------------------ 45 | # Copy Qt5 DLLs 46 | # ------------------------------------------------------------------------------ 47 | if (WIN32) 48 | foreach (QT_LIB ${QT_LIB_LIST}) 49 | add_custom_command(TARGET ${BUILD_TARGET} POST_BUILD 50 | COMMAND ${CMAKE_COMMAND} -E copy 51 | ARGS ${CMAKE_PREFIX_PATH}/bin/${QT_LIB}.dll 52 | "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") 53 | endforeach() 54 | endif(WIN32) 55 | -------------------------------------------------------------------------------- /sources/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "maingui.h" 3 | 4 | int main(int argc, char** argv) { 5 | QApplication app(argc, argv); 6 | MainGui gui; 7 | gui.show(); 8 | return app.exec(); 9 | } -------------------------------------------------------------------------------- /sources/maingui.cpp: -------------------------------------------------------------------------------- 1 | #include "maingui.h" 2 | 3 | MainGui::MainGui(QWidget* parent) 4 | : QMainWindow(parent) 5 | , openglWidget(new OpenGLWidget) { 6 | this->setCentralWidget(openglWidget); 7 | this->resize(800, 600); 8 | } 9 | 10 | MainGui::~MainGui() { 11 | } 12 | 13 | -------------------------------------------------------------------------------- /sources/maingui.h: -------------------------------------------------------------------------------- 1 | #ifdef _MSC_VER 2 | #pragma once 3 | #endif 4 | 5 | #ifndef _MAIN_GUI_H_ 6 | #define _MAIN_GUI_H_ 7 | 8 | #include 9 | 10 | #include "opengl_widget.h" 11 | 12 | class MainGui : public QMainWindow { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit MainGui(QWidget* parent = nullptr); 17 | virtual ~MainGui(); 18 | 19 | private: 20 | OpenGLWidget* openglWidget; 21 | }; 22 | 23 | #endif // _MAIN_GUI_H_ 24 | -------------------------------------------------------------------------------- /sources/opengl_widget.cpp: -------------------------------------------------------------------------------- 1 | #include "opengl_widget.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | OpenGLWidget::OpenGLWidget(QWidget* parent) 8 | : QOpenGLWidget(parent) { 9 | } 10 | 11 | OpenGLWidget::~OpenGLWidget() { 12 | } 13 | 14 | void OpenGLWidget::initializeGL() { 15 | glEnable(GL_DEPTH_TEST); 16 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 17 | } 18 | 19 | void OpenGLWidget::resizeGL(int w, int h) { 20 | glViewport(0, 0, w, h); 21 | } 22 | 23 | void OpenGLWidget::paintGL() { 24 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 25 | 26 | int renderMode; 27 | glGetIntegerv(GL_RENDER_MODE, &renderMode); 28 | 29 | if (renderMode != GL_SELECT) { 30 | // Matrix setting 31 | glMatrixMode(GL_PROJECTION); 32 | glLoadIdentity(); 33 | const float aspect = static_cast(width()) / height(); 34 | gluPerspective(45.0, aspect, 1.0, 1000.0); 35 | } 36 | 37 | glMatrixMode(GL_MODELVIEW); 38 | glLoadIdentity(); 39 | gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 40 | 41 | drawObjects(); 42 | } 43 | 44 | void OpenGLWidget::mousePressEvent(QMouseEvent* ev) { 45 | // Selection buffer 46 | std::fill(selectBuffer.begin(), selectBuffer.end(), 0); 47 | glSelectBuffer(selectBufferSize, &selectBuffer[0]); 48 | 49 | // Draw for selection buffer 50 | glRenderMode(GL_SELECT); 51 | 52 | // Matrix setting 53 | glMatrixMode(GL_PROJECTION); 54 | glPushMatrix(); 55 | glLoadIdentity(); 56 | 57 | int viewport[4]; 58 | glGetIntegerv(GL_VIEWPORT, viewport); 59 | gluPickMatrix(ev->x(), height() - ev->y(), 5, 5, viewport); 60 | const float aspect = static_cast(viewport[2]) / viewport[3]; 61 | gluPerspective(45.0, aspect, 1.0, 1000.0); 62 | 63 | // Draw 64 | paintGL(); 65 | 66 | // Reset matrix setting 67 | glMatrixMode(GL_PROJECTION); 68 | glPopMatrix(); 69 | 70 | // Revert render mode 71 | int hits = glRenderMode(GL_RENDER); 72 | 73 | // Show selection 74 | printf("%d hits\n", hits); 75 | if (hits > 0) { 76 | int id = 0; 77 | for (int i = 0; i < hits; i++) { 78 | printf("Level: %u\n", selectBuffer[id + 0]); 79 | printf(" Min: %f\n", (double)selectBuffer[id + 1] / UINT_MAX); 80 | printf(" Max: %f\n", (double)selectBuffer[id + 2] / UINT_MAX); 81 | printf(" ID: %u\n", selectBuffer[id + 3]); 82 | id += 4; 83 | } 84 | } 85 | } 86 | 87 | void OpenGLWidget::mouseMoveEvent(QMouseEvent* ev) { 88 | } 89 | 90 | void OpenGLWidget::mouseReleaseEvent(QMouseEvent* ev) { 91 | } 92 | 93 | void OpenGLWidget::drawObjects() const { 94 | // Prepare for selection 95 | glInitNames(); 96 | glPushName(0); 97 | 98 | // First 99 | glColor3f(1.0f, 0.0f, 0.0f); 100 | glLoadName(1); 101 | glBegin(GL_TRIANGLES); 102 | glVertex3f(-1.0f, -1.0f, 0.0f); 103 | glVertex3f(-1.0f, 1.0f, 0.0f); 104 | glVertex3f( 1.0f, 1.0f, 0.0f); 105 | glEnd(); 106 | 107 | // Second 108 | glColor3f(0.0f, 1.0f, 0.0f); 109 | glLoadName(2); 110 | glBegin(GL_TRIANGLES); 111 | glVertex3f(-1.0f, -1.0f, 0.0f); 112 | glVertex3f( 1.0f, 1.0f, 0.0f); 113 | glVertex3f( 1.0f, -1.0f, 0.0f); 114 | glEnd(); 115 | } -------------------------------------------------------------------------------- /sources/opengl_widget.h: -------------------------------------------------------------------------------- 1 | #ifdef _MSC_VER 2 | #pragma once 3 | #endif 4 | 5 | #ifndef _OPENGL_WIDGET_H_ 6 | #define _OPENGL_WIDGET_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | class OpenGLWidget : public QOpenGLWidget { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit OpenGLWidget(QWidget* parent = nullptr); 17 | virtual ~OpenGLWidget(); 18 | 19 | protected: 20 | virtual void initializeGL() override; 21 | virtual void paintGL() override; 22 | virtual void resizeGL(int w, int h) override; 23 | virtual void mousePressEvent(QMouseEvent* ev) override; 24 | virtual void mouseMoveEvent(QMouseEvent* ev) override; 25 | virtual void mouseReleaseEvent(QMouseEvent* ev) override; 26 | 27 | private: 28 | void drawObjects() const; 29 | 30 | using uint = unsigned int; 31 | static const int selectBufferSize = 100; 32 | std::vector selectBuffer = std::vector(selectBufferSize); 33 | 34 | 35 | }; // class OpenGLWidget 36 | 37 | #endif // _OPENGL_WIDGET_H_ --------------------------------------------------------------------------------