• 将文本转换成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);

  • 相关阅读:
    解决MyBatis的Mapper XML错误,系统起不来,也不报错问题
    tomcat启动卡在“INFO com.alibaba.druid.pool.DruidDataSource
    加速github访问速度
    LAN、WAN和WLAN的区别
    面试记录一
    C++纯虚函数(接口类)的使用
    CentOS 安装 Docker CE
    通过 plsql 连接远程 Oracle
    Yum 软件仓库配置
    qW3xT.2,解决挖矿病毒
  • 原文地址:https://www.cnblogs.com/lancidie/p/2108890.html
Copyright © 2020-2023  润新知