mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 04:30:05 +00:00 
			
		
		
		
	Create a text shader and font utility
This commit is contained in:
		
							parent
							
								
									817a59f741
								
							
						
					
					
						commit
						82b265b6d4
					
				
					 11 changed files with 473 additions and 5 deletions
				
			
		|  | @ -13,6 +13,7 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) | |||
| include(${PROJECT_SOURCE_DIR}/external/cmake-conan/conan.cmake) | ||||
| 
 | ||||
| conan_cmake_configure(REQUIRES boost/1.76.0 | ||||
|                                freetype/2.10.4 | ||||
|                                geographiclib/1.52 | ||||
|                                glm/0.9.9.8 | ||||
|                                gtest/cci.20210126 | ||||
|  |  | |||
							
								
								
									
										12
									
								
								scwx-qt/gl/text.frag
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								scwx-qt/gl/text.frag
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| #version 330 core | ||||
| in vec2 texCoords; | ||||
| out vec4 color; | ||||
| 
 | ||||
| uniform sampler2D text; | ||||
| uniform vec4 textColor; | ||||
| 
 | ||||
| void main() | ||||
| { | ||||
|    vec4 sampled = vec4(1.0f, 1.0f, 1.0f, texture(text, texCoords).r); | ||||
|    color        = textColor * sampled; | ||||
| } | ||||
							
								
								
									
										11
									
								
								scwx-qt/gl/text.vert
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								scwx-qt/gl/text.vert
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| #version 330 core | ||||
| layout (location = 0) in vec4 vertex; | ||||
| out vec2 texCoords; | ||||
| 
 | ||||
| uniform mat4 projection; | ||||
| 
 | ||||
| void main() | ||||
| { | ||||
|    gl_Position = projection * vec4(vertex.xy, 0.0f, 1.0f); | ||||
|    texCoords   = vertex.zw; | ||||
| } | ||||
|  | @ -12,6 +12,7 @@ set(CMAKE_CXX_STANDARD 17) | |||
| set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||||
| 
 | ||||
| find_package(Boost) | ||||
| find_package(Freetype) | ||||
| find_package(geographiclib) | ||||
| find_package(glm) | ||||
| 
 | ||||
|  | @ -51,6 +52,8 @@ set(HDR_MAIN source/scwx/qt/main/main_window.hpp) | |||
| set(SRC_MAIN source/scwx/qt/main/main.cpp | ||||
|              source/scwx/qt/main/main_window.cpp) | ||||
| set(UI_MAIN  source/scwx/qt/main/main_window.ui) | ||||
| set(HDR_GL source/scwx/qt/gl/text_shader.hpp) | ||||
| set(SRC_GL source/scwx/qt/gl/text_shader.cpp) | ||||
| set(HDR_MANAGER source/scwx/qt/manager/radar_manager.hpp) | ||||
| set(SRC_MANAGER source/scwx/qt/manager/radar_manager.cpp) | ||||
| set(HDR_MAP source/scwx/qt/map/map_widget.hpp | ||||
|  | @ -61,16 +64,20 @@ set(SRC_MAP source/scwx/qt/map/map_widget.cpp | |||
|             source/scwx/qt/map/radar_layer.cpp | ||||
|             source/scwx/qt/map/radar_range_layer.cpp | ||||
|             source/scwx/qt/map/triangle_layer.cpp) | ||||
| set(HDR_UTIL source/scwx/qt/util/gl.hpp | ||||
| set(HDR_UTIL source/scwx/qt/util/font.hpp | ||||
|              source/scwx/qt/util/gl.hpp | ||||
|              source/scwx/qt/util/shader_program.hpp) | ||||
| set(SRC_UTIL source/scwx/qt/util/shader_program.cpp) | ||||
| set(SRC_UTIL source/scwx/qt/util/font.cpp | ||||
|              source/scwx/qt/util/shader_program.cpp) | ||||
| set(HDR_VIEW source/scwx/qt/view/radar_view.hpp) | ||||
| set(SRC_VIEW source/scwx/qt/view/radar_view.cpp) | ||||
| 
 | ||||
| set(RESOURCE_FILES scwx-qt.qrc) | ||||
| 
 | ||||
| set(SHADER_FILES gl/radar.frag | ||||
|                  gl/radar.vert) | ||||
|                  gl/radar.vert | ||||
|                  gl/text.frag | ||||
|                  gl/text.vert) | ||||
| 
 | ||||
| set(TS_FILES ts/scwx_en_US.ts) | ||||
| 
 | ||||
|  | @ -122,6 +129,7 @@ target_link_libraries(scwx-qt PRIVATE Qt${QT_VERSION_MAJOR}::Widgets | |||
|                                       Boost::timer | ||||
|                                       qmapboxgl | ||||
|                                       opengl32 | ||||
|                                       Freetype::Freetype | ||||
|                                       GeographicLib::GeographicLib | ||||
|                                       glm::glm | ||||
|                                       wxdata) | ||||
|  |  | |||
|  | @ -2,5 +2,7 @@ | |||
|     <qresource prefix="/"> | ||||
|         <file>gl/radar.frag</file> | ||||
|         <file>gl/radar.vert</file> | ||||
|         <file>gl/text.frag</file> | ||||
|         <file>gl/text.vert</file> | ||||
|     </qresource> | ||||
| </RCC> | ||||
|  |  | |||
							
								
								
									
										155
									
								
								scwx-qt/source/scwx/qt/gl/text_shader.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								scwx-qt/source/scwx/qt/gl/text_shader.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,155 @@ | |||
| #include <scwx/qt/gl/text_shader.hpp> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| #include <glm/gtc/type_ptr.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace gl | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "[scwx::qt::gl::text_shader] "; | ||||
| 
 | ||||
| class TextShaderImpl | ||||
| { | ||||
| public: | ||||
|    explicit TextShaderImpl(OpenGLFunctions& gl) : | ||||
|        gl_ {gl}, | ||||
|        projectionLocation_(GL_INVALID_INDEX), | ||||
|        textColorLocation_(GL_INVALID_INDEX), | ||||
|        vao_ {GL_INVALID_INDEX}, | ||||
|        vbo_ {GL_INVALID_INDEX} | ||||
|    { | ||||
|    } | ||||
| 
 | ||||
|    ~TextShaderImpl() {} | ||||
| 
 | ||||
|    OpenGLFunctions& gl_; | ||||
| 
 | ||||
|    GLint projectionLocation_; | ||||
|    GLint textColorLocation_; | ||||
| 
 | ||||
|    GLuint vao_; | ||||
|    GLuint vbo_; | ||||
| }; | ||||
| 
 | ||||
| TextShader::TextShader(OpenGLFunctions& gl) : | ||||
|     ShaderProgram(gl), p(std::make_unique<TextShaderImpl>(gl)) | ||||
| { | ||||
| } | ||||
| TextShader::~TextShader() = default; | ||||
| 
 | ||||
| TextShader::TextShader(TextShader&&) noexcept = default; | ||||
| TextShader& TextShader::operator=(TextShader&&) noexcept = default; | ||||
| 
 | ||||
| bool TextShader::Initialize() | ||||
| { | ||||
|    OpenGLFunctions& gl = p->gl_; | ||||
| 
 | ||||
|    // Load and configure shader
 | ||||
|    bool success = Load(":/gl/text.vert", ":/gl/text.frag"); | ||||
| 
 | ||||
|    p->projectionLocation_ = gl.glGetUniformLocation(id(), "projection"); | ||||
|    if (p->projectionLocation_ == -1) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Could not find projection"; | ||||
|    } | ||||
| 
 | ||||
|    p->textColorLocation_ = gl.glGetUniformLocation(id(), "textColor"); | ||||
|    if (p->textColorLocation_ == -1) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Could not find textColor"; | ||||
|    } | ||||
| 
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
|    gl.glGenBuffers(1, &p->vbo_); | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||
|    gl.glBufferData( | ||||
|       GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, nullptr, GL_DYNAMIC_DRAW); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
|    gl.glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||
|    gl.glBindVertexArray(0); | ||||
| 
 | ||||
|    return success; | ||||
| } | ||||
| 
 | ||||
| void TextShader::RenderText(const std::string&               text, | ||||
|                             float                            x, | ||||
|                             float                            y, | ||||
|                             float                            scale, | ||||
|                             const glm::mat4&                 projection, | ||||
|                             const boost::gil::rgba8_pixel_t& color, | ||||
|                             const std::unordered_map<char, util::Glyph>& glyphs) | ||||
| { | ||||
|    OpenGLFunctions& gl = p->gl_; | ||||
| 
 | ||||
|    Use(); | ||||
| 
 | ||||
|    gl.glEnable(GL_BLEND); | ||||
|    gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| 
 | ||||
|    gl.glUniformMatrix4fv( | ||||
|       p->projectionLocation_, 1, GL_FALSE, glm::value_ptr(projection)); | ||||
|    gl.glUniform4f( | ||||
|       p->textColorLocation_, color[0], color[1], color[2], color[3]); | ||||
| 
 | ||||
|    gl.glActiveTexture(GL_TEXTURE0); | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|    for (auto c = text.cbegin(); c != text.cend(); c++) | ||||
|    { | ||||
|       if (glyphs.find(*c) == glyphs.end()) | ||||
|       { | ||||
|          continue; | ||||
|       } | ||||
| 
 | ||||
|       const util::Glyph& g = glyphs.at(*c); | ||||
| 
 | ||||
|       float xpos = x + g.bearing.x * scale; | ||||
|       float ypos = y - (g.size.y - g.bearing.y) * scale; | ||||
| 
 | ||||
|       float w = g.size.x * scale; | ||||
|       float h = g.size.y * scale; | ||||
| 
 | ||||
|       // Glyph vertices
 | ||||
|       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
 | ||||
|       gl.glBindTexture(GL_TEXTURE_2D, g.textureId); | ||||
| 
 | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||
|       gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); | ||||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||
| 
 | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, 6); | ||||
| 
 | ||||
|       // Advance to the next glyph
 | ||||
|       x += (g.advance >> 6) * scale; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void TextShader::SetProjection(const glm::mat4& projection) | ||||
| { | ||||
|    p->gl_.glUniformMatrix4fv( | ||||
|       p->projectionLocation_, 1, GL_FALSE, glm::value_ptr(projection)); | ||||
| } | ||||
| 
 | ||||
| void TextShader::SetTextColor(const boost::gil::rgba8_pixel_t color) | ||||
| { | ||||
|    p->gl_.glUniform4f( | ||||
|       p->textColorLocation_, color[0], color[1], color[2], color[3]); | ||||
| } | ||||
| 
 | ||||
| } // namespace gl
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										49
									
								
								scwx-qt/source/scwx/qt/gl/text_shader.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								scwx-qt/source/scwx/qt/gl/text_shader.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/qt/util/shader_program.hpp> | ||||
| #include <scwx/qt/util/font.hpp> | ||||
| 
 | ||||
| #include <memory> | ||||
| 
 | ||||
| #include <boost/gil.hpp> | ||||
| #include <glm/glm.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace gl | ||||
| { | ||||
| 
 | ||||
| class TextShaderImpl; | ||||
| 
 | ||||
| class TextShader : public ShaderProgram | ||||
| { | ||||
| public: | ||||
|    explicit TextShader(OpenGLFunctions& gl); | ||||
|    ~TextShader(); | ||||
| 
 | ||||
|    TextShader(const TextShader&) = delete; | ||||
|    TextShader& operator=(const TextShader&) = delete; | ||||
| 
 | ||||
|    TextShader(TextShader&&) noexcept; | ||||
|    TextShader& operator=(TextShader&&) noexcept; | ||||
| 
 | ||||
|    bool Initialize(); | ||||
|    void RenderText(const std::string&                           text, | ||||
|                    float                                        x, | ||||
|                    float                                        y, | ||||
|                    float                                        scale, | ||||
|                    const glm::mat4&                             projection, | ||||
|                    const boost::gil::rgba8_pixel_t&             color, | ||||
|                    const std::unordered_map<char, util::Glyph>& glyphs); | ||||
|    void SetProjection(const glm::mat4& projection); | ||||
|    void SetTextColor(const boost::gil::rgba8_pixel_t color); | ||||
| 
 | ||||
| private: | ||||
|    std::unique_ptr<TextShaderImpl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace gl
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										179
									
								
								scwx-qt/source/scwx/qt/util/font.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								scwx-qt/source/scwx/qt/util/font.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,179 @@ | |||
| #include <scwx/qt/util/font.hpp> | ||||
| 
 | ||||
| #include <mutex> | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| #include <ft2build.h> | ||||
| #include <QFile> | ||||
| 
 | ||||
| #include FT_FREETYPE_H | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace util | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "[scwx::qt::util::font] "; | ||||
| 
 | ||||
| static std::unordered_map<std::string, std::shared_ptr<Font>> fontMap_; | ||||
| 
 | ||||
| static FT_Library ft_ {nullptr}; | ||||
| static std::mutex ftMutex_; | ||||
| 
 | ||||
| static bool InitializeFreeType(); | ||||
| 
 | ||||
| class FontImpl | ||||
| { | ||||
| public: | ||||
|    explicit FontImpl(const std::string& resource) : | ||||
|        resource_(resource), fontData_(), face_ {nullptr} | ||||
|    { | ||||
|    } | ||||
| 
 | ||||
|    ~FontImpl() {} | ||||
| 
 | ||||
|    const std::string resource_; | ||||
| 
 | ||||
|    QByteArray fontData_; | ||||
|    FT_Face    face_; | ||||
| }; | ||||
| 
 | ||||
| Font::Font(const std::string& resource) : | ||||
|     p(std::make_unique<FontImpl>(resource)) | ||||
| { | ||||
| } | ||||
| Font::~Font() | ||||
| { | ||||
|    FT_Done_Face(p->face_); | ||||
| } | ||||
| 
 | ||||
| void Font::GenerateGlyphs(OpenGLFunctions&                 gl, | ||||
|                           std::unordered_map<char, Glyph>& glyphs, | ||||
|                           unsigned int                     height) | ||||
| { | ||||
|    FT_Error error; | ||||
|    FT_Face& face = p->face_; | ||||
| 
 | ||||
|    // Allow single-byte texture colors
 | ||||
|    gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||
| 
 | ||||
|    FT_Set_Pixel_Sizes(p->face_, 0, 48); | ||||
| 
 | ||||
|    for (unsigned char c = 0; c < 128; c++) | ||||
|    { | ||||
|       if (glyphs.find(c) != glyphs.end()) | ||||
|       { | ||||
|          BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Found glyph " | ||||
|                                     << static_cast<uint16_t>(c) << ", skipping"; | ||||
|          continue; | ||||
|       } | ||||
| 
 | ||||
|       if ((error = FT_Load_Char(face, c, FT_LOAD_RENDER)) != 0) | ||||
|       { | ||||
|          BOOST_LOG_TRIVIAL(error) << logPrefix_ << "Failed to load glyph " | ||||
|                                   << static_cast<uint16_t>(c) << ": " << error; | ||||
|          continue; | ||||
|       } | ||||
| 
 | ||||
|       GLuint texture; | ||||
|       gl.glGenTextures(1, &texture); | ||||
|       gl.glBindTexture(GL_TEXTURE_2D, texture); | ||||
| 
 | ||||
|       gl.glTexImage2D(GL_TEXTURE_2D, | ||||
|                       0, | ||||
|                       GL_RED, | ||||
|                       face->glyph->bitmap.width, | ||||
|                       face->glyph->bitmap.rows, | ||||
|                       0, | ||||
|                       GL_RED, | ||||
|                       GL_UNSIGNED_BYTE, | ||||
|                       face->glyph->bitmap.buffer); | ||||
| 
 | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|       gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
| 
 | ||||
|       glyphs.insert( | ||||
|          {c, | ||||
|           Glyph { | ||||
|              texture, | ||||
|              glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows), | ||||
|              glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top), | ||||
|              face->glyph->advance.x}}); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<Font> Font::Create(const std::string& resource) | ||||
| { | ||||
|    std::shared_ptr<Font> font = nullptr; | ||||
|    FT_Error              error; | ||||
| 
 | ||||
|    if (!InitializeFreeType()) | ||||
|    { | ||||
|       return font; | ||||
|    } | ||||
| 
 | ||||
|    auto it = fontMap_.find(resource); | ||||
|    if (it != fontMap_.end()) | ||||
|    { | ||||
|       return it->second; | ||||
|    } | ||||
| 
 | ||||
|    QFile fontFile(resource.c_str()); | ||||
|    fontFile.open(QIODevice::ReadOnly); | ||||
|    if (!fontFile.isOpen()) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(error) | ||||
|          << logPrefix_ << "Could not read font file: " << resource; | ||||
|       return font; | ||||
|    } | ||||
| 
 | ||||
|    font               = std::make_shared<Font>(resource); | ||||
|    font->p->fontData_ = fontFile.readAll(); | ||||
| 
 | ||||
|    { | ||||
|       std::scoped_lock(ftMutex_); | ||||
|       if ((error = FT_New_Memory_Face( | ||||
|               ft_, | ||||
|               reinterpret_cast<const FT_Byte*>(font->p->fontData_.data()), | ||||
|               font->p->fontData_.size(), | ||||
|               0, | ||||
|               &font->p->face_)) != 0) | ||||
|       { | ||||
|          BOOST_LOG_TRIVIAL(error) | ||||
|             << logPrefix_ << "Failed to load font: " << error; | ||||
|          font.reset(); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    if (font != nullptr) | ||||
|    { | ||||
|       fontMap_.insert({resource, font}); | ||||
|    } | ||||
| 
 | ||||
|    return font; | ||||
| } | ||||
| 
 | ||||
| static bool InitializeFreeType() | ||||
| { | ||||
|    std::scoped_lock(ftMutex_); | ||||
| 
 | ||||
|    FT_Error error; | ||||
| 
 | ||||
|    if (ft_ == nullptr && (error = FT_Init_FreeType(&ft_)) != 0) | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(error) | ||||
|          << logPrefix_ << "Could not init FreeType library: " << error; | ||||
|       ft_ = nullptr; | ||||
|    } | ||||
| 
 | ||||
|    return (ft_ != nullptr); | ||||
| } | ||||
| 
 | ||||
| } // namespace util
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										51
									
								
								scwx-qt/source/scwx/qt/util/font.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								scwx-qt/source/scwx/qt/util/font.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/qt/util/gl.hpp> | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <string> | ||||
| 
 | ||||
| #include <glm/glm.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace util | ||||
| { | ||||
| 
 | ||||
| struct Glyph | ||||
| { | ||||
|    GLuint     textureId; | ||||
|    glm::ivec2 size;    // pixels
 | ||||
|    glm::ivec2 bearing; // pixels
 | ||||
|    GLint      advance; // 1/64 pixels
 | ||||
| }; | ||||
| 
 | ||||
| class FontImpl; | ||||
| 
 | ||||
| class Font | ||||
| { | ||||
| public: | ||||
|    explicit Font(const std::string& resource); | ||||
|    ~Font(); | ||||
| 
 | ||||
|    Font(const Font&) = delete; | ||||
|    Font& operator=(const Font&) = delete; | ||||
| 
 | ||||
|    Font(Font&&)  = delete; | ||||
|    Font& operator=(Font&&) = delete; | ||||
| 
 | ||||
|    void GenerateGlyphs(OpenGLFunctions&                 gl, | ||||
|                        std::unordered_map<char, Glyph>& glyphs, | ||||
|                        unsigned int                     height); | ||||
| 
 | ||||
|    static std::shared_ptr<Font> Create(const std::string& resource); | ||||
| 
 | ||||
| private: | ||||
|    std::unique_ptr<FontImpl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace util
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
|  | @ -147,7 +147,7 @@ bool ShaderProgram::Load(const std::string& vertexPath, | |||
|    gl.glDeleteShader(vertexShader); | ||||
|    gl.glDeleteShader(fragmentShader); | ||||
| 
 | ||||
|    return false; | ||||
|    return success; | ||||
| } | ||||
| 
 | ||||
| void ShaderProgram::Use() const | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ class ShaderProgram | |||
| { | ||||
| public: | ||||
|    explicit ShaderProgram(OpenGLFunctions& gl); | ||||
|    ~ShaderProgram(); | ||||
|    virtual ~ShaderProgram(); | ||||
| 
 | ||||
|    ShaderProgram(const ShaderProgram&) = delete; | ||||
|    ShaderProgram& operator=(const ShaderProgram&) = delete; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat