gl_quickpreview.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. };
  27. static GLuint load_shader(const char *path, GLenum type)
  28. {
  29. check_gl();
  30. FILE *f = fopen(path, "r");
  31. fseek(f, 0, SEEK_END);
  32. GLint size = ftell(f);
  33. char *source = malloc(sizeof(char) * size);
  34. fseek(f, 0, SEEK_SET);
  35. if (fread(source, size, 1, f) == 0) {
  36. printf("Failed to read shader file\n");
  37. return 0;
  38. }
  39. GLuint shader = glCreateShader(type);
  40. assert(shader != 0);
  41. glShaderSource(shader, 1, (const GLchar * const*)&source, &size);
  42. glCompileShader(shader);
  43. check_gl();
  44. // Check compile status
  45. GLint success;
  46. glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
  47. if (success == GL_FALSE) {
  48. printf("Shader compilation failed for %s\n", path);
  49. }
  50. GLint log_length;
  51. glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
  52. if (log_length > 0) {
  53. char *log = malloc(sizeof(char) * log_length);
  54. glGetShaderInfoLog(shader, log_length - 1, &log_length, log);
  55. printf("Shader %s log: %s\n", path, log);
  56. free(log);
  57. }
  58. free(source);
  59. return shader;
  60. }
  61. GLQuickPreview *gl_quick_preview_new()
  62. {
  63. GLuint frame_buffer;
  64. glGenFramebuffers(1, &frame_buffer);
  65. check_gl();
  66. GLuint vert = load_shader("data/debayer.vert", GL_VERTEX_SHADER);
  67. GLuint frag = load_shader("data/debayer.frag", GL_FRAGMENT_SHADER);
  68. GLuint program = glCreateProgram();
  69. glAttachShader(program, vert);
  70. glAttachShader(program, frag);
  71. glBindAttribLocation(program, VERTEX_ATTRIBUTE, "vert");
  72. check_gl();
  73. glBindAttribLocation(program, TEX_COORD_ATTRIBUTE, "tex_coord");
  74. check_gl();
  75. glLinkProgram(program);
  76. check_gl();
  77. GLint success;
  78. glGetProgramiv(program, GL_LINK_STATUS, &success);
  79. if (success == GL_FALSE) {
  80. printf("Program linking failed\n");
  81. }
  82. GLint log_length;
  83. glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
  84. if (log_length > 0) {
  85. char *log = malloc(sizeof(char) * log_length);
  86. glGetProgramInfoLog(program, log_length - 1, &log_length, log);
  87. printf("Program log: %s\n", log);
  88. free(log);
  89. }
  90. check_gl();
  91. GLQuickPreview *self = malloc(sizeof(GLQuickPreview));
  92. self->frame_buffer = frame_buffer;
  93. self->program = program;
  94. self->uniform_transform = glGetUniformLocation(self->program, "transform");
  95. check_gl();
  96. self->uniform_pixel_size = glGetUniformLocation(self->program, "pixel_size");
  97. check_gl();
  98. self->uniform_texture = glGetUniformLocation(self->program, "texture");
  99. check_gl();
  100. return self;
  101. }
  102. void gl_quick_preview_free(GLQuickPreview *self)
  103. {
  104. glDeleteFramebuffers(1, &self->frame_buffer);
  105. free(self);
  106. }
  107. bool
  108. ql_quick_preview_supports_format(GLQuickPreview *self, const MPPixelFormat format)
  109. {
  110. return format == MP_PIXEL_FMT_BGGR8;
  111. }
  112. bool
  113. gl_quick_preview(GLQuickPreview *self,
  114. GLuint dst_id,
  115. const uint32_t dst_width, const uint32_t dst_height,
  116. GLuint source_id,
  117. const uint32_t src_width, const uint32_t src_height,
  118. const MPPixelFormat format,
  119. const uint32_t rotation,
  120. const bool mirrored,
  121. const float *colormatrix,
  122. const uint8_t blacklevel)
  123. {
  124. assert(ql_quick_preview_supports_format(self, format));
  125. glBindFramebuffer(GL_FRAMEBUFFER, self->frame_buffer);
  126. glBindTexture(GL_TEXTURE_2D, dst_id);
  127. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_id, 0);
  128. check_gl();
  129. glViewport(0, 0, dst_width, dst_height);
  130. check_gl();
  131. assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
  132. glUseProgram(self->program);
  133. check_gl();
  134. GLfloat rotation_list[4] = { 1, 0, -1, 0 };
  135. int rotation_index = 4 - rotation / 90;
  136. GLfloat sin_rot = rotation_list[rotation_index];
  137. GLfloat cos_rot = rotation_list[(rotation_index + 1) % 4];
  138. GLfloat scale_x = mirrored ? 1 : -1;
  139. GLfloat matrix[9] = {
  140. cos_rot * scale_x, sin_rot, 0,
  141. -sin_rot * scale_x, cos_rot, 0,
  142. 0, 0, 1,
  143. };
  144. glUniformMatrix3fv(self->uniform_transform, 1, GL_FALSE, matrix);
  145. check_gl();
  146. GLfloat pixel_size_x = 1.0f / src_width;
  147. GLfloat pixel_size_y = 1.0f / src_height;
  148. glUniform2f(self->uniform_pixel_size, pixel_size_x, pixel_size_y);
  149. check_gl();
  150. glActiveTexture(GL_TEXTURE0);
  151. glBindTexture(GL_TEXTURE_2D, source_id);
  152. glUniform1i(self->uniform_texture, 0);
  153. check_gl();
  154. glVertexAttribPointer(VERTEX_ATTRIBUTE, 2, GL_FLOAT, 0, 0, square_vertices);
  155. check_gl();
  156. glEnableVertexAttribArray(VERTEX_ATTRIBUTE);
  157. check_gl();
  158. glVertexAttribPointer(TEX_COORD_ATTRIBUTE, 2, GL_FLOAT, 0, 0, square_texcoords);
  159. check_gl();
  160. glEnableVertexAttribArray(TEX_COORD_ATTRIBUTE);
  161. check_gl();
  162. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  163. check_gl();
  164. // TODO: Render
  165. // glClearColor(0, 0, 1, 0);
  166. // glClear(GL_COLOR_BUFFER_BIT);
  167. // glBindTexture(GL_TEXTURE_2D, 0);
  168. // glBindFramebuffer(GL_FRAMEBUFFER, 0);
  169. glUseProgram(0);
  170. check_gl();
  171. return true;
  172. }