Skip to content

Instantly share code, notes, and snippets.

@vittorioromeo
Created October 10, 2015 11:07
Show Gist options
  • Save vittorioromeo/5c5ad838fe5fe1bf54f9 to your computer and use it in GitHub Desktop.
Save vittorioromeo/5c5ad838fe5fe1bf54f9 to your computer and use it in GitHub Desktop.
SDL2 + OpenGL ES 2.0 - "Hello triangle" example that works both on X11 and Emscripten
#include <exception>
#include <functional>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#define GL_GLEXT_PROTOTYPES 1
#include <SDL_opengles2.h>
#else
#include <SDL2/SDL.h>
#define GL_GLEXT_PROTOTYPES 1
#include <SDL2/SDL_opengles2.h>
#endif
// Shader sources
const GLchar* vertexSource =
"attribute vec4 position; \n"
"void main() \n"
"{ \n"
" gl_Position = vec4(position.xyz, 1.0); \n"
"} \n";
const GLchar* fragmentSource =
"precision mediump float;\n"
"void main() \n"
"{ \n"
" gl_FragColor = vec4 (1.0, 1.0, 1.0, 1.0 );\n"
"} \n";
std::function<void()> loop;
void main_loop() { loop(); }
int main(int argc, char** argv)
{
// SDL_Init(SDL_INIT_VIDEO);
auto wnd(
SDL_CreateWindow("test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN));
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetSwapInterval(0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
auto glc = SDL_GL_CreateContext(wnd);
auto rdr = SDL_CreateRenderer(
wnd, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
// Create Vertex Array Object
GLuint vao;
glGenVertexArraysOES(1, &vao);
glBindVertexArrayOES(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers(1, &vbo);
GLfloat vertices[] = {0.0f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
// glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
loop = [&]
{
SDL_Event e;
while(SDL_PollEvent(&e))
{
if(e.type == SDL_QUIT) std::terminate();
}
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw a triangle from the 3 vertices
glDrawArrays(GL_TRIANGLES, 0, 3);
SDL_GL_SwapWindow(wnd);
};
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(main_loop, 0, true);
#else
while(true) main_loop();
#endif
return 0;
}
@hor63
Copy link

hor63 commented Jul 24, 2024

Any idea why I'd be getting this compilation error?

» clang++ --std=c++14 -Wreturn-type -g -O0 -D_GLIBCXX_DEBUG -DCXXPOOL_ENABLE_THREAD_AFFINITIES `sdl2-config  --cflags --libs` -lGLESv2 -lEGL ./hello_triangle.cpp -lpthread -lstdc++fs -o hello_triangle
/tmp/hello_triangle-263b5f.o: In function `main':
/home/mako/programming/toying/./hello_triangle.cpp:62: undefined reference to `glGenVertexArraysOES'
/home/mako/programming/toying/./hello_triangle.cpp:63: undefined reference to `glBindVertexArrayOES'

Yes this an GLES2.0 extension which is not available on all implementations. If not available you must repeat binding the buffers, and setting the data layout within the render loop. Creating the buffers and filling it with data can be kept outside the loop.

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