Sophie

Sophie

distrib > Mageia > 7 > armv7hl > media > core-release > by-pkgid > 4385fe4d2beb794f6ab11a7801f18ad5 > files > 241

gtkglextmm-doc-1.2.0-11.mga7.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>gtkglextmm: shapes.cc</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.4 -->
<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="namespacemembers.html">Namespace&nbsp;Members</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="globals.html">File&nbsp;Members</a> | <a class="qindex" href="examples.html">Examples</a></div>
<h1>shapes.cc</h1>Geometric object rendering example.<p>
<div class="fragment"><pre class="fragment"><span class="comment">// -*- C++ -*-</span>
<span class="comment">/*</span>
<span class="comment"> * shapes.cc:</span>
<span class="comment"> * shapes demo.</span>
<span class="comment"> *</span>
<span class="comment"> * written by Naofumi Yasufuku  &lt;naofumi@users.sourceforge.net&gt;</span>
<span class="comment"> */</span>

<span class="preprocessor">#include &lt;iostream&gt;</span>
<span class="preprocessor">#include &lt;cstdlib&gt;</span>
<span class="preprocessor">#include &lt;cstring&gt;</span>
<span class="preprocessor">#include &lt;cmath&gt;</span>

<span class="preprocessor">#ifdef G_OS_WIN32</span>
<span class="preprocessor"></span><span class="preprocessor">#define WIN32_LEAN_AND_MEAN 1</span>
<span class="preprocessor"></span><span class="preprocessor">#include &lt;windows.h&gt;</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor"></span>
<span class="preprocessor">#include &lt;GL/gl.h&gt;</span>
<span class="preprocessor">#include &lt;GL/glu.h&gt;</span>

<span class="preprocessor">#include "shapes.h"</span>

<span class="comment">//</span>
<span class="comment">// Trackball utilities.</span>
<span class="comment">//</span>
<span class="keyword">namespace </span>Trackball {
  <span class="keyword">extern</span> <span class="stringliteral">"C"</span> {
<span class="preprocessor">    #include "trackball.h"</span>
  }
}

<span class="preprocessor">#define DIG_2_RAD (G_PI / 180.0)</span>
<span class="preprocessor"></span><span class="preprocessor">#define RAD_2_DIG (180.0 / G_PI)</span>
<span class="preprocessor"></span>

<span class="comment">//</span>
<span class="comment">// OpenGL frame buffer configuration utilities.</span>
<span class="comment">//</span>
<span class="comment"></span>
<span class="keyword">struct </span>GLConfigUtil
{
  <span class="keyword">static</span> <span class="keywordtype">void</span> print_gl_attrib(<span class="keyword">const</span> Glib::RefPtr&lt;const Gdk::GL::Config&gt;&amp; glconfig,
                              <span class="keyword">const</span> <span class="keywordtype">char</span>* attrib_str,
                              <span class="keywordtype">int</span> attrib,
                              <span class="keywordtype">bool</span> is_boolean);

  <span class="keyword">static</span> <span class="keywordtype">void</span> examine_gl_attrib(<span class="keyword">const</span> Glib::RefPtr&lt;const Gdk::GL::Config&gt;&amp; glconfig);
};

<span class="comment">//</span>
<span class="comment">// Print a configuration attribute.</span>
<span class="comment">//</span>
<span class="keywordtype">void</span> GLConfigUtil::print_gl_attrib(<span class="keyword">const</span> Glib::RefPtr&lt;const Gdk::GL::Config&gt;&amp; glconfig,
                                   <span class="keyword">const</span> <span class="keywordtype">char</span>* attrib_str,
                                   <span class="keywordtype">int</span> attrib,
                                   <span class="keywordtype">bool</span> is_boolean)
{
  <span class="keywordtype">int</span> value;

  <span class="keywordflow">if</span> (glconfig-&gt;get_attrib(attrib, value))
    {
      std::cout &lt;&lt; attrib_str &lt;&lt; <span class="stringliteral">" = "</span>;
      <span class="keywordflow">if</span> (is_boolean)
        std::cout &lt;&lt; (value == <span class="keyword">true</span> ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) &lt;&lt; std::endl;
      <span class="keywordflow">else</span>
        std::cout &lt;&lt; value &lt;&lt; std::endl;
    }
  <span class="keywordflow">else</span>
    {
      std::cout &lt;&lt; <span class="stringliteral">"*** Cannot get "</span>
                &lt;&lt; attrib_str
                &lt;&lt; <span class="stringliteral">" attribute value\n"</span>;
    }
}

<span class="comment">//</span>
<span class="comment">// Print configuration attributes.</span>
<span class="comment">//</span>
<span class="keywordtype">void</span> GLConfigUtil::examine_gl_attrib(<span class="keyword">const</span> Glib::RefPtr&lt;const Gdk::GL::Config&gt;&amp; glconfig)
{
  std::cout &lt;&lt; <span class="stringliteral">"\nOpenGL visual configurations :\n\n"</span>;

  std::cout &lt;&lt; <span class="stringliteral">"glconfig-&gt;is_rgba() = "</span>
            &lt;&lt; (glconfig-&gt;is_rgba() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>)
            &lt;&lt; std::endl;
  std::cout &lt;&lt; <span class="stringliteral">"glconfig-&gt;is_double_buffered() = "</span>
            &lt;&lt; (glconfig-&gt;is_double_buffered() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>)
            &lt;&lt; std::endl;
  std::cout &lt;&lt; <span class="stringliteral">"glconfig-&gt;is_stereo() = "</span>
            &lt;&lt; (glconfig-&gt;is_stereo() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>)
            &lt;&lt; std::endl;
  std::cout &lt;&lt; <span class="stringliteral">"glconfig-&gt;has_alpha() = "</span>
            &lt;&lt; (glconfig-&gt;has_alpha() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>)
            &lt;&lt; std::endl;
  std::cout &lt;&lt; <span class="stringliteral">"glconfig-&gt;has_depth_buffer() = "</span>
            &lt;&lt; (glconfig-&gt;has_depth_buffer() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>)
            &lt;&lt; std::endl;
  std::cout &lt;&lt; <span class="stringliteral">"glconfig-&gt;has_stencil_buffer() = "</span>
            &lt;&lt; (glconfig-&gt;has_stencil_buffer() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>)
            &lt;&lt; std::endl;
  std::cout &lt;&lt; <span class="stringliteral">"glconfig-&gt;has_accum_buffer() = "</span>
            &lt;&lt; (glconfig-&gt;has_accum_buffer() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>)
            &lt;&lt; std::endl;

  std::cout &lt;&lt; std::endl;

  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::USE_GL"</span>,           <a name="a119"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a15">Gdk::GL::USE_GL</a>,           <span class="keyword">true</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::BUFFER_SIZE"</span>,      <a name="a120"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a16">Gdk::GL::BUFFER_SIZE</a>,      <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::LEVEL"</span>,            <a name="a121"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a17">Gdk::GL::LEVEL</a>,            <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::RGBA"</span>,             <a name="a122"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a18">Gdk::GL::RGBA</a>,             <span class="keyword">true</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::DOUBLEBUFFER"</span>,     <a name="a123"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a19">Gdk::GL::DOUBLEBUFFER</a>,     <span class="keyword">true</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::STEREO"</span>,           <a name="a124"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a20">Gdk::GL::STEREO</a>,           <span class="keyword">true</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::AUX_BUFFERS"</span>,      <a name="a125"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a21">Gdk::GL::AUX_BUFFERS</a>,      <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::RED_SIZE"</span>,         <a name="a126"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a22">Gdk::GL::RED_SIZE</a>,         <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::GREEN_SIZE"</span>,       <a name="a127"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a23">Gdk::GL::GREEN_SIZE</a>,       <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::BLUE_SIZE"</span>,        <a name="a128"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a24">Gdk::GL::BLUE_SIZE</a>,        <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::ALPHA_SIZE"</span>,       <a name="a129"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a25">Gdk::GL::ALPHA_SIZE</a>,       <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::DEPTH_SIZE"</span>,       <a name="a130"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a26">Gdk::GL::DEPTH_SIZE</a>,       <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::STENCIL_SIZE"</span>,     <a name="a131"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a27">Gdk::GL::STENCIL_SIZE</a>,     <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::ACCUM_RED_SIZE"</span>,   <a name="a132"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a28">Gdk::GL::ACCUM_RED_SIZE</a>,   <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::ACCUM_GREEN_SIZE"</span>, <a name="a133"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a29">Gdk::GL::ACCUM_GREEN_SIZE</a>, <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::ACCUM_BLUE_SIZE"</span>,  <a name="a134"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a30">Gdk::GL::ACCUM_BLUE_SIZE</a>,  <span class="keyword">false</span>);
  print_gl_attrib(glconfig, <span class="stringliteral">"Gdk::GL::ACCUM_ALPHA_SIZE"</span>, <a name="a135"></a><a class="code" href="group__gdkmm__glEnums.html#gga36a31">Gdk::GL::ACCUM_ALPHA_SIZE</a>, <span class="keyword">false</span>);

  std::cout &lt;&lt; std::endl;
}


<span class="comment">//</span>
<span class="comment">// Shapes classes.</span>
<span class="comment">//</span>
<span class="comment"></span>
<span class="keyword">namespace </span>Shapes
{

  <span class="comment">//</span>
  <span class="comment">// View class implementation.</span>
  <span class="comment">//</span>

  <span class="keyword">const</span> <span class="keywordtype">float</span> View::NEAR_CLIP   = 5.0;
  <span class="keyword">const</span> <span class="keywordtype">float</span> View::FAR_CLIP    = 60.0;

  <span class="keyword">const</span> <span class="keywordtype">float</span> View::INIT_POS_X  = 0.0;
  <span class="keyword">const</span> <span class="keywordtype">float</span> View::INIT_POS_Y  = 0.0;
  <span class="keyword">const</span> <span class="keywordtype">float</span> View::INIT_POS_Z  = -10.0;

  <span class="keyword">const</span> <span class="keywordtype">float</span> View::INIT_AXIS_X = 1.0;
  <span class="keyword">const</span> <span class="keywordtype">float</span> View::INIT_AXIS_Y = 0.0;
  <span class="keyword">const</span> <span class="keywordtype">float</span> View::INIT_AXIS_Z = 0.0;
  <span class="keyword">const</span> <span class="keywordtype">float</span> View::INIT_ANGLE  = 0.0;

  <span class="keyword">const</span> <span class="keywordtype">float</span> View::INIT_SCALE  = 1.0;

  <span class="keyword">const</span> <span class="keywordtype">float</span> View::SCALE_MAX   = 2.0;
  <span class="keyword">const</span> <span class="keywordtype">float</span> View::SCALE_MIN   = 0.5;

  <span class="keyword">const</span> <span class="keywordtype">float</span> View::ANIMATE_THRESHOLD = 25.0;

  View::View()
    : m_Scale(INIT_SCALE),
      m_BeginX(0.0), m_BeginY(0.0),
      m_DX(0.0), m_DY(0.0),
      m_Animate(false)
  {
    reset();
  }

  View::~View()
  {
  }

  <span class="keywordtype">void</span> View::frustum(<span class="keywordtype">int</span> w, <span class="keywordtype">int</span> h)
  {
    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    <span class="keywordflow">if</span> (w &gt; h) {
      <span class="keywordtype">float</span> aspect = static_cast&lt;float&gt;(w) / static_cast&lt;float&gt;(h);
      glFrustum(-aspect, aspect, -1.0, 1.0, NEAR_CLIP, FAR_CLIP);
    } <span class="keywordflow">else</span> {
      <span class="keywordtype">float</span> aspect = static_cast&lt;float&gt;(h) / static_cast&lt;float&gt;(w);
      glFrustum(-1.0, 1.0, -aspect, aspect, NEAR_CLIP, FAR_CLIP);
    }

    glMatrixMode(GL_MODELVIEW);
  }

  <span class="keywordtype">void</span> View::xform()
  {
    glTranslatef(m_Pos[0], m_Pos[1], m_Pos[2]);

    glScalef(m_Scale, m_Scale, m_Scale);

    <span class="keywordtype">float</span> m[4][4];
    Trackball::add_quats(m_QuatDiff, m_Quat, m_Quat);
    Trackball::build_rotmatrix(m, m_Quat);
    glMultMatrixf(&amp;m[0][0]);
  }

  <span class="keywordtype">void</span> View::reset()
  {
    m_Pos[0] = INIT_POS_X;
    m_Pos[1] = INIT_POS_Y;
    m_Pos[2] = INIT_POS_Z;

    <span class="keywordtype">float</span> sine = sin(0.5 * INIT_ANGLE * DIG_2_RAD);
    m_Quat[0] = INIT_AXIS_X * sine;
    m_Quat[1] = INIT_AXIS_Y * sine;
    m_Quat[2] = INIT_AXIS_Z * sine;
    m_Quat[3] = cos(0.5 * INIT_ANGLE * DIG_2_RAD);

    m_Scale = INIT_SCALE;

    m_QuatDiff[0] = 0.0;
    m_QuatDiff[1] = 0.0;
    m_QuatDiff[2] = 0.0;
    m_QuatDiff[3] = 1.0;
  }

  <span class="keywordtype">void</span> View::enable_animation()
  {
    m_Animate = <span class="keyword">true</span>;
  }

  <span class="keywordtype">void</span> View::disable_animation()
  {
    m_Animate = <span class="keyword">false</span>;

    m_QuatDiff[0] = 0.0;
    m_QuatDiff[1] = 0.0;
    m_QuatDiff[2] = 0.0;
    m_QuatDiff[3] = 1.0;
  }

  <span class="keywordtype">bool</span> View::on_button_press_event(GdkEventButton* event,
                                   Scene* scene)
  {
    <span class="keywordflow">if</span> (is_animate()) {
      <span class="keywordflow">if</span> (event-&gt;button == 1) {
        disable_animation();
        scene-&gt;idle_remove();
        scene-&gt;invalidate();
      }
    } <span class="keywordflow">else</span> {
      m_QuatDiff[0] = 0.0;
      m_QuatDiff[1] = 0.0;
      m_QuatDiff[2] = 0.0;
      m_QuatDiff[3] = 1.0;
    }

    m_BeginX = event-&gt;x;
    m_BeginY = event-&gt;y;

    <span class="comment">// don't block</span>
    <span class="keywordflow">return</span> <span class="keyword">false</span>;
  }

  <span class="keywordtype">bool</span> View::on_button_release_event(GdkEventButton* event,
                                     Scene* scene)
  {
    <span class="keywordflow">if</span> (!is_animate()) {
      <span class="keywordflow">if</span> (event-&gt;button == 1 &amp;&amp;
          ((m_DX*m_DX + m_DY*m_DY) &gt; ANIMATE_THRESHOLD)) {
        enable_animation();
        scene-&gt;idle_add();
      }
    }

    m_DX = 0.0;
    m_DY = 0.0;

    <span class="comment">// don't block</span>
    <span class="keywordflow">return</span> <span class="keyword">false</span>;
  }

  <span class="keywordtype">bool</span> View::on_motion_notify_event(GdkEventMotion* event,
                                    Scene* scene)
  {
    <span class="keywordtype">float</span> w = scene-&gt;get_width();
    <span class="keywordtype">float</span> h = scene-&gt;get_height();
    <span class="keywordtype">float</span> x = event-&gt;x;
    <span class="keywordtype">float</span> y = event-&gt;y;
    <span class="keywordtype">bool</span> redraw = <span class="keyword">false</span>;

    <span class="comment">// Rotation.</span>
    <span class="keywordflow">if</span> (event-&gt;state &amp; GDK_BUTTON1_MASK) {
      Trackball::trackball(m_QuatDiff,
                           (2.0 * m_BeginX - w) / w,
                           (h - 2.0 * m_BeginY) / h,
                           (2.0 * x - w) / w,
                           (h - 2.0 * y) / h);

      m_DX = x - m_BeginX;
      m_DY = y - m_BeginY;

      redraw = <span class="keyword">true</span>;
    }

    <span class="comment">// Scaling.</span>
    <span class="keywordflow">if</span> (event-&gt;state &amp; GDK_BUTTON2_MASK) {
      m_Scale = m_Scale * (1.0 + (y - m_BeginY) / h);
      <span class="keywordflow">if</span> (m_Scale &gt; SCALE_MAX)
        m_Scale = SCALE_MAX;
      <span class="keywordflow">else</span> <span class="keywordflow">if</span> (m_Scale &lt; SCALE_MIN)
        m_Scale = SCALE_MIN;

      redraw = <span class="keyword">true</span>;
    }

    m_BeginX = x;
    m_BeginY = y;

    <span class="keywordflow">if</span> (redraw)
      scene-&gt;invalidate();

    <span class="comment">// don't block</span>
    <span class="keywordflow">return</span> <span class="keyword">false</span>;
  }


  <span class="comment">//</span>
  <span class="comment">// Model class implementation.</span>
  <span class="comment">//</span>

  <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Model::NUM_SHAPES = 9;

  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_CUBE         = CUBE;
  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_SPHERE       = SPHERE;
  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_CONE         = CONE;
  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_TORUS        = TORUS;
  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_TETRAHEDRON  = TETRAHEDRON;
  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_OCTAHEDRON   = OCTAHEDRON;
  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_DODECAHEDRON = DODECAHEDRON;
  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_ICOSAHEDRON  = ICOSAHEDRON;
  <span class="keyword">const</span> Model::ShapeType Model::SHAPE_TEAPOT       = TEAPOT;

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_EMERALD = {
    {0.0215, 0.1745, 0.0215, 1.0},
    {0.07568, 0.61424, 0.07568, 1.0},
    {0.633, 0.727811, 0.633, 1.0},
    0.6
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_JADE = {
    {0.135, 0.2225, 0.1575, 1.0},
    {0.54, 0.89, 0.63, 1.0},
    {0.316228, 0.316228, 0.316228, 1.0},
    0.1
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_OBSIDIAN = {
    {0.05375, 0.05, 0.06625, 1.0},
    {0.18275, 0.17, 0.22525, 1.0},
    {0.332741, 0.328634, 0.346435, 1.0},
    0.3
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_PEARL = {
    {0.25, 0.20725, 0.20725, 1.0},
    {1.0, 0.829, 0.829, 1.0},
    {0.296648, 0.296648, 0.296648, 1.0},
    0.088
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_RUBY = {
    {0.1745, 0.01175, 0.01175, 1.0},
    {0.61424, 0.04136, 0.04136, 1.0},
    {0.727811, 0.626959, 0.626959, 1.0},
    0.6
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_TURQUOISE = {
    {0.1, 0.18725, 0.1745, 1.0},
    {0.396, 0.74151, 0.69102, 1.0},
    {0.297254, 0.30829, 0.306678, 1.0},
    0.1
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_BRASS = {
    {0.329412, 0.223529, 0.027451, 1.0},
    {0.780392, 0.568627, 0.113725, 1.0},
    {0.992157, 0.941176, 0.807843, 1.0},
    0.21794872
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_BRONZE = {
    {0.2125, 0.1275, 0.054, 1.0},
    {0.714, 0.4284, 0.18144, 1.0},
    {0.393548, 0.271906, 0.166721, 1.0},
    0.2
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_CHROME = {
    {0.25, 0.25, 0.25, 1.0},
    {0.4, 0.4, 0.4, 1.0},
    {0.774597, 0.774597, 0.774597, 1.0},
    0.6
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_COPPER = {
    {0.19125, 0.0735, 0.0225, 1.0},
    {0.7038, 0.27048, 0.0828, 1.0},
    {0.256777, 0.137622, 0.086014, 1.0},
    0.1
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_GOLD = {
    {0.24725, 0.1995, 0.0745, 1.0},
    {0.75164, 0.60648, 0.22648, 1.0},
    {0.628281, 0.555802, 0.366065, 1.0},
    0.4
  };

  <span class="keyword">const</span> Model::MaterialProp Model::MAT_SILVER = {
    {0.19225, 0.19225, 0.19225, 1.0},
    {0.50754, 0.50754, 0.50754, 1.0},
    {0.508273, 0.508273, 0.508273, 1.0},
    0.4
  };

  Model::Model()
    : m_ListBase(0),
      m_CurrentShape(TEAPOT),
      m_CurrentMat(&amp;MAT_SILVER)
  {
  }

  Model::~Model()
  {
  }

  <span class="keywordtype">void</span> Model::init_gl(Glib::RefPtr&lt;Gdk::GL::Drawable&gt;&amp; gldrawable)
  {
    <span class="comment">/* Shape display lists */</span>
    m_ListBase = glGenLists(NUM_SHAPES);

    <span class="comment">/* Cube */</span>
    glNewList(m_ListBase + CUBE, GL_COMPILE);
      gldrawable-&gt;draw_cube(<span class="keyword">true</span>, 1.5);
    glEndList();

    <span class="comment">/* Sphere */</span>
    glNewList(m_ListBase + SPHERE, GL_COMPILE);
      gldrawable-&gt;draw_sphere(<span class="keyword">true</span>, 1.0, 30, 30);
    glEndList();

    <span class="comment">/* Cone */</span>
    glNewList(m_ListBase + CONE, GL_COMPILE);
      glPushMatrix();
        glTranslatef(0.0, 0.0, -1.0);
        gldrawable-&gt;draw_cone(<span class="keyword">true</span>, 1.0, 2.0, 30, 30);
      glPopMatrix();
    glEndList();

    <span class="comment">/* Torus */</span>
    glNewList(m_ListBase + TORUS, GL_COMPILE);
      gldrawable-&gt;draw_torus(<span class="keyword">true</span>, 0.4, 0.8, 30, 30);
    glEndList();

    <span class="comment">/* Tetrahedron */</span>
    glNewList(m_ListBase + TETRAHEDRON, GL_COMPILE);
      glPushMatrix();
        glScalef(1.2, 1.2, 1.2);
        gldrawable-&gt;draw_tetrahedron(<span class="keyword">true</span>);
      glPopMatrix();
    glEndList();

    <span class="comment">/* Octahedron */</span>
    glNewList(m_ListBase + OCTAHEDRON, GL_COMPILE);
      glPushMatrix();
        glScalef(1.2, 1.2, 1.2);
        gldrawable-&gt;draw_octahedron(<span class="keyword">true</span>);
      glPopMatrix();
    glEndList();

    <span class="comment">/* Dodecahedron */</span>
    glNewList(m_ListBase + DODECAHEDRON, GL_COMPILE);
      glPushMatrix();
        glScalef(0.7, 0.7, 0.7);
        gldrawable-&gt;draw_dodecahedron(<span class="keyword">true</span>);
      glPopMatrix();
    glEndList();

    <span class="comment">/* Icosahedron */</span>
    glNewList(m_ListBase + ICOSAHEDRON, GL_COMPILE);
      glPushMatrix();
        glScalef(1.2, 1.2, 1.2);
        gldrawable-&gt;draw_icosahedron(<span class="keyword">true</span>);
      glPopMatrix();
    glEndList();

    <span class="comment">/* Teapot */</span>
    glNewList(m_ListBase + TEAPOT, GL_COMPILE);
      gldrawable-&gt;draw_teapot(<span class="keyword">true</span>, 1.0);
    glEndList();
  }

  <span class="keywordtype">void</span> Model::draw(Glib::RefPtr&lt;Gdk::GL::Drawable&gt;&amp; gldrawable)
  {
    <span class="comment">// Init GL context.</span>
    <span class="keyword">static</span> <span class="keywordtype">bool</span> initialized = <span class="keyword">false</span>;
    <span class="keywordflow">if</span> (!initialized) {
      init_gl(gldrawable);
      initialized = <span class="keyword">true</span>;
    }

    <span class="comment">// Render shape</span>
    glMaterialfv(GL_FRONT, GL_AMBIENT, m_CurrentMat-&gt;ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, m_CurrentMat-&gt;diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, m_CurrentMat-&gt;specular);
    glMaterialf(GL_FRONT, GL_SHININESS, m_CurrentMat-&gt;shininess * 128.0);
    glCallList(m_ListBase + m_CurrentShape);
  }


  <span class="comment">//</span>
  <span class="comment">// Scene class implementation.</span>
  <span class="comment">//</span>

  <span class="keyword">const</span> <span class="keywordtype">float</span> Scene::CLEAR_COLOR[4] = { 0.5, 0.5, 0.8, 1.0 };
  <span class="keyword">const</span> <span class="keywordtype">float</span> Scene::CLEAR_DEPTH    = 1.0;

  <span class="keyword">const</span> <span class="keywordtype">float</span> Scene::LIGHT0_POSITION[4] = { 0.0, 3.0, 3.0, 0.0 };
  <span class="keyword">const</span> <span class="keywordtype">float</span> Scene::LIGHT0_AMBIENT[4]  = { 0.0, 0.0, 0.0, 1.0 };
  <span class="keyword">const</span> <span class="keywordtype">float</span> Scene::LIGHT0_DIFFUSE[4]  = { 1.0, 1.0, 1.0, 1.0 };

  <span class="keyword">const</span> <span class="keywordtype">float</span> Scene::LIGHT_MODEL_AMBIENT[4]       = { 0.2, 0.2, 0.2, 1.0 };
  <span class="keyword">const</span> <span class="keywordtype">float</span> Scene::LIGHT_MODEL_LOCAL_VIEWER[1]  = { 0.0 };

  Scene::Scene()
    : m_Menu(0)
  {
    <span class="comment">//</span>
    <span class="comment">// Configure OpenGL-capable visual.</span>
    <span class="comment">//</span>

    Glib::RefPtr&lt;Gdk::GL::Config&gt; glconfig;

    <span class="comment">// Try double-buffered visual</span>
    glconfig = <a name="a136"></a><a class="code" href="classGdk_1_1GL_1_1Config.html#e0">Gdk::GL::Config::create</a>(<a name="a137"></a><a class="code" href="group__gdkmm__glEnums.html#gga35a0">Gdk::GL::MODE_RGB</a>    |
                                       <a name="a138"></a><a class="code" href="group__gdkmm__glEnums.html#gga35a7">Gdk::GL::MODE_DEPTH</a>  |
                                       <a name="a139"></a><a class="code" href="group__gdkmm__glEnums.html#gga35a4">Gdk::GL::MODE_DOUBLE</a>);
    <span class="keywordflow">if</span> (!glconfig) {
      std::cerr &lt;&lt; <span class="stringliteral">"*** Cannot find the double-buffered visual.\n"</span>
                &lt;&lt; <span class="stringliteral">"*** Trying single-buffered visual.\n"</span>;

      <span class="comment">// Try single-buffered visual</span>
      glconfig = <a class="code" href="classGdk_1_1GL_1_1Config.html#e0">Gdk::GL::Config::create</a>(<a class="code" href="group__gdkmm__glEnums.html#gga35a0">Gdk::GL::MODE_RGB</a>   |
                                         <a class="code" href="group__gdkmm__glEnums.html#gga35a7">Gdk::GL::MODE_DEPTH</a>);
      <span class="keywordflow">if</span> (!glconfig) {
        std::cerr &lt;&lt; <span class="stringliteral">"*** Cannot find any OpenGL-capable visual.\n"</span>;
        std::exit(1);
      }
    }

    <span class="comment">// print frame buffer attributes.</span>
    GLConfigUtil::examine_gl_attrib(glconfig);

    <span class="comment">//</span>
    <span class="comment">// Set OpenGL-capability to the widget.</span>
    <span class="comment">//</span>

    set_gl_capability(glconfig);

    <span class="comment">//</span>
    <span class="comment">// Add events.</span>
    <span class="comment">//</span>
    add_events(Gdk::BUTTON1_MOTION_MASK    |
               Gdk::BUTTON2_MOTION_MASK    |
               Gdk::BUTTON_PRESS_MASK      |
               Gdk::BUTTON_RELEASE_MASK    |
               Gdk::VISIBILITY_NOTIFY_MASK);

    <span class="comment">// View transformation signals.</span>
    signal_button_press_event().connect(
      sigc::bind(sigc::mem_fun(m_View, &amp;View::on_button_press_event), <span class="keyword">this</span>));
    signal_button_release_event().connect(
      sigc::bind(sigc::mem_fun(m_View, &amp;View::on_button_release_event), <span class="keyword">this</span>));
    signal_motion_notify_event().connect(
      sigc::bind(sigc::mem_fun(m_View, &amp;View::on_motion_notify_event), <span class="keyword">this</span>));

    <span class="comment">//</span>
    <span class="comment">// Popup menu.</span>
    <span class="comment">//</span>

    m_Menu = create_popup_menu();
  }

  Scene::~Scene()
  {
  }

  <span class="keywordtype">void</span> Scene::on_realize()
  {
    <span class="comment">// We need to call the base on_realize()</span>
    Gtk::DrawingArea::on_realize();

    <span class="comment">//</span>
    <span class="comment">// Get GL::Drawable.</span>
    <span class="comment">//</span>

    Glib::RefPtr&lt;Gdk::GL::Drawable&gt; gldrawable = get_gl_drawable();

    <span class="comment">//</span>
    <span class="comment">// GL calls.</span>
    <span class="comment">//</span>

    <span class="comment">// *** OpenGL BEGIN ***</span>
    <span class="keywordflow">if</span> (!gldrawable-&gt;gl_begin(get_gl_context()))
      <span class="keywordflow">return</span>;

    glClearColor(CLEAR_COLOR[0], CLEAR_COLOR[1], CLEAR_COLOR[2], CLEAR_COLOR[3]);
    glClearDepth(CLEAR_DEPTH);

    glLightfv(GL_LIGHT0, GL_POSITION, LIGHT0_POSITION);
    glLightfv(GL_LIGHT0, GL_AMBIENT,  LIGHT0_AMBIENT);
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  LIGHT0_DIFFUSE);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LIGHT_MODEL_AMBIENT);
    glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, LIGHT_MODEL_LOCAL_VIEWER);

    glFrontFace(GL_CW);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_AUTO_NORMAL);
    glEnable(GL_NORMALIZE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    gldrawable-&gt;gl_end();
    <span class="comment">// *** OpenGL END ***</span>
  }

  <span class="keywordtype">bool</span> Scene::on_configure_event(GdkEventConfigure* event)
  {
    <span class="comment">//</span>
    <span class="comment">// Get GL::Drawable.</span>
    <span class="comment">//</span>

    Glib::RefPtr&lt;Gdk::GL::Drawable&gt; gldrawable = get_gl_drawable();

    <span class="comment">//</span>
    <span class="comment">// GL calls.</span>
    <span class="comment">//</span>

    <span class="comment">// *** OpenGL BEGIN ***</span>
    <span class="keywordflow">if</span> (!gldrawable-&gt;gl_begin(get_gl_context()))
      <span class="keywordflow">return</span> <span class="keyword">false</span>;

    m_View.frustum(get_width(), get_height());

    gldrawable-&gt;gl_end();
    <span class="comment">// *** OpenGL END ***</span>

    <span class="keywordflow">return</span> <span class="keyword">true</span>;
  }

  <span class="keywordtype">bool</span> Scene::on_expose_event(GdkEventExpose* event)
  {
    <span class="comment">//</span>
    <span class="comment">// Get GL::Drawable.</span>
    <span class="comment">//</span>

    Glib::RefPtr&lt;Gdk::GL::Drawable&gt; gldrawable = get_gl_drawable();

    <span class="comment">//</span>
    <span class="comment">// GL calls.</span>
    <span class="comment">//</span>

    <span class="comment">// *** OpenGL BEGIN ***</span>
    <span class="keywordflow">if</span> (!gldrawable-&gt;gl_begin(get_gl_context()))
      <span class="keywordflow">return</span> <span class="keyword">false</span>;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    <span class="comment">// View transformation.</span>
    m_View.xform();

    <span class="comment">// Logo model.</span>
    m_Model.draw(gldrawable);

    <span class="comment">// Swap buffers.</span>
    <span class="keywordflow">if</span> (gldrawable-&gt;is_double_buffered())
      gldrawable-&gt;swap_buffers();
    <span class="keywordflow">else</span>
      glFlush();

    gldrawable-&gt;gl_end();
    <span class="comment">// *** OpenGL END ***</span>

    <span class="keywordflow">return</span> <span class="keyword">true</span>;
  }

  <span class="keywordtype">bool</span> Scene::on_button_press_event(GdkEventButton* event)
  {
    <span class="keywordflow">if</span> (event-&gt;button == 3) {
      m_Menu-&gt;popup(event-&gt;button, event-&gt;time);
      <span class="keywordflow">return</span> <span class="keyword">true</span>;
    }

    <span class="comment">// don't block</span>
    <span class="keywordflow">return</span> <span class="keyword">false</span>;
  }

  <span class="keywordtype">bool</span> Scene::on_unmap_event(GdkEventAny* event)
  {
    idle_remove();

    <span class="keywordflow">return</span> <span class="keyword">true</span>;
  }

  <span class="keywordtype">bool</span> Scene::on_visibility_notify_event(GdkEventVisibility* event)
  {
    <span class="keywordflow">if</span> (m_View.is_animate()) {
      <span class="keywordflow">if</span> (event-&gt;state == GDK_VISIBILITY_FULLY_OBSCURED)
        idle_remove();
      <span class="keywordflow">else</span>
        idle_add();
    }

    <span class="keywordflow">return</span> <span class="keyword">true</span>;
  }

  <span class="keywordtype">bool</span> Scene::on_idle()
  {
    <span class="comment">// Invalidate whole window.</span>
    invalidate();
    <span class="comment">// Update window synchronously (fast).</span>
    update();

    <span class="keywordflow">return</span> <span class="keyword">true</span>;
  }

  <span class="keywordtype">void</span> Scene::idle_add()
  {
    <span class="keywordflow">if</span> (!m_ConnectionIdle.connected())
      m_ConnectionIdle = Glib::signal_idle().connect(
        sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::on_idle), GDK_PRIORITY_REDRAW);
  }

  <span class="keywordtype">void</span> Scene::idle_remove()
  {
    <span class="keywordflow">if</span> (m_ConnectionIdle.connected())
      m_ConnectionIdle.disconnect();
  }

  <span class="keywordtype">void</span> Scene::change_shape(Model::ShapeType shape)
  {
    m_Model.set_shape(shape);
    m_View.reset();
  }

  <span class="keywordtype">void</span> Scene::change_material(<span class="keyword">const</span> Model::MaterialProp* material)
  {
    m_Model.set_material(material);
  }

  Gtk::Menu* Scene::create_popup_menu()
  {

    <span class="comment">// Shapes submenu</span>
    Gtk::Menu* shapes_menu = Gtk::manage(<span class="keyword">new</span> Gtk::Menu());
    {
      Gtk::Menu::MenuList&amp; menu_list = shapes_menu-&gt;items();

      <span class="comment">// Cube</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Cube"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_CUBE)));

      <span class="comment">// Sphere</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Sphere"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_SPHERE)));

      <span class="comment">// Cone</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Cone"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_CONE)));

      <span class="comment">// Torus</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Torus"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_TORUS)));

      <span class="comment">// Tetrahedron</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Tetrahedron"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_TETRAHEDRON)));

      <span class="comment">// Octahedron</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Octahedron"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_OCTAHEDRON)));

      <span class="comment">// Dodecahedron</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Dodecahedron"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_DODECAHEDRON)));

      <span class="comment">// Icosahedron</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Icosahedron"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_ICOSAHEDRON)));

      <span class="comment">// Teapot</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Teapot"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_shape),
                   Model::SHAPE_TEAPOT)));

    }

    <span class="comment">// Materials submenu</span>
    Gtk::Menu* materials_menu = Gtk::manage(<span class="keyword">new</span> Gtk::Menu());
    {
      Gtk::Menu::MenuList&amp; menu_list = materials_menu-&gt;items();

      <span class="comment">// Emerald</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Emerald"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_EMERALD)));

      <span class="comment">// Jade</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Jade"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_JADE)));

      <span class="comment">// Obsidian</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Obsidian"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_OBSIDIAN)));

      <span class="comment">// Pearl</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Pearl"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_PEARL)));

      <span class="comment">// Ruby</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Ruby"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_RUBY)));

      <span class="comment">// Turquoise</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Turquoise"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_TURQUOISE)));

      <span class="comment">// Brass</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Brass"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_BRASS)));

      <span class="comment">// Bronze</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Bronze"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_BRONZE)));

      <span class="comment">// Chrome</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Chrome"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_CHROME)));

      <span class="comment">// Copper</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Copper"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_COPPER)));

      <span class="comment">// Gold</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Gold"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_GOLD)));

      <span class="comment">// Silver</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Silver"</span>,
        sigc::bind(sigc::mem_fun(*<span class="keyword">this</span>, &amp;Scene::change_material),
                   &amp;Model::MAT_SILVER)));

    }

    <span class="comment">// Root popup menu</span>
    Gtk::Menu* menu = Gtk::manage(<span class="keyword">new</span> Gtk::Menu());
    {
      Gtk::Menu::MenuList&amp; menu_list = menu-&gt;items();

      <span class="comment">// Shapes submenu</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Shapes"</span>,
                                                      *shapes_menu));

      <span class="comment">// Materials submenu</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Materials"</span>,
                                                      *materials_menu));

      <span class="comment">// Quit</span>
      menu_list.push_back(Gtk::Menu_Helpers::MenuElem(<span class="stringliteral">"Quit"</span>,
        sigc::ptr_fun(&amp;Gtk::Main::quit)));
    }

    <span class="keywordflow">return</span> menu;
  }


  <span class="comment">//</span>
  <span class="comment">// Application class implementation.</span>
  <span class="comment">//</span>

  <span class="keyword">const</span> Glib::ustring Application::APP_NAME = <span class="stringliteral">"Shapes"</span>;

  Application::Application()
    : m_VBox(false, 0), m_ButtonQuit(<span class="stringliteral">"Quit"</span>)
  {
    <span class="comment">//</span>
    <span class="comment">// Top-level window.</span>
    <span class="comment">//</span>

    set_title(APP_NAME);

    <span class="comment">// Get automatically redrawn if any of their children changed allocation.</span>
    set_reallocate_redraws(<span class="keyword">true</span>);

    add(m_VBox);

    <span class="comment">//</span>
    <span class="comment">// Scene.</span>
    <span class="comment">//</span>

    m_Scene.set_size_request(300, 300);

    m_VBox.pack_start(m_Scene);

    <span class="comment">//</span>
    <span class="comment">// Simple quit button.</span>
    <span class="comment">//</span>

    m_ButtonQuit.signal_clicked().connect(
      sigc::mem_fun(*<span class="keyword">this</span>, &amp;Application::on_button_quit_clicked));

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

    <span class="comment">//</span>
    <span class="comment">// Show window.</span>
    <span class="comment">//</span>

    show_all();
  }

  Application::~Application()
  {
  }

  <span class="keywordtype">void</span> Application::on_button_quit_clicked()
  {
    Gtk::Main::quit();
  }

  <span class="keywordtype">bool</span> Application::on_key_press_event(GdkEventKey* event)
  {
    <span class="keywordflow">switch</span> (event-&gt;keyval) {
    <span class="keywordflow">case</span> GDK_Escape:
      Gtk::Main::quit();
      <span class="keywordflow">break</span>;
    <span class="keywordflow">default</span>:
      <span class="keywordflow">return</span> <span class="keyword">true</span>;
    }

    m_Scene.invalidate();

    <span class="keywordflow">return</span> <span class="keyword">true</span>;
  }


} <span class="comment">// namespace Shapes</span>


<span class="comment">//</span>
<span class="comment">// Main.</span>
<span class="comment">//</span>
<span class="comment"></span>
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>** argv)
{
  Gtk::Main kit(argc, argv);

  <span class="comment">//</span>
  <span class="comment">// Init gtkglextmm.</span>
  <span class="comment">//</span>

  <a name="a140"></a><a class="code" href="namespaceGtk_1_1GL.html#a2">Gtk::GL::init</a>(argc, argv);

  <span class="comment">//</span>
  <span class="comment">// Query OpenGL extension version.</span>
  <span class="comment">//</span>

  <span class="keywordtype">int</span> major, minor;
  <a name="a141"></a><a class="code" href="namespaceGdk_1_1GL.html#a116">Gdk::GL::query_version</a>(major, minor);
  std::cout &lt;&lt; <span class="stringliteral">"OpenGL extension version - "</span>
            &lt;&lt; major &lt;&lt; <span class="stringliteral">"."</span> &lt;&lt; minor &lt;&lt; std::endl;

  <span class="comment">//</span>
  <span class="comment">// Instantiate and run the application.</span>
  <span class="comment">//</span>

  Shapes::Application application;

  kit.run(application);

  <span class="keywordflow">return</span> 0;
}
</pre></div> <hr size="1"><address style="align: right;"><small>Generated on Mon Feb 27 18:46:52 2006 for gtkglextmm by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.4 </small></address>
</body>
</html>