网上看了几个例子,不是编译一堆错误,就是运行没反映
对OpenGL_ES还是不属性,估计是哪里设置不对。 尤其是坐标,搞晕了。但有时候又觉得其实很简单。
思路:1: 创建内存DC ,为DC选择需要的字体,计算字符串在内存DC中的长宽;
2:创建与字符串长宽对应的设备无关位图,选入内存DC,并把字符串DrawText入内存DC;
3:处理设备无关位图的数据 (设置位图数据的alpha值,置换R/B值)
4:用设备无关位图数据生成纹理。
5:贴图......
注:BMP图片的字节对齐,在我的机器上模式不对齐也没问题。。。
###将字符串生成纹理的函数###
LONG COpenGLES::Align(LONG val,LONG align) //来自强大的norains
{
return ((val + align - 1) & (~(align - 1)));
}
void COpenGLES::CreateTextTexture(TCHAR *str,GLuint TexID)
{
HDC hScrDC, hMemDC;
BYTE *lpBitmapBits = NULL;
hScrDC = GetDC(NULL);
hMemDC = CreateCompatibleDC(hScrDC);
LOGFONTW lf;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfEscapement = 0;
wcscpy(lf.lfFaceName, L"liu");
lf.lfHeight = 25;
lf.lfItalic = FALSE;
lf.lfOrientation = 0;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfStrikeOut = FALSE;
lf.lfUnderline = FALSE;
lf.lfWidth = 0;
lf.lfWeight = FW_NORMAL;
HFONT hFont = CreateFontIndirectW(&lf);
HGDIOBJ hOldFont = SelectObject(hMemDC, hFont);
SetBkMode(hMemDC,TRANSPARENT);
SetTextColor(hMemDC, RGB(255, 0, 0));
SIZE strSize;
GetTextExtentPoint(hMemDC,str,_tcslen(str),&strSize);
printf("strSize:cx=%d ,cy = %d/n",strSize.cx,strSize.cy);
unsigned int bpp = 32;
BITMAPINFO RGB24BitsBITMAPINFO;
ZeroMemory(&RGB24BitsBITMAPINFO, sizeof(BITMAPINFO));
RGB24BitsBITMAPINFO.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
RGB24BitsBITMAPINFO.bmiHeader.biWidth = strSize.cx;
RGB24BitsBITMAPINFO.bmiHeader.biHeight = strSize.cy;
RGB24BitsBITMAPINFO.bmiHeader.biPlanes = 1;
RGB24BitsBITMAPINFO.bmiHeader.biBitCount = bpp;
HBITMAP directBmp = CreateDIBSection(hMemDC, (BITMAPINFO*)&RGB24BitsBITMAPINFO,
DIB_RGB_COLORS, (void **)&lpBitmapBits, NULL, 0);
HGDIOBJ previousObject = SelectObject(hMemDC, directBmp);
RECT rt = {0,0,strSize.cx,strSize.cy}; //像素宽度和高度
HBRUSH hBrush =CreateSolidBrush(RGB(0,0,0));
HGDIOBJ hOldBursh =SelectObject(hMemDC,hBrush);
Rectangle(hMemDC,0,0,strSize.cx,strSize.cy);
SelectObject(hMemDC,hOldBursh);
DeleteObject(hBrush);
DrawText(hMemDC,str,-1,&rt,DT_LEFT);
LONG lAlignRowSize = Align(strSize.cx * bpp,32) / 8; //对于32位可以省去位对齐?
//strSize.cx*bpp位数,位数进行32位对齐。除以8得出字节数。
LONG lAlignImageSize = strSize.cy * lAlignRowSize; //对齐后的文件大小
GLuint temp;
for(GLuint i=0; i<int(lAlignImageSize); i+=bpp/8)
{
if ( lpBitmapBits[i] == 0x00
&&lpBitmapBits[i+1] == 0x00
&&lpBitmapBits[i+2] == 0x00
)
{
lpBitmapBits[i+3] = 0x00; //黑色的alpha值为0
}
else
{
lpBitmapBits[i+3] = 0xff; // 其他颜色的alpha值为255;
temp = lpBitmapBits[i]; //交换R B值
lpBitmapBits[i] = lpBitmapBits[i + 2];
lpBitmapBits[i + 2] = temp;
}
}
glBindTexture(GL_TEXTURE_2D, TexID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
lAlignRowSize/(bpp/8), strSize.cy,
0, GL_RGBA, GL_UNSIGNED_BYTE, lpBitmapBits);
//delete
SelectObject(hMemDC, previousObject);
SelectObject(hMemDC, hOldFont);
DeleteDC(hMemDC);
DeleteObject(hScrDC);
DeleteObject(directBmp);
DeleteObject(hFont);
}
###OpenGL_ES平行投影设置函数###
void COpenGLES::OrthoBegin(void)
{
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0.0f, 800.0f, 0.0f, 480.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
###字符串输出封装函数###
void COpenGLES::TextOut(TCHAR *str,GLfloat x,GLfloat y,GLfloat cx,GLfloat cy)
{
y = 480 - y - cy;//转换成以左下角为原点的坐标
GLuint texID;
glGenTextures(1,&texID);
CreateTextTexture(str,texID);
GLfloat pCubeVertex[]={
0.0f, 0.0f, //0 (FrontR) 左下,,,
cx, 0.0f, //1 右下
cx, cy, //2 右上
0.0f, cy, //3 左上
};
GLushort pCubeIndex[]={
0,1,2,
0,2,3, //
};
//纹理坐标
GLfixed pTexCoord[]={
glF(0.0f), glF(0.0f), //左下
glF(1.0f), glF(0.0f), //右下
glF(1.0f), glF(1.0f), //右上
glF(0.0f), glF(1.0f), //左上
};
OrthoBegin();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(x,y,0);
glRotatef(45,0.0f,0.0f,1.0f);//绕X轴旋转
glBindTexture(GL_TEXTURE_2D,texID);
glVertexPointer(2, GL_FLOAT, 0, pCubeVertex);
glTexCoordPointer(2,GL_FIXED,0,pTexCoord);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER,0);
glPushMatrix();
glDrawElements(GL_TRIANGLES,2*3,GL_UNSIGNED_SHORT,pCubeIndex);
glPopMatrix();
EGLFlush();
glDeleteTextures(1,&texID);
glDisable(GL_ALPHA_TEST);
}
初始化OpenGL_ES后调用:
gl.TextOut(L"OpenGL_ES泪牛面貌",100,240,250,30);

乱哄哄的只是实现了下自己的想法,很多地方能够优化 、封装。
另一种思路 :根据设备无关位图的像素数据 生成坐标顶点数组,在用glDrawElements将数组输出,有心情再弄吧。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ezhong的博客签名-------------------------------------
以上内容来自ezhong的博客园,作者:ezhong
ezhong的博客园: http://www.cnblogs.com/ezhong
感谢您的阅读。感谢您的分享。
浙公网安备 33010602011771号