Skip to content

Instantly share code, notes, and snippets.

@koute
Created November 9, 2013 23:16
Show Gist options
  • Save koute/7391344 to your computer and use it in GitHub Desktop.
Save koute/7391344 to your computer and use it in GitHub Desktop.
Minimal SDL2 + OpenGL3 example.
/*
Minimal SDL2 + OpenGL3 example.
Author: https://github.com/koute
This file is in the public domain; you can do whatever you want with it.
In case the concept of public domain doesn't exist in your jurisdiction
you can also use this code under the terms of Creative Commons CC0 license,
either version 1.0 or (at your option) any later version; for details see:
http://creativecommons.org/publicdomain/zero/1.0/
This software is distributed without any warranty whatsoever.
Compile and run with: gcc opengl3_hello.c `sdl2-config --libs --cflags` -lGL -Wall && ./a.out
*/
#define GL_GLEXT_PROTOTYPES
#include <SDL.h>
#include <SDL_opengl.h>
#include <stdio.h>
typedef float t_mat4x4[16];
static inline void mat4x4_ortho( t_mat4x4 out, float left, float right, float bottom, float top, float znear, float zfar )
{
#define T(a, b) (a * 4 + b)
out[T(0,0)] = 2.0f / (right - left);
out[T(0,1)] = 0.0f;
out[T(0,2)] = 0.0f;
out[T(0,3)] = 0.0f;
out[T(1,1)] = 2.0f / (top - bottom);
out[T(1,0)] = 0.0f;
out[T(1,2)] = 0.0f;
out[T(1,3)] = 0.0f;
out[T(2,2)] = -2.0f / (zfar - znear);
out[T(2,0)] = 0.0f;
out[T(2,1)] = 0.0f;
out[T(2,3)] = 0.0f;
out[T(3,0)] = -(right + left) / (right - left);
out[T(3,1)] = -(top + bottom) / (top - bottom);
out[T(3,2)] = -(zfar + znear) / (zfar - znear);
out[T(3,3)] = 1.0f;
#undef T
}
static const char * vertex_shader =
"#version 130\n"
"in vec2 i_position;\n"
"in vec4 i_color;\n"
"out vec4 v_color;\n"
"uniform mat4 u_projection_matrix;\n"
"void main() {\n"
" v_color = i_color;\n"
" gl_Position = u_projection_matrix * vec4( i_position, 0.0, 1.0 );\n"
"}\n";
static const char * fragment_shader =
"#version 130\n"
"in vec4 v_color;\n"
"out vec4 o_color;\n"
"void main() {\n"
" o_color = v_color;\n"
"}\n";
typedef enum t_attrib_id
{
attrib_position,
attrib_color
} t_attrib_id;
int main( int argc, char * argv[] )
{
SDL_Init( SDL_INIT_VIDEO );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
static const int width = 800;
static const int height = 600;
SDL_Window * window = SDL_CreateWindow( "", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
SDL_GLContext context = SDL_GL_CreateContext( window );
GLuint vs, fs, program;
vs = glCreateShader( GL_VERTEX_SHADER );
fs = glCreateShader( GL_FRAGMENT_SHADER );
int length = strlen( vertex_shader );
glShaderSource( vs, 1, ( const GLchar ** )&vertex_shader, &length );
glCompileShader( vs );
GLint status;
glGetShaderiv( vs, GL_COMPILE_STATUS, &status );
if( status == GL_FALSE )
{
fprintf( stderr, "vertex shader compilation failed\n" );
return 1;
}
length = strlen( fragment_shader );
glShaderSource( fs, 1, ( const GLchar ** )&fragment_shader, &length );
glCompileShader( fs );
glGetShaderiv( fs, GL_COMPILE_STATUS, &status );
if( status == GL_FALSE )
{
fprintf( stderr, "fragment shader compilation failed\n" );
return 1;
}
program = glCreateProgram();
glAttachShader( program, vs );
glAttachShader( program, fs );
glBindAttribLocation( program, attrib_position, "i_position" );
glBindAttribLocation( program, attrib_color, "i_color" );
glLinkProgram( program );
glUseProgram( program );
glDisable( GL_DEPTH_TEST );
glClearColor( 0.5, 0.0, 0.0, 0.0 );
glViewport( 0, 0, width, height );
GLuint vao, vbo;
glGenVertexArrays( 1, &vao );
glGenBuffers( 1, &vbo );
glBindVertexArray( vao );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glEnableVertexAttribArray( attrib_position );
glEnableVertexAttribArray( attrib_color );
glVertexAttribPointer( attrib_color, 4, GL_FLOAT, GL_FALSE, sizeof( float ) * 6, 0 );
glVertexAttribPointer( attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof( float ) * 6, ( void * )(4 * sizeof(float)) );
const GLfloat g_vertex_buffer_data[] = {
/* R, G, B, A, X, Y */
1, 0, 0, 1, 0, 0,
0, 1, 0, 1, width, 0,
0, 0, 1, 1, width, height,
1, 0, 0, 1, 0, 0,
0, 0, 1, 1, width, height,
1, 1, 1, 1, 0, height
};
glBufferData( GL_ARRAY_BUFFER, sizeof( g_vertex_buffer_data ), g_vertex_buffer_data, GL_STATIC_DRAW );
t_mat4x4 projection_matrix;
mat4x4_ortho( projection_matrix, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 100.0f );
glUniformMatrix4fv( glGetUniformLocation( program, "u_projection_matrix" ), 1, GL_FALSE, projection_matrix );
for( ;; )
{
glClear( GL_COLOR_BUFFER_BIT );
SDL_Event event;
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_KEYUP:
if( event.key.keysym.sym == SDLK_ESCAPE )
return 0;
break;
}
}
glBindVertexArray( vao );
glDrawArrays( GL_TRIANGLES, 0, 6 );
SDL_GL_SwapWindow( window );
SDL_Delay( 1 );
}
SDL_GL_DeleteContext( context );
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}
@0xBAMA
Copy link

0xBAMA commented Dec 18, 2019

This was really helpful - I was following the LazyFoo tutorials and was having issues getting their OpenGL3 stuff to compile - this is much simpler and more to-the-point. Thanks very much - jb

@shenlebantongying
Copy link

Hahahaha, random dude throw some code on GitHub, then it DOES EXACTLY WHAT I WANT!!!!!!

@shenlebantongying
Copy link

CMake complie:

cmake_minimum_required(VERSION 3.19)
project(openGL)

set(CMAKE_CXX_STANDARD 20)

find_package(SDL2 REQUIRED)
find_package(OpenGL REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
include_directories(${OPENGL_INCLUDE_DIR})

add_executable(prog main.cpp)
target_link_libraries(prog ${SDL2_LIBRARIES})
target_link_libraries(prog ${OPENGL_LIBRARIES})

@dogstar25
Copy link

Hi. I do not use cmake. I'm buiilding with visual studio and vcpkg library management, and Im getting unresolved externals. I've made sure that opengl32.lib, sdl2.lib are available. What lib do I need to make available? Thank you.

1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glBindAttribLocation
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glShaderSource
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glBindBuffer
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glBindVertexArray
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glVertexAttribPointer
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glUniformMatrix4fv
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glCreateProgram
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glEnableVertexAttribArray
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glBufferData
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glGenBuffers
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glGenVertexArrays
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glCompileShader
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glLinkProgram
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glGetUniformLocation
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glCreateShader
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glAttachShader
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glUseProgram
1>testOpenGL.obj : error LNK2001: unresolved external symbol __imp_glGetShaderiv

@RagnarDa
Copy link

And for others trying to run it in MacOS: change both ""#version 130\n" into "#version 330\n" or something similar and it will work (at least for me). Some sources suggest "#version 330 core\n"...

@chastitywhiterose
Copy link

This code is beautiful and compiles for me fine. I have no idea how it works yet but you are a genius for making this and sharing it with us all! Thanks a billion!

@Kitsune64
Copy link

Kitsune64 commented Mar 4, 2024

Work with

#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

-lSDL2 and -lGL in linker settings

Tested on Codeblocks under Debian (Linux)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment