touch.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * touch.c
  3. * written by Holmes Futrell
  4. * use however you want
  5. */
  6. #include "SDL.h"
  7. #include <math.h>
  8. #include "common.h"
  9. #define BRUSH_SIZE 32 /* width and height of the brush */
  10. #define PIXELS_PER_ITERATION 5 /* number of pixels between brush blots when forming a line */
  11. static SDL_Texture *brush = 0; /* texture for the brush */
  12. /*
  13. draws a line from (startx, starty) to (startx + dx, starty + dy)
  14. this is accomplished by drawing several blots spaced PIXELS_PER_ITERATION apart
  15. */
  16. void
  17. drawLine(SDL_Renderer *renderer, float startx, float starty, float dx, float dy)
  18. {
  19. float distance = SDL_sqrt(dx * dx + dy * dy); /* length of line segment (pythagoras) */
  20. int iterations = distance / PIXELS_PER_ITERATION + 1; /* number of brush sprites to draw for the line */
  21. float dx_prime = dx / iterations; /* x-shift per iteration */
  22. float dy_prime = dy / iterations; /* y-shift per iteration */
  23. SDL_Rect dstRect; /* rect to draw brush sprite into */
  24. float x;
  25. float y;
  26. int i;
  27. dstRect.w = BRUSH_SIZE;
  28. dstRect.h = BRUSH_SIZE;
  29. /* setup x and y for the location of the first sprite */
  30. x = startx - BRUSH_SIZE / 2.0f;
  31. y = starty - BRUSH_SIZE / 2.0f;
  32. /* draw a series of blots to form the line */
  33. for (i = 0; i < iterations; i++) {
  34. dstRect.x = x;
  35. dstRect.y = y;
  36. /* shift x and y for next sprite location */
  37. x += dx_prime;
  38. y += dy_prime;
  39. /* draw brush blot */
  40. SDL_RenderCopy(renderer, brush, NULL, &dstRect);
  41. }
  42. }
  43. /*
  44. loads the brush texture
  45. */
  46. void
  47. initializeTexture(SDL_Renderer *renderer)
  48. {
  49. SDL_Surface *bmp_surface;
  50. bmp_surface = SDL_LoadBMP("stroke.bmp");
  51. if (bmp_surface == NULL) {
  52. fatalError("could not load stroke.bmp");
  53. }
  54. brush =
  55. SDL_CreateTextureFromSurface(renderer, bmp_surface);
  56. SDL_FreeSurface(bmp_surface);
  57. if (brush == 0) {
  58. fatalError("could not create brush texture");
  59. }
  60. /* additive blending -- laying strokes on top of eachother makes them brighter */
  61. SDL_SetTextureBlendMode(brush, SDL_BLENDMODE_ADD);
  62. /* set brush color (red) */
  63. SDL_SetTextureColorMod(brush, 255, 100, 100);
  64. }
  65. int
  66. main(int argc, char *argv[])
  67. {
  68. int x, y, dx, dy; /* mouse location */
  69. Uint8 state; /* mouse (touch) state */
  70. SDL_Event event;
  71. SDL_Window *window; /* main window */
  72. SDL_Renderer *renderer;
  73. SDL_Texture *target;
  74. int done; /* does user want to quit? */
  75. int w, h;
  76. /* initialize SDL */
  77. if (SDL_Init(SDL_INIT_VIDEO) < 0) {
  78. fatalError("Could not initialize SDL");
  79. }
  80. /* create main window and renderer */
  81. window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI);
  82. renderer = SDL_CreateRenderer(window, 0, 0);
  83. SDL_GetWindowSize(window, &w, &h);
  84. SDL_RenderSetLogicalSize(renderer, w, h);
  85. /* load brush texture */
  86. initializeTexture(renderer);
  87. /* fill canvass initially with all black */
  88. target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h);
  89. SDL_SetRenderTarget(renderer, target);
  90. SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
  91. SDL_RenderClear(renderer);
  92. SDL_SetRenderTarget(renderer, NULL);
  93. done = 0;
  94. while (!done) {
  95. while (SDL_PollEvent(&event) == 1) {
  96. switch (event.type) {
  97. case SDL_QUIT:
  98. done = 1;
  99. break;
  100. case SDL_MOUSEMOTION:
  101. state = SDL_GetMouseState(&x, &y); /* get its location */
  102. SDL_GetRelativeMouseState(&dx, &dy); /* find how much the mouse moved */
  103. if (state & SDL_BUTTON_LMASK) { /* is the mouse (touch) down? */
  104. SDL_SetRenderTarget(renderer, target);
  105. drawLine(renderer, x - dx, y - dy, dx, dy); /* draw line segment */
  106. SDL_SetRenderTarget(renderer, NULL);
  107. }
  108. break;
  109. }
  110. }
  111. SDL_RenderCopy(renderer, target, NULL, NULL);
  112. SDL_RenderPresent(renderer);
  113. }
  114. /* cleanup */
  115. SDL_DestroyTexture(brush);
  116. SDL_DestroyTexture(target);
  117. SDL_Quit();
  118. return 0;
  119. }