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

gears.cc

3-D gear wheels demo.
// -*- C++ -*-
/*
 * 3-D gear wheels.  This program is in the public domain.
 *
 * Brian Paul
 */

/* Conversion to gtkglextmm by Naofumi Yasufuku */

#include <iostream>
#include <cstdlib>
#include <cmath>

#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;
}


//
// Gears scene.
//

class GearsScene : public Gtk::GL::DrawingArea
{
public:
  explicit GearsScene(bool is_sync = true);
  virtual ~GearsScene();

protected:
  void gear(GLfloat inner_radius,
            GLfloat outer_radius,
            GLfloat width,
            GLint   teeth,
            GLfloat tooth_depth);

protected:
  // signal handlers:
  virtual void on_realize();
  virtual bool on_configure_event(GdkEventConfigure* event);
  virtual bool on_expose_event(GdkEventExpose* event);
  virtual bool on_map_event(GdkEventAny* event);
  virtual bool on_unmap_event(GdkEventAny* event);
  virtual bool on_visibility_notify_event(GdkEventVisibility* event);
  virtual bool on_idle();

public:
  // Invalidate whole window.
  void invalidate() {
    GtkAllocation allocation = get_allocation();
    get_window()->invalidate_rect(Gdk::Rectangle(&allocation), false);
  }

  // Update window synchronously (fast).
  void update()
  { get_window()->process_updates(false); }

protected:
  // idle signal connection:
  SigC::Connection m_ConnectionIdle;

public:
  // get & set view rotation values.
  void get_view_rot(GLfloat& x, GLfloat& y, GLfloat& z)
  { x = m_ViewRotX; y = m_ViewRotY; z = m_ViewRotZ; }

  void set_view_rot(GLfloat x, GLfloat y, GLfloat z)
  { m_ViewRotX = x; m_ViewRotY = y; m_ViewRotZ = z; }

protected:
  // OpenGL scene related variables:
  GLint m_Gear1;
  GLint m_Gear2;
  GLint m_Gear3;

  GLfloat m_ViewRotX;
  GLfloat m_ViewRotY;
  GLfloat m_ViewRotZ;

  GLfloat m_Angle;

  bool m_IsSync;

protected:
  // frame rate evaluation stuff:
  Glib::Timer m_Timer;
  int m_Frames;
};

GearsScene::GearsScene(bool is_sync)
  : m_Gear1(0), m_Gear2(0), m_Gear3(0),
    m_ViewRotX(20.0), m_ViewRotY(30.0), m_ViewRotZ(0.0),
    m_Angle(0.0), m_IsSync(is_sync),
    m_Frames(0)
{
  //
  // 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.is_null())
    {
      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.is_null())
        {
          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);

  // Add events.
  add_events(Gdk::VISIBILITY_NOTIFY_MASK);
}

GearsScene::~GearsScene()
{
}

/*
 * Draw a gear wheel.  You'll probably want to call this function when
 * building a display list since we do a lot of trig here.
 *
 * Input:  inner_radius - radius of hole at center
 * outer_radius - radius at center of teeth
 * width - width of gear
 * teeth - number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth
 * tooth_depth - o- number of teeth