游戏开发论坛

 找回密码
 立即注册
搜索
查看: 8697|回复: 9

[SDL+OpenGL+freetype]汉字问题

[复制链接]

7

主题

29

帖子

29

积分

注册会员

Rank: 2

积分
29
发表于 2008-8-7 23:52:00 | 显示全部楼层 |阅读模式
http://bbs.gameres.com/showthread.asp?threadid=64404&page=1
在参考了此帖后,我决定写一段程序
毕竟这是别人写的程序,看不太懂

于是我从写一个字开始
以下是我的程序,不知道为什么中文显示不出来,现在已经成功让屏幕打个a上去了
现在在尝试'猪'中

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include <SDL/SDL_opengl.h>
#include <iostream>
using namespace std;

class FT2
{
      public:
      int init(char* fname, int width, int height);
      GLuint loadchar(wchar_t ch);
      private:
      FT_Library ftlib;
      FT_Face face;

      int nextp2(int n);
};

int FT2::nextp2(int n)
{
        int rval=1;
        // rval<<=1 Is A Prettier Way Of Writing rval*=2;
        while(rval<n) {rval = rval* 2;}
        return rval;
}

int FT2::init(char* fname, int width, int height)
{
    if (FT_Init_FreeType(&ftlib))
    {
          cout <<"Error during lib initialization"<<endl;
          return 1;
    }
    if (FT_New_Face(ftlib,fname,0,&face))
    {
       cout <<"error during face initialization"<<endl;
       return 2;
    }
            FT_Select_Charmap(face, FT_ENCODING_UNICODE);
            FT_Set_Pixel_Sizes(face,width, height);
           return 0;
}

以下为主要内容
void FT2::loadchar(wchar_t ch)
{
    FT_GlyphSlot slot = face->glyph;
    int pen_x,pen_y;

  if(FT_Load_Char(face, ch,FT_LOAD_RENDER|FT_LOAD_FORCE_AUTOHINT|
(true ? FT_LOAD_TARGET_NORMAL : FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO) )   )
{
return;
}
   //Draw function
FT_Glyph glyph;

        if(FT_Get_Glyph( face->glyph, &glyph ))
                cout << "FT_Get_Glyph failed";

        // Convert The Glyph To A Bitmap.
    FT_Render_Glyph( face->glyph,    FT_RENDER_MODE_LCD);
        FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
        FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;

        // This Reference Will Make Accessing The Bitmap Easier.
        FT_Bitmap& bitmap = bitmap_glyph->bitmap;

        face->size->metrics.y_ppem;

        //Padding for bitmapformat
        int h = nextp2(bitmap.rows);
        int w = nextp2(bitmap.width);

        char* pBuf = new char[w * h * 4];
cout <<"before pbuf"<<endl;
   /*
        for(int j=0; j <h;j++) for(int i=0; i < w; i++) {
                pBuf[2*(i+j*w)] = 255;
        pBuf[2*(i+j*w)+1] = (i>=bitmap.width || j>=bitmap.rows) ?
                        0 : bitmap.buffer[i + bitmap.width*j];
    }
    */

         GLuint texture;
        glGenTextures( 1, &texture );

        glBindTexture(GL_TEXTURE_2D,texture);
//      /*
                    for(int j=0; j  < h ; j++)
                {
                        for(int i=0; i < w; i++)
                        {
                                unsigned char _vl =  (i>=bitmap.width || j>=bitmap.rows) ? 255 : bitmap.buffer[i + bitmap.width*j];
                                pBuf[(4*i + (h - j - 1) * w * 4)  ] = 0xff;
                                pBuf[(4*i + (h - j - 1) * w * 4)+1] = 0xff;
                                pBuf[(4*i + (h - j - 1) * w * 4)+2] = 0xff;
                                pBuf[(4*i + (h - j - 1) * w * 4)+3] = _vl;
                        }
                }
//*/
    cout <<"after pbuf"<<endl;
    FT_Done_Glyph(glyph);


   glTexImage2D( GL_TEXTURE_2D,0,GL_RGBA,32, 32,0,GL_RGBA,GL_UNSIGNED_BYTE,pBuf);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                //glTexEnvi(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,GL_REPLACE);
        glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
        cout <<"after writing data"<<endl;

        /////////////////////////////////////////


    FT_Done_FreeType(ftlib);
delete []pBuf;
}

void drawtext()
{

     FT2 text;

     int a = text.init("simhei.ttf",32,32);
        text.loadchar('猪');

     glLoadIdentity();
                    glBegin ( GL_QUADS );
                {
                        glTexCoord2f(0.0f, 0.0f); glVertex3f(30, 20,  1.0f);
                        glTexCoord2f(1.0f, 0.0f); glVertex3f(60, 20,  1.0f);
                        glTexCoord2f(1.0f, 1.0f); glVertex3f(60, 50 ,  1.0f);
                        glTexCoord2f(0.0f, 1.0f); glVertex3f(30 , 50 ,  1.0f);
                        glColor3f(1.f,0.f,0.f);
                        glVertex3f(50 , 140 ,  1.0f);
                        glVertex3f(80, 140 ,  1.0f);
                        glVertex3f(80, 120,  1.0f);
                        glVertex3f(50, 120,  1.0f);
                }
                glEnd();


                cout <<"drawtext ended"<<endl;


SDL_GL_SwapBuffers();
    //pen_x + = slot->advance.x>>6;
//glDeleteTextures(1, &texture);
}

只要一到glTexImage2D就退出

我的main.cpp是这样的
#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <SDL/SDL_image.h>

#include "SDLOGL.cpp"
#include "freetype.cpp"

using namespace std;


int main(int argc, char *argv[])
{
    //Initialize SDL + OpenGL
    init( 512, 512);
    drawtext();
    int sx =0; int sy = 0;


    SDL_GL_SwapBuffers();
      cout <<"after sdl_gl-swapbuffers"<<endl;
    SDL_Delay(3000);
    SDL_Quit();
    return 0;
}
个人认为是pBuf的原因,可我这是直接从网上抄来的,NEHE的也用过,这个论坛上找来的也用过,对付英文都没出问题,就是选中文了就退出

哪位大大知道这是什么原因吗?

7

主题

29

帖子

29

积分

注册会员

Rank: 2

积分
29
 楼主| 发表于 2008-8-8 11:11:00 | 显示全部楼层

Re:[SDL+OpenGL+freetype]汉字问题

问题解决,是我给
drawtext(wchar_t)的东西出的问题
我用drawtext('ab') 他给我画了个'慢'出来~~

用drawtext('慢')就出错了~~

靠~~那个怎么搞法啊,难道我还要搞清每个汉字是哪几个字母拼出来的不成?

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
发表于 2008-8-8 12:33:00 | 显示全部楼层

Re: [SDL+OpenGL+freetype]汉字问题

用drawtext(L'慢')试一试

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
发表于 2008-8-8 12:36:00 | 显示全部楼层

Re:[SDL+OpenGL+freetype]汉字问题

wchar_t * pText = L"慢";
drawtext(pText[0]);

7

主题

29

帖子

29

积分

注册会员

Rank: 2

积分
29
 楼主| 发表于 2008-8-9 00:28:00 | 显示全部楼层

Re:[SDL+OpenGL+freetype]汉字问题

用L'慢'的话
我就会得到
illegal byte sequence错误

网上查是因为winGW不支持unicode的关系

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
发表于 2008-8-15 21:55:00 | 显示全部楼层

Re:[SDL+OpenGL+freetype]汉字问题

// TestFT2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <GL/GL.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include <iostream>
#include <sdl/SDL.h>
#include <SDL/SDL_image.h>

using namespace std;

class FT2
{
        int gltexture;
public:
        int init(char* fname, int width, int height);
        GLuint loadchar(wchar_t ch);
private:
        FT_Library ftlib;
        FT_Face face;

        int nextp2(int n);
};

int FT2::nextp2(int n)
{
        int rval=1;
        // rval<<=1 Is A Prettier Way Of Writing rval*=2;
        while(rval<n) {rval = rval* 2;}
        return rval;
}

int FT2::init(char* fname, int width, int height)
{
        if (FT_Init_FreeType(&ftlib))
        {
                cout <<"Error during lib initialization"<<endl;
                return 1;
        }
        if (FT_New_Face(ftlib,fname,0,&face))
        {
                cout <<"error during face initialization"<<endl;
                return 2;
        }
        FT_Select_Charmap(face, FT_ENCODING_UNICODE);
        FT_Set_Pixel_Sizes(face,width, height);
        gltexture = 0;
        return 0;
}


GLuint FT2::loadchar(wchar_t ch)
{
        FT_GlyphSlot slot = face->glyph;
        int pen_x,pen_y;

        if(FT_Load_Char(face, ch,FT_LOAD_RENDER|FT_LOAD_FORCE_AUTOHINT|
                (true ? FT_LOAD_TARGET_NORMAL : FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO) )   )
        {
                return 0;
        }
        //Draw function
        FT_Glyph glyph;

        if(FT_Get_Glyph( face->glyph, &glyph ))
                cout << "FT_Get_Glyph failed";

        // Convert The Glyph To A Bitmap.
        FT_Render_Glyph( face->glyph,    FT_RENDER_MODE_LCD);
        FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
        FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;

        // This Reference Will Make Accessing The Bitmap Easier.
        FT_Bitmap& bitmap = bitmap_glyph->bitmap;

        face->size->metrics.y_ppem;

        //Padding for bitmapformat
        int h = nextp2(bitmap.rows);
        int w = nextp2(bitmap.width);

        char* pBuf = new char[w * h * 4];
        cout <<"before pbuf"<<endl;
        /*
        for(int j=0; j <h;j++) for(int i=0; i < w; i++) {
        pBuf[2*(i+j*w)] = 255;
        pBuf[2*(i+j*w)+1] = (i>=bitmap.width || j>=bitmap.rows) ?
        0 : bitmap.buffer[i + bitmap.width*j];
        }
        */

        GLuint texture;
        glGenTextures( 1, &texture );

        glBindTexture(GL_TEXTURE_2D,texture);
        memset(pBuf, 0 , w * h * 4);
        //      /*
        for(int j=0; j  < bitmap.rows ; j++)
        {
                for(int i=0; i < bitmap.width; i++)
                {
                        unsigned char _vl =  (i>=bitmap.width || j>=bitmap.rows) ? 255 : bitmap.buffer[i + bitmap.width*j];
                        pBuf[(4*i + (h - j - 1) * w * 4)  ] = 0xff;
                        pBuf[(4*i + (h - j - 1) * w * 4)+1] = 0xff;
                        pBuf[(4*i + (h - j - 1) * w * 4)+2] = 0xff;
                        pBuf[(4*i + (h - j - 1) * w * 4)+3] = _vl;
                }
        }
        //*/
        cout <<"after pbuf"<<endl;
        FT_Done_Glyph(glyph);


        glTexImage2D( GL_TEXTURE_2D,0,GL_RGBA,32, 32,0,GL_RGBA,GL_UNSIGNED_BYTE,pBuf);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        //glTexEnvi(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,GL_REPLACE);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
        cout <<"after writing data"<<endl;

        /////////////////////////////////////////


        FT_Done_FreeType(ftlib);
        delete []pBuf;
        gltexture = texture;
        return 0;
}

void drawtext()
{
        glClearColor(1.0f,1.0f,1.0f,1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDisable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glLoadIdentity();
        glBegin ( GL_QUADS );
        {
                glTexCoord2f(0.0f, 0.0f); glVertex3f(30, 20,  1.0f);
                glTexCoord2f(1.0f, 0.0f); glVertex3f(60, 20,  1.0f);
                glTexCoord2f(1.0f, 1.0f); glVertex3f(60, 50 ,  1.0f);
                glTexCoord2f(0.0f, 1.0f); glVertex3f(30 , 50 ,  1.0f);
                glColor3f(1.f,0.f,0.f);
                glVertex3f(50 , 140 ,  1.0f);
                glVertex3f(80, 140 ,  1.0f);
                glVertex3f(80, 120,  1.0f);
                glVertex3f(50, 120,  1.0f);
        }
        glEnd();


        cout <<"drawtext ended"<<endl;


        SDL_GL_SwapBuffers();
        //pen_x + = slot->advance.x>>6;
        //glDeleteTextures(1, &texture);
}

void init(int w , int h )
{
        SDL_Init(SDL_INIT_EVERYTHING);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
        SDL_Surface* drawContext;
        Uint32 flags;
        flags = SDL_OPENGL | SDL_RESIZABLE;
        drawContext = SDL_SetVideoMode(w, h, 0, flags);

        glMatrixMode(GL_PROJECTION);
        glOrtho(0,w , 0 , h , -1000,1000);
        glMatrixMode(GL_MODELVIEW);

        FT2 text;
        int a = text.init("c:\\windows\\fonts\\simhei.ttf",32,32);
        text.loadchar((L"猪")[0]);

}
#pragma  comment(lib, "SDL.lib")
#pragma  comment(lib, "opengl32.lib")
#pragma  comment(lib,"freetype.lib")

void EventLoop(void)
{
        SDL_Event event;
    bool done = false;
        while(!done)
        {
                while( SDL_PeepEvents(&event,1,SDL_GETEVENT,0) )
                {
                        switch(event.type)
                        {
                        case SDL_KEYDOWN:
                                done = true;
                                // Handle any key presses here.
                                break;

                        case SDL_MOUSEBUTTONDOWN:

                                // Handle mouse clicks here.
                                break;

                        case SDL_QUIT:
                                done = true;
                                break;

                        default:
                                break;
                        }   // End switch
                }
                drawtext();
                SDL_GL_SwapBuffers();
        }   // End while

}

int _tmain(int argc, char *argv[])
{
        //Initialize SDL + OpenGL
        init( 512, 512);
        EventLoop();
        SDL_Quit();
        return 0;
}

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
发表于 2008-8-15 21:55:00 | 显示全部楼层

Re:[SDL+OpenGL+freetype]汉字问题

今天心血来潮。给楼主改好了。

7

主题

29

帖子

29

积分

注册会员

Rank: 2

积分
29
 楼主| 发表于 2008-9-3 05:27:00 | 显示全部楼层

Re: Re:[SDL+OpenGL+freetype]汉字问题

xpertsoft: Re:[SDL+OpenGL+freetype]汉字问题

今天心血来潮。给楼主改好了。

很抱歉~~你那段代码我根本就运行不起来-_-

我就把pbuf的那段抄过去
把编译器改成了UTF-8的

7

主题

29

帖子

29

积分

注册会员

Rank: 2

积分
29
 楼主| 发表于 2008-9-3 05:52:00 | 显示全部楼层

Re: Re: Re:[SDL+OpenGL+freetype]汉字问题

问题解决
谢谢大大

3

主题

35

帖子

131

积分

注册会员

Rank: 2

积分
131
QQ
发表于 2008-9-26 10:10:00 | 显示全部楼层

Re:[SDL+OpenGL+freetype]汉字问题

改用WORD就没问题了。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-21 05:59

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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