+ image struct stores pointer to images surface and texture now

+ replaced surface drawing via SDL_UpdateWindowSurface with SDL_Renderer calls -> much better ram usage since before, because SDL_Texture is used to store the drawn image instead the surface itself
This commit is contained in:
Ano-sys
2026-08-15 18:22:04 +02:00
parent 3487bdfb1f
commit 9297b4c062
+26 -22
View File
@@ -20,6 +20,8 @@ typedef struct Image{
int y; int y;
int channels; int channels;
unsigned char* pixels; unsigned char* pixels;
SDL_Surface* surface;
SDL_Texture* texture;
} Image; } Image;
typedef struct{ typedef struct{
@@ -27,13 +29,13 @@ typedef struct{
int h; int h;
} window_size_delta; } window_size_delta;
Image load_image(const char* filepath){ Image load_image_pixels_from_file(const char* filepath){
Image image; Image image;
image.pixels = stbi_load(filepath, &image.x, &image.y, &image.channels, DESIRED_IMAGE_CHANNELS); image.pixels = stbi_load(filepath, &image.x, &image.y, &image.channels, DESIRED_IMAGE_CHANNELS);
return image; return image;
} }
void free_image_buffer(Image* image){ void free_image_pixels_buffer(Image* image){
if(image->pixels) stbi_image_free(image->pixels); if(image->pixels) stbi_image_free(image->pixels);
image->pixels = NULL; image->pixels = NULL;
} }
@@ -66,8 +68,10 @@ SDL_Window* create_window(const char* title, int w, int h){
return window; return window;
} }
SDL_Surface* create_image_surface(SDL_Surface* surface, Image* image){ void populate_image(SDL_Window* window, Image* image){
SDL_Surface* image_surface = SDL_CreateSurface(image->x, image->y, SDL_PIXELFORMAT_RGBA32); SDL_Surface* surface = SDL_GetWindowSurface(window);
image->surface = SDL_CreateSurface(image->x, image->y, SDL_PIXELFORMAT_RGBA32);
SDL_Rect pixel = { 0, 0, 1, 1 }; SDL_Rect pixel = { 0, 0, 1, 1 };
int center_x = ((surface->w + 1) / 2 - 1); int center_x = ((surface->w + 1) / 2 - 1);
@@ -82,20 +86,20 @@ SDL_Surface* create_image_surface(SDL_Surface* surface, Image* image){
pixel.y = dst_y + y; pixel.y = dst_y + y;
const int current_pixel_idx = (y * image->x + x) * DESIRED_IMAGE_CHANNELS; const int current_pixel_idx = (y * image->x + x) * DESIRED_IMAGE_CHANNELS;
Uint32 color = SDL_MapSurfaceRGBA(image_surface, Uint32 color = SDL_MapSurfaceRGBA(image->surface,
image->pixels[current_pixel_idx + 0], image->pixels[current_pixel_idx + 0],
image->pixels[current_pixel_idx + 1], image->pixels[current_pixel_idx + 1],
image->pixels[current_pixel_idx + 2], image->pixels[current_pixel_idx + 2],
image->pixels[current_pixel_idx + 3]); image->pixels[current_pixel_idx + 3]);
SDL_FillSurfaceRect(image_surface, &pixel, color); SDL_FillSurfaceRect(image->surface, &pixel, color);
} }
} }
return image_surface; image->texture = SDL_CreateTextureFromSurface(SDL_GetRenderer(window), image->surface);
} }
void draw_image(SDL_Window* window, SDL_Surface* image_surface, Image* image, float pixel_size_delta, int image_start_x, int image_start_y){ void draw_image(SDL_Window* window, Image* image, float pixel_size_delta, int image_start_x, int image_start_y){
SDL_Surface* surface = SDL_GetWindowSurface(window); SDL_Surface* surface = SDL_GetWindowSurface(window);
float pixel_size = pixel_size_delta; float pixel_size = pixel_size_delta;
@@ -105,13 +109,14 @@ void draw_image(SDL_Window* window, SDL_Surface* image_surface, Image* image, fl
Uint64 start = SDL_GetTicksNS(); Uint64 start = SDL_GetTicksNS();
SDL_Rect dst = { center_x - (image->x * pixel_size / 2) + image_start_x, center_y - (image->y * pixel_size / 2) + image_start_y, image->x * pixel_size, image->y * pixel_size }; SDL_FRect dst = { center_x - (image->x * pixel_size / 2) + image_start_x, center_y - (image->y * pixel_size / 2) + image_start_y, image->x * pixel_size, image->y * pixel_size };
SDL_ClearSurface(surface, 0, 0, 0, 255); SDL_Renderer* renderer = SDL_GetRenderer(window);
SDL_BlitSurfaceScaled(image_surface, NULL, surface, &dst, SDL_SCALEMODE_LINEAR); SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, image->texture, NULL, &dst);
SDL_RenderPresent(renderer);
printf("Redraw time: %.3fms\n", (SDL_GetTicksNS() - start) / 1000000.0); printf("Redraw time: %.3fms\n", (SDL_GetTicksNS() - start) / 1000000.0);
SDL_UpdateWindowSurface(window);
} }
int clamp(const int in, const int low, const int high){ int clamp(const int in, const int low, const int high){
@@ -152,7 +157,7 @@ void on_wheel(SDL_Event* event, SDL_Window* window){
SDL_SetWindowSize(window, new_w, new_h); SDL_SetWindowSize(window, new_w, new_h);
} }
void loop(SDL_Window* window, SDL_Surface* image_surface, Image* image){ void loop(SDL_Window* window, Image* image){
bool drag_left_mouse = false; bool drag_left_mouse = false;
bool drag_right_mouse = false; bool drag_right_mouse = false;
int last_pointer_x = 0; int last_pointer_x = 0;
@@ -221,7 +226,7 @@ void loop(SDL_Window* window, SDL_Surface* image_surface, Image* image){
if(redraw){ if(redraw){
redraw = false; redraw = false;
draw_image(window, image_surface, image, pixel_size_delta, current_image_start_x, current_image_start_y); draw_image(window, image, pixel_size_delta, current_image_start_x, current_image_start_y);
} }
} }
} }
@@ -239,7 +244,7 @@ int main(int argc, char** argv){
exit(2); exit(2);
} }
Image image = load_image(filepath); Image image = load_image_pixels_from_file(filepath);
if(image.pixels == NULL){ if(image.pixels == NULL){
printf("Failed to load image!"); printf("Failed to load image!");
exit(3); exit(3);
@@ -257,15 +262,14 @@ int main(int argc, char** argv){
exit(5); exit(5);
} }
SDL_Surface* image_surface = create_image_surface(surface, &image); populate_image(window, &image);
free_image_buffer(&image); free_image_pixels_buffer(&image);
draw_image(window, image_surface, &image, 1.0f, 0, 0); draw_image(window, &image, 1.0f, 0, 0);
SDL_UpdateWindowSurface(window); loop(window, &image);
loop(window, image_surface, &image); SDL_DestroyTexture(image.texture);
SDL_DestroySurface(image.surface);
SDL_DestroySurface(image_surface);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
} }