# HG changeset patch # User Michael Pavone # Date 1713416084 25200 # Node ID a0837ea61fdaa0e7796f2fa5e18476b646be9823 # Parent fd04b139a73a5c7c317e32052bd1b6cf74047416 Get static images working in GL mode diff -r fd04b139a73a -r a0837ea61fda render_sdl.c --- a/render_sdl.c Wed Apr 17 20:50:24 2024 -0700 +++ b/render_sdl.c Wed Apr 17 21:54:44 2024 -0700 @@ -34,23 +34,29 @@ SDL_Window *win; SDL_Renderer *renderer; SDL_Texture *sdl_texture; + SDL_Texture **static_images; window_close_handler on_close; uint32_t width; uint32_t height; + uint8_t num_static; #ifndef DISABLE_OPENGL SDL_GLContext *gl_context; uint32_t *texture_buf; uint32_t tex_width; uint32_t tex_height; GLuint gl_texture; + GLuint *gl_static_images; GLuint vshader; GLuint fshader; GLuint program; - GLuint gl_buffers[2]; + GLuint gl_buffers[3]; + GLuint image_buffer; + GLfloat *image_vertices; GLint un_texture; GLint un_width; GLint un_height; GLint at_pos; + GLint at_uv; #endif } extra_window; @@ -337,6 +343,13 @@ 1.0f, 1.0f }; +static GLfloat uvs[] = { + 0.0f, 1.0f, + 1.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f +}; + static GLfloat vertex_data[8]; static const GLushort element_data[] = {0, 1, 2, 3}; @@ -1551,11 +1564,13 @@ } extras[win_idx].texture_buf = calloc(extras[win_idx].tex_width * extras[win_idx].tex_height, sizeof(uint32_t)); glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, extras[win_idx].tex_width, extras[win_idx].tex_height, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, extras[win_idx].texture_buf); - glGenBuffers(2, extras[win_idx].gl_buffers); + glGenBuffers(3, extras[win_idx].gl_buffers); glBindBuffer(GL_ARRAY_BUFFER, extras[win_idx].gl_buffers[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_default), vertex_data_default, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, extras[win_idx].gl_buffers[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, extras[win_idx].gl_buffers[2]); + glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW); extras[win_idx].vshader = load_shader("extra_window.v.glsl", GL_VERTEX_SHADER); extras[win_idx].fshader = load_shader("extra_window.f.glsl", GL_FRAGMENT_SHADER); extras[win_idx].program = glCreateProgram(); @@ -1573,6 +1588,7 @@ extras[win_idx].un_width = glGetUniformLocation(program, "width"); extras[win_idx].un_height = glGetUniformLocation(program, "height"); extras[win_idx].at_pos = glGetAttribLocation(program, "pos"); + extras[win_idx].at_uv = glGetAttribLocation(program, "uv"); } else { sdl_renderer: #endif @@ -1622,52 +1638,126 @@ extras[win_idx].win = NULL; } -SDL_Texture **static_images; -uint8_t num_static; +#ifndef DISABLE_OPENGL +static void extra_draw_quad(extra_window *extra, GLuint texture, float width, float height) +{ + glUseProgram(extra->program); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(extra->un_texture, 0); + + glUniform1f(extra->un_width, width); + glUniform1f(extra->un_height, height); + + glVertexAttribPointer(extra->at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); + glEnableVertexAttribArray(extra->at_pos); + + glBindBuffer(GL_ARRAY_BUFFER, extra->gl_buffers[2]); + glVertexAttribPointer(extra->at_uv, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); + glEnableVertexAttribArray(extra->at_uv); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, extra->gl_buffers[1]); + glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); +} +#endif + uint8_t render_static_image(uint8_t window, uint8_t *buffer, uint32_t size) { window -= FRAMEBUFFER_USER_START; + extra_window *extra = extras + window; uint32_t width, height; uint32_t *pixels = load_png(buffer, size, &width, &height); if (!pixels) { return 0xFF; } uint8_t img_index = 0; - if (!num_static) { - num_static = 8; - static_images = calloc(num_static, sizeof(SDL_Texture*)); + if (!extra->num_static) { + extra->num_static = 8; +#ifndef DISABLE_OPENGL + if (render_gl) { + extra->gl_static_images = calloc(extra->num_static, sizeof(GLuint)); + extra->image_vertices = malloc(sizeof(vertex_data_default)); + memcpy(extra->image_vertices, vertex_data_default, sizeof(vertex_data_default)); + SDL_GL_MakeCurrent(extra->win, extra->gl_context); + glGenBuffers(1, &extra->image_buffer); + glBindBuffer(GL_ARRAY_BUFFER, extra->image_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_default), extra->image_vertices, GL_DYNAMIC_DRAW); + } else +#endif + { + extra->static_images = calloc(extra->num_static, sizeof(SDL_Texture*)); + } } - for (; img_index < num_static; img_index++) + for (; img_index < extra->num_static; img_index++) { - if (!static_images[img_index]) { +#ifndef DISABLE_OPENGL + if (render_gl) { + if (!extra->gl_static_images[img_index]) { + break; + } + } else +#endif + if (!extra->static_images[img_index]) { break; } } - if (img_index == num_static) { - num_static *= 2; - static_images = realloc(static_images, num_static * sizeof(SDL_Texture*)); + if (img_index == extra->num_static) { + extra->num_static *= 2; +#ifndef DISABLE_OPENGL + if (render_gl) { + extra->gl_static_images = realloc(extra->static_images, extra->num_static * sizeof(GLuint)); + } else +#endif + { + extra->static_images = realloc(extra->static_images, extra->num_static * sizeof(SDL_Texture*)); + } } - static_images[img_index] = SDL_CreateTexture(extras[window].renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); - SDL_UpdateTexture(static_images[img_index], NULL, pixels, sizeof(uint32_t) * width); +#ifndef DISABLE_OPENGL + if (render_gl) { + SDL_GL_MakeCurrent(extra->win, extra->gl_context); + + glGenTextures(1, extra->gl_static_images + img_index); + glBindTexture(GL_TEXTURE_2D, extra->gl_static_images[img_index]); + 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); + //TODO: maybe make this respect the npot texture setting? + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, width, height, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, pixels); + } else +#endif + { + extra->static_images[img_index] = SDL_CreateTexture(extra->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); + SDL_UpdateTexture(extra->static_images[img_index], NULL, pixels, sizeof(uint32_t) * width); + } free(pixels); return img_index; } void render_draw_image(uint8_t window, uint8_t image, int x, int y, int width, int height) { - uint8_t win_idx = window - FRAMEBUFFER_USER_START; - if (extras[win_idx].renderer) { + extra_window *extra = extras + window - FRAMEBUFFER_USER_START; + if (extra->renderer) { SDL_Rect dst = { .x = x, .y = y, .w = width, .h = height }; - SDL_RenderCopy(extras[win_idx].renderer, static_images[image], NULL, &dst); + SDL_RenderCopy(extra->renderer, extra->static_images[image], NULL, &dst); } #ifndef DISABLE_OPENGL else { - //TODO: implement me + memcpy(extra->image_vertices, vertex_data_default, sizeof(vertex_data_default)); + extra->image_vertices[0] = extra->image_vertices[4] = 2.0f * x / (float)extra->width - 1.0f; + extra->image_vertices[2] = extra->image_vertices[6] = 2.0f * (x + width) / (float)extra->width - 1.0f; + extra->image_vertices[1] = extra->image_vertices[3] = -2.0f * (y + height) / (float)extra->height + 1.0f; + extra->image_vertices[5] = extra->image_vertices[7] = -2.0f * y / (float)extra->height + 1.0f; + + SDL_GL_MakeCurrent(extra->win, extra->gl_context); + glBindBuffer(GL_ARRAY_BUFFER, extra->image_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_default), extra->image_vertices, GL_DYNAMIC_DRAW); + extra_draw_quad(extra, extra->gl_static_images[image], 1.0f, 1.0f); } #endif } @@ -1942,20 +2032,13 @@ glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgram(extras[win_idx].program); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, extras[win_idx].gl_texture); - glUniform1i(extras[win_idx].un_texture, 0); - - glUniform1f(extras[win_idx].un_width, (float)extras[win_idx].width / (float)extras[win_idx].tex_width); - glUniform1f(extras[win_idx].un_height, (float)extras[win_idx].height / (float)extras[win_idx].tex_height); - glBindBuffer(GL_ARRAY_BUFFER, extras[win_idx].gl_buffers[0]); - glVertexAttribPointer(extras[win_idx].at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); - glEnableVertexAttribArray(extras[win_idx].at_pos); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, extras[win_idx].gl_buffers[1]); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); + extra_draw_quad( + extras + win_idx, + extras[win_idx].gl_texture, + (float)extras[win_idx].width / (float)extras[win_idx].tex_width, + (float)extras[win_idx].height / (float)extras[win_idx].tex_height + ); SDL_GL_SwapWindow(extras[win_idx].win); } diff -r fd04b139a73a -r a0837ea61fda shaders/extra_window.v.glsl --- a/shaders/extra_window.v.glsl Wed Apr 17 20:50:24 2024 -0700 +++ b/shaders/extra_window.v.glsl Wed Apr 17 21:54:44 2024 -0700 @@ -1,10 +1,11 @@ attribute vec2 pos; +attribute vec2 uv; varying mediump vec2 texcoord; uniform mediump float width, height; void main() { gl_Position = vec4(pos, 0.0, 1.0); - texcoord = sign(pos) * vec2(0.5 * width, -0.5 * height) + vec2(0.5 * width, 0.5 * height); + texcoord = uv; }