Last active
June 20, 2022 16:09
-
-
Save bynect/c4ed0693b9f0667e0be867f7dfe1780a to your computer and use it in GitHub Desktop.
Grid with 2d rotation example in SDL2
This file contains 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
#!/bin/sh | |
set -xe | |
gcc -o main main.c -lSDL2 |
This file contains 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_events.h> | |
#include <SDL2/SDL_rect.h> | |
#include <SDL2/SDL_render.h> | |
#include <SDL2/SDL_stdinc.h> | |
#include <SDL2/SDL_surface.h> | |
#include <stdio.h> | |
#include <stdbool.h> | |
#include <string.h> | |
#include <SDL2/SDL.h> | |
#ifdef DEBUG | |
#define debug(...) printf(__VA_ARGS__) | |
#else | |
#define debug(...) | |
#endif | |
#define error() do { printf("%s:%s:%d ERROR: %s\n", __FILE__, __func__, __LINE__, SDL_GetError()); abort(); } while (false) | |
#define cn(...) if ((__VA_ARGS__) == NULL) error(); | |
#define cz(...) if ((__VA_ARGS__) < 0) error(); | |
#define SCREEN_WIDTH 800 | |
#define SCREEN_HEIGHT 800 | |
#define LINE_SPACE 20 | |
#define LINE_LENGHT 10 | |
typedef struct { | |
int x, y; | |
} vec2i; | |
// Angle in degrees | |
vec2i rotate(vec2i pos, vec2i orig, double angle) | |
{ | |
double radians = (3.14159265 / 180) * angle; | |
int px = pos.x - orig.x; | |
int py = pos.y - orig.y; | |
vec2i new = { | |
.x = px*SDL_cos(radians) - py*SDL_sin(radians), | |
.y = px*SDL_sin(radians) + py*SDL_cos(radians), | |
}; | |
new.x += orig.x; | |
new.y += orig.y; | |
return new; | |
} | |
int main() | |
{ | |
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0) | |
{ | |
printf("Unable to initialize SDL2: %s\n", SDL_GetError()); | |
return 1; | |
} | |
SDL_Window *window = SDL_CreateWindow("rotation", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, | |
SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); | |
cn(window); | |
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); | |
cn(renderer); | |
cz(SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND)); | |
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_UNKNOWN, SDL_TEXTUREACCESS_TARGET, 128, 128); | |
cn(texture); | |
cz(SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND)); | |
cz(SDL_SetRenderTarget(renderer, texture)); | |
cz(SDL_SetRenderDrawColor(renderer, 255, 255, 255, 150)); | |
cz(SDL_RenderClear(renderer)); | |
cz(SDL_SetRenderTarget(renderer, NULL)); | |
cz(SDL_SetRenderDrawColor(renderer, 18, 18, 18, 255)); | |
cz(SDL_RenderClear(renderer)); | |
cz(SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255)); | |
cz(SDL_RenderDrawLine(renderer, 0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT / 2)); | |
cz(SDL_RenderDrawLine(renderer, SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2, SCREEN_HEIGHT)); | |
cz(SDL_RenderDrawLine(renderer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); | |
cz(SDL_RenderDrawLine(renderer, 0, SCREEN_HEIGHT, SCREEN_WIDTH, 0)); | |
for (int i = 0; i < SCREEN_HEIGHT / LINE_SPACE; ++i) | |
{ | |
cz(SDL_RenderDrawLine(renderer, SCREEN_WIDTH / 2 - LINE_LENGHT / 2, i * LINE_SPACE, SCREEN_WIDTH / 2 + LINE_LENGHT / 2, i * LINE_SPACE)); | |
} | |
for (int i = 0; i < SCREEN_WIDTH / LINE_SPACE; ++i) | |
{ | |
cz(SDL_RenderDrawLine(renderer, i * LINE_SPACE, SCREEN_HEIGHT / 2 - LINE_LENGHT / 2, i * LINE_SPACE, SCREEN_HEIGHT / 2 + LINE_LENGHT / 2)); | |
} | |
double deg_angle = 45; | |
SDL_Rect rect = { | |
.x = SCREEN_WIDTH / 2 - 200, | |
.y = SCREEN_HEIGHT / 2 - 25, | |
.w = 400, | |
.h = 50, | |
}; | |
cz(SDL_RenderCopyEx(renderer, texture, NULL, &rect, 0, NULL, SDL_FLIP_NONE)); | |
cz(SDL_RenderCopyEx(renderer, texture, NULL, &rect, deg_angle, NULL, SDL_FLIP_NONE)); | |
cz(SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255)); | |
cz(SDL_RenderDrawLine(renderer, rect.x, rect.y + rect.h / 2, rect.x + rect.w, rect.y + rect.h / 2)); | |
vec2i orig = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2}; | |
vec2i pos11 = {rect.x, rect.y + rect.h / 2}; | |
vec2i pos21 = {rect.x + rect.w, rect.y + rect.h / 2}; | |
vec2i pos12 = rotate(pos11, orig, deg_angle); | |
vec2i pos22 = rotate(pos21, orig, deg_angle); | |
cz(SDL_RenderDrawLine(renderer, pos12.x, pos12.y, pos22.x, pos22.y)); | |
printf("x1=%d, y1=%d, x2=%d, y2=%d\n", pos12.x, pos12.y, pos22.x, pos22.y); | |
vec2i v11 = {rect.x, rect.y}; | |
vec2i v21 = {rect.x, rect.y + rect.h}; | |
vec2i v31 = {rect.x + rect.w, rect.y}; | |
vec2i v41 = {rect.x + rect.w, rect.y + rect.h}; | |
vec2i v12 = rotate(v11, orig, deg_angle); | |
vec2i v22 = rotate(v21, orig, deg_angle); | |
vec2i v32 = rotate(v31, orig, deg_angle); | |
vec2i v42 = rotate(v41, orig, deg_angle); | |
SDL_Rect bounding_rect = { | |
.x = v22.x, | |
.y = v12.y, | |
.w = v32.x - v22.x, | |
.h = v42.y - v12.y, | |
}; | |
SDL_RenderDrawRect(renderer, &bounding_rect); | |
SDL_RenderPresent(renderer); | |
SDL_Event event; | |
while (SDL_WaitEvent(&event)) | |
{ | |
if (event.type == SDL_QUIT) break; | |
else if (event.type == SDL_MOUSEBUTTONDOWN) | |
{ | |
int x = event.button.x; | |
int y = event.button.y; | |
printf("x=%d, y=%d\n", x, y); | |
} | |
} | |
SDL_DestroyRenderer(renderer); | |
SDL_DestroyWindow(window); | |
SDL_Quit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment