网上看了几个例子,不是编译一堆错误,就是运行没反映
对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
感谢您的阅读。感谢您的分享。