Merge branch 'master' of https://github.com/Shyotl/SingularityViewer
This commit is contained in:
@@ -268,9 +268,15 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
|
||||
const LLFontGlyphInfo* next_glyph = NULL;
|
||||
|
||||
// Remember last-used texture to avoid unnecesssary bind calls.
|
||||
LLImageGL *last_bound_texture = NULL;
|
||||
const S32 GLYPH_BATCH_SIZE = 30;
|
||||
static LL_ALIGN_16(LLVector4a vertices[GLYPH_BATCH_SIZE * 4]);
|
||||
static LLVector2 uvs[GLYPH_BATCH_SIZE * 4];
|
||||
static LLColor4U colors[GLYPH_BATCH_SIZE * 4];
|
||||
|
||||
LLColor4U text_color(color);
|
||||
|
||||
S32 bitmap_num = -1;
|
||||
S32 glyph_count = 0;
|
||||
for (i = begin_offset; i < begin_offset + length; i++)
|
||||
{
|
||||
llwchar wch = wstr[i];
|
||||
@@ -299,11 +305,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
break;
|
||||
}
|
||||
|
||||
if (last_bound_texture != ext_image)
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(ext_image);
|
||||
last_bound_texture = ext_image;
|
||||
}
|
||||
gGL.getTexUnit(0)->bind(ext_image);
|
||||
|
||||
// snap origin to whole screen pixel
|
||||
const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX));
|
||||
@@ -311,7 +313,23 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
|
||||
LLRectf uv_rect(0.f, 1.f, 1.f, 0.f);
|
||||
LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y);
|
||||
drawGlyph(screen_rect, uv_rect, LLColor4::white, style, shadow, drop_shadow_strength);
|
||||
|
||||
if (glyph_count > 0)
|
||||
{
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
|
||||
}
|
||||
gGL.end();
|
||||
glyph_count = 0;
|
||||
}
|
||||
renderQuad(vertices, uvs, colors, screen_rect, uv_rect, LLColor4U::white, 0);
|
||||
//No batching here. It will never happen.
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
gGL.vertexBatchPreTransformed(vertices, uvs, colors, 4);
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
if (!label.empty())
|
||||
{
|
||||
@@ -320,13 +338,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
/*llfloor*/(ext_x / sScaleX) + ext_image->getWidth() + EXT_X_BEARING - sCurOrigin.mX,
|
||||
/*llfloor*/(cur_render_y / sScaleY) - sCurOrigin.mY,
|
||||
color,
|
||||
halign, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL,
|
||||
halign, BASELINE, UNDERLINE, NO_SHADOW, S32_MAX, S32_MAX, NULL,
|
||||
TRUE );
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
gGL.color4fv(color.mV);
|
||||
|
||||
chars_drawn++;
|
||||
cur_x += ext_advance;
|
||||
if (((i + 1) < length) && wstr[i+1])
|
||||
@@ -349,11 +365,24 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
break;
|
||||
}
|
||||
// Per-glyph bitmap texture.
|
||||
LLImageGL *image_gl = font_bitmap_cache->getImageGL(fgi->mBitmapNum);
|
||||
if (last_bound_texture != image_gl)
|
||||
S32 next_bitmap_num = fgi->mBitmapNum;
|
||||
if (next_bitmap_num != bitmap_num)
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(image_gl);
|
||||
last_bound_texture = image_gl;
|
||||
// Actually draw the queued glyphs before switching their texture;
|
||||
// otherwise the queued glyphs will be taken from wrong textures.
|
||||
if (glyph_count > 0)
|
||||
{
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
|
||||
}
|
||||
gGL.end();
|
||||
glyph_count = 0;
|
||||
}
|
||||
|
||||
bitmap_num = next_bitmap_num;
|
||||
LLImageGL *font_image = font_bitmap_cache->getImageGL(bitmap_num);
|
||||
gGL.getTexUnit(0)->bind(font_image);
|
||||
}
|
||||
|
||||
if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
|
||||
@@ -368,13 +397,24 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
(fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
|
||||
(fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
|
||||
(fgi->mYBitmapOffset - PAD_UVY) * inv_height);
|
||||
// snap glyph origin to whole screen pixel
|
||||
LLRectf screen_rect((F32)llround(cur_render_x + (F32)fgi->mXBearing),
|
||||
// snap glyph origin to whole screen pixel
|
||||
LLRectf screen_rect((F32)llround(cur_render_x + (F32)fgi->mXBearing),
|
||||
(F32)llround(cur_render_y + (F32)fgi->mYBearing),
|
||||
(F32)llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
|
||||
(F32)llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
|
||||
|
||||
drawGlyph(screen_rect, uv_rect, color, style, shadow, drop_shadow_strength);
|
||||
if (glyph_count >= GLYPH_BATCH_SIZE)
|
||||
{
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
glyph_count = 0;
|
||||
}
|
||||
|
||||
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, text_color, style, shadow, drop_shadow_strength);
|
||||
|
||||
chars_drawn++;
|
||||
cur_x += fgi->mXAdvance;
|
||||
@@ -400,6 +440,13 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
}
|
||||
}
|
||||
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
|
||||
if (right_x)
|
||||
{
|
||||
*right_x = (cur_x - origin.mV[VX]) / sScaleX;
|
||||
@@ -1243,95 +1290,95 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source)
|
||||
return *this;
|
||||
}
|
||||
|
||||
void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const
|
||||
void LLFontGL::renderQuad(LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const
|
||||
{
|
||||
gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
|
||||
gGL.vertex2f(llfont_round_x(screen_rect.mRight),
|
||||
llfont_round_y(screen_rect.mTop));
|
||||
S32 index = 0;
|
||||
|
||||
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
|
||||
gGL.vertex2f(llfont_round_x(screen_rect.mLeft),
|
||||
llfont_round_y(screen_rect.mTop));
|
||||
vertex_out[index].set(screen_rect.mRight, screen_rect.mTop, 0.f);
|
||||
uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
|
||||
colors_out[index] = color;
|
||||
index++;
|
||||
|
||||
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
|
||||
gGL.vertex2f(llfont_round_x(screen_rect.mLeft + slant_amt),
|
||||
llfont_round_y(screen_rect.mBottom));
|
||||
vertex_out[index].set(screen_rect.mLeft, screen_rect.mTop, 0.f);
|
||||
uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
|
||||
colors_out[index] = color;
|
||||
index++;
|
||||
|
||||
gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
|
||||
gGL.vertex2f(llfont_round_x(screen_rect.mRight + slant_amt),
|
||||
llfont_round_y(screen_rect.mBottom));
|
||||
vertex_out[index].set(screen_rect.mLeft, screen_rect.mBottom, 0.f);
|
||||
uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
|
||||
colors_out[index] = color;
|
||||
index++;
|
||||
|
||||
vertex_out[index].set(screen_rect.mRight, screen_rect.mBottom, 0.f);
|
||||
uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
|
||||
colors_out[index] = color;
|
||||
}
|
||||
|
||||
void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
|
||||
void LLFontGL::drawGlyph(S32& glyph_count, LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
|
||||
{
|
||||
F32 slant_offset;
|
||||
slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f);
|
||||
|
||||
gGL.begin(LLRender::QUADS);
|
||||
//FIXME: bold and drop shadow are mutually exclusive only for convenience
|
||||
//Allow both when we need them.
|
||||
if (style & BOLD)
|
||||
{
|
||||
//FIXME: bold and drop shadow are mutually exclusive only for convenience
|
||||
//Allow both when we need them.
|
||||
if (style & BOLD)
|
||||
for (S32 pass = 0; pass < 2; pass++)
|
||||
{
|
||||
gGL.color4fv(color.mV);
|
||||
for (S32 pass = 0; pass < 2; pass++)
|
||||
{
|
||||
LLRectf screen_rect_offset = screen_rect;
|
||||
LLRectf screen_rect_offset = screen_rect;
|
||||
|
||||
screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f);
|
||||
renderQuad(screen_rect_offset, uv_rect, slant_offset);
|
||||
}
|
||||
screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f);
|
||||
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, color, slant_offset);
|
||||
glyph_count++;
|
||||
}
|
||||
else if (shadow == DROP_SHADOW_SOFT)
|
||||
{
|
||||
LLColor4 shadow_color = LLFontGL::sShadowColor;
|
||||
shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH;
|
||||
gGL.color4fv(shadow_color.mV);
|
||||
for (S32 pass = 0; pass < 5; pass++)
|
||||
{
|
||||
LLRectf screen_rect_offset = screen_rect;
|
||||
|
||||
switch(pass)
|
||||
{
|
||||
case 0:
|
||||
screen_rect_offset.translate(-1.f, -1.f);
|
||||
break;
|
||||
case 1:
|
||||
screen_rect_offset.translate(1.f, -1.f);
|
||||
break;
|
||||
case 2:
|
||||
screen_rect_offset.translate(1.f, 1.f);
|
||||
break;
|
||||
case 3:
|
||||
screen_rect_offset.translate(-1.f, 1.f);
|
||||
break;
|
||||
case 4:
|
||||
screen_rect_offset.translate(0, -2.f);
|
||||
break;
|
||||
}
|
||||
|
||||
renderQuad(screen_rect_offset, uv_rect, slant_offset);
|
||||
}
|
||||
gGL.color4fv(color.mV);
|
||||
renderQuad(screen_rect, uv_rect, slant_offset);
|
||||
}
|
||||
else if (shadow == DROP_SHADOW)
|
||||
{
|
||||
LLColor4 shadow_color = LLFontGL::sShadowColor;
|
||||
shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength;
|
||||
gGL.color4fv(shadow_color.mV);
|
||||
LLRectf screen_rect_shadow = screen_rect;
|
||||
screen_rect_shadow.translate(1.f, -1.f);
|
||||
renderQuad(screen_rect_shadow, uv_rect, slant_offset);
|
||||
gGL.color4fv(color.mV);
|
||||
renderQuad(screen_rect, uv_rect, slant_offset);
|
||||
}
|
||||
else // normal rendering
|
||||
{
|
||||
gGL.color4fv(color.mV);
|
||||
renderQuad(screen_rect, uv_rect, slant_offset);
|
||||
}
|
||||
|
||||
}
|
||||
gGL.end();
|
||||
else if (shadow == DROP_SHADOW_SOFT)
|
||||
{
|
||||
LLColor4U shadow_color = LLFontGL::sShadowColor;
|
||||
shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH);
|
||||
for (S32 pass = 0; pass < 5; pass++)
|
||||
{
|
||||
LLRectf screen_rect_offset = screen_rect;
|
||||
|
||||
switch(pass)
|
||||
{
|
||||
case 0:
|
||||
screen_rect_offset.translate(-1.f, -1.f);
|
||||
break;
|
||||
case 1:
|
||||
screen_rect_offset.translate(1.f, -1.f);
|
||||
break;
|
||||
case 2:
|
||||
screen_rect_offset.translate(1.f, 1.f);
|
||||
break;
|
||||
case 3:
|
||||
screen_rect_offset.translate(-1.f, 1.f);
|
||||
break;
|
||||
case 4:
|
||||
screen_rect_offset.translate(0, -2.f);
|
||||
break;
|
||||
}
|
||||
|
||||
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, shadow_color, slant_offset);
|
||||
glyph_count++;
|
||||
}
|
||||
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
|
||||
glyph_count++;
|
||||
}
|
||||
else if (shadow == DROP_SHADOW)
|
||||
{
|
||||
LLColor4U shadow_color = LLFontGL::sShadowColor;
|
||||
shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength);
|
||||
LLRectf screen_rect_shadow = screen_rect;
|
||||
screen_rect_shadow.translate(1.f, -1.f);
|
||||
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_shadow, uv_rect, shadow_color, slant_offset);
|
||||
glyph_count++;
|
||||
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
|
||||
glyph_count++;
|
||||
}
|
||||
else // normal rendering
|
||||
{
|
||||
renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
|
||||
glyph_count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ protected:
|
||||
LLFontDescriptor mFontDescriptor;
|
||||
LLPointer<LLFontFreetype> mFontFreetype;
|
||||
|
||||
void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
|
||||
void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
|
||||
void renderQuad(LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const;
|
||||
void drawGlyph(S32& glyph_count, LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
|
||||
|
||||
// Registry holds all instantiated fonts.
|
||||
static LLFontRegistry* sFontRegistry;
|
||||
|
||||
Reference in New Issue
Block a user