/* * touch.c * written by Holmes Futrell * use however you want */ #include "SDL.h" #include <math.h> #include "common.h" #define BRUSH_SIZE 32 /* width and height of the brush */ #define PIXELS_PER_ITERATION 5 /* number of pixels between brush blots when forming a line */ static SDL_Texture *brush = 0; /* texture for the brush */ /* draws a line from (startx, starty) to (startx + dx, starty + dy) this is accomplished by drawing several blots spaced PIXELS_PER_ITERATION apart */ void drawLine(SDL_Renderer *renderer, float startx, float starty, float dx, float dy) { float distance = SDL_sqrt(dx * dx + dy * dy); /* length of line segment (pythagoras) */ int iterations = distance / PIXELS_PER_ITERATION + 1; /* number of brush sprites to draw for the line */ float dx_prime = dx / iterations; /* x-shift per iteration */ float dy_prime = dy / iterations; /* y-shift per iteration */ SDL_Rect dstRect; /* rect to draw brush sprite into */ float x; float y; int i; dstRect.w = BRUSH_SIZE; dstRect.h = BRUSH_SIZE; /* setup x and y for the location of the first sprite */ x = startx - BRUSH_SIZE / 2.0f; y = starty - BRUSH_SIZE / 2.0f; /* draw a series of blots to form the line */ for (i = 0; i < iterations; i++) { dstRect.x = x; dstRect.y = y; /* shift x and y for next sprite location */ x += dx_prime; y += dy_prime; /* draw brush blot */ SDL_RenderCopy(renderer, brush, NULL, &dstRect); } } /* loads the brush texture */ void initializeTexture(SDL_Renderer *renderer) { SDL_Surface *bmp_surface; bmp_surface = SDL_LoadBMP("stroke.bmp"); if (bmp_surface == NULL) { fatalError("could not load stroke.bmp"); } brush = SDL_CreateTextureFromSurface(renderer, bmp_surface); SDL_FreeSurface(bmp_surface); if (!brush) { fatalError("could not create brush texture"); } /* additive blending -- laying strokes on top of eachother makes them brighter */ SDL_SetTextureBlendMode(brush, SDL_BLENDMODE_ADD); /* set brush color (red) */ SDL_SetTextureColorMod(brush, 255, 100, 100); } int main(int argc, char *argv[]) { int x, y, dx, dy; /* mouse location */ Uint8 state; /* mouse (touch) state */ SDL_Event event; SDL_Window *window; /* main window */ SDL_Renderer *renderer; SDL_Texture *target; int done; /* does user want to quit? */ int w, h; /* initialize SDL */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { fatalError("Could not initialize SDL"); } /* create main window and renderer */ window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI); renderer = SDL_CreateRenderer(window, 0, 0); SDL_GetWindowSize(window, &w, &h); SDL_RenderSetLogicalSize(renderer, w, h); /* load brush texture */ initializeTexture(renderer); /* fill canvass initially with all black */ target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h); SDL_SetRenderTarget(renderer, target); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_SetRenderTarget(renderer, NULL); done = 0; while (!done) { while (SDL_PollEvent(&event) == 1) { switch (event.type) { case SDL_QUIT: done = 1; break; case SDL_MOUSEMOTION: state = SDL_GetMouseState(&x, &y); /* get its location */ SDL_GetRelativeMouseState(&dx, &dy); /* find how much the mouse moved */ if (state & SDL_BUTTON_LMASK) { /* is the mouse (touch) down? */ SDL_SetRenderTarget(renderer, target); drawLine(renderer, x - dx, y - dy, dx, dy); /* draw line segment */ SDL_SetRenderTarget(renderer, NULL); } break; } } SDL_RenderCopy(renderer, target, NULL, NULL); SDL_RenderPresent(renderer); } /* cleanup */ SDL_DestroyTexture(brush); SDL_DestroyTexture(target); SDL_Quit(); return 0; }