Opengles 显示文字 (Opengl ES笔记)

来源:互联网 发布:js获取字符串位置 编辑:程序博客网 时间:2024/06/06 20:22

             使用OpengL ES 显示文字的实现  (Wince)

使用OpengL ES 显示文字对opengl es 初学者来说,可谓一个不大不小的麻烦。有人是利用了Opengl ES API封装了一些dll库来实现,例如glfont,不过用起来就像浮云,很不灵活。这里简单描述下,我在wince上实现opengl es显示文字的思路。显示文字的实质其实也就是显示一张纹理,显示一个纹理很简单,那么我们的重点即是如何产生一个上面写有文字的纹理。

实现的思路是这样的:

1.创建一张与设备相关的GDI位图。

2.创建一个兼容DC,把步骤1创建的位图选入到DC中。

3.调用GDI,DrawText等把文字画到步骤2创建的DC上(可以用Truetype实现更加平滑的漂亮文字)。

4.利用此已画好文字的DC,再创建一个设备无关的位图,并用其像素数据生成纹理。

   补充:对于需要把文字写在一个底图上的情况,我想也不用多述了吧,需要进行透明的文字显示时,亦可在此思路上略做补充就得了。

下面给出参考代码,注意代码的组织顺序跟我上面说的思路有点出入。

bool CDrawText::CreateText(CString strText,GLuint *id)  //创建文字纹理无底图

{   

CRect TextOffsetRect;

if(m_bDown)

TextOffsetRect = m_ActiveOffsetRect;

else

TextOffsetRect = m_OffsetRect;

int TextWidth = m_EffectRect.Width(); //图片宽度

int TextHeight = m_EffectRect.Height(); //图片高度

CFont m_font;

m_font.CreateFont(m_FontSize,  /*< 字体高度 */

0,                        /*< 字体宽度 */

0,                        /*< 字体的旋转角度 Angle Of Escapement */

0,                        /*< 字体底线的旋转角度Orientation Angle */

m_iWeight,                /*< 字体的重量 */

m_bItalic,                /**< 是否使用斜体 */

m_bUnderLine,             /**< 是否使用下划线 */

FALSE,                    /*< 是否使用删除线 */

ANSI_CHARSET,             /*< 设置字符集 */

OUT_DEFAULT_PRECIS,       /**< 输出精度 */

CLIP_DEFAULT_PRECIS,      /*< 裁剪精度 */

/*ANTIALIASED_QUALITY*/CLEARTYPE_COMPAT_QUALITY,      /**< 输出质量 */

FF_DONTCARE|DEFAULT_PITCH,        /*< Family And Pitch */

L"宋体");  

CDC* pDC = new CDC;

pDC->Attach(GetHDC());

//定义指向DIB数据区的指针

BYTE  *lpBitmapBits = NULL; 

CDC dcMem; //绘制最终结果的DC

dcMem.CreateCompatibleDC(pDC);

HDC hMemDC = dcMem.GetSafeHdc();

BITMAPINFO bitInfo;

bitInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

bitInfo.bmiHeader.biWidth=TextWidth;

bitInfo.bmiHeader.biHeight=-TextHeight;

bitInfo.bmiHeader.biPlanes=1;

bitInfo.bmiHeader.biBitCount=24;

bitInfo.bmiHeader.biCompression=BI_RGB;

bitInfo.bmiHeader.biSizeImage=0;

bitInfo.bmiHeader.biXPelsPerMeter=0;

bitInfo.bmiHeader.biYPelsPerMeter=0;

bitInfo.bmiHeader.biClrUsed=0;

bitInfo.bmiHeader.biClrImportant=0;

bitInfo.bmiColors[0].rgbBlue=255;

bitInfo.bmiColors[0].rgbGreen=255;

bitInfo.bmiColors[0].rgbRed=255;

bitInfo.bmiColors[0].rgbReserved=255;

//创建位图

HBITMAP directBmp = CreateDIBSection(hMemDC, (BITMAPINFO*)&bitInfo, 

DIB_RGB_COLORS, (void **)&lpBitmapBits, NULL, 0);

HGDIOBJ previousObject = SelectObject(hMemDC, directBmp);

    

CBitmap bmp;

bmp.CreateCompatibleBitmap(pDC,TextWidth,TextHeight);

CDC dcBmp; //后台绘制图片的DC,最终要将此DC BltdcMem

dcBmp.CreateCompatibleDC(pDC);

CBitmap* COldBitamp = (CBitmap*)dcBmp.SelectObject(&bmp);

HDC hBmpDC = dcBmp.GetSafeHdc();

/* img.Draw2(dcBmp.GetSafeHdc(),0,0,iImgWidth,iImgHeight); //绘制图片到BmpDC*/

dcBmp.FillSolidRect(CRect(0,0,TextWidth,TextHeight),m_BackColor);

int len=strText.GetLength();

CFont* COldFont = (CFont*)dcBmp.SelectObject(&m_font);

dcBmp.SetBkMode(TRANSPARENT);

if(!m_bDown)

dcBmp.SetTextColor(m_FontColor);

else

dcBmp.SetTextColor(m_ActiveFontColor);

dcBmp.DrawText(strText,len,&TextOffsetRect,m_uAlign); 

BitBlt(hMemDC,0,0,TextWidth,TextHeight,hBmpDC,0,0,SRCCOPY);

int tmpPower = 2;

bool bGetW = false,bGetH = false;

while (true)

{

if (TextWidth <= tmpPower && !bGetW)

{

m_wBkImgx = tmpPower;

bGetW = true;

}

if (TextHeight <= tmpPower && !bGetH)

{

m_wBkImgy = tmpPower;

bGetH = true;

}

if (bGetW&&bGetH)

break;

tmpPower += tmpPower;

}

//GLubyte* pTexture = (GLubyte *)malloc(sizeof(GLubyte) * m_wBkImgx * m_wBkImgy *4);

if (pTexture == NULL)

{

TRACE(L"malloc mem fail");

TRACE(L"malloc mem fail");

return false;

}

    memset(pTexture,0x00,m_wBkImgx * m_wBkImgy *4);

int nPitch = TextWidth*bitInfo.bmiHeader.biBitCount/8; //Width*3

while (nPitch%4) nPitch++;

LPBYTE lpData, lpLine, lpCurPixel;

lpData = lpLine = lpBitmapBits;

int nBytesPP = bitInfo.bmiHeader.biBitCount >> 3;//左移三位即除以8,获取图像每像素字节数

int linepos = 0;

for (int i=m_wBkImgy-1;i>=m_wBkImgy-TextHeight;i--)//

{

lpLine = lpData + (linepos++) * nPitch;

for(int j = 0; j < TextWidth; j++)

{

lpCurPixel = lpLine + j * nBytesPP;

int pos = (i * m_wBkImgx + j)*4;

pTexture[pos++] = *(lpCurPixel + 2);     //R

pTexture[pos++] = *(lpCurPixel + 1); //G

pTexture[pos++] = *lpCurPixel;       //B

pTexture[pos++] = 255;//img.AlphaGet(j,linepos); //A

}

}

glGenTextures(1, id);     //绑定纹理

glBindTexture(GL_TEXTURE_2D, *id);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nTexWidth, nTexHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pTexture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_wBkImgx, m_wBkImgy, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexture); 

    m_TextTexture.size = m_wBkImgx * m_wBkImgy;

//free(pTexture);

dcBmp.SelectObject(COldFont);

dcBmp.SelectObject(COldBitamp);

m_font.DeleteObject();

bmp.DeleteObject();

dcBmp.DeleteDC();

SelectObject(hMemDC,previousObject);

DeleteObject(directBmp);

dcMem.DeleteDC();

pDC->Detach();

pDC->DeleteDC();

delete pDC;

return true;

}

原创粉丝点击