demo: Añadido efecto de fuego en el fondo
This commit is contained in:
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user