Text rendering working ok.
This commit is contained in:
parent
eef93efc29
commit
4849d83fcf
10 changed files with 127 additions and 42 deletions
|
@ -5,9 +5,9 @@ FontGlyph::FontGlyph(unsigned width, unsigned height, unsigned bearingX, unsigne
|
|||
: mImage(std::move(image)),
|
||||
mWidth(width),
|
||||
mHeight(height),
|
||||
mBearingX(mBearingX),
|
||||
mBearingY(mBearingY),
|
||||
mAdvanceX(mAdvanceX)
|
||||
mBearingX(bearingX),
|
||||
mBearingY(bearingY),
|
||||
mAdvanceX(advanceX)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,16 @@ public:
|
|||
mPath = path;
|
||||
}
|
||||
|
||||
const std::string& getFaceName() const
|
||||
{
|
||||
return mFaceName;
|
||||
}
|
||||
|
||||
unsigned getSize() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned mSize{16};
|
||||
std::string mFaceName;
|
||||
|
|
|
@ -20,8 +20,12 @@ IFontEngine* FontsManager::getFontEngine() const
|
|||
return mFontEngine.get();
|
||||
}
|
||||
|
||||
FontGlyph* FontsManager::getGlyph(char c)
|
||||
FontGlyph* FontsManager::getGlyph(const std::string& fontFace, int size, char c)
|
||||
{
|
||||
auto path = std::filesystem::path("truetype/msttcorefonts/arial.ttf");
|
||||
|
||||
mFontEngine->loadFontFace(path, size);
|
||||
|
||||
auto iter = mGlyphs.find(c);
|
||||
if(iter != mGlyphs.end())
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ public:
|
|||
|
||||
IFontEngine* getFontEngine() const;
|
||||
|
||||
FontGlyph* getGlyph(char c);
|
||||
FontGlyph* getGlyph(const std::string& fontFace, int size, char c);
|
||||
|
||||
private:
|
||||
std::unique_ptr<IFontEngine> mFontEngine;
|
||||
|
|
|
@ -25,6 +25,11 @@ void FreeTypeFontEngine::loadFontFace(const std::filesystem::path& fontFile, int
|
|||
initialize();
|
||||
}
|
||||
|
||||
if (mWorkingFontFace)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto full_path = mSystemFontLocation / fontFile;
|
||||
const auto error = FT_New_Face(mLibrary, full_path.c_str(), 0, &mWorkingFontFace );
|
||||
if ( error == FT_Err_Unknown_File_Format )
|
||||
|
@ -40,7 +45,7 @@ void FreeTypeFontEngine::loadFontFace(const std::filesystem::path& fontFile, int
|
|||
|
||||
std::unique_ptr<FontGlyph> FreeTypeFontEngine::loadGlyph(unsigned charCode)
|
||||
{
|
||||
auto glyph_index = FT_Get_Char_Index( mWorkingFontFace, 65 );
|
||||
auto glyph_index = FT_Get_Char_Index( mWorkingFontFace, charCode );
|
||||
if (glyph_index == 0)
|
||||
{
|
||||
MLOG_ERROR("Got the null glyph");
|
||||
|
|
|
@ -34,3 +34,8 @@ OpenGlFontTexture::OpenGlFontTexture(FontGlyph* glyph)
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
}
|
||||
|
||||
FontGlyph* OpenGlFontTexture::getGlyph() const
|
||||
{
|
||||
return mGlyph;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,13 @@ class OpenGlFontTexture
|
|||
public:
|
||||
OpenGlFontTexture(FontGlyph* glyph);
|
||||
|
||||
unsigned int getHandle() const
|
||||
{
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
FontGlyph* getGlyph() const;
|
||||
|
||||
private:
|
||||
unsigned int mHandle{0};
|
||||
FontGlyph* mGlyph{nullptr};
|
||||
|
|
|
@ -72,23 +72,80 @@ void OpenGlPainter::renderTextLayer(const TextData& textData, DrawingContext* co
|
|||
initializeTextShader();
|
||||
}
|
||||
|
||||
auto first_char = textData.mContent[0];
|
||||
auto iter = mFontTextures.find(first_char);
|
||||
OpenGlFontTexture* working_texture{nullptr};
|
||||
if (iter == mFontTextures.end())
|
||||
for (auto c : textData.mContent)
|
||||
{
|
||||
auto glyph = context->getFontsManager()->getGlyph(first_char);
|
||||
auto new_texture = std::make_unique<OpenGlFontTexture>(nullptr);
|
||||
working_texture = new_texture.get();
|
||||
mFontTextures[first_char] = std::move(new_texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
working_texture = iter->second.get();
|
||||
if (auto iter = mFontTextures.find(c); iter == mFontTextures.end())
|
||||
{
|
||||
auto glyph = context->getFontsManager()->getGlyph(textData.mFont.getFaceName(), textData.mFont.getSize(), c);
|
||||
auto new_texture = std::make_unique<OpenGlFontTexture>(glyph);
|
||||
mFontTextures[c] = std::move(new_texture);
|
||||
}
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
const auto width = float(context->getSurface()->getWidth());
|
||||
const auto height = float(context->getSurface()->getHeight());
|
||||
|
||||
glm::mat4 projection = glm::ortho(0.0f, width, 0.0f, height);
|
||||
|
||||
unsigned int VAO, VBO;
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glUseProgram(mTextShaderProgram->getHandle());
|
||||
glUniform3f(glGetUniformLocation(mTextShaderProgram->getHandle(), "textColor"), 0.0, 0.0, 0.0);
|
||||
glUniformMatrix4fv(glGetUniformLocation(mTextShaderProgram->getHandle(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
// iterate through all characters
|
||||
float x = textData.mLocation.GetX();
|
||||
const float y = textData.mLocation.GetY();
|
||||
|
||||
for (auto c : textData.mContent)
|
||||
{
|
||||
auto texture = mFontTextures[c].get();
|
||||
|
||||
float xpos = x + texture->getGlyph()->getBearingX();
|
||||
float ypos = y - (texture->getGlyph()->getHeight() - texture->getGlyph()->getBearingY());
|
||||
|
||||
float w = texture->getGlyph()->getWidth();
|
||||
float h = texture->getGlyph()->getHeight();
|
||||
// update VBO for each character
|
||||
float vertices[6][4] = {
|
||||
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||
{ xpos, ypos, 0.0f, 1.0f },
|
||||
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||
|
||||
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||
{ xpos + w, ypos + h, 1.0f, 0.0f }
|
||||
};
|
||||
|
||||
// render glyph texture over quad
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getHandle());
|
||||
// update content of VBO memory
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
// render quad
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
||||
x += (texture->getGlyph()->getAdvanceX() >> 6); // bitshift by 6 to get value in pixels (2^6 = 64)
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void OpenGlPainter::renderMeshLayer(TriMesh* mesh, DrawingContext* context)
|
||||
|
@ -193,6 +250,8 @@ void OpenGlPainter::paint(DrawingContext* context)
|
|||
|
||||
glViewport(0, 0, width, height);
|
||||
//glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
||||
glOrtho(0, width, 0, height, -1.0, 1.0);
|
||||
|
||||
//glScissor(0, 0, width, height);
|
||||
//glMatrixMode(GL_PROJECTION);
|
||||
//glLoadIdentity();
|
||||
|
|
|
@ -145,8 +145,7 @@ uint32_t XcbInterface::getEventMask()
|
|||
return XCB_EVENT_MASK_KEY_RELEASE |
|
||||
XCB_EVENT_MASK_BUTTON_PRESS |
|
||||
XCB_EVENT_MASK_BUTTON_RELEASE |
|
||||
XCB_EVENT_MASK_EXPOSURE |
|
||||
XCB_EVENT_MASK_RESIZE_REDIRECT;
|
||||
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||
}
|
||||
|
||||
void XcbInterface::addWindow(mt::Window* window)
|
||||
|
@ -211,42 +210,39 @@ void XcbInterface::loop()
|
|||
mDesktopManager->onUiEvent(std::move(ui_event));
|
||||
break;
|
||||
}
|
||||
case XCB_RESIZE_REQUEST:
|
||||
case XCB_CONFIGURE_NOTIFY:
|
||||
{
|
||||
auto resize = (xcb_resize_request_event_t*) event;
|
||||
int width = 1;
|
||||
int height = 1;
|
||||
if (resize->width > 0)
|
||||
auto config_event = (xcb_configure_notify_event_t*) event;
|
||||
auto mainWindow = mDesktopManager->getWindowManager()->getMainWindow();
|
||||
auto width = mainWindow->getWidth();
|
||||
auto height = mainWindow->getHeight();
|
||||
|
||||
bool changed = false;
|
||||
if (config_event->width != width)
|
||||
{
|
||||
width = resize->width;
|
||||
width = config_event->width;
|
||||
changed = true;
|
||||
}
|
||||
if (resize->height > 0)
|
||||
if (config_event->height != height)
|
||||
{
|
||||
height = resize->height;
|
||||
height = config_event->height;
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
auto ui_event = std::make_unique<ResizeEvent>(width, height);
|
||||
mDesktopManager->onUiEvent(std::move(ui_event));
|
||||
}
|
||||
auto ui_event = std::make_unique<ResizeEvent>(width, height);
|
||||
mDesktopManager->onUiEvent(std::move(ui_event));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Unknown event type, ignore it */
|
||||
break;
|
||||
}
|
||||
onEventsDispatched();
|
||||
free(event);
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInterface::onEventsDispatched()
|
||||
{
|
||||
if (mDesktopManager->isModified())
|
||||
{
|
||||
mDesktopManager->setIsModified(false);
|
||||
auto mainWindow = mDesktopManager->getWindowManager()->getMainWindow();
|
||||
mainWindow->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void XcbInterface::shutDown()
|
||||
{
|
||||
mDesktopManager->getWindowManager()->clearPlatformWindows();
|
||||
|
|
|
@ -38,7 +38,6 @@ public:
|
|||
private:
|
||||
void initialize() override;
|
||||
void onPaint();
|
||||
void onEventsDispatched();
|
||||
void onExposeEvent(xcb_expose_event_t* event);
|
||||
|
||||
void initializeHardwareRendering() override;
|
||||
|
|
Loading…
Reference in a new issue