diff options
author | =?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com> | 2015-07-26 13:08:22 -0700 |
---|---|---|
committer | =?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com> | 2015-07-26 13:08:22 -0700 |
commit | 4755aa94deb0a8fb90bf74033d370e9370d69ca2 (patch) | |
tree | 5d1b387714337fd8a8299d3764bcef95f60c7efa | |
parent | 711f53c6685783e5effb17e493450ed5d09b3aa1 (diff) |
Use SDL2 renderer as a fallback
-rwxr-xr-x | render_sdl.c | 275 |
1 files changed, 146 insertions, 129 deletions
diff --git a/render_sdl.c b/render_sdl.c index a80acc4..b20808e 100755 --- a/render_sdl.c +++ b/render_sdl.c @@ -12,19 +12,19 @@ #include "io.h" #include "util.h" +#ifndef DISABLE_OPENGL #include <GL/glew.h> +#endif SDL_Window *main_window; -#ifdef DISABLE_OPENGL SDL_Renderer *main_renderer; SDL_Texture *main_texture; SDL_Rect main_clip; -#else SDL_GLContext *main_context; -#endif uint8_t render_dbg = 0; uint8_t debug_pal = 0; +uint8_t render_gl = 1; uint32_t last_frame = 0; @@ -101,6 +101,7 @@ uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b) return 255 << 24 | r << 16 | g << 8 | b; } +#ifndef DISABLE_OPENGL GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], un_width, at_pos; GLfloat vertex_data[] = { @@ -154,6 +155,7 @@ GLuint load_shader(char * fname, GLenum shader_type) } return ret; } +#endif void render_alloc_surfaces(vdp_context * context) { @@ -161,48 +163,52 @@ void render_alloc_surfaces(vdp_context * context) memset(context->oddbuf, 0, 512 * 256 * 4 * 2); context->evenbuf = ((char *)context->oddbuf) + 512 * 256 * 4; -#ifdef DISABLE_OPENGL - /* height=480 to fit interlaced output */ - main_texture = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 480); -#else - glGenTextures(3, textures); - for (int i = 0; i < 3; i++) - { - glBindTexture(GL_TEXTURE_2D, textures[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (i < 2) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, i ? context->evenbuf : context->oddbuf); - } else { - uint32_t blank = 255 << 24; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank); +#ifndef DISABLE_OPENGL + if (render_gl) { + glGenTextures(3, textures); + for (int i = 0; i < 3; i++) + { + glBindTexture(GL_TEXTURE_2D, textures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (i < 2) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, i ? context->evenbuf : context->oddbuf); + } else { + uint32_t blank = 255 << 24; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank); + } } + glGenBuffers(2, buffers); + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); + tern_val def = {.ptrval = "default.v.glsl"}; + vshader = load_shader(tern_find_path_default(config, "video\0vertex_shader\0", def).ptrval, GL_VERTEX_SHADER); + def.ptrval = "default.f.glsl"; + fshader = load_shader(tern_find_path_default(config, "video\0fragment_shader\0", def).ptrval, GL_FRAGMENT_SHADER); + program = glCreateProgram(); + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); + GLint link_status; + glGetProgramiv(program, GL_LINK_STATUS, &link_status); + if (!link_status) { + fputs("Failed to link shader program\n", stderr); + exit(1); + } + un_textures[0] = glGetUniformLocation(program, "textures[0]"); + un_textures[1] = glGetUniformLocation(program, "textures[1]"); + un_width = glGetUniformLocation(program, "width"); + at_pos = glGetAttribLocation(program, "pos"); + } else { +#endif + /* height=480 to fit interlaced output */ + main_texture = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 480); +#ifndef DISABLE_OPENGL } - glGenBuffers(2, buffers); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); - tern_val def = {.ptrval = "default.v.glsl"}; - vshader = load_shader(tern_find_path_default(config, "video\0vertex_shader\0", def).ptrval, GL_VERTEX_SHADER); - def.ptrval = "default.f.glsl"; - fshader = load_shader(tern_find_path_default(config, "video\0fragment_shader\0", def).ptrval, GL_FRAGMENT_SHADER); - program = glCreateProgram(); - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); - GLint link_status; - glGetProgramiv(program, GL_LINK_STATUS, &link_status); - if (!link_status) { - fputs("Failed to link shader program\n", stderr); - exit(1); - } - un_textures[0] = glGetUniformLocation(program, "textures[0]"); - un_textures[1] = glGetUniformLocation(program, "textures[1]"); - un_width = glGetUniformLocation(program, "width"); - at_pos = glGetAttribLocation(program, "pos"); #endif } @@ -238,18 +244,9 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full height = mode.h; } -#ifdef DISABLE_OPENGL - SDL_CreateWindowAndRenderer(width, height, flags, &main_window, &main_renderer); + render_gl = 0; - if (!main_window || !main_renderer) { - fprintf(stderr, "unable to create SDL window: %s\n", SDL_GetError()); - SDL_Quit(); - exit(1); - } - main_clip.x = main_clip.y = 0; - main_clip.w = width; - main_clip.h = height; -#else +#ifndef DISABLE_OPENGL flags |= SDL_WINDOW_OPENGL; SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); @@ -266,15 +263,30 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full GLenum res = glewInit(); if (res != GLEW_OK) { fprintf(stderr, "Initialization of GLEW failed with code %d\n", res); - SDL_Quit(); - exit(1); + SDL_DestroyWindow(main_window); } - if (!GLEW_VERSION_2_0) { - fputs("BlastEm requires at least OpenGL 2.0, but it is unavailable\n", stderr); - SDL_Quit(); - exit(1); + + if (GLEW_VERSION_2_0) { + render_gl = 1; } + else { + SDL_DestroyWindow(main_window); + fputs("OpenGL 2.0 is unavailable, falling back to SDL2 renderer\n", stderr); #endif + SDL_CreateWindowAndRenderer(width, height, flags, &main_window, &main_renderer); + + if (!main_window || !main_renderer) { + fprintf(stderr, "unable to create SDL window: %s\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } + main_clip.x = main_clip.y = 0; + main_clip.w = width; + main_clip.h = height; +#ifndef DISABLE_OPENGL + } +#endif + SDL_GetWindowSize(main_window, &width, &height); printf("Window created with size: %d x %d\n", width, height); float src_aspect = 4.0/3.0; @@ -282,28 +294,31 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full tern_val def = {.ptrval = "normal"}; int stretch = fabs(aspect - src_aspect) > 0.01 && !strcmp(tern_find_path_default(config, "video\0aspect\0", def).ptrval, "stretch"); -#ifdef DISABLE_OPENGL - if (!stretch) { - float scale_x = (float)width / 320.0; - float scale_y = (float)height / 240.0; - float scale = scale_x > scale_y ? scale_y : scale_x; - main_clip.w = 320.0 * scale; - main_clip.h = 240.0 * scale; - main_clip.x = (width - main_clip.w) / 2; - main_clip.y = (height - main_clip.h) / 2; - } -#else if (!stretch) { - for (int i = 0; i < 4; i++) - { - if (aspect > src_aspect) { - vertex_data[i*2] *= src_aspect/aspect; - } else { - vertex_data[i*2+1] *= aspect/src_aspect; +#ifndef DISABLE_OPENGL + if (render_gl) { + for (int i = 0; i < 4; i++) + { + if (aspect > src_aspect) { + vertex_data[i*2] *= src_aspect/aspect; + } else { + vertex_data[i*2+1] *= aspect/src_aspect; + } } + } else { +#endif + float scale_x = (float)width / 320.0; + float scale_y = (float)height / 240.0; + float scale = scale_x > scale_y ? scale_y : scale_x; + main_clip.w = 320.0 * scale; + main_clip.h = 240.0 * scale; + main_clip.x = (width - main_clip.w) / 2; + main_clip.y = (height - main_clip.h) / 2; +#ifndef DISABLE_OPENGL } - } #endif + } + caption = title; min_delay = 0; for (int i = 0; i < 100; i++) { @@ -376,75 +391,77 @@ void render_context(vdp_context * context) int height = 240; last_frame = SDL_GetTicks(); -#ifdef DISABLE_OPENGL - SDL_Rect area; +#ifndef DISABLE_OPENGL + if (render_gl) { + glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);; - area.x = area.y = 0; - area.w = width; - area.h = height; + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); - if (context->regs[REG_MODE_4] & BIT_INTERLACE) - { - unsigned skip; - uint32_t *src = (uint32_t*)context->framebuf; - uint8_t *dst; - int i; + glUseProgram(program); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textures[0]); + glUniform1i(un_textures[0], 0); - area.h *= 2; + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, (context->regs[REG_MODE_4] & BIT_INTERLACE) ? textures[1] : textures[2]); + glUniform1i(un_textures[1], 1); - SDL_LockTexture(main_texture, &area, (void**)&dst, &skip); + glUniform1f(un_width, width); - if (context->framebuf == context->evenbuf) - dst += skip; + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); + glEnableVertexAttribArray(at_pos); - skip *= 2; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); + glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); - for (i = 0; i < 240; ++i) - { - memcpy(dst, src, width*sizeof(uint32_t)); - src += 320; - dst += skip; - } + glDisableVertexAttribArray(at_pos); - SDL_UnlockTexture(main_texture); - } - else /* possibly faster path for non-interlaced output */ - SDL_UpdateTexture(main_texture, &area, context->framebuf, 320*sizeof(uint32_t)); + SDL_GL_SwapWindow(main_window); + } else { +#endif + SDL_Rect area; - SDL_RenderClear(main_renderer); - SDL_RenderCopy(main_renderer, main_texture, &area, &main_clip); - SDL_RenderPresent(main_renderer); -#else - glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);; + area.x = area.y = 0; + area.w = width; + area.h = height; - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + if (context->regs[REG_MODE_4] & BIT_INTERLACE) { + unsigned skip; + uint32_t *src = (uint32_t*)context->framebuf; + uint8_t *dst; + int i; - glUseProgram(program); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textures[0]); - glUniform1i(un_textures[0], 0); + area.h *= 2; - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, (context->regs[REG_MODE_4] & BIT_INTERLACE) ? textures[1] : textures[2]); - glUniform1i(un_textures[1], 1); + SDL_LockTexture(main_texture, &area, (void**)&dst, &skip); - glUniform1f(un_width, width); + if (context->framebuf == context->evenbuf) + dst += skip; - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); - glEnableVertexAttribArray(at_pos); + skip *= 2; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); + for (i = 0; i < 240; ++i) { + memcpy(dst, src, width*sizeof(uint32_t)); + src += 320; + dst += skip; + } - glDisableVertexAttribArray(at_pos); + SDL_UnlockTexture(main_texture); + } + else /* possibly faster path for non-interlaced output */ + SDL_UpdateTexture(main_texture, &area, context->framebuf, 320*sizeof(uint32_t)); - SDL_GL_SwapWindow(main_window); + SDL_RenderClear(main_renderer); + SDL_RenderCopy(main_renderer, main_texture, &area, &main_clip); + SDL_RenderPresent(main_renderer); +#ifndef DISABLE_OPENGL + } #endif - if (context->regs[REG_MODE_4] & BIT_INTERLACE) - { + + if (context->regs[REG_MODE_4] & BIT_INTERLACE) { context->framebuf = context->framebuf == context->oddbuf ? context->evenbuf : context->oddbuf; } } |