游戏开发论坛

 找回密码
 立即注册
搜索
查看: 45671|回复: 56

FreeType的教程代码. 使用GLUT.

[复制链接]

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
发表于 2006-9-21 00:33:00 | 显示全部楼层 |阅读模式
在Nehe的代码基础上改的:

以下是基础代码:
struct xCharTexture
{
        GLuint  m_texID;
        wchar_t m_chaID;
        int     m_Width;
        int     m_Height;

    int     m_adv_x;
    int     m_adv_y;
    int     m_delta_x;
    int     m_delta_y;
public:
        xCharTexture()
        {
                m_texID  = 0;
                m_chaID  = 0;
                m_Width  = 0;
                m_Height = 0;
        }
}g_TexID[65536];
class xFreeTypeLib
{
    FT_Library m_FT2Lib;
        FT_Face    m_FT_Face;

        int   m_w;
        int   m_h;
public:
        xFreeTypeLib()
        {
                if (FT_Init_FreeType( &m_FT2Lib) )
                        exit(0);
        }

        void load(const char* font_file , int _w , int _h)
        {
                //加载一个字体,取默认的Face,一般为Regualer
                if (FT_New_Face( m_FT2Lib, font_file, 0, &m_FT_Face ))
                        exit(0);
                FT_Select_Charmap(m_FT_Face, FT_ENCODING_UNICODE);
                m_w = _w ; m_h = _h;
                m_FT_Face->num_fixed_sizes;
                //大小要乘64.这是规定。照做就可以了。
                //FT_Set_Char_Size( m_FT_Face , 0 , m_w << 6, 96, 96);
                FT_Set_Pixel_Sizes(m_FT_Face,m_w, m_h);
        }

        GLuint loadChar(wchar_t ch)
        {
                if(g_TexID[ch].m_texID)
                        return g_TexID[ch].m_texID;

                if(FT_Load_Char(m_FT_Face, ch,FT_LOAD_RENDER|FT_LOAD_FORCE_AUTOHINT|
                        (true ? FT_LOAD_TARGET_NORMAL : FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO) )   )
                {
                        return 0;
                }

        xCharTexture& charTex = g_TexID[ch];
               
                //得到字模
                FT_Glyph glyph;
                if(FT_Get_Glyph( m_FT_Face->glyph, &glyph ))
                        return 0;

                //转化成位图
                FT_Render_Glyph( m_FT_Face->glyph,   FT_RENDER_MODE_LCD );//FT_RENDER_MODE_NORMAL  );
                FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
                FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;

                //取道位图数据
                FT_Bitmap& bitmap=bitmap_glyph->bitmap;

                //把位图数据拷贝自己定义的数据区里.这样旧可以画到需要的东西上面了。
                int width  =  bitmap.width;
                int height =  bitmap.rows;

                m_FT_Face->size->metrics.y_ppem;
                m_FT_Face->glyph->metrics.horiAdvance;


                charTex.m_Width = width;
                charTex.m_Height = height;
                charTex.m_adv_x = m_FT_Face->glyph->advance.x / 64.0f;
                charTex.m_adv_y = m_FT_Face->size->metrics.y_ppem; //m_FT_Face->glyph->metrics.horiBearingY / 64.0f;
                charTex.m_delta_x = (float)bitmap_glyph->left;
                charTex.m_delta_y = (float)bitmap_glyph->top - height;
                glGenTextures(1,&charTex.m_texID);
        glBindTexture(GL_TEXTURE_2D,charTex.m_texID);
                char* pBuf = new char[width * height * 4];
                for(int j=0; j  < height ; j++)
                {
                        for(int i=0; i < width; i++)
                        {
                                unsigned char _vl =  (i>=bitmap.width || j>=bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];
                                pBuf[(4*i + (height - j - 1) * width * 4)  ] = 0xff;
                                pBuf[(4*i + (height - j - 1) * width * 4)+1] = 0xff;
                                pBuf[(4*i + (height - j - 1) * width * 4)+2] = 0xff;
                                pBuf[(4*i + (height - j - 1) * width * 4)+3] = _vl;
                        }
                }

                glTexImage2D( GL_TEXTURE_2D,0,GL_RGBA,width, height,0,GL_RGBA,GL_UNSIGNED_BYTE,pBuf);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP);
                glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
                glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
                glTexEnvi(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,GL_REPLACE);
                delete[]pBuf;
                return charTex.m_chaID;
        }

}g_FreeTypeLib;


绘制代码如下:
void drawText(wchar_t* _strText,int x , int y, int maxW , int h)
{
        int sx = x;
        int sy = y;
        int maxH = h;
        for(int i = 0 ; i < wcslen(_strText) ; i ++)
        {
               
                if(_strText =='\n')
                {
                        sx = x ; sy += maxH + 12;
                        continue;
                }
                xCharTexture* pCharTex = getTextChar(_strText);
                glBindTexture(GL_TEXTURE_2D,pCharTex->m_texID);
                glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
                glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
                glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
                //glDisable(GL_TEXTURE_2D);
                int w = pCharTex->m_Width;
                int h = pCharTex->m_Height;

                int ch_x = sx + pCharTex->m_delta_x;
                int ch_y = sy - h - pCharTex->m_delta_y;

                if(maxH < h) maxH = h;
                glBegin ( GL_QUADS );
                {
                        glTexCoord2f(0.0f, 1.0f); glVertex3f(ch_x      , ch_y    ,  1.0f);
                        glTexCoord2f(1.0f, 1.0f); glVertex3f(ch_x +  w, ch_y    ,  1.0f);
                        glTexCoord2f(1.0f, 0.0f); glVertex3f(ch_x +  w, ch_y + h,  1.0f);
                        glTexCoord2f(0.0f, 0.0f); glVertex3f(ch_x     , ch_y + h,  1.0f);
                }
                glEnd();
                sx += pCharTex->m_adv_x;
                if(sx > x + maxW)
                {
                        sx = x ; sy += maxH + 12;
                }
        }

}

sf_200692103315.rar

4.85 KB, 下载次数:

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
 楼主| 发表于 2006-9-21 00:35:00 | 显示全部楼层

Re: FreeType的教程代码. 使用GLUT.

图片如下
sf_200692103510.png

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
 楼主| 发表于 2006-9-21 00:49:00 | 显示全部楼层

Re:FreeType的教程代码. 使用GLUT.

注意. freetype可以到www.freetype.org去下.
glut用google找。
simhei.ttf在windows下偷

139

主题

2005

帖子

2057

积分

金牌会员

Rank: 6Rank: 6

积分
2057
QQ
发表于 2006-9-21 01:12:00 | 显示全部楼层

Re:FreeType的教程代码. 使用GLUT.

你真是……就不在我那贴

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
 楼主| 发表于 2006-9-21 02:39:00 | 显示全部楼层

Re:FreeType的教程代码. 使用GLUT.

贴了。

8

主题

91

帖子

93

积分

注册会员

Rank: 2

积分
93
发表于 2006-9-21 09:15:00 | 显示全部楼层

Re:FreeType的教程代码. 使用GLUT.

这个不错,顶一个

197

主题

1041

帖子

1104

积分

金牌会员

Rank: 6Rank: 6

积分
1104
QQ
发表于 2006-9-21 09:41:00 | 显示全部楼层

Re:FreeType的教程代码. 使用GLUT.

原创贴我肯定是要路过的

2万

主题

2万

帖子

6万

积分

论坛元老

Rank: 8Rank: 8

积分
66489
QQ
发表于 2006-9-22 09:24:00 | 显示全部楼层

Re:FreeType的教程代码. 使用GLUT.

帅哥!你还有问题需要解决O!

一、字体不够美观问题,FreeType本身存在一个Bug就是精度不够,所以在对于笔画过多的中文时一般都不怎么好看。你截图上的黑体字是否比Mac/Win上的差很多?

二、小字符问题。试一下小于20x20的字,会有些麻烦。

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
 楼主| 发表于 2006-9-22 10:14:00 | 显示全部楼层

Re:FreeType的教程代码. 使用GLUT.

16x16以下的小字体是个很恶心的问题. 我正在看看libXfont是如何处理的.不过有一点是肯定的.LCD上,Mac/Win可以用sub-pixel. 我是没法用那个.有空的时候看看Windows的ClearType技术.

2万

主题

2万

帖子

6万

积分

论坛元老

Rank: 8Rank: 8

积分
66489
QQ
发表于 2006-9-22 14:47:00 | 显示全部楼层

Re:FreeType的教程代码. 使用GLUT.

NO,Windows是另存了一份点阵字库,在显示宋体等字库时,小字使用点阵字库。

而mac不是,mac使用的是postscript技术,小字也可以处理的很好看。
但这是一项专利,全世界只有apple/adobe/方正可以解决,adobe/apple用的是同一种技术。
方正是另一种,对于中文来说解决的最好的是方正。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 14:12

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表