gl_quickpreview.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #include "camera.h"
  2. #include "gl_quickpreview.h"
  3. #include "gl_utils.h"
  4. #include <stdint.h>
  5. #include <stdlib.h>
  6. #define VERTEX_ATTRIBUTE 0
  7. #define TEX_COORD_ATTRIBUTE 1
  8. static const GLfloat square_vertices[] = {
  9. -1, -1,
  10. 1, -1,
  11. -1, 1,
  12. 1, 1,
  13. };
  14. static const GLfloat square_texcoords[] = {
  15. 1, 1,
  16. 1, 0,
  17. 0, 1,
  18. 0, 0,
  19. };
  20. struct _GLQuickPreview {
  21. GLuint frame_buffer;
  22. GLuint program;
  23. GLuint uniform_transform;
  24. GLuint uniform_pixel_size;
  25. GLuint uniform_texture;
  26. GLuint uniform_srgb_map;
  27. GLuint uniform_color_matrix;
  28. GLuint srgb_texture;
  29. };
  30. static GLuint load_shader(const char *path, GLenum type)
  31. {
  32. check_gl();
  33. FILE *f = fopen(path, "r");
  34. fseek(f, 0, SEEK_END);
  35. GLint size = ftell(f);
  36. char *source = malloc(sizeof(char) * size);
  37. fseek(f, 0, SEEK_SET);
  38. if (fread(source, size, 1, f) == 0) {
  39. printf("Failed to read shader file\n");
  40. return 0;
  41. }
  42. GLuint shader = glCreateShader(type);
  43. assert(shader != 0);
  44. glShaderSource(shader, 1, (const GLchar * const*)&source, &size);
  45. glCompileShader(shader);
  46. check_gl();
  47. // Check compile status
  48. GLint success;
  49. glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
  50. if (success == GL_FALSE) {
  51. printf("Shader compilation failed for %s\n", path);
  52. }
  53. GLint log_length;
  54. glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
  55. if (log_length > 0) {
  56. char *log = malloc(sizeof(char) * log_length);
  57. glGetShaderInfoLog(shader, log_length - 1, &log_length, log);
  58. printf("Shader %s log: %s\n", path, log);
  59. free(log);
  60. }
  61. free(source);
  62. return shader;
  63. }
  64. // static const uint8_t srgb[] = {
  65. // 0, 12, 21, 28, 33, 38, 42, 46, 49, 52, 55, 58, 61, 63, 66, 68, 70,
  66. // 73, 75, 77, 79, 81, 82, 84, 86, 88, 89, 91, 93, 94, 96, 97, 99, 100,
  67. // 102, 103, 104, 106, 107, 109, 110, 111, 112, 114, 115, 116, 117, 118,
  68. // 120, 121, 122, 123, 124, 125, 126, 127, 129, 130, 131, 132, 133, 134,
  69. // 135, 136, 137, 138, 139, 140, 141, 142, 142, 143, 144, 145, 146, 147,
  70. // 148, 149, 150, 151, 151, 152, 153, 154, 155, 156, 157, 157, 158, 159,
  71. // 160, 161, 161, 162, 163, 164, 165, 165, 166, 167, 168, 168, 169, 170,
  72. // 171, 171, 172, 173, 174, 174, 175, 176, 176, 177, 178, 179, 179, 180,
  73. // 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189,
  74. // 190, 191, 191, 192, 193, 193, 194, 194, 195, 196, 196, 197, 197, 198,
  75. // 199, 199, 200, 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206,
  76. // 207, 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214,
  77. // 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222,
  78. // 222, 223, 223, 224, 224, 225, 226, 226, 227, 227, 228, 228, 229, 229,
  79. // 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235, 236, 236,
  80. // 237, 237, 237, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, 243,
  81. // 243, 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249,
  82. // 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255
  83. // };
  84. GLQuickPreview *gl_quick_preview_new()
  85. {
  86. GLuint frame_buffer;
  87. glGenFramebuffers(1, &frame_buffer);
  88. check_gl();
  89. GLuint vert = load_shader("data/debayer.vert", GL_VERTEX_SHADER);
  90. GLuint frag = load_shader("data/debayer.frag", GL_FRAGMENT_SHADER);
  91. GLuint program = glCreateProgram();
  92. glAttachShader(program, vert);
  93. glAttachShader(program, frag);
  94. glBindAttribLocation(program, VERTEX_ATTRIBUTE, "vert");
  95. glBindAttribLocation(program, TEX_COORD_ATTRIBUTE, "tex_coord");
  96. glLinkProgram(program);
  97. check_gl();
  98. GLint success;
  99. glGetProgramiv(program, GL_LINK_STATUS, &success);
  100. if (success == GL_FALSE) {
  101. printf("Program linking failed\n");
  102. }
  103. GLint log_length;
  104. glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
  105. if (log_length > 0) {
  106. char *log = malloc(sizeof(char) * log_length);
  107. glGetProgramInfoLog(program, log_length - 1, &log_length, log);
  108. printf("Program log: %s\n", log);
  109. free(log);
  110. }
  111. check_gl();
  112. // GLuint srgb_texture;
  113. // glGenTextures(1, &srgb_texture);
  114. // check_gl();
  115. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  116. check_gl();
  117. // glBindTexture(GL_TEXTURE_2D, srgb_texture);
  118. // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  119. // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  120. // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  121. // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  122. // check_gl();
  123. // glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 256, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, srgb);
  124. // check_gl();
  125. // glBindTexture(GL_TEXTURE_2D, 0);
  126. GLQuickPreview *self = malloc(sizeof(GLQuickPreview));
  127. self->frame_buffer = frame_buffer;
  128. self->program = program;
  129. self->uniform_transform = glGetUniformLocation(self->program, "transform");
  130. self->uniform_pixel_size = glGetUniformLocation(self->program, "pixel_size");
  131. self->uniform_texture = glGetUniformLocation(self->program, "texture");
  132. self->uniform_color_matrix = glGetUniformLocation(self->program, "color_matrix");
  133. self->uniform_srgb_map = glGetUniformLocation(self->program, "srgb_map");
  134. // self->srgb_texture = srgb_texture;
  135. return self;
  136. }
  137. void gl_quick_preview_free(GLQuickPreview *self)
  138. {
  139. glDeleteFramebuffers(1, &self->frame_buffer);
  140. free(self);
  141. }
  142. bool
  143. ql_quick_preview_supports_format(GLQuickPreview *self, const MPPixelFormat format)
  144. {
  145. return format == MP_PIXEL_FMT_BGGR8;
  146. }
  147. bool
  148. gl_quick_preview(GLQuickPreview *self,
  149. GLuint dst_id,
  150. const uint32_t dst_width, const uint32_t dst_height,
  151. GLuint source_id,
  152. const uint32_t src_width, const uint32_t src_height,
  153. const MPPixelFormat format,
  154. const uint32_t rotation,
  155. const bool mirrored,
  156. const float *colormatrix,
  157. const uint8_t blacklevel)
  158. {
  159. assert(ql_quick_preview_supports_format(self, format));
  160. glBindFramebuffer(GL_FRAMEBUFFER, self->frame_buffer);
  161. glBindTexture(GL_TEXTURE_2D, dst_id);
  162. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_id, 0);
  163. check_gl();
  164. glViewport(0, 0, dst_width, dst_height);
  165. check_gl();
  166. assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
  167. glUseProgram(self->program);
  168. check_gl();
  169. GLfloat rotation_list[4] = { 1, 0, -1, 0 };
  170. int rotation_index = 4 - rotation / 90;
  171. GLfloat sin_rot = rotation_list[rotation_index];
  172. GLfloat cos_rot = rotation_list[(rotation_index + 1) % 4];
  173. GLfloat scale_x = mirrored ? 1 : -1;
  174. GLfloat matrix[9] = {
  175. cos_rot * scale_x, sin_rot, 0,
  176. -sin_rot * scale_x, cos_rot, 0,
  177. 0, 0, 1,
  178. };
  179. glUniformMatrix3fv(self->uniform_transform, 1, GL_FALSE, matrix);
  180. check_gl();
  181. GLfloat pixel_size_x = 1.0f / src_width;
  182. GLfloat pixel_size_y = 1.0f / src_height;
  183. glUniform2f(self->uniform_pixel_size, pixel_size_x, pixel_size_y);
  184. check_gl();
  185. glActiveTexture(GL_TEXTURE0);
  186. glBindTexture(GL_TEXTURE_2D, source_id);
  187. glUniform1i(self->uniform_texture, 0);
  188. check_gl();
  189. // glActiveTexture(GL_TEXTURE1);
  190. // glBindTexture(GL_TEXTURE_2D, self->srgb_texture);
  191. // glUniform1i(self->uniform_srgb_map, 1);
  192. // check_gl();
  193. if (colormatrix)
  194. {
  195. GLfloat transposed[9];
  196. for (int i = 0; i < 3; ++i)
  197. for (int j = 0; j < 3; ++j)
  198. transposed[i + j * 3] = colormatrix[j + i * 3];
  199. glUniformMatrix3fv(self->uniform_color_matrix, 1, GL_FALSE, transposed);
  200. }
  201. else
  202. {
  203. static const GLfloat identity[9] = {
  204. 1, 0, 0,
  205. 0, 1, 0,
  206. 0, 0, 1,
  207. };
  208. glUniformMatrix3fv(self->uniform_color_matrix, 1, GL_FALSE, identity);
  209. }
  210. glVertexAttribPointer(VERTEX_ATTRIBUTE, 2, GL_FLOAT, 0, 0, square_vertices);
  211. check_gl();
  212. glEnableVertexAttribArray(VERTEX_ATTRIBUTE);
  213. check_gl();
  214. glVertexAttribPointer(TEX_COORD_ATTRIBUTE, 2, GL_FLOAT, 0, 0, square_texcoords);
  215. check_gl();
  216. glEnableVertexAttribArray(TEX_COORD_ATTRIBUTE);
  217. check_gl();
  218. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  219. check_gl();
  220. // TODO: Render
  221. // glClearColor(0, 0, 1, 0);
  222. // glClear(GL_COLOR_BUFFER_BIT);
  223. // glBindTexture(GL_TEXTURE_2D, 0);
  224. // glBindFramebuffer(GL_FRAMEBUFFER, 0);
  225. glUseProgram(0);
  226. check_gl();
  227. return true;
  228. }