summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2019-09-07 10:49:21 +0200
committerLudovic Pouzenc <ludovic@pouzenc.fr>2019-09-07 10:49:21 +0200
commit25effd17ef1a1a05d671382b9a51be29734226a0 (patch)
tree6423936fde1f874e2e68b29daeaedda66d371606 /src
parentdf3ce9eb9e0d8633cdb32a0106a5aa1ca9300e2b (diff)
downloaddemoscene-eo-25effd17ef1a1a05d671382b9a51be29734226a0.tar.gz
demoscene-eo-25effd17ef1a1a05d671382b9a51be29734226a0.tar.bz2
demoscene-eo-25effd17ef1a1a05d671382b9a51be29734226a0.zip
Multi-process done. GL has to be done cleanly now.
Diffstat (limited to 'src')
-rw-r--r--src/main.c90
-rw-r--r--src/main.h2
-rw-r--r--src/scene00.c18
-rw-r--r--src/scene01.c34
4 files changed, 101 insertions, 43 deletions
diff --git a/src/main.c b/src/main.c
index 9b151b1..d519034 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,8 +32,18 @@
#include <stdint.h> // uint32_t
#include <stdio.h> // printf()
-
+#ifdef DEBUG
#define TRACE(hint) printf("%s(): %s\n", __func__, hint)
+#else
+#define TRACE(hint)
+#endif
+
+#ifdef DEBUG_SEM
+#define TRACE_SEM(sem,op,hint) printf("%s(): %s(%s) %s\n", __func__, op, #sem, hint)
+#else
+#define TRACE_SEM(sem,op,hint)
+#endif
+
#define SCENE_COUNT 3
#define SCENE_NEXT do { shm->scene = (shm->scene+1)%SCENE_COUNT; } while(0)
@@ -42,13 +52,13 @@
#define SEM_POST(sem,errcode) \
do { \
- /* printf("%s(): sem_post(%s,%i)\n", __func__, #sem, errcode); */ \
+ TRACE_SEM(sem,"sem_post",""); \
if ( sem_post(sem) == -1 ) { return errcode; } \
} while(0)
#define SEM_WAIT(sem,errcode) \
do { \
- /* printf("%s(): sem_wait(%s,%i) call\n", __func__, #sem, errcode); */\
+ TRACE_SEM(sem,"sem_wait","call"); \
while ( sem_wait(sem) == -1 ) { \
switch(errno) { \
case EINTR: \
@@ -58,7 +68,7 @@
return errcode; \
} \
} \
- /* printf("%s(): sem_wait(%s,%i) done\n", __func__, #sem, errcode); */\
+ TRACE_SEM(sem,"sem_wait","done"); \
} while(0)
typedef struct {
@@ -140,7 +150,6 @@ int parent() {
// init / free if scene transition
if ( lastscene != shm->scene ) {
switch(lastscene) {
- //FIXME call free_gl and free_sdl in respective processes too
case 0: scene00_free_caca(&shm->ge, &shm->s00e); break;
case 1: scene01_free_caca(&shm->ge, &shm->s01e); break;
case 2: scene02_free_caca(&shm->ge, &shm->s02e); break;
@@ -150,7 +159,6 @@ int parent() {
shm->ge.sdl_ticks = SDL_GetTicks();
shm->ge.sc_framecount = 0;
switch(shm->scene) {
- //FIXME call init_gl and init_sdl in respective processes too
case 0: res = scene00_init_caca(&shm->ge, &shm->s00e); break;
case 1: res = scene01_init_caca(&shm->ge, &shm->s01e); break;
case 2: res = scene02_init_caca(&shm->ge, &shm->s02e); break;
@@ -220,8 +228,8 @@ int parent() {
}
int worker_sdl() {
- int res;
- Uint32 sdl_win_flags = 0; //XXX for final version, consider sdl_win_flags = SDL_WINDOW_HIDDEN;
+ int lastscene=-1, res;
+ Uint32 sdl_win_flags = 0; //XXX for final version, consider adding SDL_WINDOW_HIDDEN
SDL_RendererInfo renderer_info;
SDL_Event sdl_ev;
@@ -247,6 +255,30 @@ int worker_sdl() {
//FIXME change for TRYWAIT for event handling (+delay)
SEM_WAIT(&shm->worker_sdl_can_render,20);
+ if (!shm->paused) {
+ // init / free if scene transition
+ if ( lastscene != shm->scene ) {
+ switch(lastscene) {
+ case 0: scene00_free_sdl(&shm->ge, &shm->s00e); break;
+ case 1: scene01_free_sdl(&shm->ge, &shm->s01e); break;
+ case 2: scene02_free_sdl(&shm->ge, &shm->s02e); break;
+ }
+ }
+ while ( lastscene != shm->scene ) {
+ shm->ge.sdl_ticks = SDL_GetTicks();
+ shm->ge.sc_framecount = 0;
+ switch(shm->scene) {
+ case 0: res = scene00_init_sdl(&shm->ge, &shm->s00e); break;
+ case 1: res = scene01_init_sdl(&shm->ge, &shm->s01e); break;
+ case 2: res = scene02_init_sdl(&shm->ge, &shm->s02e); break;
+ }
+ // If scene init fail, skip to the next one
+ if (res) SCENE_NEXT; else lastscene = shm->scene;
+ }
+ }
+
+ TRACE("before next_sdl");
+ printf("DEBUG shm->scene : %i\n", shm->scene);
// Compute current scene frame (sdl part)
switch(shm->scene) {
case 0: res = scene00_next_sdl(&shm->ge, &shm->s00e); break;
@@ -254,6 +286,7 @@ int worker_sdl() {
case 2: res = scene02_next_sdl(&shm->ge, &shm->s02e); break;
}
if (res) SCENE_NEXT;
+ TRACE("after next_sdl");
// Event handling for the SDL window (debug purposes)
while(SDL_PollEvent(&sdl_ev)) {
@@ -272,8 +305,10 @@ int worker_sdl() {
break;
}
}
+ TRACE("after SDL_PollEvent loop");
SEM_POST(&shm->parent_can_read_result, 21);
+ TRACE("after sem_post");
}
SDL_DestroyRenderer(shm->ge.sdl_rndr);
@@ -284,8 +319,9 @@ int worker_sdl() {
}
int worker_gl() {
- int res;
- //Uint32 sdl_win_flags = SDL_WINDOW_OPENGL;
+ int lastscene=-1, res;
+ Uint32 sdl_win_flags = SDL_WINDOW_OPENGL; //XXX for final version, consider adding SDL_WINDOW_HIDDEN
+ SDL_RendererInfo renderer_info;
SDL_Event gl_ev;
TRACE("call");
@@ -307,7 +343,17 @@ int worker_gl() {
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
// Initialize OpenGL
- shm->ge.gl_win = SDL_CreateWindow("GL Debug", SDL_WINDOWPOS_CENTERED, 0, FBUF_W, FBUF_H, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
+ //shm->ge.gl_win = SDL_CreateWindow("GL Debug", SDL_WINDOWPOS_CENTERED, 0, FBUF_W, FBUF_H, sdl_win_flags);
+
+ res = SDL_CreateWindowAndRenderer(FBUF_W, FBUF_H, sdl_win_flags, &shm->ge.gl_win, &shm->ge.gl_rndr);
+ if ( res == -1) return 4;
+ SDL_SetWindowTitle(shm->ge.gl_win, "GL debug");
+ res = SDL_GetRendererInfo(shm->ge.gl_rndr, &renderer_info);
+ if ( res < 0 ) return 5;
+ if ( !(renderer_info.flags & SDL_RENDERER_ACCELERATED)) return 6;
+ if ( !(renderer_info.flags & SDL_RENDERER_TARGETTEXTURE)) return 7;
+ shm->ge.gl_target = SDL_CreateTexture(shm->ge.gl_rndr, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, FBUF_W, FBUF_H);
+ if ( shm->ge.gl_target == NULL ) return 9;
shm->ge.gl_ctx = SDL_GL_CreateContext(shm->ge.gl_win);
if ( shm->ge.gl_ctx == NULL ) return 11;
@@ -315,6 +361,28 @@ int worker_gl() {
//FIXME change for TRYWAIT for event handling (+delay)
SEM_WAIT(&shm->worker_gl_can_render,10);
+ if (!shm->paused) {
+ // init / free if scene transition
+ if ( lastscene != shm->scene ) {
+ switch(lastscene) {
+ case 0: scene00_free_gl(&shm->ge, &shm->s00e); break;
+ case 1: scene01_free_gl(&shm->ge, &shm->s01e); break;
+ case 2: scene02_free_gl(&shm->ge, &shm->s02e); break;
+ }
+ }
+ while ( lastscene != shm->scene ) {
+ shm->ge.sdl_ticks = SDL_GetTicks();
+ shm->ge.sc_framecount = 0;
+ switch(shm->scene) {
+ case 0: res = scene00_init_gl(&shm->ge, &shm->s00e); break;
+ case 1: res = scene01_init_gl(&shm->ge, &shm->s01e); break;
+ case 2: res = scene02_init_gl(&shm->ge, &shm->s02e); break;
+ }
+ // If scene init fail, skip to the next one
+ if (res) SCENE_NEXT; else lastscene = shm->scene;
+ }
+ }
+
// Compute current scene frame (gl part)
switch(shm->scene) {
case 0: res = scene00_next_gl(&shm->ge, &shm->s00e); break;
diff --git a/src/main.h b/src/main.h
index 4510b19..363a614 100644
--- a/src/main.h
+++ b/src/main.h
@@ -24,6 +24,8 @@ typedef struct {
// OpenGL worker
SDL_Window* gl_win;
SDL_GLContext gl_ctx;
+ SDL_Renderer *gl_rndr;
+ SDL_Texture *gl_target;
// framebuffer to inject OpenGL or SDL result in caca canvas
uint32_t raw_target[FBUF_W*FBUF_H];
// Timing
diff --git a/src/scene00.c b/src/scene00.c
index b1e4e57..f8df185 100644
--- a/src/scene00.c
+++ b/src/scene00.c
@@ -51,11 +51,7 @@ int scene00_next_gl(graphical_env_t *ge, scene00_env_t *se) {
int scene00_next_sdl(graphical_env_t *ge, scene00_env_t *se) {
// Shorthands
- caca_canvas_t *cv = ge->cv;
- int w = ge->w, h = ge->h;
SDL_Renderer *r = ge->sdl_rndr;
- // Local vars
- int res;
// https://gist.github.com/Twinklebear/8265888
// https://forums.libsdl.org/viewtopic.php?p=51634
@@ -65,17 +61,16 @@ int scene00_next_sdl(graphical_env_t *ge, scene00_env_t *se) {
SDL_RenderCopy(r, se->eo1, NULL, NULL);
// [...]
- // Copy the SDL screen to SDL debug window (and display it, not mandatory)
+#ifdef DEBUG
+ // Copy the target texture to SDL debug window (and display it, not mandatory)
SDL_SetRenderTarget(r, NULL);
SDL_RenderCopy(r, ge->sdl_target, NULL, NULL);
SDL_RenderPresent(r);
+ SDL_SetRenderTarget(r, ge->sdl_target);
+#endif
// Download the rendered texture from videocard to main memory
- SDL_SetRenderTarget(r, ge->sdl_target);
- res = SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, 256*4);
-
- // "convert" the raw pixel stream to ASCII art on caca canevas
- if ( res == 0 ) caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target);
+ SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, FBUF_W*4);
return 0;
}
@@ -86,6 +81,9 @@ int scene00_next_caca(graphical_env_t *ge, scene00_env_t *se) {
int w = ge->w, h = ge->h;
Uint32 frame = ge->sc_framecount;
+ // "convert" the raw pixel stream from SDL to ASCII art on caca canevas
+ caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target);
+
// Add things on top of caca canvas
caca_set_color_ansi(cv, CACA_BLACK, CACA_WHITE);
caca_put_str(cv, (w-17)/2, h/2, "This is a message");
diff --git a/src/scene01.c b/src/scene01.c
index 527e81a..7a6aed1 100644
--- a/src/scene01.c
+++ b/src/scene01.c
@@ -169,35 +169,20 @@ void scene01_free_caca(graphical_env_t *ge, scene01_env_t *se) {
}
int scene01_next_gl(graphical_env_t *ge, scene01_env_t *se) {
- // Shorthands
- caca_canvas_t *cv = ge->cv;
- int w = ge->w, h = ge->h;
- SDL_Renderer *r = ge->sdl_rndr;
- // Local vars
- int res;
+ SDL_Renderer *r = ge->gl_rndr;
// https://gist.github.com/Twinklebear/8265888
// https://forums.libsdl.org/viewtopic.php?p=51634
- // Render all the stuff on target texture
- SDL_SetRenderTarget(r, ge->sdl_target);
-
- glClear( GL_COLOR_BUFFER_BIT );
- glBindVertexArray( se->vao );
- glDrawArrays( GL_TRIANGLES, 0, 6 );
+ glClear(GL_COLOR_BUFFER_BIT);
+ glBindVertexArray(se->vao);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ // [...]
- // Copy the SDL screen to SDL debug window (and display it, not mandatory)
- SDL_SetRenderTarget(r, NULL);
- SDL_RenderCopy(r, ge->sdl_target, NULL, NULL);
- SDL_RenderPresent(r);
+ SDL_GL_SwapWindow(ge->gl_win);
// Download the rendered texture from videocard to main memory
- SDL_SetRenderTarget(r, ge->sdl_target);
- res = SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, 256*4);
-
- // "convert" the raw pixel stream to ASCII art on caca canevas
- caca_set_dither_gamma(ge->d, 1.0);
- if ( res == 0 ) caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target);
+ SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, FBUF_W*4);
return 0;
}
@@ -212,6 +197,11 @@ int scene01_next_caca(graphical_env_t *ge, scene01_env_t *se) {
int w = ge->w, h = ge->h;
Uint32 frame = ge->sc_framecount;
+ // "convert" the raw pixel stream from SDL to ASCII art on caca canevas
+ caca_set_dither_gamma(ge->d, 1.0);
+ caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target);
+
+ // Add things on top of caca canvas
caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK);
caca_put_str(cv, (w-17)/2, h/2, "This is a message");