Share this diff
1#include <stdlib.h> 1#include <stdlib.h>
2#include <stdio.h> 2#include <stdio.h>
3#include <string.h> 3#include <string.h>
4#include <GL/glew.h> 4#include <GL/glew.h>
5#include <GL/freeglut.h> 5#include <GL/freeglut.h>
6#define WINDOW_TITLE_PREFIX "Chapter 2" 6#define WINDOW_TITLE_PREFIX "Chapter 2"
7 7
8int CurrentWidth = 800, 8int CurrentWidth = 800,
9 CurrentHeight = 600, 9CurrentHeight = 600,
10 WindowHandle = 0; 10WindowHandle = 0;
11 11
12unsigned FrameCount = 0; 12unsigned FrameCount = 0;
13 13
14GLuint 14GLuint
15 VertexShaderId, 15VertexShaderId,
16 FragmentShaderId, 16FragmentShaderId,
17 ProgramId, 17ProgramId,
18 VaoId, 18VaoId,
19 VboId, 19VboId,
20 ColorBufferId; 20ColorBufferId;
21 21
22const GLchar* VertexShader = 22const GLchar* VertexShader =
23{ 23{
24 "#version 400\n"\ 24 "#version 400\n"\
25 25
26 "layout(location=0) in vec4 in_Position;\n"\ 26 "layout(location=0) in vec4 in_Position;\n"\
27 "layout(location=1) in vec4 in_Color;\n"\ 27 "layout(location=1) in vec4 in_Color;\n"\
28 "out vec4 ex_Color;\n"\ 28 "out vec4 ex_Color;\n"\
29 29
30 "void main(void)\n"\ 30 "void main(void)\n"\
31 "{\n"\ 31 "{\n"\
32 " gl_Position = in_Position;\n"\ 32 " gl_Position = in_Position;\n"\
33 " ex_Color = in_Color;\n"\ 33 " ex_Color = in_Color;\n"\
34 "}\n" 34 "}\n"
35}; 35};
36 36
37const GLchar* FragmentShader = 37const GLchar* FragmentShader =
38{ 38{
39 "#version 400\n"\ 39 "#version 400\n"\
40 40
41 "in vec4 ex_Color;\n"\ 41 "in vec4 ex_Color;\n"\
42 "out vec4 out_Color;\n"\ 42 "out vec4 out_Color;\n"\
43 43
44 "void main(void)\n"\ 44 "void main(void)\n"\
45 "{\n"\ 45 "{\n"\
46 " out_Color = ex_Color;\n"\ 46 " out_Color = ex_Color;\n"\
47 "}\n" 47 "}\n"
48}; 48};
49 49
50void Initialize(int, char*[]); 50void Initialize(int, char*[]);
51void InitWindow(int, char*[]); 51void InitWindow(int, char*[]);
52void ResizeFunction(int, int); 52void ResizeFunction(int, int);
53void RenderFunction(void); 53void RenderFunction(void);
54void TimerFunction(int); 54void TimerFunction(int);
55void IdleFunction(void); 55void IdleFunction(void);
 56
56void Cleanup(void); 57void Cleanup(void);
57void CreateVBO(void); 58void CreateVBO(void);
58void DestroyVBO(void); 59void DestroyVBO(void);
59void CreateShaders(void); 60void CreateShaders(void);
60void DestroyShaders(void); 61void DestroyShaders(void);
61 62
62int main(int argc, char* argv[]) 63int main(int argc, char* argv[])
63{ 64{
64 Initialize(argc, argv); 65 Initialize(argc, argv);
65 66
66 glutMainLoop(); 67 glutMainLoop();
67 68
68 exit(EXIT_SUCCESS); 69 exit(EXIT_SUCCESS);
69} 70}
70 71
71void Initialize(int argc, char* argv[]) 72void Initialize(int argc, char* argv[])
72{ 73{
73 GLenum GlewInitResult; 74 GLenum GlewInitResult;
74 75
75 InitWindow(argc, argv); 76 InitWindow(argc, argv);
76 77
77 glewExperimental = GL_TRUE;  
78 GlewInitResult = glewInit(); 78 GlewInitResult = glewInit();
79 79
80 if (GLEW_OK != GlewInitResult) { 80 if (GLEW_OK != GlewInitResult)
81 fprintf( 81 {
82 stderr, 82 fprintf(stderr, "ERROR: %s/n", glewGetErrorString(GlewInitResult));
83 "ERROR: %s\n",  
84 glewGetErrorString(GlewInitResult)  
85 );  
86 exit(EXIT_FAILURE); 83 exit(EXIT_FAILURE);
87 } 84 }
88 85
89 fprintf( 86 fprintf(
90 stdout, 87 stdout,
91 "INFO: OpenGL Version: %s\n", 88 "INFO: OpenGL Version: %s\n",
92 glGetString(GL_VERSION) 89 glGetString(GL_VERSION)
93 ); 90 );
94 91
95 CreateShaders(); 92 CreateShaders();
96 CreateVBO(); 93 CreateVBO();
97 94 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
98 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);  
99} 95}
100 96
101void InitWindow(int argc, char* argv[]) 97void InitWindow(int argc, char* argv[])
102{ 98{
103 glutInit(&argc, argv); 99 glutInit(&argc, argv);
104 100
105 glutInitContextVersion(4, 0); 101 glutInitContextVersion(4, 0);
106 glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); 102 glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
107 glutInitContextProfile(GLUT_CORE_PROFILE); 103 glutInitContextProfile(GLUT_CORE_PROFILE);
108 104
109 glutSetOption( 105 glutSetOption(
110 GLUT_ACTION_ON_WINDOW_CLOSE, 106 GLUT_ACTION_ON_WINDOW_CLOSE,
111 GLUT_ACTION_GLUTMAINLOOP_RETURNS 107 GLUT_ACTION_GLUTMAINLOOP_RETURNS
112 ); 108 );
113 109
114 glutInitWindowSize(CurrentWidth, CurrentHeight); 110 glutInitWindowSize(CurrentWidth, CurrentHeight);
115 111
116 glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); 112 glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
117 113
118 WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX); 114 WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
119 115
120 if(WindowHandle < 1) { 116 if (WindowHandle < 1)
 117 {
121 fprintf( 118 fprintf(
122 stderr, 119 stderr,
123 "ERROR: Could not create a new rendering window.\n" 120 "ERROR: Could not create a new rendering window.\n"
124 ); 121 );
125 exit(EXIT_FAILURE); 122 exit(EXIT_FAILURE);
126 } 123 }
127 124
128 glutReshapeFunc(ResizeFunction); 125 glutReshapeFunc(ResizeFunction);
129 glutDisplayFunc(RenderFunction); 126 glutDisplayFunc(RenderFunction);
130 glutIdleFunc(IdleFunction); 127 glutIdleFunc(IdleFunction);
131 glutTimerFunc(0, TimerFunction, 0); 128 glutTimerFunc(0, TimerFunction, 0);
132 glutCloseFunc(Cleanup); 129 glutCloseFunc(Cleanup);
133} 130}
134 131
135void ResizeFunction(int Width, int Height) 132void ResizeFunction(int Width, int Height)
136{ 133{
137 CurrentWidth = Width; 134 CurrentWidth = Width;
138 CurrentHeight = Height; 135 CurrentHeight = Height;
139 glViewport(0, 0, CurrentWidth, CurrentHeight); 136 glViewport(0, 0, CurrentWidth, CurrentHeight);
140} 137}
141 138
142void RenderFunction(void) 139void RenderFunction(void)
143{ 140{
144 ++FrameCount; 141 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
145  
146 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 142 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
147 143
148 glDrawArrays(GL_TRIANGLES, 0, 3); 144 glDrawArrays(GL_TRIANGLES, 0, 3);
149 145
150 glutSwapBuffers(); 146 glutSwapBuffers();
151 glutPostRedisplay(); 147 glutPostRedisplay();
 148 ++FrameCount;
152} 149}
153 150
154void IdleFunction(void) 151void IdleFunction(void)
155{ 152{
156 glutPostRedisplay(); 153 glutPostRedisplay();
157} 154}
158 155
159void TimerFunction(int Value) 156void TimerFunction(int Value)
160{ 157{
161 if (0 != Value) { 158 if (0 != Value)
162 char* TempString = (char*) 159 {
 160 char * TempString = (char*)
163 malloc(512 + strlen(WINDOW_TITLE_PREFIX)); 161 malloc(512 + strlen(WINDOW_TITLE_PREFIX));
164 162
165 sprintf( 163 sprintf(TempString, "%s: %d Frames Per Second @ %d x %d", WINDOW_TITLE_PREFIX, FrameCount * 4, CurrentWidth, CurrentHeight);
166 TempString,  
167 "%s: %d Frames Per Second @ %d x %d",  
168 WINDOW_TITLE_PREFIX,  
169 FrameCount * 4,  
170 CurrentWidth,  
171 CurrentHeight  
172 );  
173 164
174 glutSetWindowTitle(TempString); 165 glutSetWindowTitle(TempString);
175 free(TempString); 166 free(TempString);
176 } 167 }
177 168
178 FrameCount = 0; 169 FrameCount = 0;
179 glutTimerFunc(250, TimerFunction, 1); 170 glutTimerFunc(250, TimerFunction, 1);
180} 171}
181 172
182void Cleanup(void) 173void Cleanup(void)
183{ 174{
184 DestroyShaders(); 175 DestroyShaders();
185 DestroyVBO(); 176 DestroyVBO();
186} 177}
187 178
188void CreateVBO(void) 179void CreateVBO(void)
189{ 180{
190 GLfloat Vertices[] = 181 GLfloat Vertices[] =
191 { 182 {
192 -0.8f, -0.8f, 0.0f, 1.0f, 183 -0.8f, -0.8f, 0.0f, 1.0f,
193 0.0f, 0.8f, 0.0f, 1.0f, 184 0.0f, 0.8f, 0.0f, 1.0f,
194 0.8f, -0.8f, 0.0f, 1.0f 185 0.8f, -0.8f, 0.0f, 1.0f
195 }; 186 };
196 187
197 GLfloat Colors[] = 188 GLfloat Colors[] =
198 { 189 {
199 1.0f, 0.0f, 0.0f, 1.0f, 190 1.0f, 0.0f, 0.0f, 1.0f,
200 0.0f, 1.0f, 0.0f, 1.0f, 191 0.0f, 1.0f, 0.0f, 1.0f,
201 0.0f, 0.0f, 1.0f, 1.0f 192 0.0f, 0.0f, 1.0f, 1.0f
202 }; 193 };
203 194
204 GLenum ErrorCheckValue = glGetError(); 195 GLenum ErrorCheckValue = glGetError();
205 196
206 glGenVertexArrays(1, &VaoId); 197 glGenVertexArrays(1, &VaoId);
207 glBindVertexArray(VaoId); 198 glBindVertexArray(VaoId);
208 199
209 glGenBuffers(1, &VboId); 200 glGenBuffers(1, &VboId);
210 glBindBuffer(GL_ARRAY_BUFFER, VboId); 201 glBindBuffer(GL_ARRAY_BUFFER, VboId);
211 glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 202 glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
212 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 203 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
213 glEnableVertexAttribArray(0); 204 glEnableVertexAttribArray(0);
214 205
215 glGenBuffers(1, &ColorBufferId); 206 glGenBuffers(1, &ColorBufferId);
216 glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId); 207 glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId);
217 glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW); 208 glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW);
218 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); 209 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
219 glEnableVertexAttribArray(1); 210 glEnableVertexAttribArray(1);
220 211
221 ErrorCheckValue = glGetError(); 212 ErrorCheckValue = glGetError();
222 if (ErrorCheckValue != GL_NO_ERROR) 213 if (ErrorCheckValue != GL_NO_ERROR)
223 { 214 {
224 fprintf( 215 fprintf(
225 stderr, 216 stderr,
226 "ERROR: Could not create a VBO: %s \n", 217 "ERROR: Could not create a VBO: %s \n",
227 gluErrorString(ErrorCheckValue) 218 gluErrorString(ErrorCheckValue)
228 ); 219 );
229 220
230 exit(-1); 221 exit(-1);
231 } 222 }
232} 223}
233 224
234void DestroyVBO(void) 225void DestroyVBO(void)
235{ 226{
236 GLenum ErrorCheckValue = glGetError(); 227 GLenum ErrorCheckValue = glGetError();
237 228
238 glDisableVertexAttribArray(1); 229 glDisableVertexAttribArray(1);
239 glDisableVertexAttribArray(0); 230 glDisableVertexAttribArray(0);
240 231
241 glBindBuffer(GL_ARRAY_BUFFER, 0); 232 glBindBuffer(GL_ARRAY_BUFFER, 0);
242 233
243 glDeleteBuffers(1, &ColorBufferId); 234 glDeleteBuffers(1, &ColorBufferId);
244 glDeleteBuffers(1, &VboId); 235 glDeleteBuffers(1, &VboId);
245 236
246 glBindVertexArray(0); 237 glBindVertexArray(0);
247 glDeleteVertexArrays(1, &VaoId); 238 glDeleteVertexArrays(1, &VaoId);
248 239
249 ErrorCheckValue = glGetError(); 240 ErrorCheckValue = glGetError();
250 if (ErrorCheckValue != GL_NO_ERROR) 241 if (ErrorCheckValue != GL_NO_ERROR)
251 { 242 {
252 fprintf( 243 fprintf(
253 stderr, 244 stderr,
254 "ERROR: Could not destroy the VBO: %s \n", 245 "ERROR: Could not destroy the VBO: %s \n",
255 gluErrorString(ErrorCheckValue) 246 gluErrorString(ErrorCheckValue)
256 ); 247 );
257 248
258 exit(-1); 249 exit(-1);
259 } 250 }
260} 251}
261 252
262void CreateShaders(void) 253void CreateShaders(void)
263{ 254{
264 GLenum ErrorCheckValue = glGetError(); 255 GLenum ErrorCheckValue = glGetError();
265 256
266 VertexShaderId = glCreateShader(GL_VERTEX_SHADER); 257 VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
267 glShaderSource(VertexShaderId, 1, &VertexShader, NULL); 258 glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
268 glCompileShader(VertexShaderId); 259 glCompileShader(VertexShaderId);
269 260
270 FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); 261 FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
271 glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL); 262 glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
272 glCompileShader(FragmentShaderId); 263 glCompileShader(FragmentShaderId);
273 264
274 ProgramId = glCreateProgram(); 265 ProgramId = glCreateProgram();
275 glAttachShader(ProgramId, VertexShaderId); 266 glAttachShader(ProgramId, VertexShaderId);
276 glAttachShader(ProgramId, FragmentShaderId); 267 glAttachShader(ProgramId, FragmentShaderId);
277 glLinkProgram(ProgramId); 268 glLinkProgram(ProgramId);
278 glUseProgram(ProgramId); 269 glUseProgram(ProgramId);
279 270
280 ErrorCheckValue = glGetError(); 271 ErrorCheckValue = glGetError();
281 if (ErrorCheckValue != GL_NO_ERROR) 272 if (ErrorCheckValue != GL_NO_ERROR)
282 { 273 {
283 fprintf( 274 fprintf(
284 stderr, 275 stderr,
285 "ERROR: Could not create the shaders: %s \n", 276 "ERROR: Could not create the shaders: %s \n",
286 gluErrorString(ErrorCheckValue) 277 gluErrorString(ErrorCheckValue)
287 ); 278 );
288 279
289 exit(-1); 280 exit(-1);
290 } 281 }
291} 282}
292 283
 284
293void DestroyShaders(void) 285void DestroyShaders(void)
294{ 286{
295 GLenum ErrorCheckValue = glGetError(); 287 GLenum ErrorCheckValue = glGetError();
296 288
297 glUseProgram(0); 289 glUseProgram(0);
298 290
299 glDetachShader(ProgramId, VertexShaderId); 291 glDetachShader(ProgramId, VertexShaderId);
300 glDetachShader(ProgramId, FragmentShaderId); 292 glDetachShader(ProgramId, FragmentShaderId);
301 293
302 glDeleteShader(FragmentShaderId); 294 glDeleteShader(FragmentShaderId);
303 glDeleteShader(VertexShaderId); 295 glDeleteShader(VertexShaderId);
304 296
305 glDeleteProgram(ProgramId); 297 glDeleteProgram(ProgramId);
306 298
307 ErrorCheckValue = glGetError(); 299 ErrorCheckValue = glGetError();
308 if (ErrorCheckValue != GL_NO_ERROR) 300 if (ErrorCheckValue != GL_NO_ERROR)
309 { 301 {
310 fprintf( 302 fprintf(
311 stderr, 303 stderr,
312 "ERROR: Could not destroy the shaders: %s \n", 304 "ERROR: Could not destroy the shaders: %s \n",
313 gluErrorString(ErrorCheckValue) 305 gluErrorString(ErrorCheckValue)
314 ); 306 );
315 307
316 exit(-1); 308 exit(-1);
317 } 309 }
318} 310}
ORIGINAL TEXT
CHANGED TEXT