1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#include "../include/RoundedRectangle.hpp"
#include <SFML/Graphics/Shader.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <assert.h>
namespace QuickMedia {
RoundedRectangle::RoundedRectangle(sf::Vector2f size, float radius, sf::Color color, sf::Shader *rounded_rectangle_shader) :
radius(radius), pos(0.0f, 0.0f), size(size), rounded_rectangle_shader(rounded_rectangle_shader), band_color(sf::Color::Transparent)
{
assert(rounded_rectangle_shader);
set_color(color);
vertices[0].texCoords = sf::Vector2f(0.0f, 0.0f);
vertices[1].texCoords = sf::Vector2f(1.0f, 0.0f);
vertices[2].texCoords = sf::Vector2f(1.0f, 1.0f);
vertices[3].texCoords = sf::Vector2f(0.0f, 1.0f);
const sf::Color shadow_color(0, 0, 0, 50);
// Sides
for(size_t i = 0; i < 16; i += 4) {
drop_shadow_vertices[i + 0].color = sf::Color(shadow_color.r, shadow_color.g, shadow_color.b, 0);
drop_shadow_vertices[i + 1].color = sf::Color(shadow_color.r, shadow_color.g, shadow_color.b, 0);
drop_shadow_vertices[i + 2].color = shadow_color;
drop_shadow_vertices[i + 3].color = shadow_color;
}
// Corners
for(size_t i = 16; i < 32; i += 4) {
drop_shadow_vertices[i + 0].color = sf::Color(shadow_color.r, shadow_color.g, shadow_color.b, 0);
drop_shadow_vertices[i + 1].color = sf::Color(shadow_color.r, shadow_color.g, shadow_color.b, 0);
drop_shadow_vertices[i + 2].color = sf::Color(shadow_color.r, shadow_color.g, shadow_color.b, 0);
drop_shadow_vertices[i + 3].color = sf::Color(shadow_color.r, shadow_color.g, shadow_color.b, 100);
}
}
void RoundedRectangle::set_position(sf::Vector2f pos) {
this->pos = pos;
vertices[0].position = pos;
vertices[1].position = pos + sf::Vector2f(size.x, 0.0f);
vertices[2].position = pos + sf::Vector2f(size.x, size.y);
vertices[3].position = pos + sf::Vector2f(0.0f, size.y);
const float shadow_radius = 5.0f;
// Top
drop_shadow_vertices[0].position = pos + sf::Vector2f(radius*0.5f, 0.0f) - sf::Vector2f(0.0f, shadow_radius);
drop_shadow_vertices[1].position = pos + sf::Vector2f(size.x - radius*0.5f, 0.0f) - sf::Vector2f(0.0f, shadow_radius);
drop_shadow_vertices[2].position = pos + sf::Vector2f(size.x - radius*0.5f, 0.0f);
drop_shadow_vertices[3].position = pos + sf::Vector2f(radius*0.5f, 0.0f);
// Bottom
drop_shadow_vertices[4].position = pos + sf::Vector2f(size.x - radius*0.5f, size.y + shadow_radius);
drop_shadow_vertices[5].position = pos + sf::Vector2f(radius*0.5f, size.y + shadow_radius);
drop_shadow_vertices[6].position = pos + sf::Vector2f(radius*0.5f, size.y);
drop_shadow_vertices[7].position = pos + sf::Vector2f(size.x - radius*0.5f, size.y);
// Left
drop_shadow_vertices[8].position = pos + sf::Vector2f(-shadow_radius, size.y - radius*0.5f);
drop_shadow_vertices[9].position = pos + sf::Vector2f(-shadow_radius, radius*0.5f);
drop_shadow_vertices[10].position = pos + sf::Vector2f(0.0f, radius*0.5f);
drop_shadow_vertices[11].position = pos + sf::Vector2f(0.0f, size.y - radius*0.5f);
// Right
drop_shadow_vertices[12].position = pos + sf::Vector2f(size.x + shadow_radius, radius*0.5f);
drop_shadow_vertices[13].position = pos + sf::Vector2f(size.x + shadow_radius, size.y - radius*0.5f);
drop_shadow_vertices[14].position = pos + sf::Vector2f(size.x, size.y - radius*0.5f);
drop_shadow_vertices[15].position = pos + sf::Vector2f(size.x, radius*0.5f);
const float overshoot = 1.7f;
// Top left
drop_shadow_vertices[16].position = pos + sf::Vector2f(-shadow_radius, radius*0.5f);
drop_shadow_vertices[17].position = pos + sf::Vector2f(-shadow_radius*overshoot, -shadow_radius*overshoot);
drop_shadow_vertices[18].position = pos + sf::Vector2f(radius*0.5f, -shadow_radius);
drop_shadow_vertices[19].position = pos + sf::Vector2f(radius*0.5f, radius*0.5f);
// Top right
drop_shadow_vertices[20].position = pos + sf::Vector2f(size.x - radius*0.5f, -shadow_radius);
drop_shadow_vertices[21].position = pos + sf::Vector2f(size.x + shadow_radius*overshoot, -shadow_radius*overshoot);
drop_shadow_vertices[22].position = pos + sf::Vector2f(size.x + shadow_radius, radius*0.5f);
drop_shadow_vertices[23].position = pos + sf::Vector2f(size.x - radius*0.5f, radius*0.5f);
// Bottom right
drop_shadow_vertices[24].position = pos + sf::Vector2f(size.x + shadow_radius, size.y - radius*0.5f);
drop_shadow_vertices[25].position = pos + sf::Vector2f(size.x + shadow_radius*overshoot, size.y + shadow_radius*overshoot);
drop_shadow_vertices[26].position = pos + sf::Vector2f(size.x - radius*0.5f, size.y + shadow_radius);
drop_shadow_vertices[27].position = pos + sf::Vector2f(size.x - radius*0.5f, size.y - radius*0.5f);
// Bottom left
drop_shadow_vertices[28].position = pos + sf::Vector2f(radius*0.5f, size.y + shadow_radius);
drop_shadow_vertices[29].position = pos + sf::Vector2f(-shadow_radius*overshoot, size.y + shadow_radius*overshoot);
drop_shadow_vertices[30].position = pos + sf::Vector2f(-shadow_radius, size.y - radius*0.5f);
drop_shadow_vertices[31].position = pos + sf::Vector2f(radius*0.5f, size.y - radius*0.5f);
}
void RoundedRectangle::set_size(sf::Vector2f size) {
this->size = size;
set_position(pos);
}
void RoundedRectangle::set_color(sf::Color color) {
for(size_t i = 0; i < 4; ++i)
vertices[i].color = color;
}
sf::Vector2f RoundedRectangle::get_position() const {
return pos;
}
sf::Vector2f RoundedRectangle::get_size() const {
return size;
}
void RoundedRectangle::set_band(sf::Vector2f pos, sf::Vector2f size) {
band_pos = pos;
band_size = size;
}
void RoundedRectangle::set_band_color(sf::Color color) {
band_color = color;
}
void RoundedRectangle::draw(sf::RenderTarget &target) {
if(drop_shadow_enabled)
target.draw(drop_shadow_vertices, 32, sf::Quads);
// TODO: Remove these for optimizations. Also do the same in other places where setUniform is called
rounded_rectangle_shader->setUniform("radius", radius);
rounded_rectangle_shader->setUniform("band_pos", band_pos);
rounded_rectangle_shader->setUniform("band_size", band_size);
rounded_rectangle_shader->setUniform("band_color", sf::Glsl::Vec4(band_color.r/255.0f, band_color.g/255.0f, band_color.b/255.0f, band_color.a/255.0f));
rounded_rectangle_shader->setUniform("resolution", size);
target.draw(vertices, 4, sf::Quads, rounded_rectangle_shader);
}
}
|