Continue adding opengl font support.
This commit is contained in:
parent
649079a5c7
commit
eef93efc29
37 changed files with 530 additions and 157 deletions
|
@ -51,7 +51,7 @@ In `xdg-shell-protocol.cpp` - we need access to `xdg_wm_base_interface` so expor
|
||||||
#### 3D Rendering
|
#### 3D Rendering
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install libgl-dev libegl1-mesa-dev libglu1-mesa-dev
|
sudo apt-get install libgl-dev libegl1-mesa-dev libglu1-mesa-dev libglm-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
#### fonts
|
#### fonts
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
class Color
|
class Color
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Color(unsigned r, unsigned g, unsigned b, double a = 1.0);
|
Color(unsigned r = 0, unsigned g = 0, unsigned b = 0, double a = 1.0);
|
||||||
|
|
||||||
static std::shared_ptr<Color> CreateShared(unsigned r, unsigned g, unsigned b, double a = 1.0);
|
static std::shared_ptr<Color> CreateShared(unsigned r, unsigned g, unsigned b, double a = 1.0);
|
||||||
static std::unique_ptr<Color> Create(unsigned r, unsigned g, unsigned b, double a = 1.0);
|
static std::unique_ptr<Color> Create(unsigned r, unsigned g, unsigned b, double a = 1.0);
|
||||||
|
|
|
@ -113,6 +113,22 @@ std::vector<std::string> File::readLines()
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string File::read()
|
||||||
|
{
|
||||||
|
if (!PathExists())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Open(false);
|
||||||
|
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << mInHandle->rdbuf();
|
||||||
|
|
||||||
|
Close();
|
||||||
|
return buffer.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string File::getBaseFilename(const Path& path)
|
std::string File::getBaseFilename(const Path& path)
|
||||||
{
|
{
|
||||||
return path.stem().string();
|
return path.stem().string();
|
||||||
|
|
|
@ -36,6 +36,8 @@ public:
|
||||||
|
|
||||||
std::vector<std::string> readLines();
|
std::vector<std::string> readLines();
|
||||||
|
|
||||||
|
std::string read();
|
||||||
|
|
||||||
static std::string getBaseFilename(const Path& path);
|
static std::string getBaseFilename(const Path& path);
|
||||||
|
|
||||||
bool PathExists() const;
|
bool PathExists() const;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "IFontEngine.h"
|
#include "IFontEngine.h"
|
||||||
|
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
|
#include "FontGlyph.h"
|
||||||
|
|
||||||
class BasicFontEngine : public IFontEngine
|
class BasicFontEngine : public IFontEngine
|
||||||
{
|
{
|
||||||
|
@ -10,5 +11,5 @@ class BasicFontEngine : public IFontEngine
|
||||||
|
|
||||||
virtual void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16){};
|
virtual void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16){};
|
||||||
|
|
||||||
virtual std::unique_ptr<Image<unsigned char> > loadGlyph(unsigned charCode){return nullptr;};
|
virtual std::unique_ptr<FontGlyph> loadGlyph(unsigned charCode){return nullptr;};
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,7 @@ list(APPEND fonts_LIB_INCLUDES
|
||||||
FontReader.cpp
|
FontReader.cpp
|
||||||
TrueTypeFont.cpp
|
TrueTypeFont.cpp
|
||||||
FontsManager.cpp
|
FontsManager.cpp
|
||||||
|
FontGlyph.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
|
|
43
src/fonts/FontGlyph.cpp
Normal file
43
src/fonts/FontGlyph.cpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#include "FontGlyph.h"
|
||||||
|
|
||||||
|
FontGlyph::FontGlyph(unsigned width, unsigned height, unsigned bearingX, unsigned bearingY,
|
||||||
|
unsigned advanceX, std::unique_ptr<Image<unsigned char> > image)
|
||||||
|
: mImage(std::move(image)),
|
||||||
|
mWidth(width),
|
||||||
|
mHeight(height),
|
||||||
|
mBearingX(mBearingX),
|
||||||
|
mBearingY(mBearingY),
|
||||||
|
mAdvanceX(mAdvanceX)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Image<unsigned char>* FontGlyph::getImage() const
|
||||||
|
{
|
||||||
|
return mImage.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontGlyph::getWidth() const
|
||||||
|
{
|
||||||
|
return mWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontGlyph::getHeight() const
|
||||||
|
{
|
||||||
|
return mHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontGlyph::getBearingX() const
|
||||||
|
{
|
||||||
|
return mBearingX;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontGlyph::getBearingY() const
|
||||||
|
{
|
||||||
|
return mBearingY;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontGlyph::getAdvanceX() const
|
||||||
|
{
|
||||||
|
return mAdvanceX;
|
||||||
|
}
|
29
src/fonts/FontGlyph.h
Normal file
29
src/fonts/FontGlyph.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "Image.h"
|
||||||
|
|
||||||
|
class FontGlyph
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
FontGlyph(unsigned width, unsigned height, unsigned bearingX, unsigned bearingY,
|
||||||
|
unsigned advanceX, std::unique_ptr<Image<unsigned char> > image);
|
||||||
|
|
||||||
|
Image<unsigned char>* getImage() const;
|
||||||
|
|
||||||
|
unsigned getWidth() const;
|
||||||
|
unsigned getHeight() const;
|
||||||
|
unsigned getBearingX() const;
|
||||||
|
unsigned getBearingY() const;
|
||||||
|
unsigned getAdvanceX() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned mWidth{0};
|
||||||
|
unsigned mHeight{0};
|
||||||
|
unsigned mBearingX{0};
|
||||||
|
unsigned mBearingY{0};
|
||||||
|
unsigned mAdvanceX{0};
|
||||||
|
std::unique_ptr<Image<unsigned char> > mImage;
|
||||||
|
};
|
0
src/fonts/FontItem.cpp
Normal file
0
src/fonts/FontItem.cpp
Normal file
35
src/fonts/FontItem.h
Normal file
35
src/fonts/FontItem.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class FontItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FontItem(const std::string& faceName = "Arial", unsigned size = 16)
|
||||||
|
: mFaceName(faceName),
|
||||||
|
mSize(size)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasPath() const
|
||||||
|
{
|
||||||
|
return !mPath.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::filesystem::path& getPath() const
|
||||||
|
{
|
||||||
|
return mPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPath(std::filesystem::path path)
|
||||||
|
{
|
||||||
|
mPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned mSize{16};
|
||||||
|
std::string mFaceName;
|
||||||
|
std::filesystem::path mPath;
|
||||||
|
};
|
|
@ -3,8 +3,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "IFont.h"
|
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
|
#include "IFont.h"
|
||||||
|
|
||||||
class File;
|
class File;
|
||||||
|
|
||||||
|
|
|
@ -20,4 +20,20 @@ IFontEngine* FontsManager::getFontEngine() const
|
||||||
return mFontEngine.get();
|
return mFontEngine.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FontGlyph* FontsManager::getGlyph(char c)
|
||||||
|
{
|
||||||
|
auto iter = mGlyphs.find(c);
|
||||||
|
if(iter != mGlyphs.end())
|
||||||
|
{
|
||||||
|
return iter->second.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto glyph = mFontEngine->loadGlyph(c);
|
||||||
|
auto glyph_ptr = glyph.get();
|
||||||
|
mGlyphs[c] = std::move(glyph);
|
||||||
|
return glyph_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
class IFontEngine;
|
class IFontEngine;
|
||||||
|
class FontGlyph;
|
||||||
|
|
||||||
class FontsManager
|
class FontsManager
|
||||||
{
|
{
|
||||||
|
@ -13,8 +15,12 @@ public:
|
||||||
|
|
||||||
IFontEngine* getFontEngine() const;
|
IFontEngine* getFontEngine() const;
|
||||||
|
|
||||||
|
FontGlyph* getGlyph(char c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IFontEngine> mFontEngine;
|
std::unique_ptr<IFontEngine> mFontEngine;
|
||||||
|
|
||||||
|
std::unordered_map<char, std::unique_ptr<FontGlyph> > mGlyphs;
|
||||||
};
|
};
|
||||||
|
|
||||||
using FontsManagerPtr = std::unique_ptr<FontsManager>;
|
using FontsManagerPtr = std::unique_ptr<FontsManager>;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
|
#include "FontGlyph.h"
|
||||||
|
|
||||||
void FreeTypeFontEngine::initialize()
|
void FreeTypeFontEngine::initialize()
|
||||||
{
|
{
|
||||||
|
@ -37,7 +38,7 @@ void FreeTypeFontEngine::loadFontFace(const std::filesystem::path& fontFile, int
|
||||||
FT_Set_Pixel_Sizes(mWorkingFontFace, penSize, 0);
|
FT_Set_Pixel_Sizes(mWorkingFontFace, penSize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Image<unsigned char> > FreeTypeFontEngine::loadGlyph(unsigned charCode)
|
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, 65 );
|
||||||
if (glyph_index == 0)
|
if (glyph_index == 0)
|
||||||
|
@ -83,5 +84,13 @@ std::unique_ptr<Image<unsigned char> > FreeTypeFontEngine::loadGlyph(unsigned ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image->setData(data);
|
image->setData(data);
|
||||||
return image;
|
|
||||||
|
auto glyph = std::make_unique<FontGlyph>(mWorkingFontFace->glyph->bitmap.width,
|
||||||
|
mWorkingFontFace->glyph->bitmap.rows,
|
||||||
|
mWorkingFontFace->glyph->bitmap_left,
|
||||||
|
mWorkingFontFace->glyph->bitmap_top,
|
||||||
|
mWorkingFontFace->glyph->advance.x,
|
||||||
|
std::move(image));
|
||||||
|
|
||||||
|
return glyph;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
|
|
||||||
void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16) override;
|
void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16) override;
|
||||||
|
|
||||||
std::unique_ptr<Image<unsigned char> > loadGlyph(unsigned charCode) override;
|
std::unique_ptr<FontGlyph> loadGlyph(unsigned charCode) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::filesystem::path mSystemFontLocation{"/usr/share/fonts/"};
|
std::filesystem::path mSystemFontLocation{"/usr/share/fonts/"};
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
template<typename T>
|
class FontGlyph;
|
||||||
class Image;
|
|
||||||
|
|
||||||
class IFontEngine
|
class IFontEngine
|
||||||
{
|
{
|
||||||
|
@ -16,5 +15,5 @@ public:
|
||||||
|
|
||||||
virtual void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16) = 0;
|
virtual void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16) = 0;
|
||||||
|
|
||||||
virtual std::unique_ptr<Image<unsigned char> > loadGlyph(unsigned charCode) = 0;
|
virtual std::unique_ptr<FontGlyph> loadGlyph(unsigned charCode) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IFont.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "IFont.h"
|
||||||
|
|
||||||
class TrueTypeFont : public IFont
|
class TrueTypeFont : public IFont
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,8 +19,14 @@ set(OpenGL_GL_PREFERENCE "GLVND")
|
||||||
find_package(OpenGL QUIET)
|
find_package(OpenGL QUIET)
|
||||||
if (OpenGL_FOUND)
|
if (OpenGL_FOUND)
|
||||||
list(APPEND platform_LIBS OpenGL::GL OpenGL::GLU)
|
list(APPEND platform_LIBS OpenGL::GL OpenGL::GLU)
|
||||||
list(APPEND graphics_LIB_INCLUDES opengl/OpenGlPainter.cpp)
|
list(APPEND graphics_LIB_INCLUDES
|
||||||
list(APPEND graphics_HEADERS opengl/OpenGlPainter.h)
|
opengl/OpenGlPainter.cpp
|
||||||
|
opengl/OpenGlFontTexture.cpp
|
||||||
|
opengl/OpenGlShaderProgram.cpp)
|
||||||
|
list(APPEND graphics_HEADERS
|
||||||
|
opengl/OpenGlPainter.h
|
||||||
|
opengl/OpenGlFontTexture.h
|
||||||
|
opengl/OpenGlShaderProgram.h)
|
||||||
else()
|
else()
|
||||||
message(STATUS "OpenGL headers not found - skipping OpenGL support")
|
message(STATUS "OpenGL headers not found - skipping OpenGL support")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "AbstractPainter.h"
|
#include "AbstractPainter.h"
|
||||||
#include "OpenGlPainter.h"
|
#include "OpenGlPainter.h"
|
||||||
|
#include "OpenGlShaderProgram.h"
|
||||||
|
#include "OpenGlFontTexture.h"
|
||||||
#include "RasterPainter.h"
|
#include "RasterPainter.h"
|
||||||
#include "Grid.h"
|
#include "Grid.h"
|
||||||
#include "TriMesh.h"
|
#include "TriMesh.h"
|
||||||
|
@ -40,6 +42,11 @@ DrawingSurface* DrawingContext::getSurface() const
|
||||||
return mSurface;
|
return mSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FontsManager* DrawingContext::getFontsManager() const
|
||||||
|
{
|
||||||
|
return mFontsManager;
|
||||||
|
}
|
||||||
|
|
||||||
void DrawingContext::paint()
|
void DrawingContext::paint()
|
||||||
{
|
{
|
||||||
mScene->update(mFontsManager, mDrawingMode == DrawingMode::RASTER ? mSurface->getImage() : nullptr);
|
mScene->update(mFontsManager, mDrawingMode == DrawingMode::RASTER ? mSurface->getImage() : nullptr);
|
||||||
|
|
|
@ -25,6 +25,8 @@ public:
|
||||||
|
|
||||||
DrawingSurface* getSurface() const;
|
DrawingSurface* getSurface() const;
|
||||||
|
|
||||||
|
FontsManager* getFontsManager() const;
|
||||||
|
|
||||||
void paint();
|
void paint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
36
src/graphics/opengl/OpenGlFontTexture.cpp
Normal file
36
src/graphics/opengl/OpenGlFontTexture.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#include "OpenGlFontTexture.h"
|
||||||
|
|
||||||
|
#include "FontGlyph.h"
|
||||||
|
#include "Image.h"
|
||||||
|
|
||||||
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
OpenGlFontTexture::OpenGlFontTexture(FontGlyph* glyph)
|
||||||
|
: mGlyph(glyph)
|
||||||
|
{
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
glGenTextures(1, &mHandle);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mHandle);
|
||||||
|
|
||||||
|
auto buffer = glyph->getImage()->getDataPtr();
|
||||||
|
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
GL_RED,
|
||||||
|
mGlyph->getWidth(),
|
||||||
|
mGlyph->getHeight(),
|
||||||
|
0,
|
||||||
|
GL_RED,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
}
|
13
src/graphics/opengl/OpenGlFontTexture.h
Normal file
13
src/graphics/opengl/OpenGlFontTexture.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class FontGlyph;
|
||||||
|
|
||||||
|
class OpenGlFontTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenGlFontTexture(FontGlyph* glyph);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int mHandle{0};
|
||||||
|
FontGlyph* mGlyph{nullptr};
|
||||||
|
};
|
|
@ -5,6 +5,15 @@
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "TriMesh.h"
|
#include "TriMesh.h"
|
||||||
|
|
||||||
|
#include "FontsManager.h"
|
||||||
|
#include "FontGlyph.h"
|
||||||
|
|
||||||
|
#include "OpenGlFontTexture.h"
|
||||||
|
#include "OpenGlShaderProgram.h"
|
||||||
|
#include "TextData.h"
|
||||||
|
|
||||||
|
#include "File.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,30 +23,18 @@
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
const char* vertexShaderSource = "#version 330 core\n"
|
|
||||||
"layout (location = 0) in vec3 aPos;\n"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
|
|
||||||
"}\0";
|
|
||||||
|
|
||||||
|
|
||||||
const char* fragmentShaderSource = "#version 330 core\n"
|
|
||||||
"out vec4 FragColor;\n"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
"FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
|
|
||||||
OpenGlPainter::OpenGlPainter()
|
OpenGlPainter::OpenGlPainter()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGlPainter::initialize()
|
void OpenGlPainter::initializeMeshShader()
|
||||||
{
|
{
|
||||||
if (auto context = glXGetCurrentContext())
|
if (auto context = glXGetCurrentContext())
|
||||||
{
|
{
|
||||||
|
@ -54,99 +51,70 @@ void OpenGlPainter::initialize()
|
||||||
glGetIntegerv(GL_MINOR_VERSION, &minor_version);
|
glGetIntegerv(GL_MINOR_VERSION, &minor_version);
|
||||||
std::cout << "Using opengl version " << major_version << "|" << minor_version << std::endl;
|
std::cout << "Using opengl version " << major_version << "|" << minor_version << std::endl;
|
||||||
|
|
||||||
std::cout << "Creating opengl painter" << std::endl;
|
auto vert_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/default.vert";
|
||||||
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
auto frag_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/default.frag";
|
||||||
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
|
|
||||||
glCompileShader(vertexShader);
|
|
||||||
|
|
||||||
int success;
|
mMeshShaderProgram = std::make_unique<OpenGlShaderProgram>(vert_shader_path, frag_shader_path);
|
||||||
char infoLog[512];
|
}
|
||||||
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
|
|
||||||
if(!success)
|
void OpenGlPainter::initializeTextShader()
|
||||||
|
{
|
||||||
|
auto vert_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/text.vert";
|
||||||
|
auto frag_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/text.frag";
|
||||||
|
|
||||||
|
mTextShaderProgram = std::make_unique<OpenGlShaderProgram>(vert_shader_path, frag_shader_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGlPainter::renderTextLayer(const TextData& textData, DrawingContext* context)
|
||||||
|
{
|
||||||
|
if (!mTextShaderProgram)
|
||||||
{
|
{
|
||||||
glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
|
initializeTextShader();
|
||||||
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED: " << std::string(infoLog) << std::endl;
|
}
|
||||||
|
|
||||||
if (auto errCode = glGetError(); errCode != GL_NO_ERROR)
|
auto first_char = textData.mContent[0];
|
||||||
{
|
auto iter = mFontTextures.find(first_char);
|
||||||
auto errString = gluErrorString(errCode);
|
OpenGlFontTexture* working_texture{nullptr};
|
||||||
std::cout << "Got gl error" << errString << std::endl;
|
if (iter == mFontTextures.end())
|
||||||
}
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Shader compiled ok" << std::endl;
|
working_texture = iter->second.get();
|
||||||
if (auto errCode = glGetError(); errCode != GL_NO_ERROR)
|
|
||||||
{
|
|
||||||
auto errString = gluErrorString(errCode);
|
|
||||||
std::cout << "Got gl error after ok" << errString << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int fragmentShader;
|
glEnable(GL_BLEND);
|
||||||
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
|
|
||||||
glCompileShader(fragmentShader);
|
|
||||||
|
|
||||||
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
|
|
||||||
|
|
||||||
if(!success)
|
|
||||||
{
|
|
||||||
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
|
|
||||||
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED: " << infoLog << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
mShaderProgram = glCreateProgram();
|
|
||||||
|
|
||||||
glAttachShader(mShaderProgram, vertexShader);
|
|
||||||
glAttachShader(mShaderProgram, fragmentShader);
|
|
||||||
glLinkProgram(mShaderProgram);
|
|
||||||
|
|
||||||
glGetProgramiv(mShaderProgram, GL_LINK_STATUS, &success);
|
|
||||||
if(!success)
|
|
||||||
{
|
|
||||||
glGetProgramInfoLog(mShaderProgram, 512, NULL, infoLog);
|
|
||||||
std::cout << "Shader linking FAILED\n" << infoLog << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
glDeleteShader(vertexShader);
|
|
||||||
glDeleteShader(fragmentShader);
|
|
||||||
|
|
||||||
mInitialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGlPainter::paint(DrawingContext* context)
|
void OpenGlPainter::renderMeshLayer(TriMesh* mesh, DrawingContext* context)
|
||||||
{
|
{
|
||||||
if (!mInitialized)
|
if (!mMeshShaderProgram)
|
||||||
{
|
{
|
||||||
initialize();
|
initializeMeshShader();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto surface = context->getSurface();
|
|
||||||
const auto width = double(surface->getWidth());
|
|
||||||
const auto height = double(surface->getHeight());
|
|
||||||
const auto num_mesh = context->getScene()->getNumMeshes();
|
|
||||||
|
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
//glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
|
||||||
//glScissor(0, 0, width, height);
|
|
||||||
//glMatrixMode(GL_PROJECTION);
|
|
||||||
//glLoadIdentity();
|
|
||||||
|
|
||||||
glClearColor(0.5, 0.5, 1.0, 0.0);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
//glMatrixMode(GL_MODELVIEW);
|
|
||||||
//glLoadIdentity();
|
|
||||||
|
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
-0.5f, -0.5f, 0.0f,
|
0.5f, 0.5f, 0.0f, // top right
|
||||||
0.5f, -0.5f, 0.0f,
|
0.5f, -0.5f, 0.0f, // bottom right
|
||||||
0.0f, 0.5f, 0.0f
|
-0.5f, -0.5f, 0.0f, // bottom left
|
||||||
|
-0.5f, 0.5f, 0.0f // top left
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int indices[] = { // note that we start from 0!
|
||||||
|
0, 1, 3, // first triangle
|
||||||
|
1, 2, 3 // second triangle
|
||||||
};
|
};
|
||||||
unsigned int vbo{0};
|
unsigned int vbo{0};
|
||||||
glGenBuffers(1, &vbo);
|
glGenBuffers(1, &vbo);
|
||||||
|
|
||||||
|
unsigned int EBO;
|
||||||
|
glGenBuffers(1, &EBO);
|
||||||
|
|
||||||
unsigned int VAO;
|
unsigned int VAO;
|
||||||
glGenVertexArrays(1, &VAO);
|
glGenVertexArrays(1, &VAO);
|
||||||
glBindVertexArray(VAO);
|
glBindVertexArray(VAO);
|
||||||
|
@ -154,14 +122,22 @@ void OpenGlPainter::paint(DrawingContext* context)
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
glUseProgram(mShaderProgram);
|
int vertexColorLocation = glGetUniformLocation(mMeshShaderProgram->getHandle(), "ourColor");
|
||||||
|
|
||||||
|
glUseProgram(mMeshShaderProgram->getHandle());
|
||||||
glBindVertexArray(VAO);
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glUniform4f(vertexColorLocation, 0.0f, 1.0, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
/*
|
/*
|
||||||
std::cout << "Bounds are : " << width << " | " << height << std::endl;
|
std::cout << "Bounds are : " << width << " | " << height << std::endl;
|
||||||
|
|
||||||
|
@ -207,6 +183,31 @@ void OpenGlPainter::paint(DrawingContext* context)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGlPainter::paint(DrawingContext* context)
|
||||||
|
{
|
||||||
|
auto surface = context->getSurface();
|
||||||
|
const auto width = double(surface->getWidth());
|
||||||
|
const auto height = double(surface->getHeight());
|
||||||
|
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
//glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
||||||
|
//glScissor(0, 0, width, height);
|
||||||
|
//glMatrixMode(GL_PROJECTION);
|
||||||
|
//glLoadIdentity();
|
||||||
|
|
||||||
|
glClearColor(0.5, 0.5, 1.0, 0.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
//glMatrixMode(GL_MODELVIEW);
|
||||||
|
//glLoadIdentity();
|
||||||
|
|
||||||
|
const auto num_mesh = context->getScene()->getNumMeshes();
|
||||||
|
//renderMeshLayer(nullptr, context);
|
||||||
|
|
||||||
|
auto text_data = context->getScene()->getTextData();
|
||||||
|
renderTextLayer(text_data[0], context);
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,33 @@
|
||||||
|
|
||||||
#include "AbstractPainter.h"
|
#include "AbstractPainter.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class DrawingContext;
|
class DrawingContext;
|
||||||
|
class OpenGlFontTexture;
|
||||||
|
class OpenGlShaderProgram;
|
||||||
|
|
||||||
|
class TextData;
|
||||||
|
class TriMesh;
|
||||||
|
|
||||||
class OpenGlPainter : public AbstractPainter
|
class OpenGlPainter : public AbstractPainter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OpenGlPainter();
|
OpenGlPainter();
|
||||||
|
|
||||||
|
|
||||||
void initialize();
|
|
||||||
void paint(DrawingContext* context) override;
|
void paint(DrawingContext* context) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mInitialized{false};
|
void initializeMeshShader();
|
||||||
unsigned int mShaderProgram{0};
|
void initializeTextShader();
|
||||||
|
|
||||||
|
void renderTextLayer(const TextData& textData, DrawingContext* context);
|
||||||
|
void renderMeshLayer(TriMesh* mesh, DrawingContext* context);
|
||||||
|
|
||||||
|
std::unique_ptr<OpenGlShaderProgram> mMeshShaderProgram;
|
||||||
|
std::unique_ptr<OpenGlShaderProgram> mTextShaderProgram;
|
||||||
|
std::unordered_map<char, std::unique_ptr<OpenGlFontTexture> > mFontTextures;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
68
src/graphics/opengl/OpenGlShaderProgram.cpp
Normal file
68
src/graphics/opengl/OpenGlShaderProgram.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#include "OpenGlShaderProgram.h"
|
||||||
|
|
||||||
|
#include "File.h"
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
|
|
||||||
|
OpenGlShaderProgram::OpenGlShaderProgram(const Path& vertShaderPath, const Path& fragShaderPath)
|
||||||
|
{
|
||||||
|
const auto vert_shader_source = File(vertShaderPath).read();
|
||||||
|
const auto frag_shader_source = File(fragShaderPath).read();
|
||||||
|
|
||||||
|
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
|
||||||
|
const char* vert_source = vert_shader_source.c_str();
|
||||||
|
glShaderSource(vertexShader, 1, &vert_source, nullptr);
|
||||||
|
glCompileShader(vertexShader);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
char infoLog[512];
|
||||||
|
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
|
||||||
|
MLOG_ERROR("ERROR::SHADER::VERTEX::COMPILATION_FAILED: " << infoLog);
|
||||||
|
if (auto errCode = glGetError(); errCode != GL_NO_ERROR)
|
||||||
|
{
|
||||||
|
auto errString = gluErrorString(errCode);
|
||||||
|
MLOG_ERROR("Got gl error " << errString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int fragmentShader;
|
||||||
|
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
const char* frag_source = frag_shader_source.c_str();
|
||||||
|
glShaderSource(fragmentShader, 1, &frag_source, nullptr);
|
||||||
|
glCompileShader(fragmentShader);
|
||||||
|
|
||||||
|
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
|
||||||
|
MLOG_ERROR("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED: " << infoLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
mHandle = glCreateProgram();
|
||||||
|
|
||||||
|
glAttachShader(mHandle, vertexShader);
|
||||||
|
glAttachShader(mHandle, fragmentShader);
|
||||||
|
glLinkProgram(mHandle);
|
||||||
|
|
||||||
|
glGetProgramiv(mHandle, GL_LINK_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetProgramInfoLog(mHandle, 512, NULL, infoLog);
|
||||||
|
MLOG_ERROR("Shader linking FAILED: " << infoLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(vertexShader);
|
||||||
|
glDeleteShader(fragmentShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int OpenGlShaderProgram::getHandle() const
|
||||||
|
{
|
||||||
|
return mHandle;
|
||||||
|
}
|
15
src/graphics/opengl/OpenGlShaderProgram.h
Normal file
15
src/graphics/opengl/OpenGlShaderProgram.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
using Path = std::filesystem::path;
|
||||||
|
|
||||||
|
class OpenGlShaderProgram
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenGlShaderProgram(const Path& vertShaderPath, const Path& fragShaderPath);
|
||||||
|
|
||||||
|
unsigned int getHandle() const;
|
||||||
|
private:
|
||||||
|
unsigned int mHandle{0};
|
||||||
|
};
|
11
src/graphics/opengl/shaders/default.frag
Normal file
11
src/graphics/opengl/shaders/default.frag
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in vec4 vertexColor; // the input variable from the vertex shader (same name and same type)
|
||||||
|
|
||||||
|
uniform vec4 ourColor; // we set this variable in the OpenGL code.
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = ourColor;
|
||||||
|
}
|
10
src/graphics/opengl/shaders/default.vert
Normal file
10
src/graphics/opengl/shaders/default.vert
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 aPos; // the position variable has attribute position 0
|
||||||
|
|
||||||
|
out vec4 vertexColor; // specify a color output to the fragment shader
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(aPos, 1.0); // see how we directly give a vec3 to vec4's constructor
|
||||||
|
vertexColor = vec4(aPos.x, aPos.y, 0.0, 1.0); // set the output variable to a dark-red color
|
||||||
|
}
|
12
src/graphics/opengl/shaders/text.frag
Normal file
12
src/graphics/opengl/shaders/text.frag
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#version 330 core
|
||||||
|
in vec2 TexCoords;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform sampler2D text;
|
||||||
|
uniform vec3 textColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
|
||||||
|
color = vec4(textColor, 1.0) * sampled;
|
||||||
|
}
|
11
src/graphics/opengl/shaders/text.vert
Normal file
11
src/graphics/opengl/shaders/text.vert
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>
|
||||||
|
out vec2 TexCoords;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
|
||||||
|
TexCoords = vertex.zw;
|
||||||
|
}
|
|
@ -34,25 +34,28 @@ void Scene::update(FontsManager* fontsManager, Image<unsigned char>* image)
|
||||||
node->update(fontsManager);
|
node->update(fontsManager);
|
||||||
layer->setIsDirty(false);
|
layer->setIsDirty(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
mWorkingMeshs.push_back(dynamic_cast<TriMesh*>(node->getMesh()));
|
mWorkingMeshs.push_back(dynamic_cast<TriMesh*>(node->getMesh()));
|
||||||
mTextures.push_back(nullptr);
|
mTextures.push_back(nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto node = layer->getTextNode();
|
auto node = dynamic_cast<TextNode*>(layer->getTextNode());
|
||||||
if (layer->getIsDirty())
|
if (layer->getIsDirty())
|
||||||
{
|
{
|
||||||
node->update(fontsManager);
|
node->update(fontsManager);
|
||||||
layer->setIsDirty(false);
|
layer->setIsDirty(false);
|
||||||
}
|
}
|
||||||
mWorkingMeshs.push_back(dynamic_cast<TriMesh*>(node->getMesh()));
|
mTextData.push_back(node->getTextData());
|
||||||
mTextures.push_back(node->getTexture());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<TextData>& Scene::getTextData() const
|
||||||
|
{
|
||||||
|
return mTextData;
|
||||||
|
}
|
||||||
|
|
||||||
void Scene::processRectangleNode(RectangleNode* node)
|
void Scene::processRectangleNode(RectangleNode* node)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "TextData.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -15,6 +17,7 @@ class Image;
|
||||||
class Scene
|
class Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Scene() = default;
|
Scene() = default;
|
||||||
|
|
||||||
void syncLayers(const std::vector<VisualLayer*>& layers);
|
void syncLayers(const std::vector<VisualLayer*>& layers);
|
||||||
|
@ -27,11 +30,14 @@ public:
|
||||||
|
|
||||||
Image<unsigned char>* getTexture(std::size_t idx) const;
|
Image<unsigned char>* getTexture(std::size_t idx) const;
|
||||||
|
|
||||||
private:
|
const std::vector<TextData>& getTextData() const;
|
||||||
|
|
||||||
|
private:
|
||||||
void processRectangleNode(RectangleNode* node);
|
void processRectangleNode(RectangleNode* node);
|
||||||
|
|
||||||
std::vector<TriMesh*> mWorkingMeshs;
|
|
||||||
std::vector<VisualLayer*> mLayers;
|
std::vector<VisualLayer*> mLayers;
|
||||||
|
std::vector<TriMesh*> mWorkingMeshs;
|
||||||
std::vector<Image<unsigned char>* > mTextures;
|
std::vector<Image<unsigned char>* > mTextures;
|
||||||
|
|
||||||
|
std::vector<TextData> mTextData;
|
||||||
};
|
};
|
||||||
|
|
16
src/visual_elements/TextData.h
Normal file
16
src/visual_elements/TextData.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DiscretePoint.h"
|
||||||
|
#include "Color.h"
|
||||||
|
#include "FontItem.h"
|
||||||
|
|
||||||
|
class TextData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextData() = default;
|
||||||
|
DiscretePoint mLocation;
|
||||||
|
std::string mContent;
|
||||||
|
Color mFillColor;
|
||||||
|
Color mStrokeColor;
|
||||||
|
FontItem mFont;
|
||||||
|
};
|
|
@ -4,17 +4,18 @@
|
||||||
#include "FontsManager.h"
|
#include "FontsManager.h"
|
||||||
#include "IFontEngine.h"
|
#include "IFontEngine.h"
|
||||||
#include "MeshPrimitives.h"
|
#include "MeshPrimitives.h"
|
||||||
|
#include "FontItem.h"
|
||||||
|
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
|
|
||||||
TextNode::TextNode(const std::string& content, const DiscretePoint& loc)
|
TextNode::TextNode(const std::string& content, const DiscretePoint& loc)
|
||||||
: AbstractVisualNode(loc),
|
: AbstractVisualNode(loc)
|
||||||
mContent(content),
|
|
||||||
mFontLabel("fixed"),
|
|
||||||
mFillColor(Color(255, 255, 255)),
|
|
||||||
mStrokeColor(Color(0, 0, 0))
|
|
||||||
{
|
{
|
||||||
// https://en.wikipedia.org/wiki/Fixed_(typeface)#:~:text=misc%2Dfixed%20is%20a%20collection,to%20a%20single%20font%20family.
|
mTextData.mContent = content;
|
||||||
|
mTextData.mFont = FontItem("Arial", 16);
|
||||||
|
mTextData.mLocation = loc;
|
||||||
|
mTextData.mFillColor = Color(255, 255, 255);
|
||||||
|
mTextData.mStrokeColor = Color(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextNode::~TextNode()
|
TextNode::~TextNode()
|
||||||
|
@ -29,36 +30,36 @@ std::unique_ptr<TextNode> TextNode::Create(const std::string& content, const Dis
|
||||||
|
|
||||||
const Color& TextNode::getFillColor() const
|
const Color& TextNode::getFillColor() const
|
||||||
{
|
{
|
||||||
return mFillColor;
|
return mTextData.mFillColor;
|
||||||
}
|
}
|
||||||
const Color& TextNode::getStrokeColor() const
|
const Color& TextNode::getStrokeColor() const
|
||||||
{
|
{
|
||||||
return mStrokeColor;
|
return mTextData.mStrokeColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TextNode::getFontLabel() const
|
std::string TextNode::getFontLabel() const
|
||||||
{
|
{
|
||||||
return mFontLabel;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TextNode::getContent() const
|
std::string TextNode::getContent() const
|
||||||
{
|
{
|
||||||
return mContent;
|
return mTextData.mContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextNode::setContent(const std::string& content)
|
void TextNode::setContent(const std::string& content)
|
||||||
{
|
{
|
||||||
mContent = content;
|
mTextData.mContent = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextNode::setFillColor(const Color& color)
|
void TextNode::setFillColor(const Color& color)
|
||||||
{
|
{
|
||||||
mFillColor = color;
|
mTextData.mFillColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextNode::setStrokeColor(const Color& color)
|
void TextNode::setStrokeColor(const Color& color)
|
||||||
{
|
{
|
||||||
mStrokeColor = color;
|
mTextData.mStrokeColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextNode::update(FontsManager* drawingManager)
|
void TextNode::update(FontsManager* drawingManager)
|
||||||
|
@ -67,32 +68,17 @@ void TextNode::update(FontsManager* drawingManager)
|
||||||
updateTexture(drawingManager);
|
updateTexture(drawingManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TextData& TextNode::getTextData() const
|
||||||
|
{
|
||||||
|
return mTextData;
|
||||||
|
}
|
||||||
|
|
||||||
void TextNode::updateMesh()
|
void TextNode::updateMesh()
|
||||||
{
|
{
|
||||||
double font_height = 16;
|
|
||||||
double font_width = 16;
|
|
||||||
|
|
||||||
double text_width = mContent.size() * font_width;
|
|
||||||
|
|
||||||
const auto rect = Rectangle(mLocation, text_width, font_height);
|
|
||||||
|
|
||||||
auto mesh = MeshPrimitives::build(rect);
|
|
||||||
auto color = Color(0, 0, 0, 1.0);
|
|
||||||
|
|
||||||
mesh->addConstantFaceVectorAttribute("Color", color.getAsVectorDouble());
|
|
||||||
mMesh = std::move(mesh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextNode::updateTexture(FontsManager* fontsManager)
|
void TextNode::updateTexture(FontsManager* fontsManager)
|
||||||
{
|
{
|
||||||
fontsManager->getFontEngine()->loadFontFace("truetype/msttcorefonts/arial.ttf");
|
|
||||||
auto glyph = fontsManager->getFontEngine()->loadGlyph('A');
|
|
||||||
|
|
||||||
if (!glyph)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mTexture = std::make_unique<Image<unsigned char> >(glyph->getWidth(), glyph->getHeight());
|
|
||||||
mTexture->setData(glyph->getData());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
|
|
||||||
#include "AbstractVisualNode.h"
|
#include "AbstractVisualNode.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
|
#include "FontItem.h"
|
||||||
|
#include "TextData.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class Color;
|
|
||||||
|
|
||||||
class TextNode : public AbstractVisualNode
|
class TextNode : public AbstractVisualNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -24,6 +24,9 @@ public:
|
||||||
|
|
||||||
std::string getContent() const;
|
std::string getContent() const;
|
||||||
std::string getFontLabel() const;
|
std::string getFontLabel() const;
|
||||||
|
|
||||||
|
const TextData& getTextData() const;
|
||||||
|
|
||||||
void setContent(const std::string& content);
|
void setContent(const std::string& content);
|
||||||
void setFillColor(const Color& color);
|
void setFillColor(const Color& color);
|
||||||
void setStrokeColor(const Color& color);
|
void setStrokeColor(const Color& color);
|
||||||
|
@ -34,10 +37,7 @@ private:
|
||||||
void updateMesh() override;
|
void updateMesh() override;
|
||||||
void updateTexture(FontsManager* fontsManager) override;
|
void updateTexture(FontsManager* fontsManager) override;
|
||||||
|
|
||||||
std::string mContent;
|
TextData mTextData;
|
||||||
std::string mFontLabel;
|
|
||||||
Color mFillColor;
|
|
||||||
Color mStrokeColor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using TextNodetr = std::unique_ptr<TextNode>;
|
using TextNodetr = std::unique_ptr<TextNode>;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "IFontEngine.h"
|
#include "IFontEngine.h"
|
||||||
#include "FontsManager.h"
|
#include "FontsManager.h"
|
||||||
|
#include "FontGlyph.h"
|
||||||
|
|
||||||
namespace mt
|
namespace mt
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include "FreeTypeFontEngine.h"
|
#include "FreeTypeFontEngine.h"
|
||||||
|
#include "FontGlyph.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
Loading…
Reference in a new issue