openGL+freetype 动态加载中文

2023-10-19 05:40

本文主要是介绍openGL+freetype 动态加载中文,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

   能搜索这个相信你已经openGL已经入门了,所以我只上传了加载freetype的类。如果你根据我写的实现不出效果的话,可以私信我,发你项目源码(如果我看到的话)

.h文件

#pragma once#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <vector>#include "Shader.h"struct word {unsigned int texture;unsigned int VAO;
};class LoadText
{
public:LoadText(std::string rootPath);void loadText(const wchar_t* text, GLfloat x, GLfloat y);void drawText();~LoadText(){delete this->shader;}
private:std::string rootPath;Shader* shader;std::vector< word> textVecs;void loadShader(); //加载shader的
};

.cpp文件

#include "LoadText.h"#include <fstream>
#include <sstream>#include <ft2build.h>
#include FT_FREETYPE_H#include<wchar.h>LoadText::LoadText(std::string rootPath):rootPath(rootPath)
{this->loadShader();
}// 文本 坐标
void LoadText::loadText(const wchar_t* text, GLfloat x, GLfloat y)
{std::string fontPath = this->rootPath + "\\simkai.ttf";glm::mat4 projection = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f);this->shader->use();this->shader->setMat4("projection", projection);//字体颜色this->shader->set3f("textColor", glm::vec3(0.0f, 1.0f, 0.0f));//初始化FreeType库FT_Library ft;if (FT_Init_FreeType(&ft))std::cout << "FreeType初始化失败" << std::endl;FT_Face face;if (FT_New_Face(ft, fontPath.c_str(), 0, &face))std::cout << "字体加载失败" << std::endl;//定义字体大小FT_Set_Pixel_Sizes(face, 0, 48);glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //禁用字节对齐限制int lew_w = wcslen(text);for (GLubyte i = 0; i < lew_w; i++){// 加载字符的字形 if (FT_Load_Char(face, text[i], FT_LOAD_RENDER)){std::cout << "字形加载失败" << std::endl;continue;}// 字形大小int font_width = face->glyph->bitmap.width;int font_rows = face->glyph->bitmap.rows;// 从基准线到字形左部/顶部的偏移值int font_left = face->glyph->bitmap_left;int font_top  = face->glyph->bitmap_top;// 原点距下一个字形原点的距离int font_x = face->glyph->advance.x;//unsigned char* data = face->glyph->bitmap.buffer;// 生成纹理GLuint texture;glGenTextures(1, &texture);glBindTexture(GL_TEXTURE_2D, texture);glTexImage2D(GL_TEXTURE_2D,0,GL_RED,font_width,font_rows,0,GL_RED,GL_UNSIGNED_BYTE,data);// 设置纹理选项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);GLfloat xpos = x + font_left;GLfloat ypos = y - (font_rows - font_top);GLfloat w = font_width;GLfloat h = font_rows;// 对每个字符更新VBOGLfloat vertices[6][4] = {{ xpos,			     ypos + font_rows,   0.0, 0.0 },{ xpos,				 ypos,				 0.0, 1.0 },{ xpos + font_width, ypos,				 1.0, 1.0 },{ xpos,				 ypos + font_rows,   0.0, 0.0 },{ xpos + font_width, ypos,				 1.0, 1.0 },{ xpos + font_width, ypos + font_rows,   1.0, 0.0 }};unsigned int VAO, VBO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO);glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * 4, &vertices[0][0], GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);glBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);word fw1;fw1.texture = texture;fw1.VAO = VAO;this->textVecs.push_back(fw1);x += (font_x >> 6);}glBindVertexArray(0);glBindTexture(GL_TEXTURE_2D, 0);}void LoadText::drawText()
{for (int i = 0; i < this->textVecs.size(); i++){word wf = this->textVecs[i];glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, wf.texture);glBindVertexArray(wf.VAO);glDrawArrays(GL_TRIANGLES, 0, 6);glBindVertexArray(0);glActiveTexture(GL_TEXTURE0);}
}void LoadText::loadShader()
{std::string vertCode, fragCode;std::stringstream vertexSStream, fragmentSStream;const char* vertexSource;const char* fragmentSource;try{std::ifstream vertexFile("v1.vert");std::ifstream fragmentFile("f1.frag");vertexFile.exceptions(std::ifstream::failbit || std::ifstream::badbit);fragmentFile.exceptions(std::ifstream::failbit || std::ifstream::badbit);if (!vertexFile.is_open() || !fragmentFile.is_open()) {throw std::exception("文件打开失败");}vertexSStream << vertexFile.rdbuf();vertCode = vertexSStream.str();vertexFile.close();fragmentSStream << fragmentFile.rdbuf();fragCode = fragmentSStream.str();fragmentFile.close();vertexSource = vertCode.c_str();fragmentSource = fragCode.c_str();this->shader = new Shader;this->shader->setID(vertexSource, fragmentSource);}catch (const std::exception& e){printf(e.what());}}

这是我自学来的,就是想分享一下经验,如果有语法方面的不足,勿怪哈

这篇关于openGL+freetype 动态加载中文的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/237699

相关文章

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可