LoginSignup
1
0

More than 3 years have passed since last update.

GLUT on FLTK でteapotを描く

Last updated at Posted at 2020-12-15

GLUT on FLTK のサンプルコードと落とし穴の解決

1. GLUT+FLTKでteapotを描く

GLUTを使ったOpenGL描画とFLTKを組み合わせて使いたい。
ネットに色々と記事が転がっているが、それだと上手く行かない(Segmentation Faultが出る)という事態に遭遇したので対処法を残しておく。

2.準備

Ubuntuでのfltk開発用ライブラリのインストール

$ sudo apt install libfltk1.3-dev

でOK。

3.参考にしたコード

こちらこちらで紹介されているサンプルコードを参考にさせていただきました。

4.作成したサンプルコード

サンプルコード
sample.cpp
#include <iostream>
#include <string>

//#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <FL/glut.H>

#include <FL/Fl.H>
#include <FL/Fl_Gl_Window.H>
#include <FL/Fl_Menu_Bar.H>

using namespace std;

const GLfloat MY_LIGHT0_POS[4] = { 2.0f, 4.0f, 1.0f, 0.0f };
const GLfloat MY_LIGHT_AMBI[4] = { 0.1f, 0.1f, 0.1f, 1.0f };
const GLfloat MY_LIGHT_DIFF[4] = { 0.9f, 0.9f, 0.9f, 1.0f };
const GLfloat MY_LIGHT_SPEC[4] = { 0.2f, 0.2f, 0.2f, 1.0f };


class myFlGLWindow : public Fl_Gl_Window
{
public:
// Constructor
myFlGLWindow(int x_, int y_, int w_, int h_, const char* l=0)
: Fl_Gl_Window(x_, y_, w_, h_, l) {
}
// Destructor
virtual ~myFlGLWindow() {
}

void InitGL(void)
{
cout << "OpenGL Ver. " << glGetString(GL_VERSION) << endl;
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);

// Light setting
glLightfv(GL_LIGHT0, GL_AMBIENT, MY_LIGHT_AMBI);
glLightfv(GL_LIGHT0, GL_DIFFUSE, MY_LIGHT_DIFF);
glLightfv(GL_LIGHT0, GL_SPECULAR, MY_LIGHT_SPEC);
glLightfv(GL_LIGHT0, GL_POSITION, MY_LIGHT0_POS);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);

glShadeModel(GL_SMOOTH);

glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
}

void Resize(int w, int h)
{
cout << "Resize " << w << " x " << h << endl;
glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)w/(float)h, 0.2f, 1000.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glTranslatef(0.0f, 0.0f, -5.0f);
}

// Drawing function here..
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

// glut function for drawing here
glColor3f(0.0, 0.0, 1.0);
glutSolidTeapot(1.0);
}

private:
// for redrawing event
void draw(void)
{
if(!context_valid()){
InitGL();
}
if(!valid()){
Resize(w(), h());
}

// OpenGL
Display();
}

};


int main(int argc, char *argv[])
{
Fl::scheme("gtk+");
Fl::visual(FL_DOUBLE | FL_RGB);
Fl::get_system_colors();

//glutInit(&argc, argv);
//glutCreateWindow("hoge");
Fl_Window *flwin = new Fl_Window(480,480,"hoge");

//myFlGLWindow *window = new myFlGLWindow(100, 100, 480, 480, "FLTK + GLUT TEST");
myFlGLWindow *window = new myFlGLWindow(10, 10, flwin->w()-20, flwin->h()-20);
flwin->resizable(window);
flwin->show();
return Fl::run();
}

これを

$ g++ -O3 sample.cpp -o sample -lfltk -lfltk_gl -lGLU -lGL

とすればコンパイルされるはず。実行すると下図のようにteapotが描画される。

image.png

5.ハマった落とし穴

以下の点でかなりハマってしまった。

当初、冒頭のインクルードファイルの指定を

#include <GL/gl.h>
#include <GL/glut.h>

としていて問題なく動いていた。但し、このままではglutSolidTeapotを呼んだ時に「先にglutInitを呼んでおけ」とエラーが出るので、glutInit関数を呼ぶようにしていた(サンプルコード下の方のglutInit行のコメントアウトを外していた)。
※なお、fltkのサイトのマニュアルにはglutInitを呼ぶな、との指示があるので、いずれにせよこの方法は非推奨と思われる。

システムアップデートに伴い上記の対応ではsegmentation faultが出るように(何かがnull pointerになっている?)。glutInitの後にglutCreateWindowを呼ぶとセグフォは回避されるが、変な空ウインドウが出来ることになってしまう(下図、teapotが描かれているウィンドウの右側)。

image.png

暫くもがいた結果、インクルードファイルをGL/glut.hでなく

#include <FL/glut.H>

とすればセグフォが出ないことに気づいた。但し、これをするとなぜかglu関連の関数がないよと言われるので、これに加えて

#include <GL/glu.h>

も加える必要があった。その結果導きだした解が上記のサンプルコードである。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0