Created
October 10, 2015 11:07
-
-
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
This file contains 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 <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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for your nice example. It helped us a lot to get https://github.com/jhasse/jngl running with emscripten.