Skip to content

Instantly share code, notes, and snippets.

@m1nuz
Created August 25, 2017 22:01
Show Gist options
  • Save m1nuz/5c48ddd6a3fd8fb340c037165edde1fb to your computer and use it in GitHub Desktop.
Save m1nuz/5c48ddd6a3fd8fb340c037165edde1fb to your computer and use it in GitHub Desktop.
Miminal C++ SDL2 OpenGL 4.5 example
//
// Miminal C++ SDL2 OpenGL 4.5 example
//
// by Poddubny Michael
//
// Download OpenGL header:
// wget https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h
//
// Compile:
// g++ -std=c++11 sdl2_opengl_4_5_triangle.cpp -I. -lSDL2 -o sdl2_opengl_4_5_triangle
#include <SDL2/SDL.h>
#include <iostream>
#include <glcorearb.h>
extern int main(int argc, char *argv[]) {
using namespace std;
// initialize SDL2
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
cerr << "Error: " << SDL_GetError() << '\n';
return EXIT_FAILURE;
}
atexit(SDL_Quit);
// configs
constexpr int gl_major_version = 4;
constexpr int gl_minor_version = 5;
constexpr bool gl_debug = true;
constexpr const char * window_title = "OpenGL 4.5 + SDL2 Basic window";
constexpr int window_width = 1024;
constexpr int window_height = 768;
constexpr bool fullscreen = false;
constexpr bool vsync = false;
// window without borders and show immediately
const auto window_flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | (fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
// opengl forawrd debug context flags
const auto context_flags = SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG | (gl_debug ? SDL_GL_CONTEXT_DEBUG_FLAG : 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, gl_major_version);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, gl_minor_version);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, context_flags);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// create centered window
auto window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_width, window_height, window_flags);
if (!window) {
cerr << "Error: " << SDL_GetError() << '\n';
return EXIT_FAILURE;
}
// create opengl context
auto context = SDL_GL_CreateContext(window);
if (!context) {
cerr << "Error: " << SDL_GetError() << '\n';
return EXIT_FAILURE;
}
if (vsync)
SDL_GL_SetSwapInterval(1);
// load opengl library
if (SDL_GL_LoadLibrary(NULL) != 0) {
cerr << "Error: " << SDL_GetError() << '\n';
return EXIT_FAILURE;
}
// get functions
PFNGLCLIPCONTROLPROC glClipControl = (PFNGLCLIPCONTROLPROC)SDL_GL_GetProcAddress("glClipControl");
PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)SDL_GL_GetProcAddress("glViewportIndexedf");
PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)SDL_GL_GetProcAddress("glClearNamedFramebufferfv");
PFNGLCREATEBUFFERSPROC glCreateBuffers = (PFNGLCREATEBUFFERSPROC)SDL_GL_GetProcAddress("glCreateBuffers");
PFNGLNAMEDBUFFERDATAPROC glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC)SDL_GL_GetProcAddress("glNamedBufferData");
PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC)SDL_GL_GetProcAddress("glCreateVertexArrays");
PFNGLENABLEVERTEXARRAYATTRIBPROC glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC)SDL_GL_GetProcAddress("glEnableVertexArrayAttrib");
PFNGLVERTEXARRAYATTRIBFORMATPROC glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC)SDL_GL_GetProcAddress("glVertexArrayAttribFormat");
PFNGLVERTEXARRAYVERTEXBUFFERPROC glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC)SDL_GL_GetProcAddress("glVertexArrayVertexBuffer");
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)SDL_GL_GetProcAddress("glBindVertexArray");
PFNGLDRAWARRAYSPROC glDrawArrays = (PFNGLDRAWARRAYSPROC)SDL_GL_GetProcAddress("glDrawArrays");
SDL_GL_UnloadLibrary();
bool running = true;
const float points[] = { // vertices of triangle
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
GLuint vbo; // vertex buffer
GLuint vao; // vertex array
// Create VBO
glCreateBuffers(1, &vbo);
// Allocate memory for data and send it
glNamedBufferData(vbo, sizeof (points), points, GL_STATIC_DRAW);
// Create VAO
glCreateVertexArrays(1, &vao);
// Enable vertex attribute (location = 0)
glEnableVertexArrayAttrib(vao, 0);
// Setup vertex array attributes
glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
// Setup vertex buffer for this VAO
glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(float) * 3);
glBindVertexArray(vao);
while (running) {
SDL_Event ev;
while (SDL_PollEvent(&ev)) {
if (ev.key.keysym.sym == SDLK_ESCAPE)
running = false; // Exit when esc
}
const float clear_color[4] = {0.4, 0.4, 0.4, 1};
// Clip window
glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE);
// Setup viewport 0
glViewportIndexedf(0, 0, 0, (float)window_width , (float)window_height);
// Clear color buffer of current framebuffer(0)
glClearNamedFramebufferfv(0, GL_COLOR, 0, clear_color);
// Draw triangle
glDrawArrays(GL_TRIANGLES, 0, 3);
SDL_GL_SwapWindow(window);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment