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.
Adding the class files¶
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
folderClick 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) {
// your code goes here
}
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.
Adding the Graphics 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.
How about a circle¶
This function draws a circle;
drawCircle(x,y,radius)
Here x,y is the coordinate of the center of the circle. radius is (well, you know!)
Ready for triangles?¶
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:
- Graphics.h
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
|
- Graphics.cpp
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 <GLUT/glut.h>
#include <iostream>
#else
#include <GL/glut.h>
#endif
#include "Graphics.h"
#include <cmath>
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();
}
|