zoukankan      html  css  js  c++  java
  • 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将数组输出,有心情再弄吧。

  • 相关阅读:
    php中__construct()和__initialize()的区别
    js的栈内存和堆内存
    CC攻击原理及防范方法
    html页面调用js文件里的函数报错onclick is not defined处理方法
    yii2深入理解之内核解析
    Scala Data Structure
    Scala Basis
    【MySql】牛客SQL刷题(下)
    【Flume】知识点整理
    【kafka】生产者API
  • 原文地址:https://www.cnblogs.com/ezhong/p/2171463.html
Copyright © 2011-2022 走看看