// // main.c // testsdlgl // // Created by Daniel Bokser on 9/26/18. // Copyright © 2018 dan. All rights reserved. // #include #include #include #define USE_RENDERER 0 #define LATE_INIT 1 typedef struct ThreadContext { SDL_Window *window; SDL_GLContext context; float r; float g; float b; } ThreadContext; static SDL_bool isRunning = SDL_TRUE; static SDL_atomic_t stopflag; static SDL_mutex *mutex = NULL; static void (*mark)(GLsizei, const void *) = NULL; void renderWindow(const char *title, ThreadContext *tc) { char buf[128]; SDL_snprintf(buf, sizeof (buf), "Starting %s render", title); SDL_LockMutex(mutex); if (mark) mark(0, buf); SDL_Window *curwin = SDL_GL_GetCurrentWindow(); SDL_GLContext curctx = SDL_GL_GetCurrentContext(); if ((curwin != tc->window) || (curctx != tc->context)) { printf("%s: %p %p vs %p %p\n", title, curwin, curctx, tc->window, tc->context); } SDL_GL_MakeCurrent(tc->window, tc->context); glClearColor(tc->r, tc->g, tc->b, 1.0); glClear(GL_COLOR_BUFFER_BIT); tc->r += 1.0f / 255.0f; if (tc->r > 1.0f) { tc->r = 0; } SDL_GL_SwapWindow(tc->window); SDL_snprintf(buf, sizeof (buf), "Ending %s render", title); if (mark) mark(0, buf); SDL_UnlockMutex(mutex); SDL_Delay(10); } static int threntry(void *arg) { ThreadContext *tc = (ThreadContext *) arg; while (!SDL_AtomicGet(&stopflag)) { renderWindow("window 2", tc); } return 0; } int initWindow(const char *title, ThreadContext *tc) { SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); tc->window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 300, 300, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); tc->context = SDL_GL_CreateContext(tc->window); SDL_GL_MakeCurrent(tc->window, tc->context); printf("Create %s\n", title); return 0; } int main(int argc, const char * argv[]) { SDL_Init(SDL_INIT_EVERYTHING); mutex = SDL_CreateMutex(); #if USE_RENDERER SDL_Window *window = SDL_CreateWindow("Test SDL Renderer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 300, 300, SDL_WINDOW_SHOWN ); SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); Uint8 r = 0; #else ThreadContext tc1; if (initWindow("window 1", &tc1)) { return 1; } tc1.r = 1; tc1.g = 0; tc1.b = 0; #endif mark = (void (*)(GLsizei, const void *)) SDL_GL_GetProcAddress("glStringMarkerGREMEDY"); ThreadContext tc2; SDL_Thread *thr = NULL; #if LATE_INIT int isInited = 0; int count = 30; #else if (initWindow("window 2", &tc2)) { return 1; } tc2.r = 0; tc2.g = 0; tc2.b = 1; thr = SDL_CreateThread(threntry, "2ndContext", &tc2); #endif while (isRunning) { SDL_Event e; while (SDL_PollEvent(&e)) { switch (e.type) { case SDL_QUIT: isRunning = SDL_FALSE; break; case SDL_WINDOWEVENT: if (e.window.event == SDL_WINDOWEVENT_CLOSE) { isRunning = SDL_FALSE; break; } break; } } #if LATE_INIT if (!isInited && count <= 0) { if (initWindow("window 2", &tc2)) { return 1; } tc2.r = 0; tc2.g = 0; tc2.b = 1; isInited = 1; thr = SDL_CreateThread(threntry, "2ndContext", &tc2); } else { count--; } #endif #if USE_RENDERER SDL_SetRenderDrawColor(renderer, r++, 0, 0, 255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); #else renderWindow("window 1", &tc1); #endif } if (thr) { SDL_AtomicSet(&stopflag, 1); SDL_WaitThread(thr, NULL); } SDL_Quit(); return 0; }