-
-
Save vittorioromeo/5c5ad838fe5fe1bf54f9 to your computer and use it in GitHub Desktop.
#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; | |
} |
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'
I found out. At least in sdl2.0.8 Those functions will only be defined if _MSC_VER
is defined, which means it only works on windows.
To get this to work I had to remove:
"precision mediump float;\n"
and
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
SDL_GL_SetAttribute
calls should come before SDL_CreateWindow
.
SDL2 documentation for SDL_GL_SetAttribute
says:
Use this function to set an OpenGL window attribute before window creation.
One problem I noticed is that if you call SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
before SDL_CreateWindow
on Android it will make you lose OpenGL ES context when your window loses focus. Then, when you get back to the app, nothing will be drawn on the screen as all opengl calls will fail because you have no valid context. (At least that was what happened on my device until I moved those calls to before SDL_CreateWindow
or removed the line SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
Thanks for your nice example. It helped us a lot to get https://github.com/jhasse/jngl running with emscripten.
Whenever you feel like it, come over to my place for a treat. You've really helped me out. I had to comment out the vertex ary objects though since my vendor doesnt support that.But still, thanks a lot.