1
0

texture-render.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /******************************************************************************
  2. Copyright (C) 2013 by Hugh Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. /*
  15. * This is a set of helper functions to more easily render to textures
  16. * without having to duplicate too much code.
  17. */
  18. #include <assert.h>
  19. #include "graphics.h"
  20. struct gs_texture_render {
  21. gs_texture_t *target, *prev_target;
  22. gs_zstencil_t *zs, *prev_zs;
  23. enum gs_color_space prev_space;
  24. uint32_t cx, cy;
  25. enum gs_color_format format;
  26. enum gs_zstencil_format zsformat;
  27. bool rendered;
  28. };
  29. gs_texrender_t *gs_texrender_create(enum gs_color_format format,
  30. enum gs_zstencil_format zsformat)
  31. {
  32. struct gs_texture_render *texrender;
  33. texrender = bzalloc(sizeof(struct gs_texture_render));
  34. texrender->format = format;
  35. texrender->zsformat = zsformat;
  36. return texrender;
  37. }
  38. void gs_texrender_destroy(gs_texrender_t *texrender)
  39. {
  40. if (texrender) {
  41. gs_texture_destroy(texrender->target);
  42. gs_zstencil_destroy(texrender->zs);
  43. bfree(texrender);
  44. }
  45. }
  46. static bool texrender_resetbuffer(gs_texrender_t *texrender, uint32_t cx,
  47. uint32_t cy)
  48. {
  49. if (!texrender)
  50. return false;
  51. gs_texture_destroy(texrender->target);
  52. gs_zstencil_destroy(texrender->zs);
  53. texrender->target = NULL;
  54. texrender->zs = NULL;
  55. texrender->cx = cx;
  56. texrender->cy = cy;
  57. texrender->target = gs_texture_create(cx, cy, texrender->format, 1,
  58. NULL, GS_RENDER_TARGET);
  59. if (!texrender->target)
  60. return false;
  61. if (texrender->zsformat != GS_ZS_NONE) {
  62. texrender->zs = gs_zstencil_create(cx, cy, texrender->zsformat);
  63. if (!texrender->zs) {
  64. gs_texture_destroy(texrender->target);
  65. texrender->target = NULL;
  66. return false;
  67. }
  68. }
  69. return true;
  70. }
  71. bool gs_texrender_begin(gs_texrender_t *texrender, uint32_t cx, uint32_t cy)
  72. {
  73. return gs_texrender_begin_with_color_space(texrender, cx, cy,
  74. GS_CS_SRGB);
  75. }
  76. bool gs_texrender_begin_with_color_space(gs_texrender_t *texrender, uint32_t cx,
  77. uint32_t cy, enum gs_color_space space)
  78. {
  79. if (!texrender || texrender->rendered)
  80. return false;
  81. if (!cx || !cy)
  82. return false;
  83. if (texrender->cx != cx || texrender->cy != cy)
  84. if (!texrender_resetbuffer(texrender, cx, cy))
  85. return false;
  86. if (!texrender->target)
  87. return false;
  88. gs_viewport_push();
  89. gs_projection_push();
  90. gs_matrix_push();
  91. gs_matrix_identity();
  92. texrender->prev_target = gs_get_render_target();
  93. texrender->prev_zs = gs_get_zstencil_target();
  94. texrender->prev_space = gs_get_color_space();
  95. gs_set_render_target_with_color_space(texrender->target, texrender->zs,
  96. space);
  97. gs_set_viewport(0, 0, texrender->cx, texrender->cy);
  98. return true;
  99. }
  100. void gs_texrender_end(gs_texrender_t *texrender)
  101. {
  102. if (!texrender)
  103. return;
  104. gs_set_render_target_with_color_space(texrender->prev_target,
  105. texrender->prev_zs,
  106. texrender->prev_space);
  107. gs_matrix_pop();
  108. gs_projection_pop();
  109. gs_viewport_pop();
  110. texrender->rendered = true;
  111. }
  112. void gs_texrender_reset(gs_texrender_t *texrender)
  113. {
  114. if (texrender)
  115. texrender->rendered = false;
  116. }
  117. gs_texture_t *gs_texrender_get_texture(const gs_texrender_t *texrender)
  118. {
  119. return texrender ? texrender->target : NULL;
  120. }
  121. enum gs_color_format gs_texrender_get_format(const gs_texrender_t *texrender)
  122. {
  123. return texrender->format;
  124. }