Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Examples

# simple.cc

Simple gtkglextmm example.

    // -*- C++ -*-
    /*
     * simple.cc:
     * Simple gtkglextmm example.
     *
     * written by Naofumi Yasufuku  <naofumi@users.sourceforge.net>
     */

    #include <iostream>
    #include <cstdlib>

    #include <gtkmm.h>

    #include <gtkglmm.h>

    #ifdef G_OS_WIN32
    #define WIN32_LEAN_AND_MEAN 1
    #include <windows.h>
    #endif

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

    //
    // OpenGL frame buffer configuration utilities.
    //

    struct GLConfigUtil
    {
      static void print_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig,
                                  const char* attrib_str,
                                  int attrib,
                                  bool is_boolean);

      static void examine_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig);
    };

    //
    // Print a configuration attribute.
    //
    void GLConfigUtil::print_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig,
                                       const char* attrib_str,
                                       int attrib,
                                       bool is_boolean)
    {
      int value;

      if (glconfig->get_attrib(attrib, value))
        {
          std::cout << attrib_str << " = ";
          if (is_boolean)
            std::cout << (value == true ? "true" : "false") << std::endl;
          else
            std::cout << value << std::endl;
        }
      else
        {
          std::cout << "*** Cannot get "
                    << attrib_str
                    << " attribute value\n";
        }
    }

    //
    // Print configuration attributes.
    //
    void GLConfigUtil::examine_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig)
    {
      std::cout << "\nOpenGL visual configurations :\n\n";

      std::cout << "glconfig->is_rgba() = "
                << (glconfig->is_rgba() ? "true" : "false")
                << std::endl;
      std::cout << "glconfig->is_double_buffered() = "
                << (glconfig->is_double_buffered() ? "true" : "false")
                << std::endl;
      std::cout << "glconfig->is_stereo() = "
                << (glconfig->is_stereo() ? "true" : "false")
                << std::endl;
      std::cout << "glconfig->has_alpha() = "
                << (glconfig->has_alpha() ? "true" : "false")
                << std::endl;
      std::cout << "glconfig->has_depth_buffer() = "
                << (glconfig->has_depth_buffer() ? "true" : "false")
                << std::endl;
      std::cout << "glconfig->has_stencil_buffer() = "
                << (glconfig->has_stencil_buffer() ? "true" : "false")
                << std::endl;
      std::cout << "glconfig->has_accum_buffer() = "
                << (glconfig->has_accum_buffer() ? "true" : "false")
                << std::endl;

      std::cout << std::endl;

      print_gl_attrib(glconfig, "Gdk::GL::USE_GL",           Gdk::GL::USE_GL,           true);
      print_gl_attrib(glconfig, "Gdk::GL::BUFFER_SIZE",      Gdk::GL::BUFFER_SIZE,      false);
      print_gl_attrib(glconfig, "Gdk::GL::LEVEL",            Gdk::GL::LEVEL,            false);
      print_gl_attrib(glconfig, "Gdk::GL::RGBA",             Gdk::GL::RGBA,             true);
      print_gl_attrib(glconfig, "Gdk::GL::DOUBLEBUFFER",     Gdk::GL::DOUBLEBUFFER,     true);
      print_gl_attrib(glconfig, "Gdk::GL::STEREO",           Gdk::GL::STEREO,           true);
      print_gl_attrib(glconfig, "Gdk::GL::AUX_BUFFERS",      Gdk::GL::AUX_BUFFERS,      false);
      print_gl_attrib(glconfig, "Gdk::GL::RED_SIZE",         Gdk::GL::RED_SIZE,         false);
      print_gl_attrib(glconfig, "Gdk::GL::GREEN_SIZE",       Gdk::GL::GREEN_SIZE,       false);
      print_gl_attrib(glconfig, "Gdk::GL::BLUE_SIZE",        Gdk::GL::BLUE_SIZE,        false);
      print_gl_attrib(glconfig, "Gdk::GL::ALPHA_SIZE",       Gdk::GL::ALPHA_SIZE,       false);
      print_gl_attrib(glconfig, "Gdk::GL::DEPTH_SIZE",       Gdk::GL::DEPTH_SIZE,       false);
      print_gl_attrib(glconfig, "Gdk::GL::STENCIL_SIZE",     Gdk::GL::STENCIL_SIZE,     false);
      print_gl_attrib(glconfig, "Gdk::GL::ACCUM_RED_SIZE",   Gdk::GL::ACCUM_RED_SIZE,   false);
      print_gl_attrib(glconfig, "Gdk::GL::ACCUM_GREEN_SIZE", Gdk::GL::ACCUM_GREEN_SIZE, false);
      print_gl_attrib(glconfig, "Gdk::GL::ACCUM_BLUE_SIZE",  Gdk::GL::ACCUM_BLUE_SIZE,  false);
      print_gl_attrib(glconfig, "Gdk::GL::ACCUM_ALPHA_SIZE", Gdk::GL::ACCUM_ALPHA_SIZE, false);

      std::cout << std::endl;
    }

    //
    // Simple OpenGL scene.
    //

    class SimpleGLScene : public Gtk::DrawingArea,
                          public Gtk::GL::Widget<SimpleGLScene>
    {
    public:
      SimpleGLScene();
      virtual ~SimpleGLScene();

    protected:
      virtual void on_realize();
      virtual bool on_configure_event(GdkEventConfigure* event);
      virtual bool on_expose_event(GdkEventExpose* event);

    };

    SimpleGLScene::SimpleGLScene()
    {
      //
      // Configure OpenGL-capable visual.
      //

      Glib::RefPtr<Gdk::GL::Config> glconfig;

      // Try double-buffered visual
      glconfig = Gdk::GL::Config::create(Gdk::GL::MODE_RGB    |
                                         Gdk::GL::MODE_DEPTH  |
                                         Gdk::GL::MODE_DOUBLE);
      if (!glconfig)
        {
          std::cerr << "*** Cannot find the double-buffered visual.\n"
                    << "*** Trying single-buffered visual.\n";

          // Try single-buffered visual
          glconfig = Gdk::GL::Config::create(Gdk::GL::MODE_RGB   |
                                             Gdk::GL::MODE_DEPTH);
          if (!glconfig)
            {
              std::cerr << "*** Cannot find any OpenGL-capable visual.\n";
              std::exit(1);
            }
        }

      // print frame buffer attributes.
      GLConfigUtil::examine_gl_attrib(glconfig);

      //
      // Set OpenGL-capability to the widget.
      //

      set_gl_capability(glconfig);
    }

    SimpleGLScene::~SimpleGLScene()
    {
    }

    void SimpleGLScene::on_realize()
    {
      // We need to call the base on_realize()
      Gtk::DrawingArea::on_realize();

      //
      // Get GL::Window.
      //

      Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();

      //
      // GL calls.
      //

      // *** OpenGL BEGIN ***
      if (!glwindow->gl_begin(get_gl_context()))
        return;

      GLUquadricObj* qobj = gluNewQuadric();
      gluQuadricDrawStyle(qobj, GLU_FILL);
      glNewList(1, GL_COMPILE);
      gluSphere(qobj, 1.0, 20, 20);
      glEndList();

      static GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0};
      static GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
      glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
      glLightfv(GL_LIGHT0, GL_POSITION, light_position);
      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      glEnable(GL_DEPTH_TEST);

      glClearColor(1.0, 1.0, 1.0, 1.0);
      glClearDepth(1.0);

      glViewport(0, 0, get_width(), get_height());

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(40.0, 1.0, 1.0, 10.0);

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      gluLookAt(0.0, 0.0, 3.0,
                0.0, 0.0, 0.0,
                0.0, 1.0, 0.0);
      glTranslatef(0.0, 0.0, -3.0);

      glwindow->gl_end();
      // *** OpenGL END ***
    }

    bool SimpleGLScene::on_configure_event(GdkEventConfigure* event)
    {
      //
      // Get GL::Window.
      //

      Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();

      //
      // GL calls.
      //

      // *** OpenGL BEGIN ***
      if (!glwindow->gl_begin(get_gl_context()))
        return false;

      glViewport(0, 0, get_width(), get_height());

      glwindow->gl_end();
      // *** OpenGL END ***

      return true;
    }

    bool SimpleGLScene::on_expose_event(GdkEventExpose* event)
    {
      //
      // Get GL::Window.
      //

      Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();

      //
      // GL calls.
      //

      // *** OpenGL BEGIN ***
      if (!glwindow->gl_begin(get_gl_context()))
        return false;

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

      glCallList(1);

      // Swap buffers.
      if (glwindow->is_double_buffered())
        glwindow->swap_buffers();
      else
        glFlush();

      glwindow->gl_end();
      // *** OpenGL END ***

      return true;
    }

    //
    // The application class.
    //

    class Simple : public Gtk::Window
    {
    public:
      Simple();
      virtual ~Simple();

    protected:
      // signal handlers:
      void on_button_quit_clicked();

    protected:
      // member widgets:
      Gtk::VBox m_VBox;
      SimpleGLScene m_SimpleGLScene;
      Gtk::Button m_ButtonQuit;
    };

    Simple::Simple()
      : m_VBox(false, 0), m_ButtonQuit("Quit")
    {
      //
      // Top-level window.
      //

      set_title("Simple");

      // Get automatically redrawn if any of their children changed allocation.
      set_reallocate_redraws(true);

      add(m_VBox);

      //
      // Simple OpenGL scene.
      //

      m_SimpleGLScene.set_size_request(200, 200);

      m_VBox.pack_start(m_SimpleGLScene);

      //
      // Simple quit button.
      //

      m_ButtonQuit.signal_clicked().connect(
        sigc::mem_fun(*this, &Simple::on_button_quit_clicked));

      m_VBox.pack_start(m_ButtonQuit, Gtk::PACK_SHRINK, 0);

      //
      // Show window.
      //

      show_all();
    }

    Simple::~Simple()
    {}

    void Simple::on_button_quit_clicked()
    {
      Gtk::Main::quit();
    }

    //
    // Main.
    //

    int main(int argc, char** argv)
    {
      Gtk::Main kit(argc, argv);

      //
      // Init gtkglextmm.
      //

      Gtk::GL::init(argc, argv);

      //
      // Query OpenGL extension version.
      //

      int major, minor;
      Gdk::GL::query_version(major, minor);
      std::cout << "OpenGL extension version - "
                << major << "." << minor << std::endl;

      //
      // Instantiate and run the application.
      //

      Simple simple;

      kit.run(simple);

      return 0;
    }