Last active
August 29, 2015 14:07
-
-
Save NickBeeuwsaert/38cd67c645e40215d51d to your computer and use it in GitHub Desktop.
Drawing scalable images in SDL2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <SDL2/SDL.h> | |
| #include <SDL2/SDL_image.h> | |
| #include <stdbool.h> | |
| #define MAX(a, b) ((a)>(b)?(a):(b)) | |
| /** | |
| * Renders a image with out distorting it | |
| * | |
| * @param renderer The renderer to render to | |
| * @param patch The texture to render | |
| * @param src the offsets from the edges of the texture to cut the image | |
| * @param dst The destination where the patch will be drawn | |
| */ | |
| void RenderPatch(SDL_Renderer * renderer, SDL_Texture *patch, SDL_Rect *src, SDL_Rect *dst) { | |
| //Create a copy of the dst rect so we can modify it | |
| SDL_Rect frame = *dst; | |
| //Make sure that the dst isn't too small | |
| // Sort of like how CSS box-sizing: border-box; works | |
| // if we have a width of 50px, but the padding is set to 30px, then we will have a 60px wide box | |
| frame.w = MAX(frame.w, src->x+src->w); | |
| frame.h = MAX(frame.h, src->y+src->h); | |
| int w, h; | |
| SDL_QueryTexture(patch, NULL, NULL, &w, &h); | |
| SDL_Point srcPoints[] = { | |
| {0, 0}, | |
| {src->x, src->y}, | |
| {w - src->w, h - src->h}, | |
| {w, h} | |
| }; | |
| SDL_Point dstPoints[] = { | |
| {frame.x, frame.y}, | |
| {frame.x + src->x, frame.y + src->y}, | |
| {frame.x + frame.w - src->w, frame.y + frame.h - src->h}, | |
| {frame.x + frame.w, frame.y + frame.h} | |
| }; | |
| //Loop trough and draw each rect | |
| for (int y = 0; y < 3; y++ ) { | |
| for (int x = 0; x < 3; x++) { | |
| SDL_Rect src_ = { | |
| srcPoints[x].x, | |
| srcPoints[y].y, | |
| srcPoints[x+1].x, | |
| srcPoints[y+1].y | |
| }; | |
| src_.w -= src_.x; | |
| src_.h -= src_.y; | |
| SDL_Rect dst_ = { | |
| dstPoints[x].x, | |
| dstPoints[y].y, | |
| dstPoints[x+1].x, | |
| dstPoints[y+1].y | |
| }; | |
| dst_.w -= dst_.x; | |
| dst_.h -= dst_.y; | |
| SDL_RenderCopy(renderer, patch, &src_, &dst_); | |
| } | |
| } | |
| } | |
| int main() { | |
| SDL_Init(SDL_INIT_VIDEO); | |
| IMG_Init(IMG_INIT_PNG); | |
| SDL_Window *window; | |
| SDL_Renderer *renderer; | |
| SDL_Event evt; | |
| SDL_Texture *texture; | |
| if (SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_OPENGL, &window, &renderer) != 0) { | |
| fprintf(stderr, "Problem creating window and renderer: %s\n", SDL_GetError()); | |
| return -1; | |
| } | |
| if( !(texture = IMG_LoadTexture(renderer, "texture.png"))) { | |
| fprintf(stderr, "Problem loading texture!\n"); | |
| return -1; | |
| } | |
| // Use a white background so you can see my pretty drop shadows | |
| SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); | |
| SDL_Rect patch_border = {30, 82, 30, 30}; | |
| bool running = true; | |
| while(running) { | |
| SDL_RenderClear(renderer); | |
| SDL_Rect frame; | |
| //A. Draw a medium sized window in the top left | |
| frame = (SDL_Rect){0, 0, 266, 300}; | |
| RenderPatch(renderer, texture, &patch_border, &frame); | |
| //B. Draw half that in the top center | |
| frame = (SDL_Rect){266+75, 0, 133, 150}; | |
| RenderPatch(renderer, texture, &patch_border, &frame); | |
| //C. Draw a 0x0 window to show how small sizes are handled (Badly) | |
| frame = (SDL_Rect){266*2+30, 0, 0, 0}; | |
| RenderPatch(renderer, texture, &patch_border, &frame); | |
| //D. Draw a window with the same dimensions as D | |
| frame = (SDL_Rect){266*2+90, 0, 60, 112}; | |
| RenderPatch(renderer, texture, &patch_border, &frame); | |
| //Draw a large window along the bottom | |
| frame = (SDL_Rect){0, 300, 800, 300}; | |
| RenderPatch(renderer, texture, &patch_border, &frame); | |
| SDL_RenderPresent(renderer); | |
| while(SDL_PollEvent(&evt)) { | |
| switch(evt.type) { | |
| case SDL_QUIT: | |
| running = false; | |
| break; | |
| } | |
| } | |
| } | |
| SDL_DestroyTexture(texture); | |
| SDL_DestroyRenderer(renderer); | |
| SDL_DestroyWindow(window); | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| LIBS=`sdl2-config --libs` `pkg-config SDL2_image --libs` | |
| CFLAGS=`sdl2-config --cflags` `pkg-config SDL2_image --cflags` | |
| all: main.o | |
| gcc -o main main.o $(LIBS) -Wall | |
| main.o: main.c | |
| gcc -o main.o -c main.c $(CFLAGS) -Wall | |
| clean: | |
| rm main.o main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
