<!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 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 Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Class Members</a> | <a class="qindex" href="globals.html">File 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 <naofumi@users.sourceforge.net></span> <span class="comment"> */</span> <span class="preprocessor">#include <iostream></span> <span class="preprocessor">#include <cstdlib></span> <span class="preprocessor">#include <cstring></span> <span class="preprocessor">#include <cmath></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 <windows.h></span> <span class="preprocessor">#endif</span> <span class="preprocessor"></span> <span class="preprocessor">#include <GL/gl.h></span> <span class="preprocessor">#include <GL/glu.h></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<const Gdk::GL::Config>& 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<const Gdk::GL::Config>& 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<const Gdk::GL::Config>& 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->get_attrib(attrib, value)) { std::cout << attrib_str << <span class="stringliteral">" = "</span>; <span class="keywordflow">if</span> (is_boolean) std::cout << (value == <span class="keyword">true</span> ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) << std::endl; <span class="keywordflow">else</span> std::cout << value << std::endl; } <span class="keywordflow">else</span> { std::cout << <span class="stringliteral">"*** Cannot get "</span> << attrib_str << <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<const Gdk::GL::Config>& glconfig) { std::cout << <span class="stringliteral">"\nOpenGL visual configurations :\n\n"</span>; std::cout << <span class="stringliteral">"glconfig->is_rgba() = "</span> << (glconfig->is_rgba() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) << std::endl; std::cout << <span class="stringliteral">"glconfig->is_double_buffered() = "</span> << (glconfig->is_double_buffered() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) << std::endl; std::cout << <span class="stringliteral">"glconfig->is_stereo() = "</span> << (glconfig->is_stereo() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) << std::endl; std::cout << <span class="stringliteral">"glconfig->has_alpha() = "</span> << (glconfig->has_alpha() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) << std::endl; std::cout << <span class="stringliteral">"glconfig->has_depth_buffer() = "</span> << (glconfig->has_depth_buffer() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) << std::endl; std::cout << <span class="stringliteral">"glconfig->has_stencil_buffer() = "</span> << (glconfig->has_stencil_buffer() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) << std::endl; std::cout << <span class="stringliteral">"glconfig->has_accum_buffer() = "</span> << (glconfig->has_accum_buffer() ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>) << std::endl; std::cout << 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 << 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 > h) { <span class="keywordtype">float</span> aspect = static_cast<float>(w) / static_cast<float>(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<float>(h) / static_cast<float>(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(&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->button == 1) { disable_animation(); scene->idle_remove(); scene->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->x; m_BeginY = event->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->button == 1 && ((m_DX*m_DX + m_DY*m_DY) > ANIMATE_THRESHOLD)) { enable_animation(); scene->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->get_width(); <span class="keywordtype">float</span> h = scene->get_height(); <span class="keywordtype">float</span> x = event->x; <span class="keywordtype">float</span> y = event->y; <span class="keywordtype">bool</span> redraw = <span class="keyword">false</span>; <span class="comment">// Rotation.</span> <span class="keywordflow">if</span> (event->state & 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->state & GDK_BUTTON2_MASK) { m_Scale = m_Scale * (1.0 + (y - m_BeginY) / h); <span class="keywordflow">if</span> (m_Scale > SCALE_MAX) m_Scale = SCALE_MAX; <span class="keywordflow">else</span> <span class="keywordflow">if</span> (m_Scale < 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->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(&MAT_SILVER) { } Model::~Model() { } <span class="keywordtype">void</span> Model::init_gl(Glib::RefPtr<Gdk::GL::Drawable>& 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->draw_cube(<span class="keyword">true</span>, 1.5); glEndList(); <span class="comment">/* Sphere */</span> glNewList(m_ListBase + SPHERE, GL_COMPILE); gldrawable->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->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->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->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->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->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->draw_icosahedron(<span class="keyword">true</span>); glPopMatrix(); glEndList(); <span class="comment">/* Teapot */</span> glNewList(m_ListBase + TEAPOT, GL_COMPILE); gldrawable->draw_teapot(<span class="keyword">true</span>, 1.0); glEndList(); } <span class="keywordtype">void</span> Model::draw(Glib::RefPtr<Gdk::GL::Drawable>& 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->ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, m_CurrentMat->diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, m_CurrentMat->specular); glMaterialf(GL_FRONT, GL_SHININESS, m_CurrentMat->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<Gdk::GL::Config> 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 << <span class="stringliteral">"*** Cannot find the double-buffered visual.\n"</span> << <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 << <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, &View::on_button_press_event), <span class="keyword">this</span>)); signal_button_release_event().connect( sigc::bind(sigc::mem_fun(m_View, &View::on_button_release_event), <span class="keyword">this</span>)); signal_motion_notify_event().connect( sigc::bind(sigc::mem_fun(m_View, &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<Gdk::GL::Drawable> 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->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->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<Gdk::GL::Drawable> 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->gl_begin(get_gl_context())) <span class="keywordflow">return</span> <span class="keyword">false</span>; m_View.frustum(get_width(), get_height()); gldrawable->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<Gdk::GL::Drawable> 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->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->is_double_buffered()) gldrawable->swap_buffers(); <span class="keywordflow">else</span> glFlush(); gldrawable->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->button == 3) { m_Menu->popup(event->button, event->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->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>, &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& menu_list = shapes_menu->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>, &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>, &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>, &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>, &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>, &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>, &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>, &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>, &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>, &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& menu_list = materials_menu->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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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>, &Scene::change_material), &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& menu_list = menu->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(&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>, &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->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 << <span class="stringliteral">"OpenGL extension version - "</span> << major << <span class="stringliteral">"."</span> << minor << 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 <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>