Skip to content

Commit

Permalink
Score: center labels on lines, improve exposed settings.
Browse files Browse the repository at this point in the history
  • Loading branch information
kosua20 committed Aug 15, 2023
1 parent 68cdd44 commit 88dff14
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 23 deletions.
10 changes: 4 additions & 6 deletions resources/shaders/score_labels.frag
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,14 @@ in INTERFACE {

uniform sampler2D font;
uniform vec3 color;
uniform int digitCount;
uniform int firstMeasure;


out vec4 fragColor;

void main(){
vec2 globalUV = In.uv;

int digitLoc = max(0, digitCount - int(floor(globalUV.x)) - 1);
int measure = (firstMeasure + int(In.id));
int digitLoc = int(floor(globalUV.x));
int measure = int(In.id);

if(measure < 0){
discard;
Expand All @@ -35,7 +32,8 @@ void main(){
int number = (measure / powTen) % 10;
// Remap 0,1 to 0.0, 1.0-padding on X,
const float paddingInTexture = 0.12;
vec2 localUV = fract(globalUV) * vec2(1.0-paddingInTexture, 1.0);
// Flip UVs back.
vec2 localUV = (1.0-fract(globalUV)) * vec2(1.0-paddingInTexture, 1.0);
vec2 pixelSize = 0.5 / vec2(200.0, 256.0);
localUV = clamp(localUV, pixelSize, 1.0 - pixelSize);
localUV += vec2(number % 5, 1 - (number / 5));
Expand Down
31 changes: 27 additions & 4 deletions resources/shaders/score_labels.vert
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ uniform vec2 nextOffset;
uniform vec2 scale;
uniform bool horizontalMode;
uniform int digitCount;
uniform int firstMeasure;

vec2 flipIfNeeded(vec2 inPos){
return horizontalMode ? vec2(inPos.y, -inPos.x) : inPos;
Expand All @@ -19,13 +20,35 @@ out INTERFACE {


void main(){
float fullID = float(firstMeasure + gl_InstanceID);

float currentDigitCount = floor(log(max(1, fullID))/log(10.0)) + 1;

vec2 size = vec2(currentDigitCount, 1.0);
vec2 maxSize = vec2(float(digitCount), 1.0);
vec2 finalScale = 2.f * scale * size;
vec2 maxFinalScale = 2.f * scale * maxSize;

// We directly output the position.
vec2 fullOffset = float(gl_InstanceID) * nextOffset + baseOffset;
vec2 pos = v.xy * scale * 2.0f + flipIfNeeded( fullOffset);
vec2 fullOffset = float(gl_InstanceID) * nextOffset + baseOffset;// + 0.5 * finalScale;

if(horizontalMode){
// Nothing to do on Y (which will become X) (already centered)
// just center on X (which becomes Y)
//Cheat to avoid digit touching the edge of the screen with offset 0.
fullOffset.x += 0.6 * maxFinalScale.y;
} else {
// We want to right align, so use the max scale.
fullOffset.x += maxFinalScale.x - 0.5 * finalScale.x;
// Nothing to do on the Y axis.
}
vec2 pos = v.xy * finalScale + flipIfNeeded(fullOffset);
gl_Position = vec4(pos, 0.1, 1.0);

// Output the UV coordinates computed from the positions.
Out.uv = (v.xy + 0.5) * vec2(digitCount, 1.0);
Out.id = float(gl_InstanceID);
// We flip the UVs so that the integer part corresponds to a power of ten
Out.uv = (-v.xy + 0.5) * size;
Out.id = fullID;


}
14 changes: 8 additions & 6 deletions src/rendering/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,14 +642,16 @@ void Renderer::drawScore(const std::shared_ptr<MIDIScene>& scene, float time, co
// Based on texture size.
const glm::vec2 digitResolution = glm::vec2(200.0f, 256.0f);
const glm::vec2 digitSize = textScale * qualityScale * invScreenSize * digitResolution;
const float digitCount = std::ceil(std::log10(float(scene->duration() / scene->secondsPerMeasure()) + 1.f / measureScale));
const glm::vec2 textSize = glm::vec2(digitCount, 1.0f) * digitSize;
const glm::vec2 margin = qualityScale * invScreenSize * state.digitsOffset;
const glm::vec2 offsetSize = glm::vec2(horizontalMode ? textSize.y : textSize.x, 0.f);
const float maxMeasureCount = float(scene->duration() / scene->secondsPerMeasure()) + 1.f / measureScale;
const float digitCount = std::floor(std::log10(std::max(1.f, maxMeasureCount))) + 1;

const glm::vec2 offset = 2.0f * digitSize * state.digitsOffset;
const glm::vec2 margin = horizontalMode ? glm::vec2(margin.y, margin.x) : margin;

_programScoreLabels.use();
_programScoreLabels.uniform("baseOffset", glm::vec2(-1.0f, firstBarCoord) + offsetSize + margin);
_programScoreLabels.uniform("baseOffset", glm::vec2(-1.0f, firstBarCoord) + margin);
_programScoreLabels.uniform("nextOffset", glm::vec2(0.0f, nextBarDeltaCoord));
_programScoreLabels.uniform("scale", textSize);
_programScoreLabels.uniform("scale", digitSize);
_programScoreLabels.uniform("color", state.digitsColor);
_programScoreLabels.uniform("digitCount", int(digitCount));
_programScoreLabels.uniform("firstMeasure", firstMeasure);
Expand Down
4 changes: 2 additions & 2 deletions src/rendering/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ void State::defineOptions(){
_sharedInfos["score-lines-vertical-width"] = {"Score vertical lines height, in pixels", OptionInfos::Type::FLOAT};
_sharedInfos["score-lines-horizontal-width"] = {"Score horizontal lines width, in pixels", OptionInfos::Type::FLOAT};
_sharedInfos["score-digits-size"] = {"Score digits size", OptionInfos::Type::FLOAT};
_sharedInfos["score-digits-offset-x"] = {"Score digits offset from the side, in pixels", OptionInfos::Type::FLOAT};
_sharedInfos["score-digits-offset-y"] = {"Score digits offset from the measure line, in pixels", OptionInfos::Type::FLOAT};
_sharedInfos["score-digits-offset-x"] = {"Score digits horizontal offset, as a fraction of a digit", OptionInfos::Type::FLOAT};
_sharedInfos["score-digits-offset-y"] = {"Score digits vertical offset, as a fraction of a digit", OptionInfos::Type::FLOAT};

// Paths.
_sharedInfos["bg-img-path"] = {"Path to an image on disk to use as background", OptionInfos::Type::PATH};
Expand Down
2 changes: 1 addition & 1 deletion src/rendering/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class State {
glm::vec3 hLinesColor; ///< Score lines color.
glm::vec3 vLinesColor; ///< Score lines color.
glm::vec3 digitsColor; ///< Score text
glm::vec2 digitsOffset; /// < Offset in pixels.
glm::vec2 digitsOffset; /// < Offset in fraction of a digit.
float hLinesWidth; ///< Width in pixels
float vLinesWidth; ///< Width in pixels
float digitsScale; ///< Scale
Expand Down
4 changes: 2 additions & 2 deletions src/rendering/Viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1083,9 +1083,9 @@ void Viewer::showScoreOptions(){
ImGui::PopItemWidth();

ImGuiPushItemWidth(100);
ImGui::SliderFloat("Offset X##Digits", &_state.score.digitsOffset[0], -20.f, 20.0f, "%.0fpx");
ImGuiSliderPercent("Offset X##Digits", &_state.score.digitsOffset[0], -1.f, 1.0f);
ImGuiSameLine(COLUMN_SIZE);
ImGui::SliderFloat("Offset Y##Digits", &_state.score.digitsOffset[1], -20.f, 20.0f, "%.0fpx");
ImGuiSliderPercent("Offset Y##Digits", &_state.score.digitsOffset[1], -1.f, 1.0f);
ImGui::PopItemWidth();

}
Expand Down
4 changes: 2 additions & 2 deletions src/resources/shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ const std::unordered_map<std::string, std::string> shaders = {
{ "wave_noise_frag", "#version 330\n in INTERFACE {\n vec2 uv;\n float grad;\n } In ;\n uniform vec3 waveColor;\n uniform float waveOpacity;\n uniform sampler2D textureNoise;\n out vec4 fragColor;\n void main(){\n // Premultiplied alpha.\n vec2 uv = In.uv;\n float noise = texture(textureNoise, uv).r;\n fragColor = noise * waveOpacity * vec4(waveColor, 1.0) * In.grad * 4.0;\n }\n "},
{ "score_bars_vert", "#version 330\n layout(location = 0) in vec3 v;\n uniform vec2 baseOffset;\n uniform vec2 nextOffset;\n uniform vec2 scale;\n uniform bool horizontalMode;\n vec2 flipIfNeeded(vec2 inPos){\n return horizontalMode ? vec2(inPos.y, -inPos.x) : inPos;\n }\n out INTERFACE {\n float uv;\n } Out ;\n void main(){\n \n // We directly output the position.\n vec2 pos = v.xy * scale * 2.0f + float(gl_InstanceID) * nextOffset + baseOffset;\n gl_Position = vec4(flipIfNeeded(pos), 0.0, 1.0);\n // Output the UV coordinates computed from the positions.\n Out.uv = 2.0 * (scale.x > 0.99 ? v.y : v.x);\n }\n "},
{ "score_bars_frag", "#version 330\n in INTERFACE {\n float uv;\n } In ;\n uniform vec3 color;\n out vec4 fragColor;\n void main(){\n float uv = 1.0 - abs(In.uv);\n float gradU = fwidth(uv);\n float alpha = smoothstep(0.1 - gradU, 0.1 + gradU, uv);\n fragColor = vec4(color, alpha);\n }\n "},
{ "score_labels_vert", "#version 330\n layout(location = 0) in vec3 v;\n uniform vec2 baseOffset;\n uniform vec2 nextOffset;\n uniform vec2 scale;\n uniform bool horizontalMode;\n uniform int digitCount;\n vec2 flipIfNeeded(vec2 inPos){\n return horizontalMode ? vec2(inPos.y, -inPos.x) : inPos;\n }\n out INTERFACE {\n vec2 uv;\n float id;\n } Out ;\n void main(){\n // We directly output the position.\n vec2 fullOffset = float(gl_InstanceID) * nextOffset + baseOffset;\n vec2 pos = v.xy * scale * 2.0f + flipIfNeeded( fullOffset);\n gl_Position = vec4(pos, 0.1, 1.0);\n // Output the UV coordinates computed from the positions.\n Out.uv = (v.xy + 0.5) * vec2(digitCount, 1.0);\n Out.id = float(gl_InstanceID);\n }\n "},
{ "score_labels_frag", "#version 330\n in INTERFACE {\n vec2 uv;\n float id;\n } In ;\n uniform sampler2D font;\n uniform vec3 color;\n uniform int digitCount;\n uniform int firstMeasure;\n out vec4 fragColor;\n void main(){\n vec2 globalUV = In.uv;\n int digitLoc = max(0, digitCount - int(floor(globalUV.x)) - 1);\n int measure = (firstMeasure + int(In.id));\n if(measure < 0){\n discard;\n }\n int powTen = 1;\n for(int i = 0; i < digitLoc; ++i){\n powTen *= 10;\n }\n if((measure < powTen) && (digitLoc != 0)){\n discard;\n }\n int number = (measure / powTen) % 10;\n // Remap 0,1 to 0.0, 1.0-padding on X,\n const float paddingInTexture = 0.12;\n vec2 localUV = fract(globalUV) * vec2(1.0-paddingInTexture, 1.0);\n vec2 pixelSize = 0.5 / vec2(200.0, 256.0);\n localUV = clamp(localUV, pixelSize, 1.0 - pixelSize);\n localUV += vec2(number % 5, 1 - (number / 5));\n localUV *= vec2(0.2, 0.5);\n vec2 distancesFont = textureLod(font, localUV, 0).rg;\n float sdfFont = distancesFont.r - distancesFont.g;\n // Clamp to a reasonable value here to avoid edge artifacts?\n float deltaStep = min(fwidth(sdfFont), 0.1);\n float alpha = 1.0 - smoothstep(0.01 - deltaStep, 0.01 + deltaStep, sdfFont);\n fragColor = vec4(color, alpha);\n }\n "}
{ "score_labels_vert", "#version 330\n layout(location = 0) in vec3 v;\n uniform vec2 baseOffset;\n uniform vec2 nextOffset;\n uniform vec2 scale;\n uniform bool horizontalMode;\n uniform int digitCount;\n uniform int firstMeasure;\n vec2 flipIfNeeded(vec2 inPos){\n return horizontalMode ? vec2(inPos.y, -inPos.x) : inPos;\n }\n out INTERFACE {\n vec2 uv;\n float id;\n } Out ;\n void main(){\n float fullID = float(firstMeasure + gl_InstanceID);\n float currentDigitCount = floor(log(max(1, fullID))/log(10.0)) + 1;\n vec2 size = vec2(currentDigitCount, 1.0);\n vec2 maxSize = vec2(float(digitCount), 1.0);\n vec2 finalScale = 2.f * scale * size;\n vec2 maxFinalScale = 2.f * scale * maxSize;\n // We directly output the position.\n vec2 fullOffset = float(gl_InstanceID) * nextOffset + baseOffset;// + 0.5 * finalScale;\n if(horizontalMode){\n // Nothing to do on Y (which will become X) (already centered)\n // just center on X (which becomes Y)\n //Cheat to avoid digit touching the edge of the screen with offset 0.\n fullOffset.x += 0.6 * maxFinalScale.y;\n } else {\n // We want to right align, so use the max scale.\n fullOffset.x += maxFinalScale.x - 0.5 * finalScale.x;\n // Nothing to do on the Y axis.\n }\n vec2 pos = v.xy * finalScale + flipIfNeeded(fullOffset);\n gl_Position = vec4(pos, 0.1, 1.0);\n // Output the UV coordinates computed from the positions.\n // We flip the UVs so that the integer part corresponds to a power of ten\n Out.uv = (-v.xy + 0.5) * size;\n Out.id = fullID;\n }\n "},
{ "score_labels_frag", "#version 330\n in INTERFACE {\n vec2 uv;\n float id;\n } In ;\n uniform sampler2D font;\n uniform vec3 color;\n out vec4 fragColor;\n void main(){\n vec2 globalUV = In.uv;\n int digitLoc = int(floor(globalUV.x));\n int measure = int(In.id);\n if(measure < 0){\n discard;\n }\n int powTen = 1;\n for(int i = 0; i < digitLoc; ++i){\n powTen *= 10;\n }\n if((measure < powTen) && (digitLoc != 0)){\n discard;\n }\n int number = (measure / powTen) % 10;\n // Remap 0,1 to 0.0, 1.0-padding on X,\n const float paddingInTexture = 0.12;\n // Flip UVs back.\n vec2 localUV = (1.0-fract(globalUV)) * vec2(1.0-paddingInTexture, 1.0);\n vec2 pixelSize = 0.5 / vec2(200.0, 256.0);\n localUV = clamp(localUV, pixelSize, 1.0 - pixelSize);\n localUV += vec2(number % 5, 1 - (number / 5));\n localUV *= vec2(0.2, 0.5);\n vec2 distancesFont = textureLod(font, localUV, 0).rg;\n float sdfFont = distancesFont.r - distancesFont.g;\n // Clamp to a reasonable value here to avoid edge artifacts?\n float deltaStep = min(fwidth(sdfFont), 0.1);\n float alpha = 1.0 - smoothstep(0.01 - deltaStep, 0.01 + deltaStep, sdfFont);\n fragColor = vec4(color, alpha);\n }\n "}
};

0 comments on commit 88dff14

Please sign in to comment.