# C++ Graphics¶

Once you completed the graphics setup instructions, you now have two graphics libraries on your system: OpenGL and Glut. Both of these have a huge number of folks working to build some pretty cool graphics applications. We are not ready to do that, but we can tap into their work and do some fun stuff. The problem is that even with the new addition we installed, all of this is still too complicated.

I have created a simple pair of files we can add to our projects to build simple graphics applications. Most significant programs involve more than one file, so this is not at all unusual.

The two files we will need are:

• Graphics.cpp - new graphics functions we can use
• Graphics.h - Needed to tie your program to the graphics routines

We will add the first file to our program project, then include the second file in our graphics programs. CLion will take care of hooking everything together.

### Don’t panic¶

If this scares you, don’t panic! Many other students have managed to get this working. Most of them enjoyed the projects we did in this part of the class.

## Setting up a demo¶

To get all this working do this:

• Open up CLion

• Choose File --> New Project

• Change the “Location” to build a GraphicsDemo folder
• Click on the Create button at the lower right

Now, we need to check things:

• Edit the main.cpp file for it says “Graphics Demo” instead of “Hello World”
• Run this code to make sure everything is set up correctly
• Save your project as usual

This program needs a bit more setup than our earlier work. You will be adding two more files to your project. If you are getting overwhelmed by all this, please be patient. I will give you plenty of time and help to get things going. Just follow the notes and know that many classes before you have gotten through this, and had fun with the result!

### Hello, Graphics World¶

Modify your main.cpp file so it looks like this:

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "Graphics.h"

void drawScene(void) {
}

int main(int argc, char ** argv) {
graphicsSetup(argc, argv);
glutDisplayFunc(drawScene);
glutMainLoop();
}


That stuff looks pretty scary! The first few lines will make this program work on either a Mac of a Windows PC. (That sure looks like a strange IF-THEN-ELSE, and it is, but those lines are aimed at the compiler!) You probably are using a PC, but others, including me, are using Mac systems. This is a common issue in programming since the two systems set things up differently.

Make sure you type everything you see exactly as shown. The names and function calls you see for things like glutDisplayFunc are parts of the Glut library, and they set up the program to draw the things we see in our drawScene procedure. It may seem strange to put the name of one procedure into the call to another procedure as a parameter, but it is legal, and is required by glut to make it draw images on the screen. For now, just consider it magic!

### Wait, we are not done¶

The code just shown is incomplete. See the “your code goes here” line? We will put our own code here. Make sure you do not mess anything else up! We also need to add out additional files.

Copy the needed files from the folder you set up when you worked through the CLion Graphics Setup notes.

• Graphics.cpp
• Graphics.h
• CMakeLists,txt

Once this is finished, you should have three files in your project

### Graphics Procedures¶

Now, we can now draw simple shapes

• Boxes
• Circles
• Triangles

We can also control the colors used

#### Graphics window¶

All drawing is done in a 500x500 pixel window. A pixel is one dot on your screen. There is a coordinate system associated with this window.

• X runs from 0 to 500 from left to right.
• Y runs from 0 to 500 from bottom to top
• (The origin is in the lower left corner)

The simple graphics procedures I have provided give you the ability to draw a few simple objects on the screen and control where they are and what size and color they are. The code creates a square window on your screen 500 pixels wide and 500 pixels high. (A pixel is one dot on your screen, which is probably running with 1024 pixels horizontally, and 768 vertically (or more if you have a newer system). In the procedures I have created, the origin of the system is at the lower left corner of the window. x coordinates go from 0 at the left to 500 at the right, and y goes from 0 at the bottom, to 500 at the top. You will need to figure out what coordinates (x,y) you need to work with when you use the simplified graphics procedures. Here are the routines you can use for starters:

#### Drawing boxes¶

To get started, here are a couple of new functions:

• drawBox(x1,y1,x2,y2)
• drawFilledBox(x1,y1,x2,y2)

Here x1,y1 and x2,y2 define the box. These points are the opposite corners of the box. These functions do not return a value. You call them by putting them on a line by themselves. Make sure you end the line with a semicolon!

Remember that when you use these functions in your program, they are a statement all by themselves and will need a semicolon after them like all statements in C++ do.

This function draws a circle;

Here x,y is the coordinate of the center of the circle. radius is (well, you know!)

These functions draw triangles:

• drawTriangle(x1,y1,x2,y2,x3,y3)
• drawFilledTriangle(x1,y1,x2,y2,x3,y3)

Here, x1,y1, x2,y2, and x3,y3 set the three corners.

#### Simple lines¶

We can draw a straight line using this function:

• drawLine(x1,y1,x2,y2)

The line goes from x1,y1 to x2,y2.

#### Setting colors¶

Each graphic object is drawn with a colored pen. You select the color for the pen using this function:

• setColor(color)
• where color can be one of these names:
• WHITE, BLACK, RED, BLUE, GREEN, GREY, PURPLE, FOREST_GREEN
• MIDNIGHT_BLUE, CYAN, MAGENTA, YELLOW, BROWN
• (case is important here)

You must type in the name in all caps, exactly as shown above. Lower case names, or misspellings will cause errors when you try to compile your code.

## A simple demo¶

Here is the code we need to add to test our routines

void drawScene(void) {
clearWindow();
setColor(YELLOW);
drawFilledTriangle(200,125,100,375,200,375);
glEnd();
glutSwapBuffers();
}


Let’s add a few more objects to our drawing Add these lines (inside the drawScene function:

setColor(BLACK);
drawLine(200,200,400,400);
setColor(RED);
drawFilledCircle(100,100,100);
setColor(MAGENTA);
drawFilledBox(300,300,400,400);


### Final demo output¶

If you have any problems getting this running, send me an email and I will help you through your problems. Once things are working, try the next lab assignment. It is not too hard!

## The Graphics Files¶

Just to make sure you have the current versions of these files (there are several older ones around), here are the files I am using for this class. You do not need to understand what is in these files. They are provided so you can check the files you download, if you run into problems:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #ifndef GRAPHICS_H #define GRAPHICS_H // set the drawing screen dimensions and position #define WINDOW_HEIGHT 500 #define WINDOW_WIDTH 500 #define WINDOW_X 100 #define WINDOW_Y 150 // set the pre-defined colors #define WHITE 1.0,1.0,1.0 #define BLACK 0.0,0.0,0.0 #define RED 1.0,0.0,0.0 #define BLUE 0.0,0.0,1.0 #define GREEN 0.0,1.0,0.0 #define GREY 1.0,0.5,0.0 #define PURPLE 0.5,0.25,0.0 #define FOREST_GREEN 0.0,0.25,0.0 #define MIDNIGHT_BLUE 0.0,0.0,0.25 #define CYAN 0.0,1.0,1.0 #define MAGENTA 1.0,0.0,1.0 #define YELLOW 1.0,0.5,0.0 #define BROWN 0.5,0.25,0.0 // initialization routine void graphicsSetup(int argc, char **argv); void drawScene(void); void clearWindow(void); // set line or fill color void setColor(double red, double green, double blue); // graphic object primatives void drawTriangle(int x1, int y1,int x2,int y2,int x3,int y3); void drawLine(int x1, int y1, int x2, int y2); void drawBox(int x1, int y1, int x2, int y2); void drawCircle(int x1, int y1, int radius); // filled graphics primatives void drawFilledTriangle(int x1, int y1,int x2,int y2,int x3,int y3); void drawFilledBox(int x1, int y1, int x2, int y2); void drawFilledCircle(int x1, int y1, int radius); #endif 
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 #ifdef __APPLE__ #include #include #else #include #endif #include "Graphics.h" #include double PI = acos(-1.0); double ANGLE_STEP = PI/180.0; void setColor(double red, double green, double blue) { glColor3d(red, green, blue); } void quitKey(unsigned char key, int x, int y) { #ifdef __APPLE__ if (key == 'q') std::exit(0); #else if (key == 'q') exit(0); #endif } void graphicsSetup(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(WINDOW_X,WINDOW_Y); glutInitWindowSize(WINDOW_HEIGHT,WINDOW_WIDTH); glutCreateWindow("COSC1315 - Graphics Lab"); glClearColor(WHITE,0.0); gluOrtho2D(0,WINDOW_WIDTH, 0,WINDOW_HEIGHT); glutKeyboardFunc(quitKey); } void clearWindow() { glClear(GL_COLOR_BUFFER_BIT); } void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) { glBegin(GL_LINE_STRIP); glVertex2i(x1,y1); glVertex2i(x2,y2); glVertex2i(x3,y3); glVertex2i(x1,y1); glEnd(); glFlush(); } void drawFilledTriangle(int x1, int y1, int x2, int y2, int x3, int y3) { glBegin(GL_POLYGON); glVertex2i(x1,y1); glVertex2i(x2,y2); glVertex2i(x3,y3); glVertex2i(x1,y1); glEnd(); glFlush(); } void drawLine(int x1, int y1, int x2, int y2) { glBegin(GL_LINE_STRIP); glVertex2i(x1,y1); glVertex2i(x2,y2); glEnd(); glFlush(); } void drawBox(int x1, int y1, int x2, int y2) { glBegin(GL_LINE_STRIP); glVertex2i(x1,y1); glVertex2i(x2,y1); glVertex2i(x2,y2); glVertex2i(x1,y2); glVertex2i(x1,y1); glEnd(); glFlush(); } void drawFilledBox(int x1, int y1, int x2, int y2) { glBegin(GL_POLYGON); glVertex2i(x1,y1); glVertex2i(x2,y1); glVertex2i(x2,y2); glVertex2i(x1,y2); glVertex2i(x1,y1); glEnd(); glFlush(); } void drawCircle(int x1, int y1, int radius) { double angle; int X, Y; glBegin(GL_LINE_STRIP); for (angle=0;angle< 2.0*PI + ANGLE_STEP; angle += ANGLE_STEP) { X = x1 + int(double(radius) * cos(angle)); Y = y1 + int(double(radius) * sin(angle)); glVertex2i(X,Y); } glEnd(); glFlush(); } void drawFilledCircle(int x1, int y1, int radius) { double angle; int X0, Y0, X1, Y1; glBegin(GL_TRIANGLES); X1 = x1 + radius; Y1 = y1; for (angle=0;angle< 2.0*PI + ANGLE_STEP; angle += ANGLE_STEP) { X0 = X1; Y0 = Y1; X1 = x1 + int(double(radius) * cos(angle)); Y1 = y1 + int(double(radius) * sin(angle)); glVertex2i(x1,y1); glVertex2i(X0,Y0); glVertex2i(X1,Y1); } glEnd(); glFlush(); }