From 068d3d216e58c53151da4ddd1d641d5d35ac816c Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 29 Apr 2013 19:12:34 -0700 Subject: [PATCH] Need to commit these, too, for the font rendering change. --- interface/CMakeLists.txt | 12 ++++++-- interface/src/Avatar.cpp | 27 ++++++++++------ interface/src/ChatEntry.cpp | 4 +-- interface/src/ChatEntry.h | 4 +-- interface/src/Log.cpp | 24 ++++++--------- interface/src/MenuColumn.cpp | 9 +++++- interface/src/Util.cpp | 60 +++++++++++------------------------- interface/src/Util.h | 1 + interface/src/main.cpp | 7 +++++ 9 files changed, 75 insertions(+), 73 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index e4e8dc1614..360caea152 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -30,8 +30,12 @@ include_glm(${TARGET_NAME} ${ROOT_DIR}) # create the InterfaceConfig.h file based on GL_HEADERS above configure_file(InterfaceConfig.h.in ${PROJECT_BINARY_DIR}/includes/InterfaceConfig.h) -# grab the implementation and header files from src dir +# grab the implementation and header files from src dirs file(GLOB INTERFACE_SRCS src/*.cpp src/*.h) +foreach(SUBDIR ui) + file(GLOB SUBDIR_SRCS src/${SUBDIR}/*.cpp src/${SUBDIR}/*.h) + set(INTERFACE_SRCS ${INTERFACE_SRCS} ${SUBDIR_SRCS}) +endforeach(SUBDIR) # project subdirectories add_subdirectory(src/starfield) @@ -73,10 +77,14 @@ include_directories( ${LODEPNG_INCLUDE_DIRS} ) +find_package(Qt4 REQUIRED QtCore QtGui) +include(${QT_USE_FILE}) +target_link_libraries(${TARGET_NAME} ${QT_LIBRARIES}) + if (NOT APPLE) find_package(OpenGL REQUIRED) find_package(GLUT REQUIRED) - include_directories(${GLUT_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) + include_directories(${GLUT_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${}) target_link_libraries(${TARGET_NAME} ${OPENGL_LIBRARY}) else (NOT APPLE) # link in required OS X frameworks and include the right GL headers diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 24af81dfdf..61cd83b845 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -13,6 +13,7 @@ #include #include "Avatar.h" #include "Log.h" +#include "ui/TextRenderer.h" #include #include #include @@ -39,7 +40,7 @@ bool usingBigSphereCollisionTest = true; char iris_texture_file[] = "resources/images/green_eye.png"; -float chatMessageScale = 0.00025; +float chatMessageScale = 0.001; float chatMessageHeight = 0.4; vector iris_texture; @@ -618,6 +619,11 @@ void Avatar::setDisplayingHead( bool displayingHead ) { } +static TextRenderer* textRenderer() { + static TextRenderer* renderer = new TextRenderer("Helvetica", 24); + return renderer; +} + void Avatar::render(bool lookingInMirror) { /* @@ -667,10 +673,10 @@ void Avatar::render(bool lookingInMirror) { } if (!_chatMessage.empty()) { - float width = 0; - float lastWidth; + int width = 0; + int lastWidth; for (string::iterator it = _chatMessage.begin(); it != _chatMessage.end(); it++) { - width += (lastWidth = glutStrokeWidth(GLUT_STROKE_ROMAN, *it)*chatMessageScale); + width += (lastWidth = textRenderer()->computeWidth(*it)); } glPushMatrix(); @@ -682,11 +688,14 @@ void Avatar::render(bool lookingInMirror) { glTranslatef(_position.x, _position.y + chatMessageHeight, _position.z); glRotatef(atan2(-modelview[2], -modelview[10]) * 180 / PI, 0, 1, 0); - glTranslatef(width * 0.5, 0, 0); + glColor3f(0, 1, 0); + glRotatef(180, 0, 0, 1); + glScalef(chatMessageScale, chatMessageScale, 1.0f); + glDisable(GL_LIGHTING); if (_keyState == NO_KEY_DOWN) { - drawtext(0, 0, chatMessageScale, 180, 1.0, 0, _chatMessage.c_str(), 0, 1, 0); + textRenderer()->draw(-width/2, 0, _chatMessage.c_str()); } else { // rather than using substr and allocating a new string, just replace the last @@ -694,11 +703,9 @@ void Avatar::render(bool lookingInMirror) { int lastIndex = _chatMessage.size() - 1; char lastChar = _chatMessage[lastIndex]; _chatMessage[lastIndex] = '\0'; - drawtext(0, 0, chatMessageScale, 180, 1.0, 0, _chatMessage.c_str(), 0, 1, 0); + textRenderer()->draw(-width/2, 0, _chatMessage.c_str()); _chatMessage[lastIndex] = lastChar; - glTranslatef(lastWidth - width, 0, 0); - drawtext(0, 0, chatMessageScale, 180, 3.0, - 0, _chatMessage.c_str() + lastIndex, 0, 1, 0); + textRenderer()->draw(width/2 - lastWidth, 0, _chatMessage.c_str() + lastIndex); } glEnable(GL_LIGHTING); diff --git a/interface/src/ChatEntry.cpp b/interface/src/ChatEntry.cpp index aca13a79ac..2b6144e76d 100644 --- a/interface/src/ChatEntry.cpp +++ b/interface/src/ChatEntry.cpp @@ -14,7 +14,7 @@ using namespace std; const int MAX_CONTENT_LENGTH = 140; -void ChatEntry::clear () { +void ChatEntry::clear() { _contents.clear(); _cursorPos = 0; } @@ -67,7 +67,7 @@ void ChatEntry::render(int screenWidth, int screenHeight) { float width = 0; for (string::iterator it = _contents.begin(), end = it + _cursorPos; it != end; it++) { - width += glutStrokeWidth(GLUT_STROKE_ROMAN, *it)*0.10; + width += widthChar(0.10, 0, *it); } glDisable(GL_LINE_SMOOTH); glBegin(GL_LINE_STRIP); diff --git a/interface/src/ChatEntry.h b/interface/src/ChatEntry.h index db92822158..c2f1254c41 100644 --- a/interface/src/ChatEntry.h +++ b/interface/src/ChatEntry.h @@ -14,9 +14,9 @@ class ChatEntry { public: - const std::string& getContents () const { return _contents; } + const std::string& getContents() const { return _contents; } - void clear (); + void clear(); bool key(unsigned char k); void specialKey(unsigned char k); diff --git a/interface/src/Log.cpp b/interface/src/Log.cpp index 454a64a0fb..be66bd3a76 100644 --- a/interface/src/Log.cpp +++ b/interface/src/Log.cpp @@ -14,6 +14,7 @@ #include #include "Util.h" +#include "ui/TextRenderer.h" namespace { // anonymous namespace - everything in here only exists within this very .cpp file @@ -194,6 +195,11 @@ void Log::setCharacterSize(unsigned width, unsigned height) { pthread_mutex_unlock(& _mtx); } +static TextRenderer* textRenderer() { + static TextRenderer* renderer = new TextRenderer("Helvetica"); + return renderer; +} + void Log::render(unsigned screenWidth, unsigned screenHeight) { // rendering might take some time, so create a local copy of the portion we need @@ -261,10 +267,8 @@ void Log::render(unsigned screenWidth, unsigned screenHeight) { } // get values for rendering - float scaleFactor = _valCharScale; - int yStart = int((screenHeight - _valCharYoffset) / _valCharAspect); - int yStep = int(_valCharHeight / _valCharAspect); - float yScale = _valCharAspect; + int yStep = textRenderer()->metrics().lineSpacing(); + int yStart = screenHeight - textRenderer()->metrics().descent(); // render text char** line = _ptrLinesEnd + showLines; @@ -273,11 +277,6 @@ void Log::render(unsigned screenWidth, unsigned screenHeight) { pthread_mutex_unlock(& _mtx); // ok, we got all we need - GLint matrixMode; - glGetIntegerv(GL_MATRIX_MODE, & matrixMode); - glPushMatrix(); - glScalef(1.0f, yScale, 1.0f); - for (int y = yStart; y > 0; y -= yStep) { // debug mode: check line pointer is valid @@ -299,14 +298,11 @@ void Log::render(unsigned screenWidth, unsigned screenHeight) { assert(! (chars < _ptrCharsEnd || chars >= _ptrCharsEnd + (_ptrCharsEnd - _arrChars))); // render the string - drawtext(x, y, scaleFactor, 0.0f, 1.0f, int(TEXT_MONOSPACED), - chars, TEXT_RED, TEXT_GREEN, TEXT_BLUE); + glColor3f(TEXT_RED, TEXT_GREEN, TEXT_BLUE); + textRenderer()->draw(x, y, chars); //fprintf(stderr, "Log::render, message = \"%s\"\n", chars); } - - glPopMatrix(); - glMatrixMode(matrixMode); } Log logger; diff --git a/interface/src/MenuColumn.cpp b/interface/src/MenuColumn.cpp index 94e8595c8b..2eea8e3235 100644 --- a/interface/src/MenuColumn.cpp +++ b/interface/src/MenuColumn.cpp @@ -16,6 +16,7 @@ #include "MenuColumn.h" #include "Menu.h" +#include "ui/TextRenderer.h" MenuColumn::MenuColumn() { } @@ -137,6 +138,11 @@ int MenuColumn::getMaxRowWidth() { return maxColumnWidth; } +static TextRenderer* textRenderer() { + static TextRenderer* renderer = new TextRenderer("Helvetica", 11); + return renderer; +} + void MenuColumn::render(int yOffset, int menuHeight, int lineHeight) { float scale = 0.09; int mono = 0; @@ -158,7 +164,8 @@ void MenuColumn::render(int yOffset, int menuHeight, int lineHeight) { char* rowName; for (unsigned int i = 0; i < rows.size(); ++i) { rowName = rows[i].getName(); - drawtext(leftPosition + SPACE_BEFORE_ROW_NAME, y+5 + yOffset, scale, 0, 1.0, mono, rowName, 0, 0, 0); + glColor3f(0, 0, 0); + textRenderer()->draw(leftPosition + SPACE_BEFORE_ROW_NAME, y+5 + yOffset, rowName); y += lineHeight; } renderMouseOver(yOffset); diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 55b55b12eb..1dbe95d42d 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -15,6 +15,7 @@ #include #include "Log.h" +#include "ui/TextRenderer.h" #include "world.h" #include "Util.h" @@ -25,7 +26,6 @@ using namespace std; // see http://www.opengl.org/resources/libraries/glut/spec3/node78.html static float MONO_STROKE_WIDTH_GLUT = 104.76; - void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * front, glm::vec3 * right, glm::vec3 * up) { // // Converts from three euler angles to the associated orthonormal vectors @@ -152,19 +152,18 @@ double diffclock(timeval *clock1,timeval *clock2) return diffms; } +static TextRenderer* textRenderer(int mono) { + static TextRenderer* monoRenderer = new TextRenderer("Courier"); + static TextRenderer* proportionalRenderer = new TextRenderer("Helvetica"); + return mono ? monoRenderer : proportionalRenderer; +} + int widthText(float scale, int mono, char const* string) { - int width = 0; - if (!mono) { - width = scale * glutStrokeLength(GLUT_STROKE_ROMAN, (const unsigned char *) string); - } else { -#ifndef WORKAROUND_BROKEN_GLUT_STROKES - width = scale * glutStrokeLength(GLUT_STROKE_MONO_ROMAN, (const unsigned char *) string); -#else - // return value is unreliable, so just calculate it - width = scale * float(strlen(string)) * MONO_STROKE_WIDTH_GLUT; -#endif - } - return width; + return textRenderer(mono)->computeWidth(string) * (scale / 0.10); +} + +float widthChar(float scale, int mono, char ch) { + return textRenderer(mono)->computeWidth(ch) * (scale / 0.10); } void drawtext(int x, int y, float scale, float rotate, float thick, int mono, @@ -177,35 +176,12 @@ void drawtext(int x, int y, float scale, float rotate, float thick, int mono, glPushMatrix(); glTranslatef( static_cast(x), static_cast(y), 0.0f); glColor3f(r,g,b); - glRotated(180+rotate,0,0,1); - glRotated(180,0,1,0); - glLineWidth(thick); - glScalef(scale, scale, 1.0); - len = (int) strlen(string); - for (i = 0; i < len; i++) - { - if (!mono) { - glutStrokeCharacter(GLUT_STROKE_ROMAN, int(string[i])); - } else { -#ifdef WORKAROUND_BROKEN_GLUT_STROKES - if (string[i] != 'm') { -#endif - glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, int(string[i])); -#ifdef WORKAROUND_BROKEN_GLUT_STROKES - } else { - // some glut implementations have a broken 'm'... - unsigned char tmpStr[2]; - tmpStr[0] = string[i]; - tmpStr[1] = '\0'; - float scale = MONO_STROKE_WIDTH_GLUT / glutStrokeLength(GLUT_STROKE_ROMAN, tmpStr); - glScalef(scale, 1.0f, 1.0f); - glutStrokeCharacter(GLUT_STROKE_ROMAN, int(string[i])); - // staying humble on the stack - might be in projection mode - glScalef(1.0f / scale, 1.0f, 1.0f); - } -#endif - } - } + glRotated(rotate,0,0,1); + // glLineWidth(thick); + glScalef(scale / 0.10, scale / 0.10, 1.0); + + textRenderer(mono)->draw(0, 0, string); + glPopMatrix(); } diff --git a/interface/src/Util.h b/interface/src/Util.h index b23885e6bc..70794898f6 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -28,6 +28,7 @@ float randFloat(); void render_world_box(); void render_vector(glm::vec3 * vec); int widthText(float scale, int mono, char const* string); +float widthChar(float scale, int mono, char ch); void drawtext(int x, int y, float scale, float rotate, float thick, int mono, char const* string, float r=1.0, float g=1.0, float b=1.0); void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec, diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 058d7ad2c9..ac186a2f07 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -39,6 +39,8 @@ #include #endif +#include + #include #include @@ -86,6 +88,8 @@ using namespace std; void reshape(int width, int height); // will be defined below void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below +QApplication* app; + bool enableNetworkThread = true; pthread_t networkReceiveThread; bool stopNetworkReceiveThread = false; @@ -1615,6 +1619,9 @@ int main(int argc, const char * argv[]) voxels_lib::printLog = & ::printLog; avatars_lib::printLog = & ::printLog; + // we need to create a QApplication instance in order to use Qt's font rendering + app = new QApplication(argc, const_cast(argv)); + // Quick test of the Orientation class on startup! if (cmdOptionExists(argc, argv, "--testOrientation")) { testOrientationClass();