+ 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:
+26
-22
@@ -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);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user