Skip to content

Commit d6d0cf2

Browse files
committed
Keys: improve rendering, add edges to minor keys (#130).
1 parent 9a39045 commit d6d0cf2

File tree

12 files changed

+277
-120
lines changed

12 files changed

+277
-120
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build/
2+
build*/
23
.DS_Store
34
.thumb
45
ext/

resources/shaders/keys.frag

-84
This file was deleted.

resources/shaders/majorKeys.frag

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#version 330
2+
3+
in INTERFACE {
4+
vec2 uv;
5+
} In ;
6+
7+
#define SETS_COUNT 8
8+
#define MAJOR_COUNT 75
9+
10+
uniform bool highlightKeys;
11+
uniform bool horizontalMode = false;
12+
uniform float notesCount; // (maxNoteMajor - minNoteMajor + 1)
13+
uniform int actives[128];
14+
uniform int minNoteMajor;
15+
uniform vec2 inverseScreenSize;
16+
uniform vec3 edgeColor = vec3(0.0);
17+
18+
uniform vec3 majorColor[SETS_COUNT];
19+
20+
const int majorIds[MAJOR_COUNT] = int[](0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105, 107, 108, 110, 112, 113, 115, 117, 119, 120, 122, 124, 125, 127);
21+
22+
out vec4 fragColor;
23+
24+
25+
void main(){
26+
27+
// White keys, and separators.
28+
float widthScaling = horizontalMode ? inverseScreenSize.y : inverseScreenSize.x;
29+
float majorUvX = fract(In.uv.x * notesCount);
30+
31+
// Edges on the sides
32+
float centerIntensity = 1.0 - step( 1.0 - 2.0 * notesCount * widthScaling, abs(majorUvX * 2.0 - 1.0));
33+
34+
// If the current major key is active, the majorColor is specific.
35+
int majorId = majorIds[clamp(int(In.uv.x * notesCount) + minNoteMajor, 0, 74)];
36+
int cidMajor = actives[majorId];
37+
vec3 frontColor = (highlightKeys && cidMajor >= 0) ? majorColor[cidMajor] : vec3(1.0);
38+
39+
// Mix.
40+
fragColor.rgb = mix(edgeColor, frontColor, centerIntensity);
41+
fragColor.a = 1.0;
42+
}

resources/shaders/keys.vert resources/shaders/majorKeys.vert

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ out INTERFACE {
66
vec2 uv;
77
} Out ;
88

9-
uniform float keyboardHeight = 0.25;
109
uniform bool horizontalMode = false;
10+
uniform float keyboardHeight = 0.25;
1111

1212
vec2 flipIfNeeded(vec2 inPos){
1313
return horizontalMode ? vec2(inPos.y, -inPos.x) : inPos;
@@ -16,10 +16,10 @@ vec2 flipIfNeeded(vec2 inPos){
1616
void main(){
1717
// Input are in -0.5,0.5
1818
// We directly output the position.
19-
// [-0.5, 0.5] to [-1, 2.0*keyboardHeight-1.0]
19+
// [-0.5, 0.5] to [-1, -1+2.0*keyboardHeight]
2020
float yShift = keyboardHeight * (2.0 * v.y + 1.0) - 1.0;
2121

22-
vec2 pos2D = vec2(v.x*2.0, yShift);
22+
vec2 pos2D = vec2(v.x * 2.0, yShift);
2323

2424
gl_Position.xy = flipIfNeeded(pos2D);
2525
gl_Position.zw = vec2(0.0, 1.0);

resources/shaders/minorKeys.frag

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#version 330
2+
3+
in INTERFACE {
4+
vec2 uv;
5+
float id;
6+
} In ;
7+
8+
#define SETS_COUNT 8
9+
10+
uniform bool highlightKeys;
11+
uniform bool horizontalMode = false;
12+
uniform float keyboardHeight = 0.25;
13+
uniform float notesCount; // (maxNoteMajor - minNoteMajor + 1)
14+
uniform int minNoteMajor;
15+
uniform vec2 inverseScreenSize;
16+
uniform vec3 edgeColor = vec3(0.0);
17+
18+
uniform vec3 minorColor[SETS_COUNT];
19+
uniform bool edgeOnMinors;
20+
uniform float minorsHeight = 0.6;
21+
uniform float minorsWidth = 1.0;
22+
23+
vec2 minorShift(int id){
24+
if(id == 1 || id == 6){
25+
return vec2(0.0, 0.3);
26+
}
27+
if(id == 3 || id == 10){
28+
return vec2(0.3, 0.0);
29+
}
30+
return vec2(0.1,0.1);
31+
}
32+
33+
out vec4 fragColor;
34+
35+
36+
void main(){
37+
38+
// Center uvs
39+
vec2 ndc = 2.0 * In.uv - 1.0;
40+
41+
float widthScaling = horizontalMode ? inverseScreenSize.y : inverseScreenSize.x;
42+
float heightScaling = horizontalMode ? inverseScreenSize.x : inverseScreenSize.y;
43+
float uvWidth = minorsWidth / float(notesCount) * 0.5;
44+
float uvHeight = minorsHeight * keyboardHeight * 0.5;
45+
46+
// Edges on the sides and bottom.
47+
float xStep = step(1.0 - 2.0 * widthScaling / uvWidth, abs(ndc.x));
48+
float yStep = step(1.0 - 2.0 * heightScaling / uvHeight, -ndc.y);
49+
float centerIntensity = edgeOnMinors ? ((1.0 - xStep) * (1.0 - yStep)) : 1.0;
50+
51+
// Key color changes when active.
52+
int cidMinor = int(In.id);
53+
vec3 frontColor = (highlightKeys && cidMinor >= 0) ? minorColor[cidMinor] : edgeColor;
54+
55+
// Mix
56+
fragColor.rgb = mix(edgeColor, frontColor, centerIntensity);
57+
fragColor.a = 1.0;
58+
}

resources/shaders/minorKeys.vert

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#version 330
2+
3+
layout(location = 0) in vec2 v;
4+
5+
out INTERFACE {
6+
vec2 uv;
7+
float id;
8+
} Out ;
9+
10+
uniform bool horizontalMode = false;
11+
uniform float keyboardHeight = 0.25;
12+
uniform float notesCount; // (maxNoteMajor - minNoteMajor + 1)
13+
uniform int actives[128];
14+
uniform int minNoteMajor;
15+
16+
uniform float minorsHeight = 0.6;
17+
uniform float minorsWidth = 1.0;
18+
19+
vec2 flipIfNeeded(vec2 inPos){
20+
return horizontalMode ? vec2(inPos.y, -inPos.x) : inPos;
21+
}
22+
23+
#define MINOR_COUNT 53
24+
25+
const int minorIds[MINOR_COUNT] = int[](1, 3, 6, 8, 10, 13, 15, 18, 20, 22, 25, 27, 30, 32, 34, 37, 39, 42, 44, 46, 49, 51, 54, 56, 58, 61, 63, 66, 68, 70, 73, 75, 78, 80, 82, 85, 87, 90, 92, 94, 97, 99, 102, 104, 106, 109, 111, 114, 116, 118, 121, 123, 126);
26+
27+
const int noteDelta[12] = int[](0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6);
28+
29+
30+
float minorShift(int id){
31+
if(id == 1 || id == 6){
32+
return -0.1;
33+
}
34+
if(id == 3 || id == 10){
35+
return 0.1;
36+
}
37+
return 0.0;
38+
}
39+
40+
void main(){
41+
42+
float noteWidth = 2.0 / notesCount;
43+
// Size of the note : width, height based on duration and current speed.
44+
vec2 noteSize = vec2(0.9 * noteWidth * minorsWidth, 2.0 * minorsHeight * keyboardHeight);
45+
46+
// Compute note shift.
47+
// Horizontal shift based on note id, width of keyboard, and if the note is minor or not.
48+
//float a = (1.0/(notesCount-1.0)) * (2.0 - 2.0/notesCount);
49+
//float b = -1.0 + 1.0/notesCount;
50+
// This should be in -1.0, 1.0.
51+
// input: noteId is in [0 MAJOR_COUNT]
52+
// we want minNote to -1+1/c, maxNote to 1-1/c
53+
float a = 2.0;
54+
float b = -notesCount + 1.0 - 2.0 * float(minNoteMajor);
55+
56+
int minorId = minorIds[gl_InstanceID];
57+
int noteId = (minorId/12) * 7 + noteDelta[minorId % 12];
58+
float horizLoc = (float(noteId) * a + b + 1.0) / notesCount;
59+
60+
float vertLoc = 2.0 * (1.0 - minorsHeight) * keyboardHeight - 1.0 + noteSize.y * 0.5;
61+
vec2 noteShift = vec2(horizLoc, vertLoc);
62+
63+
noteShift.x += minorShift(minorId % 12) * noteSize.x;
64+
65+
// Output position.
66+
gl_Position = vec4(flipIfNeeded(noteSize * v + noteShift), 0.0 , 1.0) ;
67+
68+
// Discard keys that are too close to the screen edges.
69+
if(abs(noteShift.x) >= 1.0 - 0.5 * noteWidth){
70+
gl_Position = vec4(-40000.0);
71+
}
72+
73+
// Output the UV coordinates computed from the positions.
74+
Out.uv = v.xy + 0.5;
75+
// And the active channel if present.
76+
Out.id = float(actives[minorId]);
77+
78+
}

src/packager.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int main( int argc, char** argv) {
3838
const std::string outputDir = baseDir + "/src/resources/";
3939

4040
std::vector<std::string> imagesToLoad = { "flash", "font", "particles"};
41-
std::vector<std::string> shadersToLoad = { "background", "flashes", "notes", "particles", "particlesblur", "screenquad", "keys", "backgroundtexture", "pedal", "wave", "fxaa"};
41+
std::vector<std::string> shadersToLoad = { "background", "flashes", "notes", "particles", "particlesblur", "screenquad", "majorKeys", "minorKeys", "backgroundtexture", "pedal", "wave", "fxaa"};
4242

4343
// Header file.
4444
std::ofstream headerFile(outputDir + "data.h");

src/rendering/Renderer.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ void Renderer::showParticleOptions(){
812812

813813
void Renderer::showKeyboardOptions(){
814814
ImGuiPushItemWidth(25);
815-
if (ImGui::ColorEdit3("Color##Keys", &_state.background.keysColor[0], ImGuiColorEditFlags_NoInputs)) {
815+
if (ImGui::ColorEdit3("Fill Color##Keys", &_state.background.keysColor[0], ImGuiColorEditFlags_NoInputs)) {
816816
_score->setColors(_state.background.linesColor, _state.background.textColor, _state.background.keysColor);
817817
}
818818
ImGui::PopItemWidth();
@@ -827,6 +827,20 @@ void Renderer::showKeyboardOptions(){
827827
}
828828
ImGui::PopItemWidth();
829829

830+
ImGuiPushItemWidth(25);
831+
if (ImGui::Checkbox("Minor edges##Keys", &_state.keyboard.minorEdges)){
832+
_scene->setMinorEdgesAndHeight(_state.keyboard.minorEdges, _state.keyboard.minorHeight);
833+
}
834+
ImGui::PopItemWidth();
835+
ImGuiSameLine(COLUMN_SIZE);
836+
837+
ImGuiPushItemWidth(100);
838+
if(ImGuiSliderPercent("Minor height##Keys", &_state.keyboard.minorHeight, 0.0f, 1.0f)){
839+
_state.keyboard.minorHeight = glm::clamp(_state.keyboard.minorHeight, 0.0f, 1.0f);
840+
_scene->setMinorEdgesAndHeight(_state.keyboard.minorEdges, _state.keyboard.minorHeight);
841+
}
842+
ImGui::PopItemWidth();
843+
830844
ImGui::Checkbox("Highlight keys", &_state.keyboard.highlightKeys);
831845

832846
if (_state.keyboard.highlightKeys) {
@@ -1388,6 +1402,7 @@ void Renderer::applyAllSettings() {
13881402
_score->setDisplay(_state.background.digits, _state.background.hLines, _state.background.vLines);
13891403
_score->setColors(_state.background.linesColor, _state.background.textColor, _state.background.keysColor);
13901404
_scene->setKeyboardSizeAndFadeout(_state.keyboard.size, _state.notesFadeOut);
1405+
_scene->setMinorEdgesAndHeight(_state.keyboard.minorEdges, _state.keyboard.minorHeight);
13911406
_score->setKeyboardSize(_state.keyboard.size);
13921407
_score->setPlayDirection(_state.reverseScroll);
13931408

src/rendering/State.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ void State::defineOptions(){
9797
_sharedInfos["bg-img-behind-keyboard"] = {"Should the background image extend behind the keyboard", OptionInfos::Type::BOOLEAN};
9898
_sharedInfos["keyboard-highlight"] = {"Should the pressed keys be highlighted", OptionInfos::Type::BOOLEAN};
9999
_sharedInfos["keyboard-custom-colors"] = {"Override notes color for pressed keys", OptionInfos::Type::BOOLEAN};
100+
_sharedInfos["keyboard-minor-edges"] = {"Show edges around minor keys", OptionInfos::Type::BOOLEAN};
100101
_sharedInfos["show-score"] = {"Should the score (lines, numbers) be shown", OptionInfos::Type::BOOLEAN};
101102
_sharedInfos["show-bg-img"] = {"Use a background texture", OptionInfos::Type::BOOLEAN};
102103
_sharedInfos["show-notes"] = {"Should the notes be shown", OptionInfos::Type::BOOLEAN};
@@ -159,7 +160,7 @@ void State::defineOptions(){
159160
_sharedInfos["sets-separator-key"].category = OptionInfos::Category::SETS;
160161

161162
_sharedInfos["keyboard-size"] = {"Vertical size of the keyboard", OptionInfos::Type::FLOAT, {0.0f, 1.0f}};
162-
163+
_sharedInfos["keyboard-minor-height"] = {"Vertical fraction of the keyboard taken by minor keys", OptionInfos::Type::FLOAT, {0.0f, 1.0f}};
163164

164165
_sharedInfos["min-key"] = {"Lowest key to display", OptionInfos::Type::KEY, {0.0f, 127.0f}};
165166
_sharedInfos["max-key"] = {"Highest key to display", OptionInfos::Type::KEY, {0.0f, 127.0f}};
@@ -241,6 +242,7 @@ void State::updateOptions(){
241242
_boolInfos["bg-img-behind-keyboard"] = &background.imageBehindKeyboard;
242243
_boolInfos["keyboard-highlight"] = &keyboard.highlightKeys;
243244
_boolInfos["keyboard-custom-colors"] = &keyboard.customKeyColors;
245+
_boolInfos["keyboard-minor-edges"] = &keyboard.minorEdges;
244246
_boolInfos["show-score"] = &showScore;
245247
_boolInfos["show-bg-img"] = &background.image;
246248
_boolInfos["show-notes"] = &showNotes;
@@ -278,6 +280,7 @@ void State::updateOptions(){
278280
_intInfos["sets-mode"] = (int*)&setOptions.mode;
279281
_intInfos["sets-separator-key"] = &setOptions.key;
280282
_floatInfos["keyboard-size"] = &keyboard.size;
283+
_floatInfos["keyboard-minor-height"] = &keyboard.minorHeight;
281284

282285
_intInfos["min-key"] = &minKey;
283286
_intInfos["max-key"] = &maxKey;
@@ -592,8 +595,10 @@ void State::reset(){
592595
scrollSpeed = 1.0f;
593596
notesFadeOut = 0.0f;
594597
keyboard.highlightKeys = true;
598+
keyboard.minorEdges = true;
595599
keyboard.customKeyColors = false;
596600
keyboard.size = 0.25f;
601+
keyboard.minorHeight = 0.6f;
597602

598603
for (int i = 0; i < layersMap.size(); ++i) {
599604
layersMap[i] = i;

0 commit comments

Comments
 (0)