57 removals.48 additions.
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <GL/freeglut.h> #include <GL/freeglut.h>
#define WINDOW_TITLE_PREFIX "Chapter 2" #define WINDOW_TITLE_PREFIX "Chapter 2"
int CurrentWidth = 800, int CurrentWidth = 800,
CurrentHeight = 600, CurrentHeight = 600,
WindowHandle = 0; WindowHandle = 0;
unsigned FrameCount = 0; unsigned FrameCount = 0;
GLuint GLuint
VertexShaderId, VertexShaderId,
FragmentShaderId, FragmentShaderId,
ProgramId, ProgramId,
VaoId, VaoId,
VboId, VboId,
ColorBufferId; ColorBufferId;
const GLchar* VertexShader = const GLchar* VertexShader =
{ {
"#version 400\n"\ "#version 400\n"\
"layout(location=0) in vec4 in_Position;\n"\ "layout(location=0) in vec4 in_Position;\n"\
"layout(location=1) in vec4 in_Color;\n"\ "layout(location=1) in vec4 in_Color;\n"\
"out vec4 ex_Color;\n"\ "out vec4 ex_Color;\n"\
"void main(void)\n"\ "void main(void)\n"\
"{\n"\ "{\n"\
" gl_Position = in_Position;\n"\ " gl_Position = in_Position;\n"\
" ex_Color = in_Color;\n"\ " ex_Color = in_Color;\n"\
"}\n" "}\n"
}; };
const GLchar* FragmentShader = const GLchar* FragmentShader =
{ {
"#version 400\n"\ "#version 400\n"\
"in vec4 ex_Color;\n"\ "in vec4 ex_Color;\n"\
"out vec4 out_Color;\n"\ "out vec4 out_Color;\n"\
"void main(void)\n"\ "void main(void)\n"\
"{\n"\ "{\n"\
" out_Color = ex_Color;\n"\ " out_Color = ex_Color;\n"\
"}\n" "}\n"
}; };
void Initialize(int, char*[]); void Initialize(int, char*[]);
void InitWindow(int, char*[]); void InitWindow(int, char*[]);
void ResizeFunction(int, int); void ResizeFunction(int, int);
void RenderFunction(void); void RenderFunction(void);
void TimerFunction(int); void TimerFunction(int);
void IdleFunction(void); void IdleFunction(void);
void Cleanup(void); void Cleanup(void);
void CreateVBO(void); void CreateVBO(void);
void DestroyVBO(void); void DestroyVBO(void);
void CreateShaders(void); void CreateShaders(void);
void DestroyShaders(void); void DestroyShaders(void);
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
Initialize(argc, argv); Initialize(argc, argv);
glutMainLoop(); glutMainLoop();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
void Initialize(int argc, char* argv[]) void Initialize(int argc, char* argv[])
{ {
GLenum GlewInitResult; GLenum GlewInitResult;
InitWindow(argc, argv); InitWindow(argc, argv);
glewExperimental = GL_TRUE;
GlewInitResult = glewInit(); GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult) { if (GLEW_OK != GlewInitResult)
fprintf( {
stderr, fprintf(stderr, "ERROR: %s/n", glewGetErrorString(GlewInitResult));
"ERROR: %s\n",
glewGetErrorString(GlewInitResult)
);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
fprintf( fprintf(
stdout, stdout,
"INFO: OpenGL Version: %s\n", "INFO: OpenGL Version: %s\n",
glGetString(GL_VERSION) glGetString(GL_VERSION)
); );
CreateShaders(); CreateShaders();
CreateVBO(); CreateVBO();
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
} }
void InitWindow(int argc, char* argv[]) void InitWindow(int argc, char* argv[])
{ {
glutInit(&argc, argv); glutInit(&argc, argv);
glutInitContextVersion(4, 0); glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE); glutInitContextProfile(GLUT_CORE_PROFILE);
glutSetOption( glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS GLUT_ACTION_GLUTMAINLOOP_RETURNS
); );
glutInitWindowSize(CurrentWidth, CurrentHeight); glutInitWindowSize(CurrentWidth, CurrentHeight);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX); WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
if(WindowHandle < 1) { if (WindowHandle < 1)
{
fprintf( fprintf(
stderr, stderr,
"ERROR: Could not create a new rendering window.\n" "ERROR: Could not create a new rendering window.\n"
); );
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
glutReshapeFunc(ResizeFunction); glutReshapeFunc(ResizeFunction);
glutDisplayFunc(RenderFunction); glutDisplayFunc(RenderFunction);
glutIdleFunc(IdleFunction); glutIdleFunc(IdleFunction);
glutTimerFunc(0, TimerFunction, 0); glutTimerFunc(0, TimerFunction, 0);
glutCloseFunc(Cleanup); glutCloseFunc(Cleanup);
} }
void ResizeFunction(int Width, int Height) void ResizeFunction(int Width, int Height)
{ {
CurrentWidth = Width; CurrentWidth = Width;
CurrentHeight = Height; CurrentHeight = Height;
glViewport(0, 0, CurrentWidth, CurrentHeight); glViewport(0, 0, CurrentWidth, CurrentHeight);
} }
void RenderFunction(void) void RenderFunction(void)
{ {
++FrameCount; glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3); glDrawArrays(GL_TRIANGLES, 0, 3);
glutSwapBuffers(); glutSwapBuffers();
glutPostRedisplay(); glutPostRedisplay();
++FrameCount;
} }
void IdleFunction(void) void IdleFunction(void)
{ {
glutPostRedisplay(); glutPostRedisplay();
} }
void TimerFunction(int Value) void TimerFunction(int Value)
{ {
if (0 != Value) { if (0 != Value)
char* TempString = (char*) {
char * TempString = (char*)
malloc(512 + strlen(WINDOW_TITLE_PREFIX)); malloc(512 + strlen(WINDOW_TITLE_PREFIX));
sprintf( sprintf(TempString, "%s: %d Frames Per Second @ %d x %d", WINDOW_TITLE_PREFIX, FrameCount * 4, CurrentWidth, CurrentHeight);
TempString,
"%s: %d Frames Per Second @ %d x %d",
WINDOW_TITLE_PREFIX,
FrameCount * 4,
CurrentWidth,
CurrentHeight
);
glutSetWindowTitle(TempString); glutSetWindowTitle(TempString);
free(TempString); free(TempString);
} }
FrameCount = 0; FrameCount = 0;
glutTimerFunc(250, TimerFunction, 1); glutTimerFunc(250, TimerFunction, 1);
} }
void Cleanup(void) void Cleanup(void)
{ {
DestroyShaders(); DestroyShaders();
DestroyVBO(); DestroyVBO();
} }
void CreateVBO(void) void CreateVBO(void)
{ {
GLfloat Vertices[] = GLfloat Vertices[] =
{ {
-0.8f, -0.8f, 0.0f, 1.0f, -0.8f, -0.8f, 0.0f, 1.0f,
0.0f, 0.8f, 0.0f, 1.0f, 0.0f, 0.8f, 0.0f, 1.0f,
0.8f, -0.8f, 0.0f, 1.0f 0.8f, -0.8f, 0.0f, 1.0f
}; };
GLfloat Colors[] = GLfloat Colors[] =
{ {
1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f 0.0f, 0.0f, 1.0f, 1.0f
}; };
GLenum ErrorCheckValue = glGetError(); GLenum ErrorCheckValue = glGetError();
glGenVertexArrays(1, &VaoId); glGenVertexArrays(1, &VaoId);
glBindVertexArray(VaoId); glBindVertexArray(VaoId);
glGenBuffers(1, &VboId); glGenBuffers(1, &VboId);
glBindBuffer(GL_ARRAY_BUFFER, VboId); glBindBuffer(GL_ARRAY_BUFFER, VboId);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glGenBuffers(1, &ColorBufferId); glGenBuffers(1, &ColorBufferId);
glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId); glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId);
glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
ErrorCheckValue = glGetError(); ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR) if (ErrorCheckValue != GL_NO_ERROR)
{ {
fprintf( fprintf(
stderr, stderr,
"ERROR: Could not create a VBO: %s \n", "ERROR: Could not create a VBO: %s \n",
gluErrorString(ErrorCheckValue) gluErrorString(ErrorCheckValue)
); );
exit(-1); exit(-1);
} }
} }
void DestroyVBO(void) void DestroyVBO(void)
{ {
GLenum ErrorCheckValue = glGetError(); GLenum ErrorCheckValue = glGetError();
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &ColorBufferId); glDeleteBuffers(1, &ColorBufferId);
glDeleteBuffers(1, &VboId); glDeleteBuffers(1, &VboId);
glBindVertexArray(0); glBindVertexArray(0);
glDeleteVertexArrays(1, &VaoId); glDeleteVertexArrays(1, &VaoId);
ErrorCheckValue = glGetError(); ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR) if (ErrorCheckValue != GL_NO_ERROR)
{ {
fprintf( fprintf(
stderr, stderr,
"ERROR: Could not destroy the VBO: %s \n", "ERROR: Could not destroy the VBO: %s \n",
gluErrorString(ErrorCheckValue) gluErrorString(ErrorCheckValue)
); );
exit(-1); exit(-1);
} }
} }
void CreateShaders(void) void CreateShaders(void)
{ {
GLenum ErrorCheckValue = glGetError(); GLenum ErrorCheckValue = glGetError();
VertexShaderId = glCreateShader(GL_VERTEX_SHADER); VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShaderId, 1, &VertexShader, NULL); glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
glCompileShader(VertexShaderId); glCompileShader(VertexShaderId);
FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL); glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
glCompileShader(FragmentShaderId); glCompileShader(FragmentShaderId);
ProgramId = glCreateProgram(); ProgramId = glCreateProgram();
glAttachShader(ProgramId, VertexShaderId); glAttachShader(ProgramId, VertexShaderId);
glAttachShader(ProgramId, FragmentShaderId); glAttachShader(ProgramId, FragmentShaderId);
glLinkProgram(ProgramId); glLinkProgram(ProgramId);
glUseProgram(ProgramId); glUseProgram(ProgramId);
ErrorCheckValue = glGetError(); ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR) if (ErrorCheckValue != GL_NO_ERROR)
{ {
fprintf( fprintf(
stderr, stderr,
"ERROR: Could not create the shaders: %s \n", "ERROR: Could not create the shaders: %s \n",
gluErrorString(ErrorCheckValue) gluErrorString(ErrorCheckValue)
); );
exit(-1); exit(-1);
} }
} }
void DestroyShaders(void) void DestroyShaders(void)
{ {
GLenum ErrorCheckValue = glGetError(); GLenum ErrorCheckValue = glGetError();
glUseProgram(0); glUseProgram(0);
glDetachShader(ProgramId, VertexShaderId); glDetachShader(ProgramId, VertexShaderId);
glDetachShader(ProgramId, FragmentShaderId); glDetachShader(ProgramId, FragmentShaderId);
glDeleteShader(FragmentShaderId); glDeleteShader(FragmentShaderId);
glDeleteShader(VertexShaderId); glDeleteShader(VertexShaderId);
glDeleteProgram(ProgramId); glDeleteProgram(ProgramId);
ErrorCheckValue = glGetError(); ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR) if (ErrorCheckValue != GL_NO_ERROR)
{ {
fprintf( fprintf(
stderr, stderr,
"ERROR: Could not destroy the shaders: %s \n", "ERROR: Could not destroy the shaders: %s \n",
gluErrorString(ErrorCheckValue) gluErrorString(ErrorCheckValue)
); );
exit(-1); exit(-1);
} }
} }
ORIGINAL TEXT
CHANGED TEXT