demo: Añadido efecto de fuego en el fondo
This commit is contained in:
61
main.cpp
61
main.cpp
@@ -15,7 +15,10 @@ Código fuente creado por JailDesigner
|
|||||||
#include "units/texture.h"
|
#include "units/texture.h"
|
||||||
#include "units/screen.h"
|
#include "units/screen.h"
|
||||||
#include "units/input.h"
|
#include "units/input.h"
|
||||||
|
#include "quickcg.h"
|
||||||
|
using namespace QuickCG;
|
||||||
|
|
||||||
|
// Punteros
|
||||||
SDL_Event *event;
|
SDL_Event *event;
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
@@ -30,24 +33,36 @@ Text *debugText;
|
|||||||
Texture *texture;
|
Texture *texture;
|
||||||
MovingSprite *sprite;
|
MovingSprite *sprite;
|
||||||
|
|
||||||
|
// Listas
|
||||||
enum e_fx // Tipos de efectos disponibles para el fondo
|
enum e_fx // Tipos de efectos disponibles para el fondo
|
||||||
{
|
{
|
||||||
fx_fire,
|
fx_fire,
|
||||||
fx_gradient
|
fx_gradient
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Variables de uso general
|
||||||
Uint32 ticks = 0; // Variable para la frecuencia de actualización de la lógica del programa
|
Uint32 ticks = 0; // Variable para la frecuencia de actualización de la lógica del programa
|
||||||
Uint32 ticksSpeed = 15; // Variable para la frecuencia de actualización de la lógica del programa
|
const Uint32 ticksSpeed = 15; // Variable para la frecuencia de actualización de la lógica del programa
|
||||||
bool should_exit = false; // Variable para saber si ha terminado el progra,a
|
bool should_exit = false; // Variable para saber si ha terminado el progra,a
|
||||||
int counter = 0; // Contador para lo que se necesite
|
int counter = 0; // Contador para lo que se necesite
|
||||||
|
string controllerName; // Nombre del primer mando detectado
|
||||||
|
string inputPressed; // Texto con el último input que se ha pulsado
|
||||||
|
e_fx fx = fx_fire; // Efecto seleccionado para el fondo
|
||||||
|
int fxTotal = 2; // Cantidad total de efectos disponibles para el fondo
|
||||||
|
|
||||||
|
// Variables para el efecto del degradado
|
||||||
int gradColorMin = 64; // Minimo color más alto del degradado
|
int gradColorMin = 64; // Minimo color más alto del degradado
|
||||||
int gradColorMax = 192; // Minimo color más alto del degradado
|
int gradColorMax = 192; // Minimo color más alto del degradado
|
||||||
int gradCurrentColor = 192; // Color actual más alto del degradado
|
int gradCurrentColor = 192; // Color actual más alto del degradado
|
||||||
int gradBreathDirection = 0; // Indica si gradCurrentColor crece o decrece
|
int gradBreathDirection = 0; // Indica si gradCurrentColor crece o decrece
|
||||||
string controllerName; // Nombre del primer mando detectado
|
|
||||||
string inputPressed; // Texto con el último input que se ha pulsado
|
// Variables para el efecto de fuego
|
||||||
e_fx fx = fx_gradient; // Efecto seleccionado para el fondo
|
const int fireScreenWidth = 320; // Ancho del efecto de fuego
|
||||||
int fxTotal = 2; // Cantidad total de efectos disponibles para el fondo
|
const int fireScreenHeight = 180; // Alto del efecto de fuego
|
||||||
|
Uint32 fire[fireScreenHeight][fireScreenWidth]; // Buffer con el fuego
|
||||||
|
Uint32 buffer[fireScreenHeight][fireScreenWidth]; // Buffer para dibujar en pantalla
|
||||||
|
ColorRGB palette[256]; // Paleta de color para el fuego
|
||||||
|
const int fireDesp = 240 - fireScreenHeight + 3; // Fila donde comienza a dibujarse el efecto de fuego
|
||||||
|
|
||||||
// Inicializa las opciones
|
// Inicializa las opciones
|
||||||
void initOptions();
|
void initOptions();
|
||||||
@@ -240,6 +255,23 @@ void initSprite()
|
|||||||
// Inicializa el efecto de fuego
|
// Inicializa el efecto de fuego
|
||||||
void initFire()
|
void initFire()
|
||||||
{
|
{
|
||||||
|
// Inicializa el buffer de fuego
|
||||||
|
for (int y = 0; y < fireScreenHeight; ++y)
|
||||||
|
for (int x = 0; x < fireScreenWidth; ++x)
|
||||||
|
fire[y][x] = 0;
|
||||||
|
|
||||||
|
// Inicializa la paleta
|
||||||
|
for (int x = 0; x < 256; ++x)
|
||||||
|
{
|
||||||
|
// HSLtoRGB is used to generate colors:
|
||||||
|
// Hue goes from 0 to 85: red to yellow
|
||||||
|
// Saturation is always the maximum: 255
|
||||||
|
// Lightness is 0..255 for x=0..128, and 255 for x=128..255
|
||||||
|
ColorRGB color = HSLtoRGB(ColorHSL(x / 3, 255, std::min(255, x * 2)));
|
||||||
|
// set the palette to the calculated RGB value
|
||||||
|
// palette[x] = RGBtoINT(color);
|
||||||
|
palette[x] = color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inicializa todo
|
// Inicializa todo
|
||||||
@@ -399,6 +431,18 @@ void updateGradient()
|
|||||||
// Actualiza el efecto de fuego
|
// Actualiza el efecto de fuego
|
||||||
void updateFire()
|
void updateFire()
|
||||||
{
|
{
|
||||||
|
// randomize the bottom row of the fire buffer
|
||||||
|
const int w = fireScreenWidth;
|
||||||
|
const int h = fireScreenHeight;
|
||||||
|
for (int x = 0; x < w; ++x)
|
||||||
|
fire[h - 1][x] = abs(32768 + rand()) % 256;
|
||||||
|
// do the fire calculations for every pixel, from top to bottom
|
||||||
|
for (int y = 0; y < h - 1; ++y)
|
||||||
|
for (int x = 0; x < w; ++x)
|
||||||
|
{
|
||||||
|
fire[y][x] =
|
||||||
|
((fire[(y + 1) % h][(x - 1 + w) % w] + fire[(y + 1) % h][(x) % w] + fire[(y + 1) % h][(x + 1) % w] + fire[(y + 2) % h][(x) % w]) * 32) / 129;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el efecto de fondo
|
// Actualiza el efecto de fondo
|
||||||
@@ -476,6 +520,13 @@ void renderGradient()
|
|||||||
// Dibuja el efecto de fuego
|
// Dibuja el efecto de fuego
|
||||||
void renderFire()
|
void renderFire()
|
||||||
{
|
{
|
||||||
|
for (int y = 0; y < fireScreenHeight; ++y)
|
||||||
|
for (int x = 0; x < fireScreenWidth; ++x)
|
||||||
|
{
|
||||||
|
const ColorRGB c = palette[fire[y][x]];
|
||||||
|
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 255);
|
||||||
|
SDL_RenderDrawPoint(renderer, x, y + fireDesp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dibuja el efecto de fondo
|
// Dibuja el efecto de fondo
|
||||||
|
|||||||
428
quickcg.cpp
Normal file
428
quickcg.cpp
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
/*
|
||||||
|
QuickCG 20191227
|
||||||
|
|
||||||
|
Copyright (c) 2004-2019, Lode Vandevenne
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
QuickCG is an SDL codebase that wraps some of the SDL functionality.
|
||||||
|
It' used by Lode's Computer Graphics Tutorial to work with simple C++ calls
|
||||||
|
to demonstrate graphical programs.
|
||||||
|
|
||||||
|
QuickCG can handle some things that standard C++ doesn't but that are commonly useful, such as:
|
||||||
|
-drawing graphics
|
||||||
|
-a bitmap font
|
||||||
|
-simplified saving and loading of files
|
||||||
|
-reading keyboard and mouse input
|
||||||
|
-playing sound
|
||||||
|
-color models
|
||||||
|
-loading images
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quickcg.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace QuickCG
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COLOR STRUCTS/////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
ColorRGB::ColorRGB(Uint8 r, Uint8 g, Uint8 b)
|
||||||
|
{
|
||||||
|
this->r = r;
|
||||||
|
this->g = g;
|
||||||
|
this->b = b;
|
||||||
|
}
|
||||||
|
ColorRGB::ColorRGB(const ColorRGB8bit &color)
|
||||||
|
{
|
||||||
|
this->r = color.r;
|
||||||
|
this->g = color.g;
|
||||||
|
this->b = color.b;
|
||||||
|
}
|
||||||
|
ColorRGB::ColorRGB()
|
||||||
|
{
|
||||||
|
this->r = 0;
|
||||||
|
this->g = 0;
|
||||||
|
this->b = 0;
|
||||||
|
}
|
||||||
|
ColorRGB8bit::ColorRGB8bit(Uint8 r, Uint8 g, Uint8 b)
|
||||||
|
{
|
||||||
|
this->r = r;
|
||||||
|
this->g = g;
|
||||||
|
this->b = b;
|
||||||
|
}
|
||||||
|
ColorRGB8bit::ColorRGB8bit(const ColorRGB &color)
|
||||||
|
{
|
||||||
|
this->r = color.r;
|
||||||
|
this->g = color.g;
|
||||||
|
this->b = color.b;
|
||||||
|
}
|
||||||
|
ColorRGB8bit::ColorRGB8bit()
|
||||||
|
{
|
||||||
|
this->r = 0;
|
||||||
|
this->g = 0;
|
||||||
|
this->b = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add two colors
|
||||||
|
ColorRGB operator+(const ColorRGB &color, const ColorRGB &color2)
|
||||||
|
{
|
||||||
|
ColorRGB c;
|
||||||
|
c.r = color.r + color2.r;
|
||||||
|
c.g = color.g + color2.g;
|
||||||
|
c.b = color.b + color2.b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtract two colors
|
||||||
|
ColorRGB operator-(const ColorRGB &color, const ColorRGB &color2)
|
||||||
|
{
|
||||||
|
ColorRGB c;
|
||||||
|
c.r = color.r - color2.r;
|
||||||
|
c.g = color.g - color2.g;
|
||||||
|
c.b = color.b - color2.b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplies a color with an integer
|
||||||
|
ColorRGB operator*(const ColorRGB &color, int a)
|
||||||
|
{
|
||||||
|
ColorRGB c;
|
||||||
|
c.r = color.r * a;
|
||||||
|
c.g = color.g * a;
|
||||||
|
c.b = color.b * a;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplies a color with an integer
|
||||||
|
ColorRGB operator*(int a, const ColorRGB &color)
|
||||||
|
{
|
||||||
|
ColorRGB c;
|
||||||
|
c.r = color.r * a;
|
||||||
|
c.g = color.g * a;
|
||||||
|
c.b = color.b * a;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Divides a color through an integer
|
||||||
|
ColorRGB operator/(const ColorRGB &color, int a)
|
||||||
|
{
|
||||||
|
if (a == 0)
|
||||||
|
return color;
|
||||||
|
ColorRGB c;
|
||||||
|
c.r = color.r / a;
|
||||||
|
c.g = color.g / a;
|
||||||
|
c.b = color.b / a;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Are both colors equal?
|
||||||
|
bool operator==(const ColorRGB &color, const ColorRGB &color2)
|
||||||
|
{
|
||||||
|
return (color.r == color2.r && color.g == color2.g && color.b == color2.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Are both colors not equal?
|
||||||
|
bool operator!=(const ColorRGB &color, const ColorRGB &color2)
|
||||||
|
{
|
||||||
|
return (!(color.r == color2.r && color.g == color2.g && color.b == color2.b));
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorHSL::ColorHSL(Uint8 h, Uint8 s, Uint8 l)
|
||||||
|
{
|
||||||
|
this->h = h;
|
||||||
|
this->s = s;
|
||||||
|
this->l = l;
|
||||||
|
}
|
||||||
|
ColorHSL::ColorHSL()
|
||||||
|
{
|
||||||
|
this->h = 0;
|
||||||
|
this->s = 0;
|
||||||
|
this->l = 0;
|
||||||
|
}
|
||||||
|
ColorHSV::ColorHSV(Uint8 h, Uint8 s, Uint8 v)
|
||||||
|
{
|
||||||
|
this->h = h;
|
||||||
|
this->s = s;
|
||||||
|
this->v = v;
|
||||||
|
}
|
||||||
|
ColorHSV::ColorHSV()
|
||||||
|
{
|
||||||
|
this->h = 0;
|
||||||
|
this->s = 0;
|
||||||
|
this->v = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COLOR CONVERSIONS/////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert colors from one type to another
|
||||||
|
r=red g=green b=blue h=hue s=saturation l=lightness v=value
|
||||||
|
Color components from the color structs are Uint8's between 0 and 255
|
||||||
|
color components used in the calculations are normalized between 0.0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Converts an RGB color to HSL color
|
||||||
|
ColorHSL RGBtoHSL(const ColorRGB &colorRGB)
|
||||||
|
{
|
||||||
|
float r, g, b, h = 0, s = 0, l; // this function works with floats between 0 and 1
|
||||||
|
r = colorRGB.r / 256.0;
|
||||||
|
g = colorRGB.g / 256.0;
|
||||||
|
b = colorRGB.b / 256.0;
|
||||||
|
|
||||||
|
float maxColor = std::max(r, std::max(g, b));
|
||||||
|
float minColor = std::min(r, std::min(g, b));
|
||||||
|
|
||||||
|
if (minColor == maxColor) // R = G = B, so it's a shade of grey
|
||||||
|
{
|
||||||
|
h = 0; // it doesn't matter what value it has
|
||||||
|
s = 0;
|
||||||
|
l = r; // doesn't matter if you pick r, g, or b
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l = (minColor + maxColor) / 2;
|
||||||
|
|
||||||
|
if (l < 0.5)
|
||||||
|
s = (maxColor - minColor) / (maxColor + minColor);
|
||||||
|
if (l >= 0.5)
|
||||||
|
s = (maxColor - minColor) / (2.0 - maxColor - minColor);
|
||||||
|
|
||||||
|
if (r == maxColor)
|
||||||
|
h = (g - b) / (maxColor - minColor);
|
||||||
|
if (g == maxColor)
|
||||||
|
h = 2.0 + (b - r) / (maxColor - minColor);
|
||||||
|
if (b == maxColor)
|
||||||
|
h = 4.0 + (r - g) / (maxColor - minColor);
|
||||||
|
|
||||||
|
h /= 6; // to bring it to a number between 0 and 1
|
||||||
|
if (h < 0)
|
||||||
|
h += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorHSL colorHSL;
|
||||||
|
colorHSL.h = int(h * 255.0);
|
||||||
|
colorHSL.s = int(s * 255.0);
|
||||||
|
colorHSL.l = int(l * 255.0);
|
||||||
|
return colorHSL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts an HSL color to RGB color
|
||||||
|
ColorRGB HSLtoRGB(const ColorHSL &colorHSL)
|
||||||
|
{
|
||||||
|
float r, g, b, h, s, l; // this function works with floats between 0 and 1
|
||||||
|
float temp1, temp2, tempr, tempg, tempb;
|
||||||
|
h = colorHSL.h / 256.0;
|
||||||
|
s = colorHSL.s / 256.0;
|
||||||
|
l = colorHSL.l / 256.0;
|
||||||
|
|
||||||
|
// If saturation is 0, the color is a shade of grey
|
||||||
|
if (s == 0)
|
||||||
|
r = g = b = l;
|
||||||
|
// If saturation > 0, more complex calculations are needed
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// set the temporary values
|
||||||
|
if (l < 0.5)
|
||||||
|
temp2 = l * (1 + s);
|
||||||
|
else
|
||||||
|
temp2 = (l + s) - (l * s);
|
||||||
|
temp1 = 2 * l - temp2;
|
||||||
|
tempr = h + 1.0 / 3.0;
|
||||||
|
if (tempr > 1.0)
|
||||||
|
tempr--;
|
||||||
|
tempg = h;
|
||||||
|
tempb = h - 1.0 / 3.0;
|
||||||
|
if (tempb < 0.0)
|
||||||
|
tempb++;
|
||||||
|
|
||||||
|
// red
|
||||||
|
if (tempr < 1.0 / 6.0)
|
||||||
|
r = temp1 + (temp2 - temp1) * 6.0 * tempr;
|
||||||
|
else if (tempr < 0.5)
|
||||||
|
r = temp2;
|
||||||
|
else if (tempr < 2.0 / 3.0)
|
||||||
|
r = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempr) * 6.0;
|
||||||
|
else
|
||||||
|
r = temp1;
|
||||||
|
|
||||||
|
// green
|
||||||
|
if (tempg < 1.0 / 6.0)
|
||||||
|
g = temp1 + (temp2 - temp1) * 6.0 * tempg;
|
||||||
|
else if (tempg < 0.5)
|
||||||
|
g = temp2;
|
||||||
|
else if (tempg < 2.0 / 3.0)
|
||||||
|
g = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempg) * 6.0;
|
||||||
|
else
|
||||||
|
g = temp1;
|
||||||
|
|
||||||
|
// blue
|
||||||
|
if (tempb < 1.0 / 6.0)
|
||||||
|
b = temp1 + (temp2 - temp1) * 6.0 * tempb;
|
||||||
|
else if (tempb < 0.5)
|
||||||
|
b = temp2;
|
||||||
|
else if (tempb < 2.0 / 3.0)
|
||||||
|
b = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempb) * 6.0;
|
||||||
|
else
|
||||||
|
b = temp1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB colorRGB;
|
||||||
|
colorRGB.r = int(r * 255.0);
|
||||||
|
colorRGB.g = int(g * 255.0);
|
||||||
|
colorRGB.b = int(b * 255.0);
|
||||||
|
return colorRGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts an RGB color to HSV color
|
||||||
|
ColorHSV RGBtoHSV(const ColorRGB &colorRGB)
|
||||||
|
{
|
||||||
|
float r, g, b, h = 0.0, s = 0.0, v; // this function works with floats between 0 and 1
|
||||||
|
r = colorRGB.r / 256.0;
|
||||||
|
g = colorRGB.g / 256.0;
|
||||||
|
b = colorRGB.b / 256.0;
|
||||||
|
|
||||||
|
float maxColor = std::max(r, std::max(g, b));
|
||||||
|
float minColor = std::min(r, std::min(g, b));
|
||||||
|
|
||||||
|
v = maxColor;
|
||||||
|
|
||||||
|
if (maxColor != 0.0) // avoid division by zero when the color is black
|
||||||
|
{
|
||||||
|
s = (maxColor - minColor) / maxColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s == 0.0)
|
||||||
|
{
|
||||||
|
h = 0.0; // it doesn't matter what value it has
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (r == maxColor)
|
||||||
|
h = (g - b) / (maxColor - minColor);
|
||||||
|
if (g == maxColor)
|
||||||
|
h = 2.0 + (b - r) / (maxColor - minColor);
|
||||||
|
if (b == maxColor)
|
||||||
|
h = 4.0 + (r - g) / (maxColor - minColor);
|
||||||
|
|
||||||
|
h /= 6.0; // to bring it to a number between 0 and 1
|
||||||
|
if (h < 0.0)
|
||||||
|
h++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorHSV colorHSV;
|
||||||
|
colorHSV.h = int(h * 255.0);
|
||||||
|
colorHSV.s = int(s * 255.0);
|
||||||
|
colorHSV.v = int(v * 255.0);
|
||||||
|
return colorHSV;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts an HSV color to RGB color
|
||||||
|
ColorRGB HSVtoRGB(const ColorHSV &colorHSV)
|
||||||
|
{
|
||||||
|
float r, g, b, h, s, v; // this function works with floats between 0 and 1
|
||||||
|
h = colorHSV.h / 256.0;
|
||||||
|
s = colorHSV.s / 256.0;
|
||||||
|
v = colorHSV.v / 256.0;
|
||||||
|
|
||||||
|
// if saturation is 0, the color is a shade of grey
|
||||||
|
if (s == 0.0)
|
||||||
|
r = g = b = v;
|
||||||
|
// if saturation > 0, more complex calculations are needed
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float f, p, q, t;
|
||||||
|
int i;
|
||||||
|
h *= 6.0; // to bring hue to a number between 0 and 6, better for the calculations
|
||||||
|
i = int(floor(h)); // e.g. 2.7 becomes 2 and 3.01 becomes 3 or 4.9999 becomes 4
|
||||||
|
f = h - i; // the fractional part of h
|
||||||
|
|
||||||
|
p = v * (1.0 - s);
|
||||||
|
q = v * (1.0 - (s * f));
|
||||||
|
t = v * (1.0 - (s * (1.0 - f)));
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
r = v;
|
||||||
|
g = t;
|
||||||
|
b = p;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
r = q;
|
||||||
|
g = v;
|
||||||
|
b = p;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
r = p;
|
||||||
|
g = v;
|
||||||
|
b = t;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
r = p;
|
||||||
|
g = q;
|
||||||
|
b = v;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
r = t;
|
||||||
|
g = p;
|
||||||
|
b = v;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
r = v;
|
||||||
|
g = p;
|
||||||
|
b = q;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
r = g = b = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColorRGB colorRGB;
|
||||||
|
colorRGB.r = int(r * 255.0);
|
||||||
|
colorRGB.g = int(g * 255.0);
|
||||||
|
colorRGB.b = int(b * 255.0);
|
||||||
|
return colorRGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint32 RGBtoINT(const ColorRGB &colorRGB)
|
||||||
|
{
|
||||||
|
return 65536 * colorRGB.r + 256 * colorRGB.g + colorRGB.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB INTtoRGB(Uint32 colorINT)
|
||||||
|
{
|
||||||
|
ColorRGB colorRGB;
|
||||||
|
colorRGB.r = (colorINT / 65536) % 256;
|
||||||
|
colorRGB.g = (colorINT / 256) % 256;
|
||||||
|
colorRGB.b = colorINT % 256;
|
||||||
|
return colorRGB;
|
||||||
|
}
|
||||||
|
}
|
||||||
189
quickcg.h
Normal file
189
quickcg.h
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
QuickCG 20191227
|
||||||
|
|
||||||
|
Copyright (c) 2004-2019, Lode Vandevenne
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
QuickCG is an SDL 1.2 codebase that wraps some of the SDL 1.2 functionality.
|
||||||
|
It's used by Lode's Computer Graphics Tutorial to work with simple function calls
|
||||||
|
to demonstrate graphical programs. It may or may not be of industrial strength
|
||||||
|
for games, though I've actually used it for some.
|
||||||
|
|
||||||
|
QuickCG can handle some things that standard C++ does not but that are useful, such as:
|
||||||
|
-drawing graphics
|
||||||
|
-a bitmap font
|
||||||
|
-simplified saving and loading of files
|
||||||
|
-reading keyboard and mouse input
|
||||||
|
-playing sound
|
||||||
|
-color models
|
||||||
|
-loading images
|
||||||
|
|
||||||
|
Contact info:
|
||||||
|
My email address is (puzzle the account and domain together with an @ symbol):
|
||||||
|
Domain: gmail dot com.
|
||||||
|
Account: lode dot vandevenne.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _quickcg_h_included
|
||||||
|
#define _quickcg_h_included
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> //std::min and std::max
|
||||||
|
|
||||||
|
namespace QuickCG
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// useful templates//////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// don't know why, but the standard C++ abs sometimes gives cryptic errors? if so use this :D
|
||||||
|
template <typename T>
|
||||||
|
const T template_abs(const T &a)
|
||||||
|
{
|
||||||
|
return (a < 0) ? -a : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// usage: std::string str = valtostr(25454.91654654f);
|
||||||
|
template <typename T>
|
||||||
|
std::string valtostr(const T &val)
|
||||||
|
{
|
||||||
|
std::ostringstream sstream;
|
||||||
|
sstream << val;
|
||||||
|
return sstream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// usage: double val = strtoval<double>("465498.654");
|
||||||
|
template <typename T>
|
||||||
|
T strtoval(const std::string &s)
|
||||||
|
{
|
||||||
|
std::istringstream sstream(s);
|
||||||
|
T val;
|
||||||
|
sstream >> val;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// length is decimal precision of the floating point number
|
||||||
|
template <typename T>
|
||||||
|
std::string valtostr(const T &val, int length, bool fixed = true)
|
||||||
|
{
|
||||||
|
std::ostringstream sstream;
|
||||||
|
if (fixed)
|
||||||
|
sstream << std::fixed;
|
||||||
|
sstream << std::setprecision(length) << val;
|
||||||
|
return sstream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COLOR STRUCTS/////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct ColorRGB8bit;
|
||||||
|
// a color with 3 components: r, g and b
|
||||||
|
struct ColorRGB
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
int g;
|
||||||
|
int b;
|
||||||
|
|
||||||
|
ColorRGB(Uint8 r, Uint8 g, Uint8 b);
|
||||||
|
ColorRGB(const ColorRGB8bit &color);
|
||||||
|
ColorRGB();
|
||||||
|
};
|
||||||
|
|
||||||
|
ColorRGB operator+(const ColorRGB &color, const ColorRGB &color2);
|
||||||
|
ColorRGB operator-(const ColorRGB &color, const ColorRGB &color2);
|
||||||
|
ColorRGB operator*(const ColorRGB &color, int a);
|
||||||
|
ColorRGB operator*(int a, const ColorRGB &color);
|
||||||
|
ColorRGB operator/(const ColorRGB &color, int a);
|
||||||
|
bool operator==(const ColorRGB &color, const ColorRGB &color2);
|
||||||
|
bool operator!=(const ColorRGB &color, const ColorRGB &color2);
|
||||||
|
|
||||||
|
static const ColorRGB RGB_Black(0, 0, 0);
|
||||||
|
static const ColorRGB RGB_Red(255, 0, 0);
|
||||||
|
static const ColorRGB RGB_Green(0, 255, 0);
|
||||||
|
static const ColorRGB RGB_Blue(0, 0, 255);
|
||||||
|
static const ColorRGB RGB_Cyan(0, 255, 255);
|
||||||
|
static const ColorRGB RGB_Magenta(255, 0, 255);
|
||||||
|
static const ColorRGB RGB_Yellow(255, 255, 0);
|
||||||
|
static const ColorRGB RGB_White(255, 255, 255);
|
||||||
|
static const ColorRGB RGB_Gray(128, 128, 128);
|
||||||
|
static const ColorRGB RGB_Grey(192, 192, 192);
|
||||||
|
static const ColorRGB RGB_Maroon(128, 0, 0);
|
||||||
|
static const ColorRGB RGB_Darkgreen(0, 128, 0);
|
||||||
|
static const ColorRGB RGB_Navy(0, 0, 128);
|
||||||
|
static const ColorRGB RGB_Teal(0, 128, 128);
|
||||||
|
static const ColorRGB RGB_Purple(128, 0, 128);
|
||||||
|
static const ColorRGB RGB_Olive(128, 128, 0);
|
||||||
|
|
||||||
|
// a color with 3 components: r, g and b
|
||||||
|
struct ColorRGB8bit
|
||||||
|
{
|
||||||
|
Uint8 r;
|
||||||
|
Uint8 g;
|
||||||
|
Uint8 b;
|
||||||
|
|
||||||
|
ColorRGB8bit(Uint8 r, Uint8 g, Uint8 b);
|
||||||
|
ColorRGB8bit(const ColorRGB &color);
|
||||||
|
ColorRGB8bit();
|
||||||
|
};
|
||||||
|
|
||||||
|
// a color with 3 components: h, s and l
|
||||||
|
struct ColorHSL
|
||||||
|
{
|
||||||
|
int h;
|
||||||
|
int s;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
ColorHSL(Uint8 h, Uint8 s, Uint8 l);
|
||||||
|
ColorHSL();
|
||||||
|
};
|
||||||
|
|
||||||
|
// a color with 3 components: h, s and v
|
||||||
|
struct ColorHSV
|
||||||
|
{
|
||||||
|
int h;
|
||||||
|
int s;
|
||||||
|
int v;
|
||||||
|
|
||||||
|
ColorHSV(Uint8 h, Uint8 s, Uint8 v);
|
||||||
|
ColorHSV();
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COLOR CONVERSIONS/////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
ColorHSL RGBtoHSL(const ColorRGB &colorRGB);
|
||||||
|
ColorRGB HSLtoRGB(const ColorHSL &colorHSL);
|
||||||
|
ColorHSV RGBtoHSV(const ColorRGB &colorRGB);
|
||||||
|
ColorRGB HSVtoRGB(const ColorHSV &colorHSV);
|
||||||
|
Uint32 RGBtoINT(const ColorRGB &colorRGB);
|
||||||
|
ColorRGB INTtoRGB(Uint32 colorINT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user