本文主要是介绍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 动态加载中文的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!