Added UI Scaling support

This commit is contained in:
2023-07-24 11:01:29 -07:00
parent 34ff460343
commit 404d1c6227
10 changed files with 83 additions and 21 deletions

View File

@ -30,6 +30,14 @@ namespace Dawn {
*/
virtual float_t getHeight() = 0;
/**
* Returns the scale (as in pixel density) of the render target. This is
* typically 1.0f, but on high DPI displays this may be 2.0f or higher.
*
* @return The scale of the render target.
*/
virtual float_t getScale() = 0;
/**
* Sets the clear color of the render target when the clear method for
* the color buffer is requested.

View File

@ -32,8 +32,8 @@ void UICanvas::rebufferShaderParameters() {
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
data.projection = glm::ortho(
0.0f,
camera->getRenderTarget()->getWidth(),
camera->getRenderTarget()->getHeight(),
camera->getRenderTarget()->getWidth() / this->getScale(),
camera->getRenderTarget()->getHeight() / this->getScale(),
0.0f
);
data.view = glm::mat4(1.0f);
@ -46,6 +46,10 @@ void UICanvas::rebufferShaderParameters() {
this->shaderBuffer.buffer(&data);
}
float_t UICanvas::getScale() {
return this->camera->getRenderTarget()->getScale();
}
float_t UICanvas::getWidth() {
return w;
}
@ -78,13 +82,13 @@ void UICanvas::onStart() {
useEffectWithTeardown([&]{
if(camera == nullptr) return evtRenderResize = [&] {};
this->w = camera->getRenderTarget()->getWidth();
this->h = camera->getRenderTarget()->getHeight();
this->w = camera->getRenderTarget()->getWidth() / this->getScale();
this->h = camera->getRenderTarget()->getHeight() / this->getScale();
this->rebufferShaderParameters();
return evtRenderResize = useEvent([&](float_t w, float_t h){
this->w = w;
this->h = h;
this->w = w / this->getScale();
this->h = h / this->getScale();
this->rebufferShaderParameters();
auto comps = this->item->findChildren<UIComponent>();

View File

@ -96,6 +96,13 @@ namespace Dawn {
*/
UICanvas(SceneItem *item);
/**
* Returns the scale of this canvas.
*
* @return The scale of the canvas, where 1 is default scaling.
*/
float_t getScale();
float_t getWidth() override;
float_t getHeight() override;
float_t getContentWidth() override;

View File

@ -130,8 +130,8 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
quadCountTotal = 0;
quadCount = -1;
std::vector<struct UILabelText> realNewTexts;
float_t maxWidth = this->width;
float_t canvasScale = this->getCanvas()->getScale();
// Reset
lines.clear();
@ -141,7 +141,7 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
// Determine font dimensions.
auto itText = newTexts.begin();
while(itText != newTexts.end()) {
position.y = mathMax<float_t>(position.y, itText->style.size/* this->lineHeight - THIS PART WOULD TAKE THE LINE HEIGHT INTO CONSIDERATION ON THE FIRST/INITIAL LINE */);
position.y = mathMax<float_t>(position.y, itText->style.size);
++itText;
}
@ -163,7 +163,7 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
// Lock the font
assertNotNull(text.style.font, "UILabel::rebufferQuads: Font cannot be null");
realText.lockId = text.style.font->lock(TrueTypeFaceTextureStyle{
text.style.size,
(uint32_t)(text.style.size * canvasScale),// Scale for resolution.
text.style.style
});
assertTrue(realText.lockId != -1, "UILabel::rebufferQuads: Failed to lock font");
@ -259,13 +259,27 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
// Get font data.
auto charInfo = realText.texture->getCharacterData(ch);
// Now we scale down the char info here. This is because we fetch the
// texture of the font based on the canvas scale, but the sizes that we
// render out need to be shrunk to match the original sizes.
glm::vec2 charSize = glm::vec2(
charInfo.bitmapSize.x / canvasScale, charInfo.bitmapSize.y / canvasScale
);
glm::vec2 charAdvance = glm::vec2(
charInfo.advanceX / canvasScale, charInfo.advanceY / canvasScale
);
glm::vec2 charPos = glm::vec2(
charInfo.bitmapPosition.x / canvasScale,
charInfo.bitmapPosition.y / canvasScale
);
// Word wrapping
if(
ch != ' ' &&
lastSpaceCharacter != -1 &&
maxWidth > charInfo.bitmapSize.x &&
(position.x + charInfo.advanceX) > maxWidth
maxWidth > charSize.x &&
(position.x + charAdvance.x) > maxWidth
) {
// Basically this rewinds everything we've done to the last space char,
// changes it to a newline, and then moves the position along.
@ -284,7 +298,7 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
continue;
}
// Buffer coordinates
// Buffer coordinates, use original (non scaled) values.
glm::vec4 uvs;
uvs.x = 0.0f;
uvs.y = charInfo.textureY / wh.y;
@ -292,10 +306,10 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
uvs.z = uvs.y + (charInfo.bitmapSize.y / wh.y);
glm::vec4 vert;
vert.x = position.x + charInfo.bitmapPosition.x;
vert.y = position.y + charInfo.bitmapPosition.y;
vert.w = vert.x + charInfo.bitmapSize.x;
vert.z = vert.y + charInfo.bitmapSize.y;
vert.x = position.x + charPos.x;
vert.y = position.y + charPos.y;
vert.w = vert.x + charSize.x;
vert.z = vert.y + charSize.y;
vertices.push_back(std::make_pair(vert, uvs));
// Decorations
@ -318,16 +332,16 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
}
// Move the current position along.
position.x += charInfo.advanceX;
position.y += charInfo.advanceY;
position.x += charAdvance.x;
position.y += charAdvance.y;
// Update the continuous dimensions
if(ch == ' ') {
lineWidth += wordWidth;
lineWidth += charInfo.advanceX;
lineWidth += charAdvance.x;
wordWidth = 0.0f;
} else {
wordWidth += charInfo.advanceX;
wordWidth += charAdvance.x;
}
// Set the part index to the quad mappings