OpenGL_ES|WinCE纹理贴图的方式绘制字符串

网上看了几个例子,不是编译一堆错误,就是运行没反映 

对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将数组输出,有心情再弄吧。

原文地址:https://www.cnblogs.com/ezhong/p/2171463.html