1 | /******************************************************************************************* |
2 | * |
3 | * raylib [textures] example - Image processing |
4 | * |
5 | * NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM) |
6 | * |
7 | * This example has been created using raylib 1.4 (www.raylib.com) |
8 | * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) |
9 | * |
10 | * Copyright (c) 2016 Ramon Santamaria (@raysan5) |
11 | * |
12 | ********************************************************************************************/ |
13 | |
14 | #include "raylib.h" |
15 | |
16 | #include <stdlib.h> // Required for: free() |
17 | |
18 | #define NUM_PROCESSES 8 |
19 | |
20 | typedef enum { |
21 | NONE = 0, |
22 | COLOR_GRAYSCALE, |
23 | COLOR_TINT, |
24 | COLOR_INVERT, |
25 | COLOR_CONTRAST, |
26 | COLOR_BRIGHTNESS, |
27 | FLIP_VERTICAL, |
28 | FLIP_HORIZONTAL |
29 | } ImageProcess; |
30 | |
31 | static const char *processText[] = { |
32 | "NO PROCESSING" , |
33 | "COLOR GRAYSCALE" , |
34 | "COLOR TINT" , |
35 | "COLOR INVERT" , |
36 | "COLOR CONTRAST" , |
37 | "COLOR BRIGHTNESS" , |
38 | "FLIP VERTICAL" , |
39 | "FLIP HORIZONTAL" |
40 | }; |
41 | |
42 | int main(void) |
43 | { |
44 | // Initialization |
45 | //-------------------------------------------------------------------------------------- |
46 | const int screenWidth = 800; |
47 | const int screenHeight = 450; |
48 | |
49 | InitWindow(screenWidth, screenHeight, "raylib [textures] example - image processing" ); |
50 | |
51 | // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) |
52 | |
53 | Image image = LoadImage("resources/parrots.png" ); // Loaded in CPU memory (RAM) |
54 | ImageFormat(&image, UNCOMPRESSED_R8G8B8A8); // Format image to RGBA 32bit (required for texture update) <-- ISSUE |
55 | Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM) |
56 | |
57 | int currentProcess = NONE; |
58 | bool textureReload = false; |
59 | |
60 | Rectangle selectRecs[NUM_PROCESSES] = { 0 }; |
61 | |
62 | for (int i = 0; i < NUM_PROCESSES; i++) selectRecs[i] = (Rectangle){ 40.0f, (float)(50 + 32*i), 150.0f, 30.0f }; |
63 | |
64 | SetTargetFPS(60); |
65 | //--------------------------------------------------------------------------------------- |
66 | |
67 | // Main game loop |
68 | while (!WindowShouldClose()) // Detect window close button or ESC key |
69 | { |
70 | // Update |
71 | //---------------------------------------------------------------------------------- |
72 | if (IsKeyPressed(KEY_DOWN)) |
73 | { |
74 | currentProcess++; |
75 | if (currentProcess > 7) currentProcess = 0; |
76 | textureReload = true; |
77 | } |
78 | else if (IsKeyPressed(KEY_UP)) |
79 | { |
80 | currentProcess--; |
81 | if (currentProcess < 0) currentProcess = 7; |
82 | textureReload = true; |
83 | } |
84 | |
85 | if (textureReload) |
86 | { |
87 | UnloadImage(image); // Unload current image data |
88 | image = LoadImage("resources/parrots.png" ); // Re-load image data |
89 | |
90 | // NOTE: Image processing is a costly CPU process to be done every frame, |
91 | // If image processing is required in a frame-basis, it should be done |
92 | // with a texture and by shaders |
93 | switch (currentProcess) |
94 | { |
95 | case COLOR_GRAYSCALE: ImageColorGrayscale(&image); break; |
96 | case COLOR_TINT: ImageColorTint(&image, GREEN); break; |
97 | case COLOR_INVERT: ImageColorInvert(&image); break; |
98 | case COLOR_CONTRAST: ImageColorContrast(&image, -40); break; |
99 | case COLOR_BRIGHTNESS: ImageColorBrightness(&image, -80); break; |
100 | case FLIP_VERTICAL: ImageFlipVertical(&image); break; |
101 | case FLIP_HORIZONTAL: ImageFlipHorizontal(&image); break; |
102 | default: break; |
103 | } |
104 | |
105 | Color *pixels = GetImageData(image); // Get pixel data from image (RGBA 32bit) |
106 | UpdateTexture(texture, pixels); // Update texture with new image data |
107 | free(pixels); // Unload pixels data from RAM |
108 | |
109 | textureReload = false; |
110 | } |
111 | //---------------------------------------------------------------------------------- |
112 | |
113 | // Draw |
114 | //---------------------------------------------------------------------------------- |
115 | BeginDrawing(); |
116 | |
117 | ClearBackground(RAYWHITE); |
118 | |
119 | DrawText("IMAGE PROCESSING:" , 40, 30, 10, DARKGRAY); |
120 | |
121 | // Draw rectangles |
122 | for (int i = 0; i < NUM_PROCESSES; i++) |
123 | { |
124 | DrawRectangleRec(selectRecs[i], (i == currentProcess) ? SKYBLUE : LIGHTGRAY); |
125 | DrawRectangleLines((int)selectRecs[i].x, (int) selectRecs[i].y, (int) selectRecs[i].width, (int) selectRecs[i].height, (i == currentProcess) ? BLUE : GRAY); |
126 | DrawText( processText[i], (int)( selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)/2), (int) selectRecs[i].y + 11, 10, (i == currentProcess) ? DARKBLUE : DARKGRAY); |
127 | } |
128 | |
129 | DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE); |
130 | DrawRectangleLines(screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, texture.width, texture.height, BLACK); |
131 | |
132 | EndDrawing(); |
133 | //---------------------------------------------------------------------------------- |
134 | } |
135 | |
136 | // De-Initialization |
137 | //-------------------------------------------------------------------------------------- |
138 | UnloadTexture(texture); // Unload texture from VRAM |
139 | UnloadImage(image); // Unload image from RAM |
140 | |
141 | CloseWindow(); // Close window and OpenGL context |
142 | //-------------------------------------------------------------------------------------- |
143 | |
144 | return 0; |
145 | } |