Mercurial > repos > blastem
comparison render_sdl.c @ 2490:a0837ea61fda
Get static images working in GL mode
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 17 Apr 2024 21:54:44 -0700 |
parents | ccee8dccd9cc |
children | 88210caedc53 |
comparison
equal
deleted
inserted
replaced
2489:fd04b139a73a | 2490:a0837ea61fda |
---|---|
32 | 32 |
33 typedef struct { | 33 typedef struct { |
34 SDL_Window *win; | 34 SDL_Window *win; |
35 SDL_Renderer *renderer; | 35 SDL_Renderer *renderer; |
36 SDL_Texture *sdl_texture; | 36 SDL_Texture *sdl_texture; |
37 SDL_Texture **static_images; | |
37 window_close_handler on_close; | 38 window_close_handler on_close; |
38 uint32_t width; | 39 uint32_t width; |
39 uint32_t height; | 40 uint32_t height; |
41 uint8_t num_static; | |
40 #ifndef DISABLE_OPENGL | 42 #ifndef DISABLE_OPENGL |
41 SDL_GLContext *gl_context; | 43 SDL_GLContext *gl_context; |
42 uint32_t *texture_buf; | 44 uint32_t *texture_buf; |
43 uint32_t tex_width; | 45 uint32_t tex_width; |
44 uint32_t tex_height; | 46 uint32_t tex_height; |
45 GLuint gl_texture; | 47 GLuint gl_texture; |
48 GLuint *gl_static_images; | |
46 GLuint vshader; | 49 GLuint vshader; |
47 GLuint fshader; | 50 GLuint fshader; |
48 GLuint program; | 51 GLuint program; |
49 GLuint gl_buffers[2]; | 52 GLuint gl_buffers[3]; |
53 GLuint image_buffer; | |
54 GLfloat *image_vertices; | |
50 GLint un_texture; | 55 GLint un_texture; |
51 GLint un_width; | 56 GLint un_width; |
52 GLint un_height; | 57 GLint un_height; |
53 GLint at_pos; | 58 GLint at_pos; |
59 GLint at_uv; | |
54 #endif | 60 #endif |
55 } extra_window; | 61 } extra_window; |
56 | 62 |
57 static SDL_Window *main_window; | 63 static SDL_Window *main_window; |
58 static extra_window *extras; | 64 static extra_window *extras; |
333 static GLfloat vertex_data_default[] = { | 339 static GLfloat vertex_data_default[] = { |
334 -1.0f, -1.0f, | 340 -1.0f, -1.0f, |
335 1.0f, -1.0f, | 341 1.0f, -1.0f, |
336 -1.0f, 1.0f, | 342 -1.0f, 1.0f, |
337 1.0f, 1.0f | 343 1.0f, 1.0f |
344 }; | |
345 | |
346 static GLfloat uvs[] = { | |
347 0.0f, 1.0f, | |
348 1.0f, 1.0f, | |
349 0.0f, 0.0f, | |
350 1.0f, 0.0f | |
338 }; | 351 }; |
339 | 352 |
340 static GLfloat vertex_data[8]; | 353 static GLfloat vertex_data[8]; |
341 | 354 |
342 static const GLushort element_data[] = {0, 1, 2, 3}; | 355 static const GLushort element_data[] = {0, 1, 2, 3}; |
1549 extras[win_idx].tex_width = nearest_pow2(width); | 1562 extras[win_idx].tex_width = nearest_pow2(width); |
1550 extras[win_idx].tex_height = nearest_pow2(height); | 1563 extras[win_idx].tex_height = nearest_pow2(height); |
1551 } | 1564 } |
1552 extras[win_idx].texture_buf = calloc(extras[win_idx].tex_width * extras[win_idx].tex_height, sizeof(uint32_t)); | 1565 extras[win_idx].texture_buf = calloc(extras[win_idx].tex_width * extras[win_idx].tex_height, sizeof(uint32_t)); |
1553 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); | 1566 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); |
1554 glGenBuffers(2, extras[win_idx].gl_buffers); | 1567 glGenBuffers(3, extras[win_idx].gl_buffers); |
1555 glBindBuffer(GL_ARRAY_BUFFER, extras[win_idx].gl_buffers[0]); | 1568 glBindBuffer(GL_ARRAY_BUFFER, extras[win_idx].gl_buffers[0]); |
1556 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_default), vertex_data_default, GL_STATIC_DRAW); | 1569 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_default), vertex_data_default, GL_STATIC_DRAW); |
1557 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, extras[win_idx].gl_buffers[1]); | 1570 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, extras[win_idx].gl_buffers[1]); |
1558 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); | 1571 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); |
1572 glBindBuffer(GL_ARRAY_BUFFER, extras[win_idx].gl_buffers[2]); | |
1573 glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW); | |
1559 extras[win_idx].vshader = load_shader("extra_window.v.glsl", GL_VERTEX_SHADER); | 1574 extras[win_idx].vshader = load_shader("extra_window.v.glsl", GL_VERTEX_SHADER); |
1560 extras[win_idx].fshader = load_shader("extra_window.f.glsl", GL_FRAGMENT_SHADER); | 1575 extras[win_idx].fshader = load_shader("extra_window.f.glsl", GL_FRAGMENT_SHADER); |
1561 extras[win_idx].program = glCreateProgram(); | 1576 extras[win_idx].program = glCreateProgram(); |
1562 glAttachShader(program, extras[win_idx].vshader); | 1577 glAttachShader(program, extras[win_idx].vshader); |
1563 glAttachShader(program, extras[win_idx].fshader); | 1578 glAttachShader(program, extras[win_idx].fshader); |
1571 } | 1586 } |
1572 extras[win_idx].un_texture = glGetUniformLocation(program, "texture"); | 1587 extras[win_idx].un_texture = glGetUniformLocation(program, "texture"); |
1573 extras[win_idx].un_width = glGetUniformLocation(program, "width"); | 1588 extras[win_idx].un_width = glGetUniformLocation(program, "width"); |
1574 extras[win_idx].un_height = glGetUniformLocation(program, "height"); | 1589 extras[win_idx].un_height = glGetUniformLocation(program, "height"); |
1575 extras[win_idx].at_pos = glGetAttribLocation(program, "pos"); | 1590 extras[win_idx].at_pos = glGetAttribLocation(program, "pos"); |
1591 extras[win_idx].at_uv = glGetAttribLocation(program, "uv"); | |
1576 } else { | 1592 } else { |
1577 sdl_renderer: | 1593 sdl_renderer: |
1578 #endif | 1594 #endif |
1579 extras[win_idx].renderer = SDL_CreateRenderer(extras[win_idx].win, -1, SDL_RENDERER_ACCELERATED); | 1595 extras[win_idx].renderer = SDL_CreateRenderer(extras[win_idx].win, -1, SDL_RENDERER_ACCELERATED); |
1580 if (!extras[win_idx].renderer) { | 1596 if (!extras[win_idx].renderer) { |
1620 SDL_DestroyWindow(extras[win_idx].win); | 1636 SDL_DestroyWindow(extras[win_idx].win); |
1621 | 1637 |
1622 extras[win_idx].win = NULL; | 1638 extras[win_idx].win = NULL; |
1623 } | 1639 } |
1624 | 1640 |
1625 SDL_Texture **static_images; | 1641 #ifndef DISABLE_OPENGL |
1626 uint8_t num_static; | 1642 static void extra_draw_quad(extra_window *extra, GLuint texture, float width, float height) |
1643 { | |
1644 glUseProgram(extra->program); | |
1645 glActiveTexture(GL_TEXTURE0); | |
1646 glBindTexture(GL_TEXTURE_2D, texture); | |
1647 glUniform1i(extra->un_texture, 0); | |
1648 | |
1649 glUniform1f(extra->un_width, width); | |
1650 glUniform1f(extra->un_height, height); | |
1651 | |
1652 glVertexAttribPointer(extra->at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); | |
1653 glEnableVertexAttribArray(extra->at_pos); | |
1654 | |
1655 glBindBuffer(GL_ARRAY_BUFFER, extra->gl_buffers[2]); | |
1656 glVertexAttribPointer(extra->at_uv, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); | |
1657 glEnableVertexAttribArray(extra->at_uv); | |
1658 | |
1659 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, extra->gl_buffers[1]); | |
1660 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); | |
1661 } | |
1662 #endif | |
1663 | |
1627 uint8_t render_static_image(uint8_t window, uint8_t *buffer, uint32_t size) | 1664 uint8_t render_static_image(uint8_t window, uint8_t *buffer, uint32_t size) |
1628 { | 1665 { |
1629 window -= FRAMEBUFFER_USER_START; | 1666 window -= FRAMEBUFFER_USER_START; |
1667 extra_window *extra = extras + window; | |
1630 uint32_t width, height; | 1668 uint32_t width, height; |
1631 uint32_t *pixels = load_png(buffer, size, &width, &height); | 1669 uint32_t *pixels = load_png(buffer, size, &width, &height); |
1632 if (!pixels) { | 1670 if (!pixels) { |
1633 return 0xFF; | 1671 return 0xFF; |
1634 } | 1672 } |
1635 uint8_t img_index = 0; | 1673 uint8_t img_index = 0; |
1636 if (!num_static) { | 1674 if (!extra->num_static) { |
1637 num_static = 8; | 1675 extra->num_static = 8; |
1638 static_images = calloc(num_static, sizeof(SDL_Texture*)); | 1676 #ifndef DISABLE_OPENGL |
1639 } | 1677 if (render_gl) { |
1640 for (; img_index < num_static; img_index++) | 1678 extra->gl_static_images = calloc(extra->num_static, sizeof(GLuint)); |
1679 extra->image_vertices = malloc(sizeof(vertex_data_default)); | |
1680 memcpy(extra->image_vertices, vertex_data_default, sizeof(vertex_data_default)); | |
1681 SDL_GL_MakeCurrent(extra->win, extra->gl_context); | |
1682 glGenBuffers(1, &extra->image_buffer); | |
1683 glBindBuffer(GL_ARRAY_BUFFER, extra->image_buffer); | |
1684 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_default), extra->image_vertices, GL_DYNAMIC_DRAW); | |
1685 } else | |
1686 #endif | |
1687 { | |
1688 extra->static_images = calloc(extra->num_static, sizeof(SDL_Texture*)); | |
1689 } | |
1690 } | |
1691 for (; img_index < extra->num_static; img_index++) | |
1641 { | 1692 { |
1642 if (!static_images[img_index]) { | 1693 #ifndef DISABLE_OPENGL |
1694 if (render_gl) { | |
1695 if (!extra->gl_static_images[img_index]) { | |
1696 break; | |
1697 } | |
1698 } else | |
1699 #endif | |
1700 if (!extra->static_images[img_index]) { | |
1643 break; | 1701 break; |
1644 } | 1702 } |
1645 } | 1703 } |
1646 if (img_index == num_static) { | 1704 if (img_index == extra->num_static) { |
1647 num_static *= 2; | 1705 extra->num_static *= 2; |
1648 static_images = realloc(static_images, num_static * sizeof(SDL_Texture*)); | 1706 #ifndef DISABLE_OPENGL |
1649 } | 1707 if (render_gl) { |
1650 static_images[img_index] = SDL_CreateTexture(extras[window].renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); | 1708 extra->gl_static_images = realloc(extra->static_images, extra->num_static * sizeof(GLuint)); |
1651 SDL_UpdateTexture(static_images[img_index], NULL, pixels, sizeof(uint32_t) * width); | 1709 } else |
1710 #endif | |
1711 { | |
1712 extra->static_images = realloc(extra->static_images, extra->num_static * sizeof(SDL_Texture*)); | |
1713 } | |
1714 } | |
1715 #ifndef DISABLE_OPENGL | |
1716 if (render_gl) { | |
1717 SDL_GL_MakeCurrent(extra->win, extra->gl_context); | |
1718 | |
1719 glGenTextures(1, extra->gl_static_images + img_index); | |
1720 glBindTexture(GL_TEXTURE_2D, extra->gl_static_images[img_index]); | |
1721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
1722 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
1723 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
1724 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
1725 //TODO: maybe make this respect the npot texture setting? | |
1726 glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, width, height, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, pixels); | |
1727 } else | |
1728 #endif | |
1729 { | |
1730 extra->static_images[img_index] = SDL_CreateTexture(extra->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); | |
1731 SDL_UpdateTexture(extra->static_images[img_index], NULL, pixels, sizeof(uint32_t) * width); | |
1732 } | |
1652 free(pixels); | 1733 free(pixels); |
1653 return img_index; | 1734 return img_index; |
1654 } | 1735 } |
1655 | 1736 |
1656 void render_draw_image(uint8_t window, uint8_t image, int x, int y, int width, int height) | 1737 void render_draw_image(uint8_t window, uint8_t image, int x, int y, int width, int height) |
1657 { | 1738 { |
1658 uint8_t win_idx = window - FRAMEBUFFER_USER_START; | 1739 extra_window *extra = extras + window - FRAMEBUFFER_USER_START; |
1659 if (extras[win_idx].renderer) { | 1740 if (extra->renderer) { |
1660 SDL_Rect dst = { | 1741 SDL_Rect dst = { |
1661 .x = x, | 1742 .x = x, |
1662 .y = y, | 1743 .y = y, |
1663 .w = width, | 1744 .w = width, |
1664 .h = height | 1745 .h = height |
1665 }; | 1746 }; |
1666 SDL_RenderCopy(extras[win_idx].renderer, static_images[image], NULL, &dst); | 1747 SDL_RenderCopy(extra->renderer, extra->static_images[image], NULL, &dst); |
1667 } | 1748 } |
1668 #ifndef DISABLE_OPENGL | 1749 #ifndef DISABLE_OPENGL |
1669 else { | 1750 else { |
1670 //TODO: implement me | 1751 memcpy(extra->image_vertices, vertex_data_default, sizeof(vertex_data_default)); |
1752 extra->image_vertices[0] = extra->image_vertices[4] = 2.0f * x / (float)extra->width - 1.0f; | |
1753 extra->image_vertices[2] = extra->image_vertices[6] = 2.0f * (x + width) / (float)extra->width - 1.0f; | |
1754 extra->image_vertices[1] = extra->image_vertices[3] = -2.0f * (y + height) / (float)extra->height + 1.0f; | |
1755 extra->image_vertices[5] = extra->image_vertices[7] = -2.0f * y / (float)extra->height + 1.0f; | |
1756 | |
1757 SDL_GL_MakeCurrent(extra->win, extra->gl_context); | |
1758 glBindBuffer(GL_ARRAY_BUFFER, extra->image_buffer); | |
1759 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_default), extra->image_vertices, GL_DYNAMIC_DRAW); | |
1760 extra_draw_quad(extra, extra->gl_static_images[image], 1.0f, 1.0f); | |
1671 } | 1761 } |
1672 #endif | 1762 #endif |
1673 } | 1763 } |
1674 | 1764 |
1675 void render_clear_window(uint8_t window, uint8_t r, uint8_t g, uint8_t b) | 1765 void render_clear_window(uint8_t window, uint8_t r, uint8_t g, uint8_t b) |
1940 #ifndef DISABLE_OPENGL | 2030 #ifndef DISABLE_OPENGL |
1941 else { | 2031 else { |
1942 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | 2032 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
1943 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 2033 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
1944 | 2034 |
1945 glUseProgram(extras[win_idx].program); | |
1946 glActiveTexture(GL_TEXTURE0); | |
1947 glBindTexture(GL_TEXTURE_2D, extras[win_idx].gl_texture); | |
1948 glUniform1i(extras[win_idx].un_texture, 0); | |
1949 | |
1950 glUniform1f(extras[win_idx].un_width, (float)extras[win_idx].width / (float)extras[win_idx].tex_width); | |
1951 glUniform1f(extras[win_idx].un_height, (float)extras[win_idx].height / (float)extras[win_idx].tex_height); | |
1952 | |
1953 glBindBuffer(GL_ARRAY_BUFFER, extras[win_idx].gl_buffers[0]); | 2035 glBindBuffer(GL_ARRAY_BUFFER, extras[win_idx].gl_buffers[0]); |
1954 glVertexAttribPointer(extras[win_idx].at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); | 2036 extra_draw_quad( |
1955 glEnableVertexAttribArray(extras[win_idx].at_pos); | 2037 extras + win_idx, |
1956 | 2038 extras[win_idx].gl_texture, |
1957 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, extras[win_idx].gl_buffers[1]); | 2039 (float)extras[win_idx].width / (float)extras[win_idx].tex_width, |
1958 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); | 2040 (float)extras[win_idx].height / (float)extras[win_idx].tex_height |
2041 ); | |
1959 | 2042 |
1960 SDL_GL_SwapWindow(extras[win_idx].win); | 2043 SDL_GL_SwapWindow(extras[win_idx].win); |
1961 } | 2044 } |
1962 #endif | 2045 #endif |
1963 } | 2046 } |