Linux miny选择字体,linux中opengl實現文字顯示的方法

前段時間為了弄畢業設計,要用opengl顯示文字,在網上找了很多方法,但大都是在windows下的實現方法,幾乎沒有linux下的,找了很久才找到。

首先,opengl本身是沒有顯示文字的函數的,必須要借助其他的庫,linux下有SDL,利用SDL本身的編程是可以顯示漢字的,但是如何將opengl和SDL融合顯示漢字!這就是難點所在!

#include

#include

#include

#include

#include

#include

#define TRUE (-1)

#define FALSE 0

typedef int BOOL;

const int SCREEN_WIDTH = 600;

const int SCREEN_HEIGHT = 400;

const int SCREEN_BPP = 32;

SDL_Surface *image = NULL;

SDL_Surface *screen = NULL;

SDL_Surface *message = NULL;

TTF_Font *font = NULL;

SDL_Color textColor = { 255, 0, 0 };

SDL_Color blackColor = { 0,0,0 };

BOOL init()

{

if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )

{

return FALSE;

}

//screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL );

if( screen == NULL )

{

return FALSE;

}

//Initialize SDL_ttf

if( TTF_Init() == -1 )

return FALSE;

SDL_WM_SetCaption( "show Chinese text @bluedrum", NULL );

//If everything initialized fine

return TRUE;

}

void clean_up()

{

SDL_FreeSurface( image );

SDL_FreeSurface( message );

TTF_CloseFont( font ); //Close the font that was used

TTF_Quit(); //Quit SDL_ttf

SDL_Quit(); //Quit SDL

}

SDL_Surface *load_image( char * filename )

{

SDL_Surface* loadedImage = NULL;

SDL_Surface* optimizedImage = NULL;

loadedImage = IMG_Load( filename);

if( loadedImage != NULL )

{

optimizedImage = SDL_DisplayFormat( loadedImage );

SDL_FreeSurface( loadedImage );

}

return optimizedImage;

}

void SDL_GL_Enter2DMode()

{

SDL_Surface *screen = SDL_GetVideoSurface();

/* Note, there may be other things you need to change,

depending on how you have your OpenGL state set up.

*/

glPushAttrib(GL_ENABLE_BIT);

glDisable(GL_DEPTH_TEST);

glDisable(GL_CULL_FACE);

glEnable(GL_TEXTURE_2D);

/* This allows alpha blending of 2D textures with the scene */

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glViewport(0, 0, screen->w, screen->h);

glMatrixMode(GL_PROJECTION);

glPushMatrix();

glLoadIdentity();

glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

glLoadIdentity();

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

}

void SDL_GL_Leave2DMode()

{

glMatrixMode(GL_MODELVIEW);

glPopMatrix();

glMatrixMode(GL_PROJECTION);

glPopMatrix();

glPopAttrib();

}

/* Quick utility function for texture creation */

static int power_of_two(int input)

{

int value = 1;

while ( value < input ) {

value <<= 1;

}

return value;

}

GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)

{

GLuint texture;

int w, h;

SDL_Surface *image;

SDL_Rect area;

Uint32 saved_flags;

Uint8 saved_alpha;

/* Use the surface width and height expanded to powers of 2 */

w = power_of_two(surface->w);

h = power_of_two(surface->h);

texcoord[0] = 0.0f; /* Min X */

texcoord[1] = 0.0f; /* Min Y */

texcoord[2] = (GLfloat)surface->w / w; /* Max X */

texcoord[3] = (GLfloat)surface->h / h; /* Max Y */

image = SDL_CreateRGBSurface(

SDL_SWSURFACE,

w, h,

32,

#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */

0x000000FF,

0x0000FF00,

0x00FF0000,

0xFF000000

#else

0xFF000000,

0x00FF0000,

0x0000FF00,

0x000000FF

#endif

);

if ( image == NULL ) {

return 0;

}

/* Save the alpha blending attributes */

saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);

#if SDL_VERSION_ATLEAST(1, 3, 0)

SDL_GetSurfaceAlphaMod(surface, &saved_alpha);

SDL_SetSurfaceAlphaMod(surface, 0xFF);

#else

saved_alpha = surface->format->alpha;

if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {

SDL_SetAlpha(surface, 0, 0);

}

#endif

/* Copy the surface into the GL texture image */

area.x = 0;

area.y = 0;

area.w = surface->w;

area.h = surface->h;

SDL_BlitSurface(surface, &area, image, &area);

/* Restore the alpha blending attributes */

#if SDL_VERSION_ATLEAST(1, 3, 0)

SDL_SetSurfaceAlphaMod(surface, saved_alpha);

#else

if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {

SDL_SetAlpha(surface, saved_flags, saved_alpha);

}

#endif

/* Create an OpenGL texture for the image */

glGenTextures(1, &texture);

glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D,

0,

GL_RGBA,

w, h,

0,

GL_RGBA,

GL_UNSIGNED_BYTE,

image->pixels);

SDL_FreeSurface(image); /* No longer needed */

return texture;

}

int main(int argc,char * argv[])

{

char a[] = "abc";

char *img_name = "./bk.jpg";

Uint16 msg[1024] = {0xc2d0,0xcbce,0xcce5,0};

wchar_t *msg1 = L"新宋體";

int w,h,done;

int i=0;

GLuint texture;

GLfloat texcoord[4];

GLfloat texMinX, texMinY;

GLfloat texMaxX, texMaxY;

SDL_Event event;

//msg2 = ConvertUnicodeToUtf8(msg1);

init();

if(argc > 1)

{

strncpy(img_name,argv[1],sizeof(img_name)-1);

img_name[sizeof(img_name)-1] = 0;

}

font = TTF_OpenFont("./simfang.ttf",20);

if(font == NULL)

{

fprintf(stderr,"font open failure %s\n",SDL_GetError());

clean_up();

exit(-1);

}

image =load_image(img_name);

TTF_SetFontStyle(font,TTF_STYLE_BOLD | TTF_STYLE_ITALIC);

message = TTF_RenderUNICODE_Solid( font, msg1, textColor );

//message = TTF_RenderText_Solid(font,"ABCEFGHIJK",blackColor);

w = message->w;

h = message->h;

//w = image->w;

//h = image->h;

texture = SDL_GL_LoadTexture(message, texcoord);

/* Make texture coordinates easy to understand */

texMinX = texcoord[0];

texMinY = texcoord[1];

texMaxX = texcoord[2];

texMaxY = texcoord[3];

/* Initialize the GL state */

glViewport( 0, 0, screen->w, screen->h );

glMatrixMode( GL_PROJECTION );

glLoadIdentity( );

glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );

glMatrixMode( GL_MODELVIEW );

glLoadIdentity( );

glEnable(GL_DEPTH_TEST);

glDepthFunc(GL_LESS);

glShadeModel(GL_SMOOTH);

/* Clear the screen */

glClearColor(1.0, 1.0, 1.0, 1.0);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* Show the text on the screen 關鍵部分*/

SDL_GL_Enter2DMode();

glBindTexture(GL_TEXTURE_2D, texture);

glBegin(GL_TRIANGLE_STRIP);

glTexCoord2f(texMinX, texMinY); glVertex2i(50, 50 );

glTexCoord2f(texMaxX, texMinY); glVertex2i(50+w, 50 );

glTexCoord2f(texMinX, texMaxY); glVertex2i(50, 50+h);

glTexCoord2f(texMaxX, texMaxY); glVertex2i(50+w, 50+h);

glEnd();

SDL_GL_Leave2DMode();

SDL_GL_SwapBuffers( );

if(SDL_Flip(screen) == -1)

return -1;

/* Wait for a keystroke,input esc to quit */

done = 0;

while ( ! done ) {

while ( SDL_PollEvent(&event) ) {

switch (event.type) {

case SDL_KEYDOWN:

case SDL_QUIT:

done = 1;

break;

default:

break;

}

}

}

//SDL_Delay(3000);

clean_up();

}

編譯用gcc test.c -o test -lSDL_image -lSDL_ttf -lglut -finput-charset='gbk' -fshort-wchar

前面幾個參數是調用庫, -finput-charset='gbk' -fshort-wchar參數是為了解決漢字的編碼問題

其中bk.jpg是圖片文件./simfang.tff是漢字庫,可以在網上下。

代碼分析,與其它的opengl函數使用來說就多了幾個函數,SDL_GL_LoadTexture;SDL_GL_Enter2DMode;SDL_GL_Leave2DMode這3個函數,它們是實現漢字顯示的關鍵函數,函數之間相互獨立,可以拷過去直接用。其根本原理還是使用了opengl的紋理映射的原理;圖片和漢字的用法也是一樣的。PS:前面做的時候,看到過中科院一個碩士的方法,看了半天論文也沒發現具體的實現方法,汗!!最后還是在SDL的官方文件中找到,再自己研究的方法。

opengl和SDL的融合還是在 SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL )中的SDL_OPENGL宏,否則就是SDL的顯示了。如果能用SDL加opengl來作界面和游戲的話,還是很給力的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值