Importing shaders from task
This commit is contained in:
parent
69d3a747fe
commit
81295e0514
@ -12,4 +12,5 @@ add_executable(
|
||||
src/Frame.h
|
||||
src/main.cpp
|
||||
src/Painter.h
|
||||
src/shaders.cpp
|
||||
)
|
160
src/shaders.cpp
Normal file
160
src/shaders.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include "Painter.h"
|
||||
|
||||
template <class ShaderClass>
|
||||
void Triangle(float x0, float y0, float x1, float y1, float x2, float y2, COLOR color, ShaderClass &shader)
|
||||
{
|
||||
// Отсортируем точки таким образом, чтобы выполнилось условие: y0 < y1 < y2
|
||||
if (y1 < y0)
|
||||
{
|
||||
swap(y1, y0);
|
||||
swap(x1, x0);
|
||||
}
|
||||
if (y2 < y1)
|
||||
{
|
||||
swap(y2, y1);
|
||||
swap(x2, x1);
|
||||
}
|
||||
if (y1 < y0)
|
||||
{
|
||||
swap(y1, y0);
|
||||
swap(x1, x0);
|
||||
}
|
||||
// Определяем номера строк пикселей, в которых располагаются точки треугольника
|
||||
int Y0 = (int) (y0 + 0.5f);
|
||||
int Y1 = (int) (y1 + 0.5f);
|
||||
int Y2 = (int) (y2 + 0.5f);
|
||||
// Отсечение невидимой части треугольника
|
||||
if (Y0 < 0) Y0 = 0;
|
||||
else if (Y0 >= height) Y0 = height;
|
||||
if (Y1 < 0) Y1 = 0;
|
||||
else if (Y1 >= height) Y1 = height;
|
||||
if (Y2 < 0) Y2 = 0;
|
||||
else if (Y2 >= height) Y2 = height;
|
||||
// Рисование верхней части треугольника
|
||||
for (float y = Y0 + 0.5f; y < Y1; y++)
|
||||
{
|
||||
int X0 = (int) ((y - y0) / (y1 - y0) * (x1 - x0) + x0 + 0.5f);
|
||||
int X1 = (int) ((y - y0) / (y2 - y0) * (x2 - x0) + x0 + 0.5f);
|
||||
if (X0 > X1) swap(X0, X1);
|
||||
if (X0 < 0) X0 = 0;
|
||||
if (X1 > width) X1 = width;
|
||||
for (int x = X0; x < X1; x++)
|
||||
{
|
||||
// f(x + 0.5, y)
|
||||
SetPixel(x, y, shader.getColor(x + 0.5f, y));
|
||||
}
|
||||
}
|
||||
// Рисование нижней части треугольника
|
||||
for (float y = Y1 + 0.5f; y < Y2; y++)
|
||||
{
|
||||
int X0 = (int)((y - y1) / (y2 - y1) * (x2 - x1) + x1 + 0.5f);
|
||||
int X1 = (int)((y - y0) / (y2 - y0) * (x2 - x0) + x0 + 0.5f);
|
||||
if (X0 > X1) swap(X0, X1);
|
||||
if (X0 < 0) X0 = 0;
|
||||
if (X1 > width) X1 = width;
|
||||
for (int x = X0; x < X1; x++)
|
||||
{
|
||||
// f(x + 0.5, y)
|
||||
SetPixel(x, y, shader.getColor(x + 0.5f, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BarycentricInterpolator
|
||||
{
|
||||
float x0, y0, x1, y1, x2, y2, S;
|
||||
COLOR C0, C1, C2;
|
||||
public:
|
||||
BarycentricInterpolator(float _x0, float _y0, float _x1, float _y1, float
|
||||
_x2, float _y2, COLOR A0, COLOR A1, COLOR A2) :
|
||||
x0(_x0), y0(_y0), x1(_x1), y1(_y1), x2(_x2), y2(_y2),
|
||||
S((_y1 - _y2)*(_x0 - _x2) + (_x2 - _x1)*(_y0 - _y2)), C0(A0), C1(A1),
|
||||
C2(A2)
|
||||
{
|
||||
}
|
||||
COLOR getColor(float x, float y)
|
||||
{
|
||||
// Барицентрическая интерполяция
|
||||
float h0 = ((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2)) / S;
|
||||
float h1 = ((y2 - y0) * (x - x2) + (x0 - x2) * (y - y2)) / S;
|
||||
float h2 = 1 - h0 - h1;
|
||||
float r = h0 * C0.RED + h1 * C1.RED + h2 * C2.RED;
|
||||
float g = h0 * C0.GREEN + h1 * C1.GREEN + h2 * C2.GREEN;
|
||||
float b = h0 * C0.BLUE + h1 * C1.BLUE + h2 * C2.BLUE;
|
||||
float a = h0 * C0.ALPHA + h1 * C1.ALPHA + h2 * C2.ALPHA;
|
||||
return COLOR(r, g, b, a);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class RadialBrush
|
||||
{
|
||||
float cx, cy; // Центр прямоугольника
|
||||
COLOR C0, C1; // Цвета радиальной заливки
|
||||
float angle; // Начальный угол заливки
|
||||
public:
|
||||
RadialBrush (float _x0, float _y0, float _x1, float _y1, COLOR A0, COLOR A1, float
|
||||
_angle) :
|
||||
cx((_x0 + _x1) / 2.0f), cy((_y0 + _y1)/ 2.0f),
|
||||
C0(A0), C1(A1), angle(_angle)
|
||||
{
|
||||
}
|
||||
COLOR getColor(float x, float y)
|
||||
{
|
||||
double dx = (double)x - cx, dy = (double)y - cy;
|
||||
double radius = sqrt(dx*dx + dy*dy);
|
||||
float h0 = (sin(radius / 10 + angle) + 1.0f) / 2;
|
||||
float h1 = 1 - h0;
|
||||
float r = h0 * C0.RED + h1 * C1.RED;
|
||||
float g = h0 * C0.GREEN + h1 * C1.GREEN;
|
||||
float b = h0 * C0.BLUE + h1 * C1.BLUE;
|
||||
return COLOR(r, g, b);
|
||||
}
|
||||
};
|
||||
|
||||
void ColorFromHSV(double hue, double saturation, double value, GLint *color)
|
||||
{
|
||||
int hi = int(floor(hue / 60)) % 6;
|
||||
double f = hue / 60 - floor(hue / 60);
|
||||
value = value * 255;
|
||||
int v = (int)(value);
|
||||
int p = (int)(value * (1 - saturation));
|
||||
int q = (int)(value * (1 - f * saturation));
|
||||
int t = (int)(value * (1 - (1 - f) * saturation));
|
||||
if (hi == 0)
|
||||
{
|
||||
color[0] = v;
|
||||
color[1] = t;
|
||||
color[2] = p;
|
||||
}
|
||||
else if (hi == 1)
|
||||
{
|
||||
color[0] = q;
|
||||
color[1] = v;
|
||||
color[2] = p;
|
||||
}
|
||||
else if (hi == 2)
|
||||
{
|
||||
color[0] = p;
|
||||
color[1] = v;
|
||||
color[2] = t;
|
||||
}
|
||||
else if (hi == 3)
|
||||
{
|
||||
color[0] = p;
|
||||
color[1] = q;
|
||||
color[2] = v;
|
||||
}
|
||||
else if (hi == 4)
|
||||
{
|
||||
color[0] = t;
|
||||
color[1] = p;
|
||||
color[2] = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
color[0] = v;
|
||||
color[1] = p;
|
||||
color[2] = q;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user