Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Copyright (C) 2011 by Eddy Luten
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <GL/glew.h>
- #include <GL/freeglut.h>
- #define WINDOW_TITLE_PREFIX "Chapter 3"
- typedef struct
- {
- float XYZW[4];
- float RGBA[4];
- } Vertex;
- int CurrentWidth = 600,
- CurrentHeight = 600,
- WindowHandle = 0;
- unsigned FrameCount = 0;
- GLuint
- VertexShaderId,
- FragmentShaderId,
- ProgramId,
- VaoId,
- BufferId,
- IndexBufferId[2],
- ActiveIndexBuffer = 0;
- const GLchar* VertexShader =
- {
- "#version 400\n"\
- "layout(location=0) in vec4 in_Position;\n"\
- "layout(location=1) in vec4 in_Color;\n"\
- "out vec4 ex_Color;\n"\
- "void main(void)\n"\
- "{\n"\
- " gl_Position = in_Position;\n"\
- " ex_Color = in_Color;\n"\
- "}\n"
- };
- const GLchar* FragmentShader =
- {
- "#version 400\n"\
- "in vec4 ex_Color;\n"\
- "out vec4 out_Color;\n"\
- "void main(void)\n"\
- "{\n"\
- " out_Color = ex_Color;\n"\
- "}\n"
- };
- void Initialize(int, char*[]);
- void InitWindow(int, char*[]);
- void ResizeFunction(int, int);
- void RenderFunction(void);
- void TimerFunction(int);
- void IdleFunction(void);
- void KeyboardFunction(unsigned char, int, int);
- void Cleanup(void);
- void CreateVBO(void);
- void DestroyVBO(void);
- void CreateShaders(void);
- void DestroyShaders(void);
- int main(int argc, char* argv[])
- {
- Initialize(argc, argv);
- glutMainLoop();
- exit(EXIT_SUCCESS);
- }
- void Initialize(int argc, char* argv[])
- {
- GLenum GlewInitResult;
- InitWindow(argc, argv);
- glewExperimental = GL_TRUE;
- GlewInitResult = glewInit();
- if (GLEW_OK != GlewInitResult) {
- fprintf(
- stderr,
- "ERROR: %s\n",
- glewGetErrorString(GlewInitResult)
- );
- exit(EXIT_FAILURE);
- }
- fprintf(
- stdout,
- "INFO: OpenGL Version: %s\n",
- glGetString(GL_VERSION)
- );
- CreateShaders();
- CreateVBO();
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- }
- void InitWindow(int argc, char* argv[])
- {
- glutInit(&argc, argv);
- glutInitContextVersion(4, 0);
- glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
- glutInitContextProfile(GLUT_CORE_PROFILE);
- glutSetOption(
- GLUT_ACTION_ON_WINDOW_CLOSE,
- GLUT_ACTION_GLUTMAINLOOP_RETURNS
- );
- glutInitWindowSize(CurrentWidth, CurrentHeight);
- glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
- WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
- if(WindowHandle < 1) {
- fprintf(
- stderr,
- "ERROR: Could not create a new rendering window.\n"
- );
- exit(EXIT_FAILURE);
- }
- glutReshapeFunc(ResizeFunction);
- glutDisplayFunc(RenderFunction);
- glutIdleFunc(IdleFunction);
- glutTimerFunc(0, TimerFunction, 0);
- glutCloseFunc(Cleanup);
- glutKeyboardFunc(KeyboardFunction);
- }
- void KeyboardFunction(unsigned char Key, int X, int Y)
- {
- X; Y; // Resolves warning C4100: unreferenced formal parameter
- switch (Key)
- {
- case 'T':
- case 't':
- {
- ActiveIndexBuffer = (ActiveIndexBuffer == 1 ? 0 : 1);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId[ActiveIndexBuffer]);
- break;
- }
- default:
- break;
- }
- }
- void ResizeFunction(int Width, int Height)
- {
- CurrentWidth = Width;
- CurrentHeight = Height;
- glViewport(0, 0, CurrentWidth, CurrentHeight);
- }
- void RenderFunction(void)
- {
- ++FrameCount;
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- if (ActiveIndexBuffer == 0) {
- glDrawElements(GL_TRIANGLES, 48, GL_UNSIGNED_BYTE, NULL);
- } else {
- glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, NULL);
- }
- glutSwapBuffers();
- glutPostRedisplay();
- }
- void IdleFunction(void)
- {
- glutPostRedisplay();
- }
- void TimerFunction(int Value)
- {
- if (0 != Value) {
- char* TempString = (char*)
- malloc(512 + strlen(WINDOW_TITLE_PREFIX));
- sprintf(
- TempString,
- "%s: %d Frames Per Second @ %d x %d",
- WINDOW_TITLE_PREFIX,
- FrameCount * 4,
- CurrentWidth,
- CurrentHeight
- );
- glutSetWindowTitle(TempString);
- free(TempString);
- }
- FrameCount = 0;
- glutTimerFunc(250, TimerFunction, 1);
- }
- void Cleanup(void)
- {
- DestroyShaders();
- DestroyVBO();
- }
- void CreateVBO(void)
- {
- Vertex Vertices[] =
- {
- { { 0.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, // 0
- // Top
- { { -0.2f, 0.8f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, // 1
- { { 0.2f, 0.8f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }, // 2
- { { 0.0f, 0.8f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } }, //3
- { { 0.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, // 4
- // Bottom
- { { -0.2f, -0.8f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }, // 5
- { { 0.2f, -0.8f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, // 6
- { { 0.0f, -0.8f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } }, //7
- { { 0.0f, -1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, // 8
- // Left
- { { -0.8f, -0.2f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, // 9
- { { -0.8f, 0.2f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }, // 10
- { { -0.8f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } }, //11
- { { -1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, // 12
- // Right
- { { 0.8f, -0.2f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }, // 13
- { { 0.8f, 0.2f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, // 14
- { { 0.8f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } }, //15
- { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } } // 16
- };
- GLubyte Indices[] = {
- // Top
- 0, 1, 3,
- 0, 3, 2,
- 3, 1, 4,
- 3, 4, 2,
- // Bottom
- 0, 5, 7,
- 0, 7, 6,
- 7, 5, 8,
- 7, 8, 6,
- // Left
- 0, 9, 11,
- 0, 11, 10,
- 11, 9, 12,
- 11, 12, 10,
- // Right
- 0, 13, 15,
- 0, 15, 14,
- 15, 13, 16,
- 15, 16, 14
- };
- GLubyte AlternateIndices[] = {
- // Outer square border:
- 3, 4, 16,
- 3, 15, 16,
- 15, 16, 8,
- 15, 7, 8,
- 7, 8, 12,
- 7, 11, 12,
- 11, 12, 4,
- 11, 3, 4,
- // Inner square
- 0, 11, 3,
- 0, 3, 15,
- 0, 15, 7,
- 0, 7, 11
- };
- GLenum ErrorCheckValue = glGetError();
- const size_t BufferSize = sizeof(Vertices);
- const size_t VertexSize = sizeof(Vertices[0]);
- const size_t RgbOffset = sizeof(Vertices[0].XYZW);
- glGenVertexArrays(1, &VaoId);
- glBindVertexArray(VaoId);
- glGenBuffers(1, &BufferId);
- glBindBuffer(GL_ARRAY_BUFFER, BufferId);
- glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW);
- glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, VertexSize, 0);
- glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, VertexSize, (GLvoid*)RgbOffset);
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glGenBuffers(2, IndexBufferId);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId[0]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId[1]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(AlternateIndices), AlternateIndices, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId[0]);
- ErrorCheckValue = glGetError();
- if (ErrorCheckValue != GL_NO_ERROR)
- {
- fprintf(
- stderr,
- "ERROR: Could not create a VBO: %s \n",
- gluErrorString(ErrorCheckValue)
- );
- exit(-1);
- }
- }
- void DestroyVBO(void)
- {
- GLenum ErrorCheckValue = glGetError();
- glDisableVertexAttribArray(1);
- glDisableVertexAttribArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDeleteBuffers(1, &BufferId);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glDeleteBuffers(2, IndexBufferId);
- glBindVertexArray(0);
- glDeleteVertexArrays(1, &VaoId);
- ErrorCheckValue = glGetError();
- if (ErrorCheckValue != GL_NO_ERROR)
- {
- fprintf(
- stderr,
- "ERROR: Could not destroy the VBO: %s \n",
- gluErrorString(ErrorCheckValue)
- );
- exit(-1);
- }
- }
- void CreateShaders(void)
- {
- GLenum ErrorCheckValue = glGetError();
- VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
- glCompileShader(VertexShaderId);
- FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
- glCompileShader(FragmentShaderId);
- ProgramId = glCreateProgram();
- glAttachShader(ProgramId, VertexShaderId);
- glAttachShader(ProgramId, FragmentShaderId);
- glLinkProgram(ProgramId);
- glUseProgram(ProgramId);
- ErrorCheckValue = glGetError();
- if (ErrorCheckValue != GL_NO_ERROR)
- {
- fprintf(
- stderr,
- "ERROR: Could not create the shaders: %s \n",
- gluErrorString(ErrorCheckValue)
- );
- exit(-1);
- }
- }
- void DestroyShaders(void)
- {
- GLenum ErrorCheckValue = glGetError();
- glUseProgram(0);
- glDetachShader(ProgramId, VertexShaderId);
- glDetachShader(ProgramId, FragmentShaderId);
- glDeleteShader(FragmentShaderId);
- glDeleteShader(VertexShaderId);
- glDeleteProgram(ProgramId);
- ErrorCheckValue = glGetError();
- if (ErrorCheckValue != GL_NO_ERROR)
- {
- fprintf(
- stderr,
- "ERROR: Could not destroy the shaders: %s \n",
- gluErrorString(ErrorCheckValue)
- );
- exit(-1);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement