715 lines
22 KiB
C++
715 lines
22 KiB
C++
/***********************************************************************
|
|
* Source File:
|
|
* User Interface Draw : put pixels on the screen
|
|
* Author:
|
|
* Br. Helfrich
|
|
* Summary:
|
|
* This is the code necessary to draw on the screen. We have a collection
|
|
* of procedural functions here because each draw function does not
|
|
* retain state. In other words, they are verbs (functions), not nouns
|
|
* (variables) or a mixture (objects)
|
|
************************************************************************/
|
|
|
|
#include <string> // need you ask?
|
|
#include <sstream> // convert an integer into text
|
|
#include <cassert> // I feel the need... the need for asserts
|
|
#include <time.h> // for clock
|
|
|
|
|
|
#ifdef __APPLE__
|
|
#include <openGL/gl.h> // Main OpenGL library
|
|
#include <GLUT/glut.h> // Second OpenGL library
|
|
#endif // __APPLE__
|
|
|
|
#ifdef __linux__
|
|
#include <GL/gl.h> // Main OpenGL library
|
|
#include <GL/glut.h> // Second OpenGL library
|
|
#endif // __linux__
|
|
|
|
#ifdef _WIN32
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <GL/glut.h> // OpenGL library we copied
|
|
#define _USE_MATH_DEFINES
|
|
#include <math.h>
|
|
#endif // _WIN32
|
|
|
|
#include "point.h"
|
|
#include "uiDraw.h"
|
|
|
|
using namespace std;
|
|
|
|
#define deg2rad(value) ((M_PI / 180) * (value))
|
|
|
|
/*********************************************
|
|
* NUMBER OUTLINES
|
|
* We are drawing the text for score and things
|
|
* like that by hand to make it look "old school."
|
|
* These are how we render each individual charactger.
|
|
* Note how -1 indicates "done". These are paired
|
|
* coordinates where the even are the x and the odd
|
|
* are the y and every 2 pairs represents a point
|
|
********************************************/
|
|
const char NUMBER_OUTLINES[10][20] =
|
|
{
|
|
{0, 0, 7, 0, 7, 0, 7,10, 7,10, 0,10, 0,10, 0, 0, -1,-1, -1,-1},//0
|
|
{7, 0, 7,10, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1},//1
|
|
{0, 0, 7, 0, 7, 0, 7, 5, 7, 5, 0, 5, 0, 5, 0,10, 0,10, 7,10},//2
|
|
{0, 0, 7, 0, 7, 0, 7,10, 7,10, 0,10, 4, 5, 7, 5, -1,-1, -1,-1},//3
|
|
{0, 0, 0, 5, 0, 5, 7, 5, 7, 0, 7,10, -1,-1, -1,-1, -1,-1, -1,-1},//4
|
|
{7, 0, 0, 0, 0, 0, 0, 5, 0, 5, 7, 5, 7, 5, 7,10, 7,10, 0,10},//5
|
|
{7, 0, 0, 0, 0, 0, 0,10, 0,10, 7,10, 7,10, 7, 5, 7, 5, 0, 5},//6
|
|
{0, 0, 7, 0, 7, 0, 7,10, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1},//7
|
|
{0, 0, 7, 0, 0, 5, 7, 5, 0,10, 7,10, 0, 0, 0,10, 7, 0, 7,10},//8
|
|
{0, 0, 7, 0, 7, 0, 7,10, 0, 0, 0, 5, 0, 5, 7, 5, -1,-1, -1,-1} //9
|
|
};
|
|
|
|
/************************************************************************
|
|
* DRAW DIGIT
|
|
* Draw a single digit in the old school line drawing style. The
|
|
* size of the glyph is 8x11 or x+(0..7), y+(0..10)
|
|
* INPUT topLeft The top left corner of the character
|
|
* digit The digit we are rendering: '0' .. '9'
|
|
*************************************************************************/
|
|
void drawDigit(const Point & topLeft, char digit)
|
|
{
|
|
// we better be only drawing digits
|
|
assert(isdigit(digit));
|
|
if (!isdigit(digit))
|
|
return;
|
|
|
|
// compute the row as specified by the digit
|
|
int r = digit - '0';
|
|
assert(r >= 0 && r <= 9);
|
|
|
|
// go through each segment.
|
|
for (int c = 0; c < 20 && NUMBER_OUTLINES[r][c] != -1; c += 4)
|
|
{
|
|
assert(NUMBER_OUTLINES[r][c ] != -1 &&
|
|
NUMBER_OUTLINES[r][c + 1] != -1 &&
|
|
NUMBER_OUTLINES[r][c + 2] != -1 &&
|
|
NUMBER_OUTLINES[r][c + 3] != -1);
|
|
|
|
//Draw a line based off of the num structure for each number
|
|
Point start;
|
|
start.setX(topLeft.getX() + NUMBER_OUTLINES[r][c]);
|
|
start.setY(topLeft.getY() - NUMBER_OUTLINES[r][c + 1]);
|
|
Point end;
|
|
end.setX(topLeft.getX() + NUMBER_OUTLINES[r][c + 2]);
|
|
end.setY(topLeft.getY() - NUMBER_OUTLINES[r][c + 3]);
|
|
|
|
drawLine(start, end);
|
|
}
|
|
}
|
|
|
|
/*************************************************************************
|
|
* DRAW NUMBER
|
|
* Display an integer on the screen using the 7-segment method
|
|
* INPUT topLeft The top left corner of the character
|
|
* digit The digit we are rendering: '0' .. '9'
|
|
*************************************************************************/
|
|
void drawNumber(const Point & topLeft, int number)
|
|
{
|
|
// our cursor, if you will. It will advance as we output digits
|
|
Point point = topLeft;
|
|
|
|
// is this negative
|
|
bool isNegative = (number < 0);
|
|
number *= (isNegative ? -1 : 1);
|
|
|
|
// render the number as text
|
|
ostringstream sout;
|
|
sout << number;
|
|
string text = sout.str();
|
|
|
|
// handle the negative
|
|
if (isNegative)
|
|
{
|
|
glBegin(GL_LINES);
|
|
glVertex2f(point.getX() + 1, point.getY() - 5);
|
|
glVertex2f(point.getX() + 5, point.getY() - 5);
|
|
glEnd();
|
|
point.addX(11);
|
|
}
|
|
|
|
// walk through the text one digit at a time
|
|
for (const char *p = text.c_str(); *p; p++)
|
|
{
|
|
assert(isdigit(*p));
|
|
drawDigit(point, *p);
|
|
point.addX(11);
|
|
}
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
* DRAW TEXT
|
|
* Draw text using a simple bitmap font
|
|
* INPUT topLeft The top left corner of the text
|
|
* text The text to be displayed
|
|
************************************************************************/
|
|
void drawText(const Point & topLeft, const char * text)
|
|
{
|
|
void *pFont = GLUT_BITMAP_HELVETICA_12; // also try _18
|
|
|
|
// prepare to draw the text from the top-left corner
|
|
glRasterPos2f(topLeft.getX(), topLeft.getY());
|
|
|
|
// loop through the text
|
|
for (const char *p = text; *p; p++)
|
|
glutBitmapCharacter(pFont, *p);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DRAW POLYGON
|
|
* Draw a POLYGON from a given location (center) of a given size (radius).
|
|
* INPUT center Center of the polygon
|
|
* radius Size of the polygon
|
|
* points How many points will we draw it. Larger the number,
|
|
* the more line segments we will use
|
|
* rotation True circles are rotation independent. However, if you
|
|
* are drawing a 3-sided polygon (triangle), this matters!
|
|
*************************************************************************/
|
|
void drawPolygon(const Point & center, int radius, int points, int rotation)
|
|
{
|
|
// begin drawing
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
//loop around a circle the given number of times drawing a line from
|
|
//one point to the next
|
|
for (double i = 0; i < 2 * M_PI; i += (2 * M_PI) / points)
|
|
{
|
|
Point temp(false /*check*/);
|
|
temp.setX(center.getX() + (radius * cos(i)));
|
|
temp.setY(center.getY() + (radius * sin(i)));
|
|
rotate(temp, center, rotation);
|
|
glVertex2f(temp.getX(), temp.getY());
|
|
}
|
|
|
|
// complete drawing
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* ROTATE
|
|
* Rotate a given point (point) around a given origin (center) by a given
|
|
* number of degrees (angle).
|
|
* INPUT point The point to be moved
|
|
* center The center point we will rotate around
|
|
* rotation Rotation in degrees
|
|
* OUTPUT point The new position
|
|
*************************************************************************/
|
|
void rotate(Point & point, const Point & origin, int rotation)
|
|
{
|
|
// because sine and cosine are expensive, we want to call them only once
|
|
double cosA = cos(deg2rad(rotation));
|
|
double sinA = sin(deg2rad(rotation));
|
|
|
|
// remember our original point
|
|
Point tmp(false /*check*/);
|
|
tmp.setX(point.getX() - origin.getX());
|
|
tmp.setY(point.getY() - origin.getY());
|
|
|
|
// find the new values
|
|
point.setX(static_cast<int> (tmp.getX() * cosA -
|
|
tmp.getY() * sinA) +
|
|
origin.getX());
|
|
point.setY(static_cast<int> (tmp.getX() * sinA +
|
|
tmp.getY() * cosA) +
|
|
origin.getY());
|
|
}
|
|
|
|
/************************************************************************
|
|
* DRAW LINE
|
|
* Draw a line on the screen from the beginning to the end.
|
|
* INPUT begin The position of the beginning of the line
|
|
* end The position of the end of the line
|
|
*************************************************************************/
|
|
void drawLine(const Point & begin, const Point & end,
|
|
float red, float green, float blue)
|
|
{
|
|
// Get ready...
|
|
glBegin(GL_LINES);
|
|
glColor3f(red, green, blue);
|
|
|
|
// Draw the actual line
|
|
glVertex2f(begin.getX(), begin.getY());
|
|
glVertex2f( end.getX(), end.getY());
|
|
|
|
// Complete drawing
|
|
glColor3f(1.0 /* red % */, 1.0 /* green % */, 1.0 /* blue % */);
|
|
glEnd();
|
|
}
|
|
|
|
/***********************************************************************
|
|
* DRAW Lander
|
|
* Draw a moon-lander spaceship on the screen at a given point
|
|
***********************************************************************/
|
|
void drawLander(const Point & point)
|
|
{
|
|
// ultra simple point
|
|
struct PT
|
|
{
|
|
int x;
|
|
int y;
|
|
} points[] =
|
|
{
|
|
{-6, 0}, {-10,0}, {-8, 0}, {-8, 3}, // left foot
|
|
{-5, 4}, {-5, 7}, {-8, 3}, {-5, 4}, // left leg
|
|
{-1, 4}, {-3, 2}, { 3, 2}, { 1, 4}, {-1, 4}, // bottom
|
|
{ 5, 4}, { 5, 7}, {-5, 7}, {-3, 7}, // engine square
|
|
{-6,10}, {-6,13}, {-3,16}, { 3,16}, // left of habitat
|
|
{ 6,13}, { 6,10}, { 3, 7}, { 5, 7}, // right of habitat
|
|
{ 5, 4}, { 8, 3}, { 5, 7}, { 5, 4}, // right leg
|
|
{ 8, 3}, { 8, 0}, {10, 0}, { 6, 0} // right foot
|
|
};
|
|
|
|
// draw it
|
|
glBegin(GL_LINE_STRIP);
|
|
for (int i = 0; i < sizeof(points) / sizeof(points[0]); i++)
|
|
glVertex2f(point.getX() + points[i].x,
|
|
point.getY() + points[i].y);
|
|
|
|
// complete drawing
|
|
glEnd();
|
|
|
|
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* DRAW Lander Flame
|
|
* Draw the flames coming out of a moonlander for thrust
|
|
***********************************************************************/
|
|
void drawLanderFlames(const Point & point,
|
|
bool bottom,
|
|
bool left,
|
|
bool right)
|
|
{
|
|
// simple point
|
|
struct PT
|
|
{
|
|
int x;
|
|
int y;
|
|
};
|
|
|
|
int iFlame = random(0, 3); // so the flame flickers
|
|
|
|
// draw it
|
|
glBegin(GL_LINE_LOOP);
|
|
glColor3f(1.0 /* red % */, 0.0 /* green % */, 0.0 /* blue % */);
|
|
|
|
// bottom thrust
|
|
if (bottom)
|
|
{
|
|
PT points[3][3] =
|
|
{
|
|
{ {-5, -6}, { 0, -1}, { 3, -10} },
|
|
{ {-3, -6}, {-1, -2}, { 0, -15} },
|
|
{ { 2, -12}, { 1, 0}, { 6, -4} }
|
|
};
|
|
|
|
glVertex2f(point.getX() - 2, point.getY() + 2);
|
|
for (int i = 0; i < 3; i++)
|
|
glVertex2f(point.getX() + points[iFlame][i].x,
|
|
point.getY() + points[iFlame][i].y);
|
|
glVertex2f(point.getX() + 2, point.getY() + 2);
|
|
}
|
|
|
|
// right thrust
|
|
if (right)
|
|
{
|
|
PT points[3][3] =
|
|
{
|
|
{ {10, 14}, { 8, 12}, {12, 12} },
|
|
{ {12, 10}, { 8, 10}, {10, 8} },
|
|
{ {14, 11}, {14, 11}, {14, 11} }
|
|
};
|
|
|
|
glVertex2f(point.getX() + 6, point.getY() + 12);
|
|
for (int i = 0; i < 3; i++)
|
|
glVertex2f(point.getX() + points[iFlame][i].x,
|
|
point.getY() + points[iFlame][i].y);
|
|
glVertex2f(point.getX() + 6, point.getY() + 10);
|
|
}
|
|
|
|
// left thrust
|
|
if (left)
|
|
{
|
|
PT points[3][3] =
|
|
{
|
|
{ {-10, 14}, { -8, 12}, {-12, 12} },
|
|
{ {-12, 10}, { -8, 10}, {-10, 8} },
|
|
{ {-14, 11}, {-14, 11}, {-14, 11} }
|
|
};
|
|
|
|
glVertex2f(point.getX() - 6, point.getY() + 12);
|
|
for (int i = 0; i < 3; i++)
|
|
glVertex2f(point.getX() + points[iFlame][i].x,
|
|
point.getY() + points[iFlame][i].y);
|
|
glVertex2f(point.getX() - 6, point.getY() + 10);
|
|
}
|
|
|
|
glColor3f(1.0 /* red % */, 1.0 /* green % */, 1.0 /* blue % */);
|
|
glEnd();
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* RANDOM
|
|
* This function generates a random number.
|
|
*
|
|
* INPUT: min, max : The number of values (min <= num <= max)
|
|
* OUTPUT <return> : Return the integer
|
|
****************************************************************/
|
|
int random(int min, int max)
|
|
{
|
|
assert(min < max);
|
|
int num = (rand() % (max - min)) + min;
|
|
assert(min <= num && num <= max);
|
|
|
|
return num;
|
|
}
|
|
|
|
/******************************************************************
|
|
* RANDOM
|
|
* This function generates a random number.
|
|
*
|
|
* INPUT: min, max : The number of values (min <= num <= max)
|
|
* OUTPUT <return> : Return the double
|
|
****************************************************************/
|
|
double random(double min, double max)
|
|
{
|
|
assert(min <= max);
|
|
double num = min + ((double)rand() / (double)RAND_MAX * (max - min));
|
|
|
|
assert(min <= num && num <= max);
|
|
|
|
return num;
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* DRAW RECTANGLE
|
|
* Draw a rectangle on the screen centered on a given point (center) of
|
|
* a given size (width, height), and at a given orientation (rotation)
|
|
* INPUT center Center of the rectangle
|
|
* width Horizontal size
|
|
* height Vertical size
|
|
* rotation Orientation
|
|
*************************************************************************/
|
|
void drawRect(const Point & center, int width, int height, int rotation)
|
|
{
|
|
Point tl(false /*check*/); // top left
|
|
Point tr(false /*check*/); // top right
|
|
Point bl(false /*check*/); // bottom left
|
|
Point br(false /*check*/); // bottom right
|
|
|
|
//Top Left point
|
|
tl.setX(center.getX() - (width / 2));
|
|
tl.setY(center.getY() + (height / 2));
|
|
|
|
//Top right point
|
|
tr.setX(center.getX() + (width / 2));
|
|
tr.setY(center.getY() + (height / 2));
|
|
|
|
//Bottom left point
|
|
bl.setX(center.getX() - (width / 2));
|
|
bl.setY(center.getY() - (height / 2));
|
|
|
|
//Bottom right point
|
|
br.setX(center.getX() + (width / 2));
|
|
br.setY(center.getY() - (height / 2));
|
|
|
|
//Rotate all points the given degrees
|
|
rotate(tl, center, rotation);
|
|
rotate(tr, center, rotation);
|
|
rotate(bl, center, rotation);
|
|
rotate(br, center, rotation);
|
|
|
|
//Finally draw the rectangle
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex2f(tl.getX(), tl.getY());
|
|
glVertex2f(tr.getX(), tr.getY());
|
|
glVertex2f(br.getX(), br.getY());
|
|
glVertex2f(bl.getX(), bl.getY());
|
|
glVertex2f(tl.getX(), tl.getY());
|
|
glEnd();
|
|
}
|
|
|
|
/************************************************************************
|
|
* DRAW CIRCLE
|
|
* Draw a circle from a given location (center) of a given size (radius).
|
|
* INPUT center Center of the circle
|
|
* radius Size of the circle
|
|
*************************************************************************/
|
|
void drawCircle(const Point & center, int radius)
|
|
{
|
|
assert(radius > 1.0);
|
|
const double increment = 1.0 / (double)radius;
|
|
|
|
// begin drawing
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
// go around the circle
|
|
for (double radians = 0; radians < M_PI * 2.0; radians += increment)
|
|
glVertex2f(center.getX() + (radius * cos(radians)),
|
|
center.getY() + (radius * sin(radians)));
|
|
|
|
// complete drawing
|
|
glEnd();
|
|
}
|
|
|
|
/************************************************************************
|
|
* DRAW DOT
|
|
* Draw a single point on the screen, 2 pixels by 2 pixels
|
|
* INPUT point The position of the dow
|
|
*************************************************************************/
|
|
void drawDot(const Point & point)
|
|
{
|
|
// Get ready, get set...
|
|
glBegin(GL_POINTS);
|
|
|
|
// Go...
|
|
glVertex2f(point.getX(), point.getY() );
|
|
glVertex2f(point.getX() + 1, point.getY() );
|
|
glVertex2f(point.getX() + 1, point.getY() + 1);
|
|
glVertex2f(point.getX(), point.getY() + 1);
|
|
|
|
// Done! OK, that was a bit too dramatic
|
|
glEnd();
|
|
}
|
|
|
|
/************************************************************************
|
|
* DRAW Tough Bird
|
|
* Draw a tough bird on the screen
|
|
* INPUT point The position of the sacred
|
|
* radius The size of the bird
|
|
* hits How many its remaining to kill the bird
|
|
*************************************************************************/
|
|
void drawToughBird(const Point & center, float radius, int hits)
|
|
{
|
|
assert(radius > 1.0);
|
|
const double increment = M_PI / 6.0;
|
|
|
|
// begin drawing
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
// three points: center, pt1, pt2
|
|
Point pt1(false /*check*/);
|
|
pt1.setX(center.getX() + (radius * cos(0.0)));
|
|
pt1.setY(center.getY() + (radius * sin(0.0)));
|
|
Point pt2(pt1);
|
|
|
|
// go around the circle
|
|
for (double radians = increment;
|
|
radians <= M_PI * 2.0 + .5;
|
|
radians += increment)
|
|
{
|
|
pt2.setX(center.getX() + (radius * cos(radians)));
|
|
pt2.setY(center.getY() + (radius * sin(radians)));
|
|
|
|
glVertex2f(center.getX(), center.getY());
|
|
glVertex2f(pt1.getX(), pt1.getY() );
|
|
glVertex2f(pt2.getX(), pt2.getY() );
|
|
|
|
pt1 = pt2;
|
|
}
|
|
|
|
// complete drawing
|
|
glEnd();
|
|
|
|
// draw the score in the center
|
|
if (hits > 0 && hits < 10)
|
|
{
|
|
glColor3f(0.0 /* red % */, 0.0 /* green % */, 0.0 /* blue % */);
|
|
glRasterPos2f(center.getX() - 4, center.getY() - 3);
|
|
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (char)(hits + '0'));
|
|
glColor3f(1.0, 1.0, 1.0); // reset to white
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* DRAW Sacred Bird
|
|
* Draw a sacred bird on the screen
|
|
* INPUT point The position of the sacred
|
|
* radius The size of the bird
|
|
*************************************************************************/
|
|
void drawSacredBird(const Point & center, float radius)
|
|
{
|
|
// handle auto-rotation
|
|
static float rotation = 0.0;
|
|
rotation += 5.0;
|
|
|
|
|
|
// begin drawing
|
|
glBegin(GL_LINE_LOOP);
|
|
glColor3f(1.0 /* red % */, 0.0 /* green % */, 0.0 /* blue % */);
|
|
|
|
|
|
//loop around a circle the given number of times drawing a line from
|
|
//one point to the next
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
Point temp(false /*check*/);
|
|
float radian = (float)i * (M_PI * 2.0) * 0.4;
|
|
temp.setX(center.getX() + (radius * cos(radian)));
|
|
temp.setY(center.getY() + (radius * sin(radian)));
|
|
rotate(temp, center, rotation);
|
|
glVertex2f(temp.getX(), temp.getY());
|
|
}
|
|
|
|
// complete drawing
|
|
glColor3f(1.0, 1.0, 1.0); // reset to white
|
|
glEnd();
|
|
}
|
|
|
|
/**********************************************************************
|
|
* DRAW SMALL ASTEROID
|
|
**********************************************************************/
|
|
void drawSmallAsteroid( const Point & center, int rotation)
|
|
{
|
|
// ultra simple point
|
|
struct PT
|
|
{
|
|
int x;
|
|
int y;
|
|
} points[] =
|
|
{
|
|
{-5, 9}, {4, 8}, {8, 4},
|
|
{8, -5}, {-2, -8}, {-2, -3},
|
|
{-8, -4}, {-8, 4}, {-5, 10}
|
|
};
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glColor3f(1.0 /* red % */, 0.0/* green % */, 1.0/* blue % */);
|
|
for (int i = 0; i < sizeof(points)/sizeof(PT); i++)
|
|
{
|
|
Point pt(center.getX() + points[i].x,
|
|
center.getY() + points[i].y);
|
|
rotate(pt, center, rotation);
|
|
glVertex2f(pt.getX(), pt.getY());
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
/**********************************************************************
|
|
* DRAW MEDIUM ASTEROID
|
|
**********************************************************************/
|
|
void drawMediumAsteroid( const Point & center, int rotation)
|
|
{
|
|
// ultra simple point
|
|
struct PT
|
|
{
|
|
int x;
|
|
int y;
|
|
} points[] =
|
|
{
|
|
{2, 8}, {8, 15}, {12, 8},
|
|
{6, 2}, {12, -6}, {2, -15},
|
|
{-6, -15}, {-14, -10}, {-15, 0},
|
|
{-4, 15}, {2, 8}
|
|
};
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glColor3f(1.0 /* red % */, 0.0/* green % */, 1.0/* blue % */);
|
|
for (int i = 0; i < sizeof(points)/sizeof(PT); i++)
|
|
{
|
|
Point pt(center.getX() + points[i].x,
|
|
center.getY() + points[i].y);
|
|
rotate(pt, center, rotation);
|
|
glVertex2f(pt.getX(), pt.getY());
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
/**********************************************************************
|
|
* DRAW LARGE ASTEROID
|
|
**********************************************************************/
|
|
void drawLargeAsteroid( const Point & center, int rotation)
|
|
{
|
|
// ultra simple point
|
|
struct PT
|
|
{
|
|
int x;
|
|
int y;
|
|
} points[] =
|
|
{
|
|
{0, 12}, {8, 20}, {16, 14},
|
|
{10, 12}, {20, 0}, {0, -20},
|
|
{-18, -10}, {-20, -2}, {-20, 14},
|
|
{-10, 20}, {0, 12}
|
|
};
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glColor3f(1.0 /* red % */, 0.0/* green % */, 0.0/* blue % */);
|
|
for (int i = 0; i < sizeof(points)/sizeof(PT); i++)
|
|
{
|
|
Point pt(center.getX() + points[i].x,
|
|
center.getY() + points[i].y);
|
|
rotate(pt, center, rotation);
|
|
glVertex2f(pt.getX(), pt.getY());
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* DRAW Ship
|
|
* Draw a spaceship on the screen
|
|
* INPUT point The position of the ship
|
|
* angle Which direction it is ponted
|
|
*************************************************************************/
|
|
void drawShip(const Point & center, int rotation, bool thrust)
|
|
{
|
|
// ultra simple point
|
|
struct PT
|
|
{
|
|
int x;
|
|
int y;
|
|
};
|
|
|
|
// draw the ship
|
|
const PT pointsShip[] =
|
|
{ // top r.wing r.engine l.engine l.wing top
|
|
{0, 6}, {6, -6}, {2, -3}, {-2, -3}, {-6, -6}, {0, 6}
|
|
};
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glColor3f(0.0 /* red % */, 0.0/* green % */, 1.0/* blue % */);
|
|
for (int i = 0; i < sizeof(pointsShip)/sizeof(PT); i++)
|
|
{
|
|
Point pt(center.getX() + pointsShip[i].x,
|
|
center.getY() + pointsShip[i].y);
|
|
rotate(pt, center, rotation);
|
|
glVertex2f(pt.getX(), pt.getY());
|
|
}
|
|
glEnd();
|
|
|
|
// draw the flame if necessary
|
|
if (thrust)
|
|
{
|
|
const PT pointsFlame[3][5] =
|
|
{
|
|
{ {-2, -3}, {-2, -13}, { 0, -6}, { 2, -13}, {2, -3} },
|
|
{ {-2, -3}, {-4, -9}, {-1, -7}, { 1, -14}, {2, -3} },
|
|
{ {-2, -3}, {-1, -14}, { 1, -7}, { 4, -9}, {2, -3} }
|
|
};
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glColor3f(1.0 /* red % */, 0.0 /* green % */, 0.0 /* blue % */);
|
|
int iFlame = random(0, 3);
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
Point pt(center.getX() + pointsFlame[iFlame][i].x,
|
|
center.getY() + pointsFlame[iFlame][i].y);
|
|
rotate(pt, center, rotation);
|
|
glVertex2f(pt.getX(), pt.getY());
|
|
}
|
|
glColor3f(1.0, 1.0, 1.0); // reset to white
|
|
glEnd();
|
|
}
|
|
}
|