are you ready for a mindfuck ? are you ready for a mindfuck?

....::::Menu::::....
...::About::...
...::Articles::...
...::Contact::...
...::Home & News::...
...::Links & Credits::... OpenGL logo
Valid XHTML 1.0!

stair

by Elie De Brauwer

Goal of this file

This file can be viewed as a little extension on the coil article. We try to create a wireframe winding stair.

History of this file

  • 14 november 2003: created
  • 21 december 2003: continued & finished

Introduction

This article describes how to create a rotating stair. It uses the axis and the error handling from the previous articles. Nothing really new occurs here but some extra exercises are always welcome.

Stair.cpp

This file doesn't contain something new. It simply initialises the window, draws the axis, handles keyboard input, prints errors.

#include <GL/glut.h>
#include <iostream>
#include "Stair.h"
using namespace std;

void disp(void);
void idle(void);
void reshape(int x,int y);
void drawAxis(void);
void handleErr(void);
void keyb(unsigned char key, int x, int y);

static Stair *stair;

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

  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  glutCreateWindow("Stair");
  glClearColor(0.0,0.0,0.0,0.0);

  stair = new Stair(0.50,0.05,0,0,0,5,20.0);
  glutDisplayFunc(disp);
  glutIdleFunc(idle);
  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyb);
  glutMainLoop();
}



void disp(void){
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glColor3f(1.0,1.0,1.0);
  glPushMatrix();
  stair->draw();
  drawAxis();
  handleErr();
  glutSwapBuffers();
  glPopMatrix();
}

void drawAxis(){
  glBegin(GL_LINES);
  glColor3f(1.0,0.0,0.0);
  glVertex3f(0.0,0.0,0.0);
  glVertex3f(0.80,0.0,0.0);
  glColor3f(0.0,1.0,0.0);
  glVertex3f(0.0,0.0,0.0);
  glVertex3f(0.0,0.80,0.0);
  glColor3f(0.0,0.0,1.0);
  glVertex3f(0.0,0.0,0.0);
  glVertex3f(0.0,0.0,0.80);
  glEnd();

  glPushMatrix();
  glColor3f(1.0,0.0,0.0);
  glTranslatef(0.80,0.0,0.0);
  glRotatef(90,0.0,1.0,0.0);
  glutSolidCone(0.05,0.1,10,10);
  glPopMatrix();
  glPushMatrix();
  glColor3f(0.0,1.0,0.0);
  glTranslatef(0.0,0.80,0.0);
  glRotatef(-90,1.0,0.0,0.0);
  glutSolidCone(0.05,0.1,10,10);
  glPopMatrix();
  glPushMatrix();
  glColor3f(0.0,0.0,1.0);
  glTranslatef(0.0,0.0,0.80);
  glutSolidCone(0.05,0.1,10,10);
  glPopMatrix();

}

void idle(void){
  glutPostRedisplay();
}


void keyb(unsigned char key, int x, int y){
 stair->setAngle(stair->getAngle()+1.0);
}

void reshape(int x,int y){
  glViewport(0,0,x,y);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(50,(x*1.0)/(y*1.0),1,6);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(2.0,0,0,0,0,0,0,1,0);
}

void handleErr(void){
  static GLenum errCode;
  errCode = glGetError();
  if(errCode != GL_NO_ERROR){
    cout << gluErrorString(errCode) << endl;;
  }
}

The stair: Stair.h

In this file the stair is defined. As you will notice from the code, the stair is created from a single GL_QUAD_STRIP and it only requires you to know what a sine and what a cosine it. A step is only a horizontal quadrilateral followed by a vertical quadrileteral. When you do this numsteps times you get your stair. But don't forget to rotate around the center axis.
The Stair class has the following prototype: Stair::Stair(double radius, double height,int startx, int starty,int startz,int numsteps,double angle). Here radius is the radius of the stair, height is the height of a step, startx, starty en startz determine the point where the step starts, numsteps determines the amount of steps do create and angle is the angle of a step.

#ifndef __stair
#define __start
#include <cmath>
using namespace std;

class Stair{
 public:
  Stair(double,double,int,int,int,int,double);
  void draw(void);
  double getAngle(void);
  void setAngle(double);
 private:
  int    startx;       // where we begin
  int    starty;       // where we begin, we rotate around this axis
  int    startz;       // where we begin
  int    numsteps;
  double radius;
  double height;
  double angle;
  double rot;
};

Stair::Stair(double radius, double height,
	     int startx, int starty,int  startz,
	     int numsteps,double angle){
  this->radius  = radius;
  this->height  = height;
  this->startx  = startx;
  this->starty  = starty;
  this->startz  = startz;
  this->numsteps= numsteps;
  this->angle   = angle; 
  this->rot     = 0;

}


///////////////////////
// Stair::draw
void Stair::draw(void){
  double ypos = starty;
  double ang  = 0;

  glRotatef(rot,0,1,0);
  glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
  glBegin(GL_QUAD_STRIP);

  // draw the first line
  glVertex3f(startx,ypos,startz);
  glVertex3f(radius*sin(ang*M_PI/180.0),ypos,radius*cos(ang*M_PI/180.0));
  
  for(int i=0;i<numsteps;i++){
    // increment ypos
    ypos+=height;
    // draw the horizontal triangle
    glVertex3f(startx,ypos,startz);
    glVertex3f(radius*sin(ang*M_PI/180.0),ypos,radius*cos(ang*M_PI/180.0));
    ang += angle;
    while(ang>360.0) ang-=360.0;
     glVertex3f(startx,ypos,startz);
    glVertex3f(radius*sin(ang*M_PI/180.0),ypos,radius*cos(ang*M_PI/180.0));

  }

  glEnd();
}


/////////////////////////////
// Stair::getAngle
double Stair::getAngle(void){
  return rot;
}

/////////////////////////////////
// Stair::setAngle
void Stair::setAngle(double rot){
  this->rot=rot;
}

#endif

In the end

I know, not such a big article now, but nothing new occured here. But still, here are some snapshots:


Snapshot1
Snapshot2
Snapshot3
The code is available: Stair.cpp and Stair.h.