现在的位置: 首页 > 综合 > 正文

[SDL+OpenGL+freetype] Demo

2013年08月22日 ⁄ 综合 ⁄ 共 4358字 ⁄ 字号 评论关闭

// 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;
}

【上篇】
【下篇】

抱歉!评论已关闭.