Fix
[matches/honours.git] / course / semester2 / pprog / assignment0 / graphics.c
1 /**
2  * @file graphics.c
3  * @purpose Wrapper for SDL and OpenGL graphics libraries. Used for N-Body simulator. Implementations. Mostly copied from internet tutorials.
4  * @author Sam Moore
5  * @date August 2012
6  */
7
8
9
10 #include "graphics.h"
11
12 #include <math.h> //For trig functions
13
14 static int screen_width = 0; 
15 static int screen_height = 0;
16
17 /**
18  * @function Graphics_Init
19  * @purpose Initialise the SDL/OpenGL graphics system
20  * @param caption - The caption to give the view window
21  * @param w - The width of the view window
22  * @param h - The height of the view window
23  */ 
24 void Graphics_Init(const char * caption, int w, int h)
25 {
26         if (SDL_Init(SDL_INIT_VIDEO) != 0)
27         {
28                 fprintf(stderr, "Graphics_Init - Couldn't initialise SDL! SDL_GetError() = %s\n",SDL_GetError());
29                 exit(EXIT_FAILURE);
30         }
31
32         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
33
34         SDL_Surface * screen = SDL_SetVideoMode(w,h, 32, SDL_OPENGL);
35         if ( screen == NULL )
36         {
37                 fprintf(stderr, "Graphics_Init - Couldn't set SDL VideoMode (%d x %d x 32). SDL_GetError() = %s\n", w, h, SDL_GetError());
38                 exit(EXIT_FAILURE);
39         } 
40
41         glEnable(GL_TEXTURE_2D);
42         glClearColor(0,0,0,0);
43         glViewport(0,0,w,h);    //DOES matter
44         glClear(GL_COLOR_BUFFER_BIT);
45         glMatrixMode(GL_PROJECTION);
46         glLoadIdentity();
47         glOrtho(0,w,h,0,-1,1);
48         glMatrixMode(GL_MODELVIEW);
49         glLoadIdentity();
50         glDisable(GL_DEPTH_TEST);
51         SDL_WM_SetCaption(caption, NULL);
52
53
54         screen_width = w; screen_height = h;
55
56         atexit(Graphics_Destroy);
57 }
58
59 /**
60  * @function Graphics_Destroy
61  * @purpose Destroy the Graphics system
62  *              Note: Just wrap to SDL_Quit for now
63  */
64 void Graphics_Destroy()
65 {
66         SDL_Quit();
67 }
68
69 /**
70  * @function Graphics_DrawPixel
71  * @purpose Draw a pixel 
72  * @param x[...] Position of pixel
73  * @param r - Red component (0-1)
74  * @param g - Green component (0-1)
75  * @param b - Blue component (0-1)
76  */
77 void Graphics_Pixel(int x[DIMENSIONS], float r, float g, float b)
78 {
79         glBegin(GL_POINTS);
80         glColor3f(r, g, b);
81         if (DIMENSIONS == 2)
82                 glVertex2f(x[0], x[1]); 
83         else if (DIMENSIONS == 3)
84                 glVertex3f(x[0], x[1], x[2]);
85         else
86         {
87                 fprintf(stderr, "Graphics_DrawPixel - DIMENSIONS = %d, expected 2 or 3\n", DIMENSIONS);
88                 exit(EXIT_FAILURE);
89         }
90
91         glColor3f(1,1,1);
92         glEnd();
93 }
94
95 /**
96  * @function Graphics_DrawLine
97  * @purpose Draw a straight line between two points
98  * @param x1[...] - First coordinate
99  * @param x2[...] - Second coordinate
100  * @param r - Red component (0-1)
101  * @param g - Green component (0-1)
102  * @param b - Blue component (0-1)
103  */
104 void Graphics_Line(int x1[DIMENSIONS], int x2[DIMENSIONS], float r, float g, float b)
105 {               
106
107         glColor3f(r, g, b);
108         glBegin(GL_LINES);
109         if (DIMENSIONS == 2)
110         {
111                 glVertex2f(x1[0], x1[1]); // origin of the line
112                 glVertex2f(x2[0], x2[1]); // ending point of the line
113         }
114         else if (DIMENSIONS == 3)
115         {
116                 glVertex3f(x1[0], x1[1], x1[2]); // origin of the line
117                 glVertex3f(x2[0], x2[1], x2[2]); // ending point of the line
118         }
119         else
120         {
121                 fprintf(stderr, "Graphics_DrawLine - DIMENSIONS = %d, expected 2 or 3\n", DIMENSIONS);
122                 exit(EXIT_FAILURE);             
123         }
124         glColor3f(1,1,1);
125         glEnd();
126
127         
128 }
129
130 /**
131  * @function Graphics_Circle
132  * @purpose Draw a 2D Circle (filled)
133  * @param x[...] Position to draw at
134  * @param radius - Radius of circle
135  * @param r - Red component (0-1)
136  * @param g - Green component (0-1)
137  * @param b - Blue component (0-1)
138  */
139
140 void Graphics_Circle(int x[2], float radius, float r, float g, float b)
141 {
142         glColor3f(r, g, b);
143
144         glBegin(GL_TRIANGLE_FAN);
145         glVertex2f(x[0], x[1]);
146         for (float angle = 0; angle < 360; angle+=1)
147         {
148                 glVertex2f(x[0] + sin(angle) * radius, x[1] + cos(angle) * radius);
149         }
150         glColor3f(1, 1, 1);
151         glEnd();
152 }
153  
154 /**
155  * @function Graphics_Clear
156  * @purpose Clear the screen
157  * @param r - Red component of clear colour
158  * @param g - Green component
159  * @param b - Blue component
160  */
161 void Graphics_Clear(float r, float g, float b)
162 {
163         glClearColor(r,g,b,1);
164         glClear(GL_COLOR_BUFFER_BIT);
165 }
166
167 /**
168  * @function Graphics_Update
169  * @purpose Update the screen
170  */
171 void Graphics_Update()
172 {
173         SDL_GL_SwapBuffers();
174         //SDL_Flip(screen);
175 }
176
177 /**
178  * @function Process_Events
179  * @purpose Handle any SDL events recieved.
180  */
181 void Process_Events()
182 {
183         static float view_v[3] = {0,0,0};
184         static float view_speed = 5.0;
185         static float view_scale = 1;
186         SDL_Event event;
187         
188         
189         
190         
191         while (SDL_PollEvent(&event)) 
192         {
193                 switch (event.type)
194                 {
195                         case SDL_KEYDOWN:
196                                 switch (event.key.keysym.sym)
197                                 {
198                                         case SDLK_LEFT:
199                                                 view_v[0] += view_speed;
200                                                 break;
201                                         case SDLK_RIGHT:
202                                                 view_v[0] -= view_speed;
203                                                 break;
204                                         case SDLK_UP:
205                                                 view_v[1] += view_speed;
206                                                 break;
207                                         case SDLK_DOWN:
208                                                 view_v[1] -= view_speed;
209                                                 break;
210                                         case SDLK_i:
211                                                 view_v[0] = 0; view_v[1] = 0; view_v[2] = 0;
212                                                 view_scale = 1;
213                                                 glLoadIdentity();
214                                                 break;
215                                         default:
216                                                 break;
217                                 }
218                                 break;
219                         case SDL_KEYUP:
220                                 switch (event.key.keysym.sym)
221                                 {
222                                         case SDLK_LEFT:
223                                         case SDLK_RIGHT:
224                                                 view_v[0] = 0;
225                                                 break;
226                                         case SDLK_UP:
227                                         case SDLK_DOWN:
228                                                 view_v[1] = 0;
229                                         default:
230                                                 break;
231                                 }
232                                 break;
233
234                         case SDL_MOUSEBUTTONDOWN:
235                         {
236                                 int mouse[2];
237                                 SDL_GetMouseState(mouse, mouse+1);
238
239                                 switch (event.button.button)
240                                 {
241                                         case SDL_BUTTON_WHEELUP:
242                                                 
243                                                 view_scale = 1.05;
244                                                 glTranslatef(screen_width/2.0, screen_height/2.0,0.0);
245                                                 glScaled(view_scale, view_scale, 1);
246                                                 glTranslatef(-screen_width/2.0, -screen_height/2.0, 0.0);
247                                                 break;
248                                         case SDL_BUTTON_WHEELDOWN:
249                                                 view_scale = 0.95;
250                                                 glTranslatef(screen_width/2.0, screen_height/2.0,0.0);
251                                                 glScaled(view_scale, view_scale, 1);
252                                                 glTranslatef(-screen_width/2.0, -screen_height/2.0, 0.0);
253                                                 break;
254                                         default:
255                                                 break;
256
257                                 }       
258                                 
259                                 break;
260                         }
261                         case SDL_MOUSEBUTTONUP:
262                                 break;
263                         case SDL_QUIT:
264                                 exit(EXIT_SUCCESS);
265                                 break;
266                 }
267         }
268
269         
270         glTranslatef(view_v[0], view_v[1], view_v[2]);
271         //SDL_Delay(1);
272 }
273

UCC git Repository :: git.ucc.asn.au