//*************************************************************************
//
// File Name: Learning geometric Primitives
// Author : Ali Baderedine
//
// Description: Displaying Geometric Primtives using OpenGL...
// + using keyboard + using mouse + glut menus.
//*************************************************************************
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <gl/glut.h>
// Link the lib files to the program. This is not necessary
// if you have added the lib names using Project/Settings/Link
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glut32.lib")
#pragma comment (lib, "glu32.lib")
// define the window position on screen
GLint window_X_position;
GLint window_Y_position;
// variables representing the window size
GLint window_width = 512;
GLint window_height = 512;
// variable representing the window title
char *window_title = "Learning geometric Primitives";
// Represents the width and height of the world coordinate system
GLdouble world_width, world_height;
// Specifies the primitive or primitives that will be created from
// vertices presented between glBegin and the subsequent glEnd.
// Ten symbolic constants are accepted: GL_POINTS, GL_LINES, GL_LINE_STRIP,
// GL_LINE_LOOP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS,
// GL_QUAD_STRIP, and GL_POLYGON.
int mode;
// an array of RGB components
GLfloat color[] = {1.0, 1.0, 0.0};
// Represents a point data structure that has coordinates and a
// pointer to the previous and next point in the list of points.
typedef struct Point
{
GLfloat x, y, z;
struct Point * pp, *np; // previous and next points
int point_num; // number representing hte point
} Point;
Point * head;
Point * tail;
// Booleans that tell whether to display a point or its number
int displayPoint = 1, displayPointNum = 1;
// Adds a point to the list of points
void addPoint (GLfloat x, GLfloat y, GLfloat z);
// deletes the last point added on the screen.
void deletePoint ();
// clears all the points
void clearPoints ();
// Function that initializes some values that won't change
// throughout the program...
void init (void);
void display (void);
// This function is responsible for keybard events...
// You have to write glutKeyboardFunc (keyboard) in
// main in order to activate it.
void keyboard (unsigned char key, int x, int y);
// This function is responsible for mouse events.
// It adds the points to the list of points.
void mouse (int button, int state, int x, int y);
// Called when the window is resized
void reshape (int w, int h);
// This function centers your window on the screen
void centerOnScreen (void);
// Sets up menus
void setupMenus (void);
// displays help to the user
void displayHelp ();
// Generates openGL code for the primitives drawn
void generateOpenGLCode ();
// Just a pointer to a font style..
// Fonts supported by GLUT are: GLUT_BITMAP_8_BY_13,
// GLUT_BITMAP_9_BY_15, GLUT_BITMAP_TIMES_ROMAN_10,
// GLUT_BITMAP_TIMES_ROMAN_24, GLUT_BITMAP_HELVETICA_10,
// GLUT_BITMAP_HELVETICA_12, and GLUT_BITMAP_HELVETICA_18.
GLvoid *font_style = GLUT_BITMAP_TIMES_ROMAN_10;
// draws a string (Just as intelligent as printf)
// If you're new to functions with varaible arguments
// then check the <stdarg.h> in some C book or
// type (man stdarg) on Unix terminal.
void printw(GLfloat x, GLfloat y, char* format, ...);
// menu callback functions declarations
void mainMenu (int value);
void colorMenu (int value);
// menu IDs declarations
int mainMenuId;
int colorMenuId;
void addPoint (GLfloat x, GLfloat y, GLfloat z)
{
if (head == NULL)
{
head = (Point *) malloc (sizeof (Point));
head->x = x;
head->y = y;
head->z = z;
head->point_num = 1;
head->pp = NULL;
head->np = NULL;
tail = head;
}
else
{
tail->np = (Point *) malloc (sizeof (Point));
tail->np->pp = tail;
tail = tail->np;
tail->x = x;
tail->y = y;
tail->z = z;
tail->point_num = tail->pp->point_num + 1;
tail->np = NULL;
}
}
void deletePoint ()
{
Point * temp;
if (tail != NULL)
{
temp = tail;
tail = temp->pp;
if (tail != NULL)
tail->np = NULL;
else
head = NULL;
free (temp);
}
}
void clearPoints ()
{
while (tail != NULL)
deletePoint ();
}
void init ()
{
// Set the clear color to be black.
glClearColor (0.0, 0.0, 0.0, 0.0);
// Set the world coordinates.
// gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
// The default world coordinates are between -1 and 1.
// So it is as if you're calling
// gluOrtho2D(-1.0, 1.0, -1.0, 1.0) (This is very imp to know)
// But in our case we are going to set our world to be between 0 and 10.
world_width = world_height = 10.0;
gluOrtho2D (0.0, world_width, 0.0, world_height);
// Initially, there are no points in the point list.
head = tail = NULL;
// Set the mode intially to GL_POINTS
mode = GL_POINTS;
// Set up menus
setupMenus ();
// Set the point size
glPointSize (4);
// display help
displayHelp ();
}
void setupMenus ()
{
// create menus
mainMenuId = glutCreateMenu (mainMenu);
colorMenuId = glutCreateMenu (colorMenu);
// Add the menus' entries
glutSetMenu(mainMenuId); // select main menu,
glutAddMenuEntry ("GL_POINTS", 1);
glutAddMenuEntry ("GL_LINES", 2);
glutAddMenuEntry ("GL_LINE_STRIP", 3);
glutAddMenuEntry ("GL_LINE_LOOP", 4);
glutAddMenuEntry ("GL_TRIANGLES", 5);
glutAddMenuEntry ("GL_TRIANGLE_STRIP", 6);
glutAddMenuEntry ("GL_TRIANGLE_FAN", 7);
glutAddMenuEntry ("GL_QUADS", 8);
glutAddMenuEntry ("GL_QUAD_STRIP", 9);
glutAddMenuEntry ("GL_POLYGON", 10);
glutAddMenuEntry ("", -1);
glutAddSubMenu ("color", colorMenuId);
glutAddMenuEntry ("", -1);
glutAddMenuEntry ("Clear", 11);
// Add the color menu items
glutSetMenu (colorMenuId);
glutAddMenuEntry ("Black", 1);
glutAddMenuEntry ("Blue", 2);
glutAddMenuEntry ("Cyan", 3);
glutAddMenuEntry ("Dark Grey", 4);
glutAddMenuEntry ("Grey", 5);
glutAddMenuEntry ("Green", 6);
glutAddMenuEntry ("Light Grey", 7);
glutAddMenuEntry ("Magenta", 8);
glutAddMenuEntry ("Orange", 9);
glutAddMenuEntry ("Pink", 10);
glutAddMenuEntry ("Red", 11);
glutAddMenuEntry ("White", 12);
glutAddMenuEntry ("Yellow", 13);
// Attach the main menu to the RMB
glutSetMenu (mainMenuId);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
void mainMenu (int value)
{
switch (value)
{
case 1:
mode = GL_POINTS;
break;
case 2:
mode = GL_LINES;
break;
case 3:
mode = GL_LINE_STRIP;
break;
case 4:
mode = GL_LINE_LOOP;
break;
case 5:
mode = GL_TRIANGLES;
break;
case 6:
mode = GL_TRIANGLE_STRIP;
break;
case 7:
mode = GL_TRIANGLE_FAN;
break;
case 8:
mode = GL_QUADS;
break;
case 9:
mode = GL_QUAD_STRIP;
break;
case 10:
mode = GL_POLYGON;
break;
case 11:
clearPoints ();
break;
}
glutPostRedisplay ();
}
void colorMenu (int value)
{
switch (value)
{
// Select black color
case 1:
color[0] = 0/255.0;
color[1] = 0/255.0;
color[2] = 0/255.0;
break;
// Select blue color
case 2:
color[0] = 0/255.0;
color[1] = 0/255.0;
color[2] = 255/255.0;
break;
// Select cyan color
case 3:
color[0] = 0/255.0;
color[1] = 255/255.0;
color[2] = 255/255.0;
break;
// Select dark grey color
case 4:
color[0] = 64/255.0;
color[1] = 64/255.0;
color[2] = 64/255.0;
break;
// Select grey color
case 5:
color[0] = 128/255.0;
color[1] = 128/255.0;
color[2] = 128/255.0;
break;
// Select green color
ca