Created
April 28, 2020 19:44
-
-
Save arthurmco/ec7356031f86a4824d390826a50fba2e to your computer and use it in GitHub Desktop.
SDL rainbow
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.h> | |
#include <SDL2/SDL_opengl.h> | |
#include <cstdio> | |
#include <string> | |
#include <cstdint> | |
#include <glm/glm.hpp> | |
#include <cmath> | |
glm::vec3 HSVtoRGB(glm::vec3 HSV) | |
{ | |
glm::vec3 RGB; | |
double H = HSV.r, S = HSV.g, V = HSV.b; | |
double P, Q, T; | |
double fract; | |
// printf("[%.2f %.2f %.2f] ", H, S, V); | |
(H == 360.)?(H = 0.):(H /= 60.); | |
fract = H - floor(H); | |
P = V*(1. - S); | |
Q = V*(1. - S*fract); | |
T = V*(1. - S*(1. - fract)); | |
if (0. <= H && H < 1.) | |
RGB = glm::vec3( V, T, P); | |
else if (1. <= H && H < 2.) | |
RGB = glm::vec3( Q, V, P); | |
else if (2. <= H && H < 3.) | |
RGB = glm::vec3( P, V, T); | |
else if (3. <= H && H < 4.) | |
RGB = glm::vec3( P, Q, V); | |
else if (4. <= H && H < 5.) | |
RGB = glm::vec3( T, P, V); | |
else if (5. <= H && H < 6.) | |
RGB = glm::vec3( V, P, Q); | |
else | |
RGB = glm::vec3( 0., 0., 0.); | |
return RGB; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
auto width=800, height=600; | |
SDL_Window* win; | |
SDL_Renderer* renderer; | |
SDL_Init(SDL_INIT_EVERYTHING); | |
win = SDL_CreateWindow("GUI Test", | |
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, | |
SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN | SDL_WINDOW_ALLOW_HIGHDPI); | |
if (!win) { | |
auto err = std::string("OpenGL context creation error: "); | |
err.append(SDL_GetError()); | |
fprintf(stderr, "%s", err.c_str()); | |
return 1; | |
} | |
SDL_ShowWindow(win); | |
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); | |
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); | |
// Clear the entire screen to our selected color. | |
SDL_RenderClear(renderer); | |
// Up until now everything was drawn behind the scenes. | |
// This will show the new, red contents of the window. | |
SDL_RenderPresent(renderer); | |
SDL_Texture* framebuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, width, height); | |
SDL_Event e; | |
bool running = true; | |
uint32_t* fbdata; | |
int fbpitch = 0; | |
auto c = 0; | |
while (running) { | |
SDL_PollEvent(&e); | |
switch (e.type) { | |
case SDL_QUIT: | |
running = false; | |
break; | |
} | |
// update the texture with the new framebuffer | |
SDL_LockTexture(framebuffer, NULL, (void**)&fbdata, &fbpitch); | |
auto fnGetColorValue = [](glm::vec4 val) { | |
uint32_t v = 0; | |
v |= ((uint32_t) glm::min(glm::max(val.r, 0.0f), 255.0f)); | |
v |= ((uint32_t) glm::min(glm::max(val.g, 0.0f), 255.0f)) << 8; | |
v |= ((uint32_t) glm::min(glm::max(val.b, 0.0f), 255.0f)) << 16; | |
v |= ((uint32_t) glm::min(glm::max(val.a, 0.0f), 255.0f)) << 24; | |
return v; | |
}; | |
for (auto i = 0; i < width*height; i++) { | |
auto xf = (width/40); | |
auto y = i/width; | |
auto x = i%width; | |
glm::vec3 color; | |
if (y > 40 && y < 50) { | |
color = glm::vec3(0, 0, 0); | |
} else if (x > (c%width)+20 && x < (c%width)+40) { | |
color = glm::vec3(255, 255, 255); | |
} else { | |
glm::vec3 rainbow = HSVtoRGB(glm::vec3(glm::max(c-(x/xf), 0) % 360, 0.7, glm::min(0.5+(y*1.0/height), 1.0) * 255)); | |
color = rainbow; | |
} | |
if (y%2 == 0) | |
fbdata[i] = fnGetColorValue(glm::vec4(color.r, color.g, color.b, 255)); | |
} | |
SDL_UnlockTexture(framebuffer); | |
// render the updated texture | |
SDL_RenderClear(renderer); | |
SDL_RenderCopy(renderer, framebuffer, NULL, NULL); | |
SDL_RenderPresent(renderer); | |
c++; | |
} | |
SDL_DestroyTexture(framebuffer); | |
SDL_DestroyRenderer(renderer); | |
SDL_DestroyWindow(win); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment