|
//---------------- setWindow ---------------
void setWindow (float left, float right, float bottom, float top)
{
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluOrtho2D ((GLdouble)1eft, (GLdouble)right, (GLdouble)bottom, (GLdouble)top);
}
//---------------- setViewport --------------
void setViewport (int left, int right, int bottom, int top)
{
glViewport(left, bottom, right - left, top - bottom );
}
|
We may use these functions to automatically set World Window and Viewport
| Aspect ratio of a rectangle = |
width ----- height |
Suppose world window has aspect ratio R, screen window has width W and height H
We can resize the window by
void myReshape( GLsize W, GLsizei H )
{
if ( R > W/H ) //use global aspect ratio R
setViewport( 0, W, 0, W/R );
else
setViewport( 0, H * R, 0, H );
}
|
class Point2: A Point with Real Coordinates
// Support Classes for Canvas
class Point2 //single point w/ floating point coordinates
{
public:
Point2(); //contructor 1
Point2(float xx, float yy); //constructor 2
void set(float xx, float yy);
float getX();
float getY();
void draw(void);
private:
float x, y;
};
//constructor 1
Point2::Point2()
{
x = y = 0.0f;
}
//constructor 2
Point2::Point2(float xx, float yy)
{
x=xx; y=yy;
}
void Point2::set(float xx, float yy)
{
x=xx; y=yy;
}
float Point2::getX()
{
return x;
}
float Point2::getY()
{
return y;
}
void Point2::draw(void)
{
glBegin(GL_POINTS); //draw this point
glVertex2f((GLfloat)x, (GLfloat)y);
glEnd();
}
|
class RealRect: A rectangle class with real coordinates
//world window rectangle class
class RealRect
{
public:
RealRect(); //constructors
RealRect(float left, float right, float bottom, float top);
void set(float left, float right, float bottom, float top);
float getL(void); //left boundary
float getR(void); //right
float getT(void);
float getB(void);
void draw(void); //draw this rectangle using OpenGL
private:
float l, r, b, t;
};
//constructors
RealRect::RealRect()
{
l = 0; r=100; b=0; t=100;
}
RealRect::RealRect(float left, float right, float bottom, float top)
{
l = left; r=right; b=bottom; t=top;
}
void RealRect::set(float left, float right, float bottom, float top)
{
l=left; r=right; b=bottom; t=top;
}
float RealRect::getL(void) //left boundary
{
return l;
}
float RealRect::getR(void) //right
{
return r;
}
float RealRect::getT(void)
{
return t;
}
float RealRect::getB(void)
{
return b;
}
void RealRect::draw(void)
{
glRectf( l, b, r, t);
}
|
class Canvas
{
public:
Canvas(int width, int height, char* windowTitle); //constructor
void setWindow(float l, float r, float b, float t);
void setViewport(int l, int r, int b, int t);
IntRect getViewport(void); //divulge the viewport data
RealRect getWindow(void); // divulge the window data
float getWindowAspectRatio(void);
void clearScreen();
void setBackgroundColor(float r, float g, float b);
void setColor(float r, float g, float b);
void lineTo(float x, float y);
void lineTo(Point2 p);
void moveTo(float x, float y);
void moveTo(Point2 p);
void moveRel(float dx, float dy);
private:
Point2 CP; //current position in the world
IntRect viewport; //the current window
RealRect window; //the current viewport
} ;
|
//constructor
Canvas:: Canvas(int width, int height, char* windowTitle)
{
char* argv[1]; //dummy argument list for glutinit()
char dummyString[8];
argv[0] = dummyString; //hook up the pointer
int argc = 1;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(width, height);
glutInitWindowPosition (20,20);
glutCreateWindow (windowTitle);
setWindow(0, (float)width, 0, (float)height); // default world window
setViewport (0, width, 0, height); //default viewport
CP.set(0.0f, 0.0f); //initialize the cp to (0,0)
}
void Canvas:: moveTo(Point2 p) //moves current point CP to point p object
{
float x1, y1;
x1 = p.getX();
y1 = p.getY();
CP.set(x1, y1);
}
void Canvas:: lineTo(Point2 p)
{
glBegin (GL_LINES);
glVertex2f((GLfloat) CP.getX(), (GLfloat) CP.getY());
glVertex2f((GLfloat) p.getX(), (GLfloat) p.getY());
glEnd();
CP.set(p.getX(), p.getY());
glFlush();
}
|
main() function
//main.cpp
//main loop for canvas graphics
#include "canvas.h"
void display( void );
void main(void)
{
extern Canvas cvs;
cvs.setWindow(-10.0, 10.0, -10.0, 10.0);
cvs.setViewport(0, 500, 0, 500);
cvs.setBackgroundColor(1.0, 1.0, 1.0);
cvs.setColor(0.0, 0.0, 0.0);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutDisplayFunc(display);
glutMainLoop();
}
|
demo_canvas
//demo_canvas.cpp
#include "canvas.h"
Canvas cvs(640, 480, "try out Canvas"); //global canvas object
void display()
{
cvs.clearScreen(); //clear screen
cvs.setColor ( 1.0, 0.0, 0.0 );
cvs.moveTo( 0, 0.0 ); //draw line
cvs.lineTo( 5, 5.0 );
cvs.setColor ( 0.0, 1.0, 0.0 );
RealRect box( -1.0, 1.0, -1.0, 2.0 ); //construct a box
box.draw(); //draw box
glFlush();
}
|
|
Canvas cvs(500, 500, "try out Canvas"); //global canvas object
void polygon(int n, float cx, float cy, float radius, float rotAngle)
{
//assumes global Canvas object, cvs
if( n < 3 ) return ; //bad number of sides
double angle = rotAngle * 3.14159265 / 180; //initial angle
double angleInc = 2 * 3.14159265 / n; //angle increment
cvs.moveTo(radius * cos(angle) + cx, radius * sin(angle) + cy);
for(int k=0; k < n; k++) //repeat n times
{
angle += angleInc;
cvs.lineTo(radius * cos(angle) + cx, radius * sin(angle) + cy);
}
} //polygon
|
void drawCircle(Point2 center, float radius)
{
glColor3f(1.0, 0.0, 0.0); //red
glLineWidth( 2.0 );
const int numVerts = 50; //many-sided polygon to approximate circle.
polygon(numVerts, center.getX(), center.getY(), radius, 0);
glPointSize ( 3 );
center.draw();
glFlush();
}//drawCircle
|
void drawArc(Point2 center, float radius, float startAngle, float sweep)
{ // startAngle and sweep are in degrees
glColor3f(0.0, 0.0, 1.0); //blue
const int n = 30; // number of intermediate segments in arc
float angle = startAngle * 3.14159265 / 180; // initial angle in radians
float angleInc = sweep * 3.14159265 /(180 * n); // angle increment
float cx = center.getX(), cy = center.getY();
cvs.moveTo(cx + radius * cos(angle), cy + radius * sin(angle));
for(int k = 1; < < n; k++, angle += angleInc)
cvs.lineTo(cx + radius * cos(angle), cy + radius * sin(angle));
}
|
void display(void)
{
int n = 5;
float radius = 3.0;
//display at upper right hand quadrant
float cx = 4.0, cy = 4.0;
cvs.clearScreen();
//draw a polygon
polygon( n, cx, cy, radius, 0.0);
//center at lower left quadrant
Point2 circle_center( -4.0, -4.5 );
drawCircle( circle_center, radius );
//center at lower right quadrant
Point2 arc_center( 4.0, -4.5 );
//starts at 30 deg, sweep through 120 degrees
drawArc( arc_center, radius, 30, 120 );
}
|
|
A coding example: drawing a hook
|
|