Skip to content

Instantly share code, notes, and snippets.

@pervognsen
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pervognsen/b52f61500d0184772259 to your computer and use it in GitHub Desktop.
Save pervognsen/b52f61500d0184772259 to your computer and use it in GitHub Desktop.
LazyFoo's SDL2/OpenGL 3.1 sample adapted from GLEW to my stuff
#include <SDL.h>
#include <SDL_opengl.h>
#include <stdio.h>
#include <string>
// PER_BEGIN
#define SDL_OPENGL_LOAD_IMPLEMENT
#include "SDL_opengl_load.h"
// PER_END
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
//Starts up SDL, creates window, and initializes OpenGL
bool init();
//Initializes rendering program and clear color
bool initGL();
//Input handler
void handleKeys( unsigned char key, int x, int y );
//Per frame update
void update();
//Renders quad to the screen
void render();
//Frees media and shuts down SDL
void close();
//Shader loading utility programs
void printProgramLog( GLuint program );
void printShaderLog( GLuint shader );
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//OpenGL context
SDL_GLContext gContext;
//Render flag
bool gRenderQuad = true;
//Graphics program
GLuint gProgramID = 0;
GLint gVertexPos2DLocation = -1;
GLuint gVBO = 0;
GLuint gIBO = 0;
bool init()
{
//Initialization flag
bool success = true;
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Use OpenGL 3.1 core
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 );
//Create window
gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
if( gWindow == NULL )
{
printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Create context
gContext = SDL_GL_CreateContext( gWindow );
if( gContext == NULL )
{
printf( "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
// PER_BEGIN
SDL_GL_LoadExtensions();
// PER_END
//Use Vsync
if( SDL_GL_SetSwapInterval( 1 ) < 0 )
{
printf( "Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError() );
}
//Initialize OpenGL
if( !initGL() )
{
printf( "Unable to initialize OpenGL!\n" );
success = false;
}
}
}
}
return success;
}
bool initGL()
{
//Success flag
bool success = true;
//Generate program
gProgramID = glCreateProgram();
//Create vertex shader
GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
//Get vertex source
const GLchar* vertexShaderSource[] =
{
"#version 140\nin vec2 LVertexPos2D; void main() { gl_Position = vec4( LVertexPos2D.x, LVertexPos2D.y, 0, 1 ); }"
};
//Set vertex source
glShaderSource( vertexShader, 1, vertexShaderSource, NULL );
//Compile vertex source
glCompileShader( vertexShader );
//Check vertex shader for errors
GLint vShaderCompiled = GL_FALSE;
glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &vShaderCompiled );
if( vShaderCompiled != GL_TRUE )
{
printf( "Unable to compile vertex shader %d!\n", vertexShader );
printShaderLog( vertexShader );
success = false;
}
else
{
//Attach vertex shader to program
glAttachShader( gProgramID, vertexShader );
//Create fragment shader
GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
//Get fragment source
const GLchar* fragmentShaderSource[] =
{
"#version 140\nout vec4 LFragment; void main() { LFragment = vec4( 1.0, 0.0, 0.0, 1.0 ); }"
};
//Set fragment source
glShaderSource( fragmentShader, 1, fragmentShaderSource, NULL );
//Compile fragment source
glCompileShader( fragmentShader );
//Check fragment shader for errors
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 );
success = false;
}
else
{
//Attach fragment shader to program
glAttachShader( gProgramID, fragmentShader );
//Link program
glLinkProgram( gProgramID );
//Check for errors
GLint programSuccess = GL_TRUE;
glGetProgramiv( gProgramID, GL_LINK_STATUS, &programSuccess );
if( programSuccess != GL_TRUE )
{
printf( "Error linking program %d!\n", gProgramID );
printProgramLog( gProgramID );
success = false;
}
else
{
//Get vertex attribute location
gVertexPos2DLocation = glGetAttribLocation( gProgramID, "LVertexPos2D" );
if( gVertexPos2DLocation == -1 )
{
printf( "LVertexPos2D is not a valid glsl program variable!\n" );
success = false;
}
else
{
//Initialize clear color
glClearColor( 0.f, 0.f, 0.f, 1.f );
//VBO data
GLfloat vertexData[] =
{
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f
};
//IBO data
GLuint indexData[] = { 0, 1, 2, 3 };
//Create VBO
glGenBuffers( 1, &gVBO );
glBindBuffer( GL_ARRAY_BUFFER, gVBO );
glBufferData( GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), vertexData, GL_STATIC_DRAW );
//Create IBO
glGenBuffers( 1, &gIBO );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, gIBO );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLuint), indexData, GL_STATIC_DRAW );
}
}
}
}
return success;
}
void handleKeys( unsigned char key, int x, int y )
{
//Toggle quad
if( key == 'q' )
{
gRenderQuad = !gRenderQuad;
}
}
void update()
{
//No per frame update needed
}
void render()
{
//Clear color buffer
glClear( GL_COLOR_BUFFER_BIT );
//Render quad
if( gRenderQuad )
{
//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 );
}
}
void close()
{
//Deallocate program
glDeleteProgram( gProgramID );
//Destroy window
SDL_DestroyWindow( gWindow );
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
void printProgramLog( GLuint program )
{
//Make sure name is shader
if( glIsProgram( program ) )
{
//Program log length
int infoLogLength = 0;
int maxLength = infoLogLength;
//Get info string length
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &maxLength );
//Allocate string
char* infoLog = new char[ maxLength ];
//Get info log
glGetProgramInfoLog( program, maxLength, &infoLogLength, infoLog );
if( infoLogLength > 0 )
{
//Print Log
printf( "%s\n", infoLog );
}
//Deallocate string
delete[] 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 = new char[ maxLength ];
//Get info log
glGetShaderInfoLog( shader, maxLength, &infoLogLength, infoLog );
if( infoLogLength > 0 )
{
//Print Log
printf( "%s\n", infoLog );
}
//Deallocate string
delete[] infoLog;
}
else
{
printf( "Name %d is not a shader\n", shader );
}
}
int main( int argc, char* args[] )
{
//Start up SDL and create window
if( !init() )
{
printf( "Failed to initialize!\n" );
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Enable text input
SDL_StartTextInput();
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit = true;
}
//Handle keypress with current mouse position
else if( e.type == SDL_TEXTINPUT )
{
int x = 0, y = 0;
SDL_GetMouseState( &x, &y );
handleKeys( e.text.text[ 0 ], x, y );
}
}
//Render quad
render();
//Update screen
SDL_GL_SwapWindow( gWindow );
}
//Disable text input
SDL_StopTextInput();
}
//Free resources and close SDL
close();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment