Created
September 6, 2014 05:30
-
-
Save agmcleod/f27e3a56063be0b163d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <SDL2/SDL.h> | |
| #include "glew.h" | |
| //#include <GL/glut.h> | |
| #include <SDL2/SDL_opengl.h> | |
| #include <stdbool.h> | |
| void close(GLuint gProgramID, SDL_Window *window); | |
| bool initGL(GLuint *gProgramID, GLint *gVertexPos2DLocation, GLuint *gVBO, GLuint *gIBO); | |
| void printProgramLog(GLuint program); | |
| void printShaderLog(GLuint shader); | |
| void render(GLuint *gProgramID, GLint *gVertexPos2DLocation, GLuint *gVBO, GLuint *gIBO); | |
| void close(GLuint gProgramID, SDL_Window *window) { | |
| //Deallocate program | |
| glDeleteProgram( gProgramID ); | |
| //Destroy window | |
| SDL_DestroyWindow( window ); | |
| window = NULL; | |
| //Quit SDL subsystems | |
| SDL_Quit(); | |
| } | |
| bool initGL(GLuint *gProgramID, GLint *gVertexPos2DLocation, GLuint *gVBO, GLuint *gIBO) { | |
| *gProgramID = glCreateProgram(); | |
| GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
| const GLchar *vertexShaderSource[] = | |
| { | |
| "#version 140\nin vec2 LVertexPos2D; void main() { gl_Position = vec4( LVertexPos2D.x, LVertexPos2D.y, 0, 1 ); }" | |
| }; | |
| glShaderSource(vertexShader, 1, vertexShaderSource, NULL); | |
| glCompileShader(vertexShader); | |
| GLint vShaderCompiled = GL_FALSE; | |
| glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vShaderCompiled); | |
| if (vShaderCompiled != GL_TRUE) { | |
| printf("Unable to compile shader %d", &vShaderCompiled); | |
| printShaderLog(vertexShader); | |
| return false; | |
| } | |
| else { | |
| glAttachShader(*gProgramID, vertexShader); | |
| GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER ); | |
| const GLchar *fragmentShaderSource[] = | |
| { | |
| "#version 140\nout vec4 LFragment; void main() { LFragment = vec4( 1.0, 1.0, 1.0, 1.0 );}" | |
| }; | |
| glShaderSource(fragmentShader, 1, fragmentShaderSource, NULL); | |
| glCompileShader(fragmentShader); | |
| GLint fShaderCompiled = GL_FALSE; | |
| glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fShaderCompiled); | |
| if(fShaderCompiled != GL_TRUE) { | |
| printf("Unable to compile fragment shader %d!\n", fragmentShader); | |
| printShaderLog(fragmentShader); | |
| return false; | |
| } | |
| else { | |
| glAttachShader(*gProgramID, fragmentShader); | |
| glLinkProgram(*gProgramID); | |
| GLint programSuccess = GL_TRUE; | |
| glGetProgramiv(*gProgramID, GL_LINK_STATUS, &programSuccess); | |
| if (programSuccess != GL_TRUE) { | |
| printf("Error linking program %d!\n", *gProgramID); | |
| printProgramLog(*gProgramID); | |
| return false; | |
| } | |
| else { | |
| *gVertexPos2DLocation = glGetAttribLocation(*gProgramID, "LVertexPos2D"); | |
| if (*gVertexPos2DLocation == -1) { | |
| printf("LVertexPos2D is not a valid glsl program variable!\n"); | |
| return false; | |
| } | |
| else { | |
| glClearColor(0.f, 0.f, 0.f, 1.f); | |
| GLfloat vertexData[] = { | |
| -0.5f, -0.5f, | |
| 0.5f, -0.5f, | |
| 0.5f, 0.5f, | |
| -0.5f, 0.5f | |
| }; | |
| GLuint indexData[] = { 0, 1, 2, 3 }; | |
| glGenBuffers(1, gVBO); | |
| glBindBuffer(GL_ARRAY_BUFFER, *gVBO); | |
| glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), vertexData, GL_STATIC_DRAW); | |
| glGenBuffers(1, gIBO); | |
| glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *gIBO); | |
| glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLuint), indexData, GL_STATIC_DRAW); | |
| return true; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| void printProgramLog(GLuint program) { | |
| if (glIsProgram(program)) { | |
| int infoLogLength = 0; | |
| int maxLength = infoLogLength; | |
| glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); | |
| char* infoLog = malloc(sizeof(char) * maxLength); | |
| glGetProgramInfoLog(program, maxLength, &infoLogLength, infoLog); | |
| if (infoLogLength > 0) { | |
| printf("%s\n", infoLog); | |
| } | |
| free(infoLog); | |
| } | |
| else { | |
| printf( "Name %d is not a program\n", program ); | |
| } | |
| } | |
| void printShaderLog(GLuint shader) { | |
| //Make sure name is shader | |
| if(glIsShader( shader )) { | |
| //Shader log length | |
| int infoLogLength = 0; | |
| int maxLength = infoLogLength; | |
| //Get info string length | |
| glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); | |
| //Allocate string | |
| char* infoLog = malloc(sizeof(char) * maxLength); | |
| //Get info log | |
| glGetShaderInfoLog(shader, maxLength, &infoLogLength, infoLog); | |
| if(infoLogLength > 0) { | |
| printf( "%s\n", infoLog ); | |
| } | |
| //Deallocate string | |
| free(infoLog); | |
| } | |
| else { | |
| printf("Name %d is not a shader\n", shader); | |
| } | |
| } | |
| void render(GLuint *gProgramID, GLint *gVertexPos2DLocation, GLuint *gVBO, GLuint *gIBO) { | |
| //Clear color buffer | |
| glClear(GL_COLOR_BUFFER_BIT); | |
| //Bind program | |
| glUseProgram(*gProgramID); | |
| //Enable vertex position | |
| glEnableVertexAttribArray(*gVertexPos2DLocation); | |
| //Set vertex data | |
| glBindBuffer(GL_ARRAY_BUFFER, *gVBO); | |
| glVertexAttribPointer(*gVertexPos2DLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), NULL); | |
| //Set index data and render | |
| glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *gIBO); | |
| glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, NULL); | |
| //Disable vertex position | |
| glDisableVertexAttribArray(*gVertexPos2DLocation); | |
| //Unbind program | |
| glUseProgram(NULL); | |
| } | |
| int main(int argc, char *argv[]) { | |
| if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { | |
| printf("SDL_Init error: %s\n", SDL_GetError()); | |
| } | |
| SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); | |
| SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); | |
| SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); | |
| SDL_Window *window = SDL_CreateWindow("Pong", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL); | |
| GLuint gProgramID = 0; | |
| GLint gVertexPos2DLocation = -1; | |
| GLuint gVBO = 0; | |
| GLuint gIBO = 0; | |
| SDL_GLContext *context = SDL_GL_CreateContext(window); | |
| if (context == NULL) { | |
| printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError()); | |
| return 1; | |
| } | |
| glewExperimental = GL_TRUE; | |
| GLenum glewError = glewInit(); | |
| if (glewError != GLEW_OK) { | |
| printf("Error initializing glew! %s\n", glewGetErrorString(glewError)); | |
| return 1; | |
| } | |
| if( SDL_GL_SetSwapInterval( 1 ) < 0 ) { | |
| printf( "Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError() ); | |
| } | |
| //Initialize OpenGL | |
| if (!initGL(&gProgramID, &gVertexPos2DLocation, &gVBO, &gIBO)) { | |
| printf( "Unable to initialize OpenGL!\n" ); | |
| return 1; | |
| } | |
| bool quit = false; | |
| SDL_Event e; | |
| while (!quit) { | |
| while (SDL_PollEvent(&e) != 0) { | |
| if (e.type == SDL_QUIT) { | |
| quit = true; | |
| } | |
| if (e.type == SDL_KEYDOWN) { | |
| SDL_Keycode keyPressed = e.key.keysym.sym; | |
| switch (keyPressed) { | |
| case SDLK_ESCAPE: | |
| quit = true; | |
| break; | |
| } | |
| } | |
| } | |
| render(&gProgramID, &gVertexPos2DLocation, &gVBO, &gIBO); | |
| SDL_GL_SwapWindow(window); | |
| } | |
| SDL_StopTextInput(); | |
| close(gProgramID, window); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment