OpenGLUTのWINDOWとQtのWigetを共存するには、普通に行うとmain関数からQtのWidgetとかGLUTのWindowを出すと、早く呼ばれたどちらかのWindowオブジェクトが表示され、後に呼ばれるもう一つのWindowオブジェクトが表示されません。
また、Qtのmainwindow.cppのコンストラクタからGLUTのWindowを呼んでも同じです。
理由は、メッセージループの話で、どちらも内部でUIイベント監視用の無限ループを作っているので、そこのルーチンに入り、もう一つのウィンドウが呼ばれないということになると考えられます。
そこで、Qthreadを使い、非同期で呼ぶソースを添付します。
今回のソースはQthreadを使ってファイアー・アンド・フォーゲットなっているので、アプリがクローズした場合のスレッドを止める処理を考えなければならない。
Mainwindow
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include "openglut_uitherad.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
openglut_uiTherad *myth;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
private:
Ui::MainWindow *ui;
void createOpenGLUTWinThread();
};
mainwindow.cpp
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "./ui_mainwindow.h"
void MainWindow::createOpenGLUTWinThread()
{
this->myth = new openglut_uiTherad();
this->myth->moveToThread(myth);
this->myth->start();
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//MultithreadでGLUTのWiNDOWを生成する
createOpenGLUTWinThread();
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
this->myth->quit();
this->myth->exit();
delete ui;
}
openGLUT_UI
openglut_ui.h
#ifndef OPENGLUT_UI_H
#define OPENGLUT_UI_H
#include <GL/glut.h>
#include <GL/freeglut.h>
#include <QDebug>
class openGLUT_UI : public QObject
{
public:
openGLUT_UI();
public:
static void initialOpenGLUT(int argc, char *argv[]);
static void dispCallback();
static void resizeCallback(int w, int h);
static void mouseCallback(int button, int state, int x, int y);
};
#endif // OPENGLUT_UI_H
openglut_ui.cpp
#include "openglut_ui.h"
openGLUT_UI::openGLUT_UI()
{
}
void openGLUT_UI::initialOpenGLUT(int argc, char *argv[])
{
glutInit(&argc,argv);
glutCreateWindow("window");
glutDisplayFunc(openGLUT_UI::dispCallback);
glutReshapeFunc(openGLUT_UI::resizeCallback);
glutMouseFunc(openGLUT_UI::mouseCallback);
glutMainLoop();
}
void openGLUT_UI::dispCallback()
{
glClear(GL_COLOR_BUFFER_BIT);
//SET light-gray color
glClearColor(211.0f/255.0f, 211.0f/255.0f, 211.0f/255.0f, 1.0f);
glBegin ( GL_TRIANGLES );
glColor3f ( 1.0 , 0.0 , 0.0 );
glVertex3f (- 0.5 , - 0.5 , 0 );
glColor3f ( 0.0 , 1.0 , 0.0 );
glVertex3f ( 0.5 , - 0.5 , 0 );
glColor3f ( 0.0 , 0.0 , 1.0 );
glVertex3f ( 0.0 , 0.5 , 0 );
glEnd ();
glFlush();
}
void openGLUT_UI::resizeCallback(int w, int h)
{
/* ウィンドウ全体をビューポートにする */
glViewport(0, 0, w, h);
/* 変換行列の初期化 */
glLoadIdentity();
/* スクリーン上の表示領域をビューポートの大きさに比例させる */
glOrtho(-w / 100, w / 100, -h / 100, h / 100, -1.0, 1.0);
}
void openGLUT_UI::mouseCallback(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON:
qDebug("left");
break;
case GLUT_MIDDLE_BUTTON:
qDebug("middle");
break;
case GLUT_RIGHT_BUTTON:
qDebug("right");
break;
default:
break;
}
}
openglut_uiTherad
openglut_uiTherad.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QThread>
#include "openglut_ui.h"
class openglut_uiTherad : public QThread
{
Q_OBJECT
public:
explicit openglut_uiTherad(QObject *parent = nullptr);
protected:
void run();
signals:
public slots:
};
#endif // MYTHREAD_H
openglut_uiTherad.cpp
#include "openglut_uitherad.h"
openglut_uiTherad::openglut_uiTherad(QObject *parent) : QThread(parent)
{
}
void openglut_uiTherad::run()
{
openGLUT_UI::initialOpenGLUT(0,nullptr);
}