Skip to content

Instantly share code, notes, and snippets.

@arthurmco
Created April 28, 2020 19:44
Show Gist options
  • Save arthurmco/ec7356031f86a4824d390826a50fba2e to your computer and use it in GitHub Desktop.
Save arthurmco/ec7356031f86a4824d390826a50fba2e to your computer and use it in GitHub Desktop.
SDL rainbow
#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