shape.C

Of course GL is no fun unless you can draw your own graphics. This is done with a subclass that you create:

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Hor_Slider.H>
#include <FL/math.h>
#include <FL/gl.h>
#include <FL/Fl_Gl_Window.H>

class shape_window : public Fl_Gl_Window {
  void draw();
public:
  int sides;
  shape_window(int x,int y,int w,int h,const char *l=0);
};

shape_window::shape_window(int x,int y,int w,int h,const char *l) :
Fl_Gl_Window(x,y,w,h,l) {
  sides = 3;
}

void shape_window::draw() {
  // the valid() property may be used to avoid reinitializing your
  // GL transformation for each redraw:
  if (!valid()) {
    valid(1);
    glLoadIdentity();
    glViewport(0,0,w(),h());
  }
  // draw an amazing graphic:
  glClear(GL_COLOR_BUFFER_BIT);
  glColor3f(.5,.6,.7);
  glBegin(GL_POLYGON);
  for (int i=0; i<sides; i++) {
    double ang = i*2*M_PI/sides;
    glVertex3f(cos(ang),sin(ang),0);
  }
  glEnd();
}

// when you change the data, as in this callback, you must call redraw():
void sides_cb(Fl_Widget *o, void *p) {
  shape_window *sw = (shape_window *)p;
  sw->sides = int(((Fl_Slider *)o)->value());
  sw->redraw();
}

int main(int argc, char **argv) {

  Fl_Window window(300, 330);

  shape_window sw(10, 10, 280, 280);
  window.resizable(&sw);

  Fl_Hor_Slider slider(50, 295, window.w()-60, 30, "Sides:");
  slider.align(FL_ALIGN_LEFT);
  slider.callback(sides_cb,&sw);
  slider.value(sw.sides);
  slider.step(1);
  slider.bounds(3,40);

  window.show(argc,argv);
    
  return Fl::run();
}

To do your own drawing, you must subclass Fl_Gl_Window. The virtual method draw() is called when the window should update. You can only draw into the window inside a draw() method. You call the method redraw() on the window to indicate that draw() needs to be called. It won't actually be called until Fl::wait() is called.

The window may be made a child of another window, as it is here. This is done by add()ing it to a parent before you show() it. If you don't want to make a child window, be sure to end() the previous window! The Fl_Gl_Window constructor automatically does end() so you don't accidentally add children to it.

The files <FL/math.h> and <FL/gl.h> are wrappers for the normal header files. You should use them to port to MSWindows because the MicroSoft header files have errors or ommisions in them.

[back to contents]