gpu.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include "./common.h"
  2. GLuint compile_shader_file(const char *file_path, GLenum shader_type)
  3. {
  4. char *buffer = cstr_slurp_file(file_path);
  5. const GLchar * const source_cstr = buffer;
  6. GLuint shader = glCreateShader(shader_type);
  7. glShaderSource(shader, 1, &source_cstr, NULL);
  8. glCompileShader(shader);
  9. GLint compiled;
  10. glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  11. if (compiled != GL_TRUE) {
  12. GLchar log[1024];
  13. GLsizei log_size = 0;
  14. glGetShaderInfoLog(shader, sizeof(log), &log_size, log);
  15. fprintf(stderr, "Failed to compile %s:%.*s\n", file_path,
  16. log_size, log);
  17. exit(1);
  18. }
  19. free(buffer);
  20. return shader;
  21. }
  22. GLuint link_program(GLuint vert_shader, GLuint frag_shader)
  23. {
  24. GLuint program = glCreateProgram();
  25. glAttachShader(program, vert_shader);
  26. glAttachShader(program, frag_shader);
  27. glLinkProgram(program);
  28. GLint linked = 0;
  29. glGetProgramiv(program, GL_LINK_STATUS, &linked);
  30. if (linked != GL_TRUE) {
  31. GLsizei log_size = 0;
  32. GLchar log[1024];
  33. glGetProgramInfoLog(program, sizeof(log), &log_size, log);
  34. fprintf(stderr, "Failed to link the shader program: %.*s\n", log_size, log);
  35. exit(1);
  36. }
  37. return program;
  38. }
  39. int main(void)
  40. {
  41. check_sdl_code(
  42. SDL_Init(SDL_INIT_VIDEO));
  43. SDL_Window * const window =
  44. check_sdl_ptr(
  45. SDL_CreateWindow(
  46. "Bezier Curves",
  47. 0, 0,
  48. SCREEN_WIDTH,
  49. SCREEN_HEIGHT,
  50. SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL));
  51. /*SDL_GLContext context = */SDL_GL_CreateContext(window);
  52. glEnable(GL_BLEND);
  53. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  54. GLuint vert_shader = compile_shader_file("./gpu.vert", GL_VERTEX_SHADER);
  55. GLuint frag_shader = compile_shader_file("./gpu.frag", GL_FRAGMENT_SHADER);
  56. GLuint program = link_program(vert_shader, frag_shader);
  57. glUseProgram(program);
  58. GLint u_p1 = glGetUniformLocation(program, "p1");
  59. GLint u_p2 = glGetUniformLocation(program, "p2");
  60. GLint u_p3 = glGetUniformLocation(program, "p3");
  61. GLint u_marker_radius = glGetUniformLocation(program, "marker_radius");
  62. GLint u_bezier_curve_threshold = glGetUniformLocation(program, "bezier_curve_threshold");
  63. Vec2 p1 = vec2(100.0f, 100.0f);
  64. Vec2 p2 = vec2(200.0f, 200.0f);
  65. Vec2 p3 = vec2(300.0f, 300.0f);
  66. Vec2 *p_selected = NULL;
  67. float bezier_curve_threshold = 10.0f;
  68. int quit = 0;
  69. while (!quit) {
  70. SDL_Event event;
  71. while (SDL_PollEvent(&event)) {
  72. switch (event.type) {
  73. case SDL_QUIT: {
  74. quit = 1;
  75. } break;
  76. case SDL_MOUSEBUTTONDOWN: {
  77. const Vec2 mouse_pos = vec2(
  78. event.button.x,
  79. SCREEN_HEIGHT - event.button.y);
  80. if (event.button.button == SDL_BUTTON_LEFT) {
  81. // TODO: dragging does not work if the window size is not correct
  82. if (vec2_length(vec2_sub(p1, mouse_pos)) < MARKER_SIZE) {
  83. p_selected = &p1;
  84. }
  85. if (vec2_length(vec2_sub(p2, mouse_pos)) < MARKER_SIZE) {
  86. p_selected = &p2;
  87. }
  88. if (vec2_length(vec2_sub(p3, mouse_pos)) < MARKER_SIZE) {
  89. p_selected = &p3;
  90. }
  91. }
  92. } break;
  93. case SDL_MOUSEBUTTONUP: {
  94. if (event.button.button == SDL_BUTTON_LEFT) {
  95. p_selected = NULL;
  96. }
  97. } break;
  98. case SDL_MOUSEMOTION: {
  99. const Vec2 mouse_pos = vec2(
  100. event.button.x,
  101. SCREEN_HEIGHT - event.button.y);
  102. if (p_selected) {
  103. *p_selected = mouse_pos;
  104. }
  105. } break;
  106. case SDL_MOUSEWHEEL: {
  107. #define BEZIER_CURVE_THRESHOLD_STEP 5.0f
  108. if (event.wheel.y > 0) {
  109. bezier_curve_threshold = bezier_curve_threshold + BEZIER_CURVE_THRESHOLD_STEP;
  110. } else if (event.wheel.y < 0) {
  111. bezier_curve_threshold = fmaxf(bezier_curve_threshold - BEZIER_CURVE_THRESHOLD_STEP, 0.0f);
  112. }
  113. } break;
  114. }
  115. }
  116. glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
  117. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  118. glClear(GL_COLOR_BUFFER_BIT);
  119. glUniform2f(u_p1, p1.x, p1.y);
  120. glUniform2f(u_p2, p2.x, p2.y);
  121. glUniform2f(u_p3, p3.x, p3.y);
  122. glUniform1f(u_marker_radius, MARKER_SIZE);
  123. glUniform1f(u_bezier_curve_threshold, bezier_curve_threshold);
  124. glDrawArrays(GL_QUADS, 0, 4);
  125. SDL_GL_SwapWindow(window);
  126. }
  127. return 0;
  128. }