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

# shapes.h

Geometric object rendering example.

    // -*- C++ -*-
    /*
     * shapes.h:
     * shapes demo.
     *
     * written by Naofumi Yasufuku  <naofumi@users.sourceforge.net>
     */

    #ifndef _SHAPES_H
    #define _SHAPES_H

    #include <gtkmm.h>

    #include <gtkglmm.h>

    //
    // Shapes classes.
    //

    namespace Shapes
    {

      class Scene;

      //
      // View class.
      //

      class View : public sigc::trackable
      {
        friend class Scene;

      public:
        static const float NEAR_CLIP;
        static const float FAR_CLIP;

        static const float INIT_POS_X;
        static const float INIT_POS_Y;
        static const float INIT_POS_Z;

        static const float INIT_AXIS_X;
        static const float INIT_AXIS_Y;
        static const float INIT_AXIS_Z;
        static const float INIT_ANGLE;

        static const float INIT_SCALE;

        static const float SCALE_MAX;
        static const float SCALE_MIN;

        static const float ANIMATE_THRESHOLD;

      public:
        View();
        virtual ~View();

      public:
        void frustum(int w, int h);

        void xform();

        void reset();

        void set_pos(float x, float y, float z)
        { m_Pos[0] = x; m_Pos[1] = y; m_Pos[2] = z; }

        void set_quat(float q0, float q1, float q2, float q3)
        { m_Quat[0] = q0; m_Quat[1] = q1; m_Quat[2] = q2; m_Quat[3] = q3; }

        void set_scale(float scale)
        { m_Scale = scale; }

        void enable_animation();

        void disable_animation();

        bool is_animate() const
        { return m_Animate; }

      protected:
        // Signal handlers:
        virtual bool on_button_press_event(GdkEventButton* event, Scene* scene);
        virtual bool on_button_release_event(GdkEventButton* event, Scene* scene);
        virtual bool on_motion_notify_event(GdkEventMotion* event, Scene* scene);

      private:
        float m_Pos[3];
        float m_Quat[4];
        float m_Scale;

        float m_QuatDiff[4];
        float m_BeginX;
        float m_BeginY;
        float m_DX;
        float m_DY;

        bool m_Animate;

      };

      //
      // Model class.
      //

      class Model
      {
        friend class Scene;

      public:
        static const unsigned int NUM_SHAPES;

        enum ShapeType
          {
            CUBE,
            SPHERE,
            CONE,
            TORUS,
            TETRAHEDRON,
            OCTAHEDRON,
            DODECAHEDRON,
            ICOSAHEDRON,
            TEAPOT,
          };

        static const ShapeType SHAPE_CUBE;
        static const ShapeType SHAPE_SPHERE;
        static const ShapeType SHAPE_CONE;
        static const ShapeType SHAPE_TORUS;
        static const ShapeType SHAPE_TETRAHEDRON;
        static const ShapeType SHAPE_OCTAHEDRON;
        static const ShapeType SHAPE_DODECAHEDRON;
        static const ShapeType SHAPE_ICOSAHEDRON;
        static const ShapeType SHAPE_TEAPOT;

      public:

        struct MaterialProp
        {
          GLfloat ambient[4];
          GLfloat diffuse[4];
          GLfloat specular[4];
          GLfloat shininess;
        };

        static const MaterialProp MAT_EMERALD;
        static const MaterialProp MAT_JADE;
        static const MaterialProp MAT_OBSIDIAN;
        static const MaterialProp MAT_PEARL;
        static const MaterialProp MAT_RUBY;
        static const MaterialProp MAT_TURQUOISE;
        static const MaterialProp MAT_BRASS;
        static const MaterialProp MAT_BRONZE;
        static const MaterialProp MAT_CHROME;
        static const MaterialProp MAT_COPPER;
        static const MaterialProp MAT_GOLD;
        static const MaterialProp MAT_SILVER;

      public:
        Model();
        virtual ~Model();

      private:
        void init_gl(Glib::RefPtr<Gdk::GL::Drawable>& gldrawable);

      public:
        void draw(Glib::RefPtr<Gdk::GL::Drawable>& gldrawable);

        void set_shape(ShapeType shape)
        { m_CurrentShape = shape; }

        void set_material(const MaterialProp* material)
        { m_CurrentMat = material; }

      private:
        unsigned int m_ListBase;
        ShapeType m_CurrentShape;
        const MaterialProp* m_CurrentMat;

      };

      //
      // Scene class.
      //

      class Scene : public Gtk::GL::DrawingArea
      {
        friend class View;
        friend class Model;

      public:
        // OpenGL scene related constants:
        static const float CLEAR_COLOR[4];
        static const float CLEAR_DEPTH;

        static const float LIGHT0_POSITION[4];
        static const float LIGHT0_AMBIENT[4];
        static const float LIGHT0_DIFFUSE[4];

        static const float LIGHT_MODEL_AMBIENT[4];
        static const float LIGHT_MODEL_LOCAL_VIEWER[1];

      public:
        explicit Scene();
        virtual ~Scene();

      protected:
        // signal handlers:
        virtual void on_realize();
        virtual bool on_configure_event(GdkEventConfigure* event);
        virtual bool on_expose_event(GdkEventExpose* event);
        virtual bool on_button_press_event(GdkEventButton* 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() {
          get_window()->invalidate_rect(get_allocation(), false);
        }

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

      protected:
        // idle signal connection:
        sigc::connection m_ConnectionIdle;

        void idle_add();
        void idle_remove();

      protected:
        void change_shape(Model::ShapeType shape);
        void change_material(const Model::MaterialProp* material);

      protected:
        Gtk::Menu* create_popup_menu();

      protected:
        // Popup menu:
        Gtk::Menu* m_Menu;

      protected:
        // OpenGL scene related objects:
        View m_View;
        Model m_Model;

      };

      //
      // Application class.
      //

      class Application : public Gtk::Window
      {
      public:
        static const Glib::ustring APP_NAME;

      public:
        Application();
        virtual ~Application();

      protected:
        // signal handlers:
        virtual void on_button_quit_clicked();
        virtual bool on_key_press_event(GdkEventKey* event);

      protected:
        // member widgets:
        Gtk::VBox m_VBox;
        Scene m_Scene;
        Gtk::Button m_ButtonQuit;
      };

    } // namespace Shapes

    #endif // _SHAPES_H