#include /* rand() */ #include #include #include #include #include "SierpinskiDA.h" using namespace std; SierpinskiDA::SierpinskiDA(const Glib::RefPtr & config) : Gtk::GL::DrawingArea(config) { set_gl_capability(config); set_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK); } void SierpinskiDA::regenerate(int npts) { #define deg2rad(x) ((x)/180.0*M_PI) const static float pts[][3] = { {0, 0, sqrt(1 + sin(deg2rad(60))*sin(deg2rad(60))+1.5*1.5)}, {0, 1, 0}, {sin(deg2rad(60)), -cos(deg2rad(60)), 0}, {-sin(deg2rad(60)), -cos(deg2rad(60)), 0} }; gl_begin(); glNewList(m_dl, GL_COMPILE); glBegin(GL_POINTS); double pt[3]; double r = rand() / RAND_MAX; for (int i = 0; i < 3; i++) { pt[i] = pts[0][i] + r * pts[1][i] - pts[0][i]; } for (int i = 0; i < npts; i++) { glVertex3dv(pt); int pt_idx = rand() & 0x3; for (int j = 0; j < 3; j++) { pt[j] = (pt[j] + pts[pt_idx][j]) / 2.0; } } glEnd(); glEndList(); gl_end(); } bool SierpinskiDA::gl_begin() { Glib::RefPtr glwindow = get_gl_window(); return glwindow->gl_begin(get_gl_context()); } void SierpinskiDA::gl_end() { Glib::RefPtr glwindow = get_gl_window(); glwindow->gl_end(); } bool SierpinskiDA::draw() { if (!gl_begin()) return false; glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, get_width()/(double)get_height(), 0.01, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, -3, 1, 0, 0, 0.7, 0, 0, 1); glCallList(m_dl); if (get_gl_window()->is_double_buffered()) get_gl_window()->swap_buffers(); else glFlush(); gl_end(); return true; } bool SierpinskiDA::on_motion_notify_event(GdkEventMotion * event) { get_pointer(m_x, m_y); return true; } bool SierpinskiDA::on_button_press_event(GdkEventButton * event) { return false; } bool SierpinskiDA::on_button_release_event(GdkEventButton * event) { return false; } bool SierpinskiDA::on_scroll_event(GdkEventScroll * event) { return false; } void SierpinskiDA::on_realize() { Gtk::GL::DrawingArea::on_realize(); if (!gl_begin()) return; glViewport(0, 0, get_width(), get_height()); m_dl = glGenLists(1); // glEnable(GL_LIGHTING); // glEnable(GL_LIGHT0); // float color[] = {1, 1, 1, 1}; // glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); glColor3f(1, 1, 1); gl_end(); regenerate(10); } /* * called on widget resizes */ bool SierpinskiDA::on_configure_event(GdkEventConfigure * event) { if (!gl_begin()) return false; glViewport(0, 0, get_width(), get_height()); gl_end(); return true; } bool SierpinskiDA::on_expose_event(GdkEventExpose * event) { return draw(); }