mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 11:37:58 +02:00
Merge pull request #335 from ey6es/master
Added gray background for chat entry, shadow/outline effects for text rendering. Enabled shadows for text contrast.
This commit is contained in:
commit
d8578ebb42
6 changed files with 61 additions and 12 deletions
|
@ -753,7 +753,7 @@ void Avatar::setDisplayingHead(bool displayingHead) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static TextRenderer* textRenderer() {
|
static TextRenderer* textRenderer() {
|
||||||
static TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24);
|
static TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT);
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,6 +833,7 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) {
|
||||||
glScalef(chatMessageScale, chatMessageScale, 1.0f);
|
glScalef(chatMessageScale, chatMessageScale, 1.0f);
|
||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
glDepthMask(false);
|
||||||
if (_keyState == NO_KEY_DOWN) {
|
if (_keyState == NO_KEY_DOWN) {
|
||||||
textRenderer()->draw(-width/2, 0, _chatMessage.c_str());
|
textRenderer()->draw(-width/2, 0, _chatMessage.c_str());
|
||||||
|
|
||||||
|
@ -848,6 +849,7 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) {
|
||||||
textRenderer()->draw(width/2 - lastWidth, 0, _chatMessage.c_str() + lastIndex);
|
textRenderer()->draw(width/2 - lastWidth, 0, _chatMessage.c_str() + lastIndex);
|
||||||
}
|
}
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
|
glDepthMask(true);
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,7 @@ void Log::setCharacterSize(unsigned width, unsigned height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static TextRenderer* textRenderer() {
|
static TextRenderer* textRenderer() {
|
||||||
static TextRenderer* renderer = new TextRenderer(FONT_FAMILY);
|
static TextRenderer* renderer = new TextRenderer(FONT_FAMILY, -1, -1, false, TextRenderer::SHADOW_EFFECT);
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ double diffclock(timeval *clock1,timeval *clock2)
|
||||||
|
|
||||||
static TextRenderer* textRenderer(int mono) {
|
static TextRenderer* textRenderer(int mono) {
|
||||||
static TextRenderer* monoRenderer = new TextRenderer(MONO_FONT_FAMILY);
|
static TextRenderer* monoRenderer = new TextRenderer(MONO_FONT_FAMILY);
|
||||||
static TextRenderer* proportionalRenderer = new TextRenderer(SANS_FONT_FAMILY);
|
static TextRenderer* proportionalRenderer = new TextRenderer(SANS_FONT_FAMILY, -1, -1, false, TextRenderer::SHADOW_EFFECT);
|
||||||
return mono ? monoRenderer : proportionalRenderer;
|
return mono ? monoRenderer : proportionalRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
const int MAX_CONTENT_LENGTH = 140;
|
const int MAX_CONTENT_LENGTH = 80;
|
||||||
|
|
||||||
ChatEntry::ChatEntry() : _cursorPos(0) {
|
ChatEntry::ChatEntry() : _cursorPos(0) {
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ bool ChatEntry::keyPressEvent(QKeyEvent* event) {
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (_contents.size() != MAX_CONTENT_LENGTH) {
|
if (_contents.size() < MAX_CONTENT_LENGTH) {
|
||||||
_contents.insert(_cursorPos, 1, text.at(0).toAscii());
|
_contents.insert(_cursorPos, 1, text.at(0).toAscii());
|
||||||
_cursorPos++;
|
_cursorPos++;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,19 @@ bool ChatEntry::keyPressEvent(QKeyEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatEntry::render(int screenWidth, int screenHeight) {
|
void ChatEntry::render(int screenWidth, int screenHeight) {
|
||||||
drawtext(20, screenHeight - 150, 0.10, 0, 1.0, 0, _contents.c_str(), 1, 1, 1);
|
// draw a gray background so that we can actually see what we're typing
|
||||||
|
int bottom = screenHeight - 150, top = screenHeight - 165;
|
||||||
|
int left = 20, right = left + 600;
|
||||||
|
|
||||||
|
glColor3f(0.2f, 0.2f, 0.2f);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2f(left - 5, bottom + 7);
|
||||||
|
glVertex2f(right + 5, bottom + 7);
|
||||||
|
glVertex2f(right + 5, top - 3);
|
||||||
|
glVertex2f(left - 5, top - 3);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
drawtext(left, bottom, 0.10, 0, 1.0, 0, _contents.c_str(), 1, 1, 1);
|
||||||
|
|
||||||
float width = 0;
|
float width = 0;
|
||||||
for (string::iterator it = _contents.begin(), end = it + _cursorPos; it != end; it++) {
|
for (string::iterator it = _contents.begin(), end = it + _cursorPos; it != end; it++) {
|
||||||
|
@ -82,7 +94,7 @@ void ChatEntry::render(int screenWidth, int screenHeight) {
|
||||||
}
|
}
|
||||||
glDisable(GL_LINE_SMOOTH);
|
glDisable(GL_LINE_SMOOTH);
|
||||||
glBegin(GL_LINE_STRIP);
|
glBegin(GL_LINE_STRIP);
|
||||||
glVertex2f(20 + width, screenHeight - 165);
|
glVertex2f(left + width, top + 2);
|
||||||
glVertex2f(20 + width, screenHeight - 150);
|
glVertex2f(left + width, bottom + 2);
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,10 @@ Glyph::Glyph(int textureID, const QPoint& location, const QRect& bounds, int wid
|
||||||
_textureID(textureID), _location(location), _bounds(bounds), _width(width) {
|
_textureID(textureID), _location(location), _bounds(bounds), _width(width) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRenderer::TextRenderer(const char* family, int pointSize, int weight, bool italic)
|
TextRenderer::TextRenderer(const char* family, int pointSize, int weight,
|
||||||
: _font(family, pointSize, weight, italic),
|
bool italic, EffectType effectType, int effectThickness)
|
||||||
_metrics(_font), _x(IMAGE_SIZE), _y(IMAGE_SIZE), _rowHeight(0) {
|
: _font(family, pointSize, weight, italic), _metrics(_font), _effectType(effectType),
|
||||||
|
_effectThickness(effectThickness), _x(IMAGE_SIZE), _y(IMAGE_SIZE), _rowHeight(0) {
|
||||||
_font.setKerning(false);
|
_font.setKerning(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +98,14 @@ const Glyph& TextRenderer::getGlyph(char c) {
|
||||||
glyph = Glyph(0, QPoint(), QRect(), _metrics.width(ch));
|
glyph = Glyph(0, QPoint(), QRect(), _metrics.width(ch));
|
||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
|
// grow the bounds to account for effect, if any
|
||||||
|
if (_effectType == SHADOW_EFFECT) {
|
||||||
|
bounds.adjust(-_effectThickness, 0, 0, _effectThickness);
|
||||||
|
|
||||||
|
} else if (_effectType == OUTLINE_EFFECT) {
|
||||||
|
bounds.adjust(-_effectThickness, -_effectThickness, _effectThickness, _effectThickness);
|
||||||
|
}
|
||||||
|
|
||||||
// grow the bounds to account for antialiasing
|
// grow the bounds to account for antialiasing
|
||||||
bounds.adjust(-1, -1, 1, 1);
|
bounds.adjust(-1, -1, 1, 1);
|
||||||
|
|
||||||
|
@ -128,6 +137,23 @@ const Glyph& TextRenderer::getGlyph(char c) {
|
||||||
image.fill(0);
|
image.fill(0);
|
||||||
QPainter painter(&image);
|
QPainter painter(&image);
|
||||||
painter.setFont(_font);
|
painter.setFont(_font);
|
||||||
|
if (_effectType == SHADOW_EFFECT) {
|
||||||
|
for (int i = 0; i < _effectThickness; i++) {
|
||||||
|
painter.drawText(-bounds.x() - i, -bounds.y() + i, ch);
|
||||||
|
}
|
||||||
|
} else if (_effectType == OUTLINE_EFFECT) {
|
||||||
|
QPainterPath path;
|
||||||
|
QFont font = _font;
|
||||||
|
font.setStyleStrategy(QFont::ForceOutline);
|
||||||
|
path.addText(-bounds.x() - 0.5, -bounds.y() + 0.5, font, ch);
|
||||||
|
QPen pen;
|
||||||
|
pen.setWidth(_effectThickness);
|
||||||
|
pen.setJoinStyle(Qt::RoundJoin);
|
||||||
|
pen.setCapStyle(Qt::RoundCap);
|
||||||
|
painter.setPen(pen);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.drawPath(path);
|
||||||
|
}
|
||||||
painter.setPen(QColor(255, 255, 255));
|
painter.setPen(QColor(255, 255, 255));
|
||||||
painter.drawText(-bounds.x(), -bounds.y(), ch);
|
painter.drawText(-bounds.x(), -bounds.y(), ch);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,10 @@ class Glyph;
|
||||||
class TextRenderer {
|
class TextRenderer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TextRenderer(const char* family, int pointSize = -1, int weight = -1, bool italic = false);
|
enum EffectType { NO_EFFECT, SHADOW_EFFECT, OUTLINE_EFFECT };
|
||||||
|
|
||||||
|
TextRenderer(const char* family, int pointSize = -1, int weight = -1, bool italic = false,
|
||||||
|
EffectType effect = NO_EFFECT, int effectThickness = 2);
|
||||||
~TextRenderer();
|
~TextRenderer();
|
||||||
|
|
||||||
const QFontMetrics& metrics() const { return _metrics; }
|
const QFontMetrics& metrics() const { return _metrics; }
|
||||||
|
@ -43,6 +46,12 @@ private:
|
||||||
// the font metrics
|
// the font metrics
|
||||||
QFontMetrics _metrics;
|
QFontMetrics _metrics;
|
||||||
|
|
||||||
|
// the type of effect to apply
|
||||||
|
EffectType _effectType;
|
||||||
|
|
||||||
|
// the thickness of the effect
|
||||||
|
int _effectThickness;
|
||||||
|
|
||||||
// maps characters to cached glyph info
|
// maps characters to cached glyph info
|
||||||
QHash<char, Glyph> _glyphs;
|
QHash<char, Glyph> _glyphs;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue