Четверг, 28 Марта 2024, 11:10

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Программирование » C/C++ » работа с freetype2 freetype
работа с freetype2 freetype
afqДата: Среда, 27 Февраля 2019, 07:49 | Сообщение # 1
Разработчик
Сейчас нет на сайте
Всем привет. Я достиг успеха в работе с freetype2. Пусть может быть эта тема будет кому нибудь полезна. Может кто в интернете незнает как работать с freetype, зайдет в эту тему и скачает текст класса.
Итак, вот чего я достиг. С помощью моего кода текст можно выводить в несколько строк. Эти строки будут включены в одну текстуру. Класс ведь правда? Одной текстурой рисовать несколько строк. А то я видел какие то примеры, вообще не понятные. Там как то странно нужно рисовать строки. В общем, вот что получается.

Вот как вызвать функцию.
Код

        wchar_t * text = L"привет gcup, я пишу в линуксе с sdl2 и opengl.\n"
                "Мне нравиться когда у меня начинает что-то получаться.\n"
                "А также я считаю что эта тема может пригодиться многим, кто хочет работать с freetype2.\n"
                "И так, код будет снизу!";
        font->init ( text, 21, 1, 4, 4, 0, 0, 0 );

Функция init принимает параметры.
\1 текст
\2 размер шрифта
\3 расстояние между шрифтами по горизонтали в пикселях
\3 расстояние между шрифтами по вертикали в пикселях
\3 размер пробела в пикселях
\4 красный цвет
\5 зеленый цвет
\6 синий цвет

Вот код font.hpp
Код

#ifndef H_FONT_H
#define H_FONT_H
#include <stdint.h>
#include <ft2build.h>
#include <string>
#include <vector>
#include <SDL2/SDL_opengl.h>
#include <SDL2/SDL_opengles2.h>
#include "gl_mat.hpp"
#include "global.hpp"
#include <wchar.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H

class Font {
    public:
  Font ( ) { }
  Font ( const char *ttf_file );
  void setPos ( int x, int y );
  void init ( wchar_t *text, int fontSize, int align, int valign, int space, uint8_t r, uint8_t g, uint8_t b );
  void setSize ( int w, int h );
  void draw ( );
    private:
  FT_Face face = 0;
  float *texture;
  float *vertices;
  int width;
  int height;
  int sampler;
  GLuint textureid;
  int x;
  int y;
  int max_draw;
  float ortho[4][4];
  float translate[4][4];
  float result[4][4];
  unsigned int program;
  FT_Library ft_library;
  FT_Face ttf;

};
#endif

Вот код font.cpp
Код

#include "font.hpp"

Font::Font ( const char *ttf_file )
{
    glm::clearMatrix4x4 ( &ortho[0] );
    glm::clearMatrix4x4 ( &translate[0] );
    glm::clearMatrix4x4 ( &result[0] );

    program = global.programs["sprite"];
    int width = global.width;
    int height = global.height;
    glm::ortho ( &ortho[0], 0.0f, width, 0.0f, height, 0.0f, 1.0f );
    setPos ( 0, 0 );

    FT_Init_FreeType( &ft_library );

#ifdef __ANDROID__
    FT_NewFace ( ft_library, ttf_file, 0, &face );
#else
    char *path = (char *) new char[255];
    sprintf ( path, "assets/%s", ttf_file );
    FT_New_Face ( ft_library, path, 0, &face );
    free ( path );
#endif
}

void Font::init ( wchar_t *es, int fontSize, int align, int vert, int space, uint8_t r, uint8_t g, uint8_t b )
{
    FT_Set_Pixel_Sizes ( face, 0, fontSize );

    FT_Glyph glyph;

    int w = 0;
    unsigned int h = 0;
    unsigned int maxh = 0;
    unsigned int toprow = 0;
    int len = wcslen ( es );
    for ( int i = 0; i < len; i++ ) {
  wchar_t charcode = es[i];
  FT_Load_Char ( face, charcode, FT_LOAD_RENDER );
  FT_UInt glyph_index = FT_Get_Char_Index ( face, charcode );

  FT_Load_Glyph ( face, glyph_index, FT_LOAD_DEFAULT );
  FT_Render_Glyph ( face->glyph, FT_RENDER_MODE_NORMAL );
  FT_Get_Glyph ( face->glyph, &glyph );

  FT_Glyph_To_Bitmap ( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
  FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph) glyph;
  FT_Bitmap bitmap = bitmap_glyph->bitmap;
  w += bitmap.width;

   int resize = bitmap.rows - bitmap_glyph->top;
   h = bitmap.rows + resize;
   if ( toprow < bitmap.rows ) toprow = bitmap.rows;
  
  if ( maxh < bitmap.rows + bitmap_glyph->top ) maxh = bitmap.rows + bitmap_glyph->top;

  if ( charcode == ' ' ) w += space;
  if ( charcode == '\n' ) {
   h += vert + maxh;
   FT_Done_Glyph ( glyph );
   continue;
  }
  w += align;

  FT_Done_Glyph ( glyph );
    }

    uint8_t im[h][w];
    memset ( &im[0][0], 0, w * h * sizeof ( uint8_t ) );

    int ih = 0;
    int iw = 0;
    int posy = 0;
    int topy = 0;
    int maxwidth = 0;
    for ( int i = 0; i < len; i++ ) {
  wchar_t charcode = es[i];
  FT_Load_Char ( face, charcode, FT_LOAD_RENDER );
  FT_UInt glyph_index = FT_Get_Char_Index ( face, charcode );

  FT_Load_Glyph ( face, glyph_index, FT_LOAD_DEFAULT );
  FT_Render_Glyph ( face->glyph, FT_RENDER_MODE_NORMAL );
  FT_Get_Glyph ( face->glyph, &glyph );

  FT_Glyph_To_Bitmap ( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
  FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph) glyph;
  FT_Bitmap bitmap = bitmap_glyph->bitmap;

  posy = bitmap_glyph->top;
  posy = bitmap.rows - posy;
  topy = toprow - bitmap.rows;

  if ( charcode == '\n' ) {
   ih += maxh;
   iw = 0;
   FT_Done_Glyph ( glyph );
   continue;
  }
  for ( unsigned int y = 0, i = 0; y < bitmap.rows; y++ ) {
   for ( unsigned int x = 0; x < bitmap.width; x++, i++ ) {
    im [ ih + posy + y + topy ] [ iw + x ] = bitmap.buffer[i];
   }
  }
  iw += bitmap.width;
  iw += align;
  if ( maxwidth < iw ) maxwidth = iw;

  if ( charcode == ' ' ) {
   iw += space;
  }

  FT_Done_Glyph ( glyph );

    }

    iw = maxwidth;
    width = iw;
    height = h;

    unsigned int size = width * height;
    uint8_t *image_data = new uint8_t [ size * 4 ];
    memset ( image_data, 255, size * 4 * sizeof ( uint8_t ) );

    for ( unsigned int i = 0, y = 0; i < size; y++ ) {
  for ( int x = 0; x < width; x++, i++ ) {
   image_data[ 4 * i + 3] = im [ y ][ x ];
   image_data[ 4 * i + 0] = r;
   image_data[ 4 * i + 1] = g;
   image_data[ 4 * i + 2] = b;
  }
    }

    glGenTextures ( 1, &textureid );
    glBindTexture ( GL_TEXTURE_2D, textureid );
    glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_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);
    
    setSize ( width, height );
    delete[] image_data;

}
void Font::setSize ( int w, int h )
{
    vertices = new float [ 12 ];
    vertices[0] = 0;
    vertices[1] = 0;
    vertices[2] = 0;
    vertices[3] = h;
    vertices[4] = w;
    vertices[5] = 0;

    vertices[6] = w;
    vertices[7] = 0;
    vertices[8] = w;
    vertices[9] = h;
    vertices[10] = 0;
    vertices[11] = h;

    texture = new float [ 12 ];
    texture[0] = 0;
    texture[1] = 1;
    texture[2] = 0;
    texture[3] = 0;
    texture[4] = 1;
    texture[5] = 1;

    texture[6] = 1;
    texture[7] = 1;
    texture[8] = 1;
    texture[9] = 0;
    texture[10] = 0;
    texture[11] = 0;
}

void Font::setPos ( int x, int y )
{
    this->x = x;
    this->y = y;
    glm::translate ( &translate[0], x, y, 0 );
    glm::sumMatrix ( &result[0], &translate[0], &ortho[0] );
}

void Font::draw ( )
{
    glUseProgram ( program );

    sampler = glGetUniformLocation ( program, "s_texture" );

    glActiveTexture ( GL_TEXTURE0 );
    glBindTexture ( GL_TEXTURE_2D, textureid );
    glUniform1i ( sampler, 0 );

    GLint projection_location = glGetUniformLocation ( program, "transform" );
    glUniformMatrix4fv ( projection_location, 1, GL_FALSE, &result[0][0] );

    glEnableVertexAttribArray ( 0 );
    glEnableVertexAttribArray ( 1 );

    glVertexAttribPointer ( 0, 2, GL_FLOAT, GL_FALSE, 0, vertices );
    glVertexAttribPointer ( 1, 2, GL_FLOAT, GL_FALSE, 0, texture );

    glDrawArrays ( GL_TRIANGLES, 0, 12 );

    glDisableVertexAttribArray ( 0 );
    glDisableVertexAttribArray ( 1 );
}

Вот код шейдера
Код

  const char *vshader =
          "#version 300 es\n"
   "layout(location = 0) in vec2 position;\n"
   "layout(location = 1) in vec2 texCoord;\n"
   "uniform mat4 transform;\n"
    "out vec2 v_texCoord;\n"
   "void main ( )\n"
   "{\n"
   " gl_Position = transform * vec4 ( position, 0.0, 1.0 );\n"
   " v_texCoord = texCoord;\n"
   "}";

  const char *fshader =
   "#version 300 es\n"
   "precision mediump float;\n"
   "in vec2 v_texCoord;\n"
   "layout(location = 0) out vec4 outColor;\n"
   "uniform sampler2D s_texture;\n"
   "void main ( )\n"
   "{\n"
   " outColor = texture ( s_texture, v_texCoord );\n"
   "}";

В пространстве glm содержаться функции по перемещению текста. Если надо, могу выложить.

Добавлено (27 Февраля 2019, 07:54)
---------------------------------------------
Как блин сделать чтобы из поисковиков на эту тему тоже была ссылка?


Сообщение отредактировал afq - Суббота, 02 Марта 2019, 13:48
drcrackДата: Среда, 27 Февраля 2019, 09:11 | Сообщение # 2
старожил
Сейчас нет на сайте
подождать пока проиндексируют
afqДата: Пятница, 15 Марта 2019, 15:44 | Сообщение # 3
Разработчик
Сейчас нет на сайте
Все изменения и обновления по поводу freetype2 я вношу по этой ссылке
Форум игроделов » Программирование » C/C++ » работа с freetype2 freetype
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг