将文本转换成IDirect3DTexture9

如有转载请注明出处:http://blog.csdn.net/tianhai110/

       在3D游戏开发中,通常需要将文本变成纹理,以便于3D显示 。本文阐述了如何通过GDI来生成D3D纹理的方法。

        由于汉字多达5000字以上,为每个汉字制作相应图片,显然是不现实的;并且不能够改变字体。  最容易想到的当然是WIN32的GDI绘字,这是最简单,最常用的方法,并且可以改变字体、大小、样式。但缺点也是显而易见的,如果每帧都不断切换GDI,性能将大打折扣。其实,D3D的 ID3DXFONT也是利用GDI来绘字,在direct3d 9.0以前的这个是相当慢的,dx9.0后,微软对其进行了大改,性能有了质的飞跃,但是实时绘制大量文字的时候性能仍然有很大的影响(我曾每帧绘制50行字,性能从300多帧,变为50多帧)。

       思路:将文字用GDI绘制出来,然后保存成纹理(实际上,游戏中的文字通常要在屏幕上呆上一段时间),对这些纹理作下管理。通过构造一个顶点缓冲区来将纹理贴到一个四边形的块上去。

下面将GDI文字保存成IDirect3DTexture9的代码:

 

IDirect3DTexture9*        texture

 HDC hDc = ::CreateCompatibleDC( NULL);                    // 通过当前桌面创建设备内容HDC
 SetTextColor( hDc, RGB( 255,255,255));                          // 设置背景颜色和文字的颜色
 SetBkColor( hDc, 0xff000000);
 SetMapMode( hDc, MM_TEXT);

 DWORD* pBitmapBits;                                                        //  创建一个位图
 BITMAPINFO bitmapInfo;
 ZeroMemory( &bitmapInfo.bmiHeader, sizeof(BITMAPINFOHEADER));
 bitmapInfo.bmiHeader.biSize  = sizeof(BITMAPINFOHEADER);
 bitmapInfo.bmiHeader.biWidth = 900;
 bitmapInfo.bmiHeader.biHeight = 900;
 bitmapInfo.bmiHeader.biPlanes = 1;
 bitmapInfo.bmiHeader.biCompression = BI_RGB;
 bitmapInfo.bmiHeader.biBitCount = 32;

 HBITMAP hBitmap = CreateDIBSection( hDc, &bitmapInfo, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
 SelectObject( hDc, hBitmap);                            // 将位图与HDC关联,这样文字时间上就保存在hBitmap里面了

 LOGFONT lf;
 ZeroMemory( &lf, sizeof(LOGFONT));
 lf.lfHeight = 72;
 lf.lfWidth = 0;

HFONT   hFont   =   CreateFontIndirect(&lf);              // 创建大小为72的字体
 
 SelectObject(hDc, hFont);
 TextOut( hDc,0,0,"在这里写字", strlen("在这里写字"));

BITMAP bmp;
 GetObject( hBitmap, sizeof(BITMAP), &bmp);
 BYTE* buffer;   
 int  blength;                                  // 整个hBitMap文件字节长度
 blength = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmp.bmWidthBytes * bmp.bmHeight;
 buffer = new BYTE[blength];

 BITMAPINFOHEADER bi;
 bi.biSize                    =  sizeof(BITMAPINFOHEADER); 
 bi.biWidth                   =  bmp.bmWidth; 
 bi.biHeight                  =  bmp.bmHeight; 
 bi.biPlanes                  =  1; 
 bi.biBitCount                =  bmp.bmBitsPixel; 
 bi.biCompression             =  BI_RGB; 
 bi.biSizeImage               =  0; 
 bi.biXPelsPerMeter           =  0; 
 bi.biYPelsPerMeter           =  0; 
 bi.biClrImportant            =  0; 
 bi.biClrUsed                 =  0;

 BITMAPFILEHEADER bmfHdr;
 bmfHdr.bfType  =  0x4D42;  //  "BM"   
 bmfHdr.bfSize  =  blength;   
 bmfHdr.bfReserved1  =  0;   
 bmfHdr.bfReserved2  =  0;   
 bmfHdr.bfOffBits  =  (DWORD)sizeof(BITMAPFILEHEADER)  +  (DWORD)sizeof(BITMAPINFOHEADER);

 memcpy( buffer, &bmfHdr, sizeof(BITMAPFILEHEADER));
 memcpy( &buffer[sizeof(BITMAPFILEHEADER)], &bi, sizeof(BITMAPINFOHEADER));
 memcpy( &buffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)],
  bmp.bmBits, blength - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER));


 // 将刚才构建好的bmp数据,转成IDirect3DTexture9*  的纹理  
 if ( FAILED( D3DXCreateTextureFromFileInMemory( g_pDev, buffer, blength, &texture)))
 {
  return S_FALSE;
 }

 delete[] buffer;
 DeleteObject(hFont);
 DeleteObject( hBitmap);
 DeleteDC( hDc);

你可能感兴趣的:(text)