使用OPENGL ES开发一个应用,显示字符串都那么麻烦,虽然POWERVR等基于OPENGL ES的SDK提供了APPPRINT3D这样的封装类来处理字符串显示,但鉴于开发中我用的不是POWERVR。网上还有一个封装好的类,glfonts for WINCE,把这个类放到程序中,也不知道是否自己的使用是否正确,反正没啥效果。最后发现可以通过这么一种方式实现,首先把字符串打印在dc上,然后生成位图,最后位图纹理贴图。All works are done.
1 void glTextShow(WCHAR *fontname, int fontsize, int style, int x, int y, const WCHAR *string)
2
{
3 int len, xx = 0 , yy = 0 , nbpoints = 0 , i;
4 GLshort * points;
5 GLushort * indices;
6 HFONT font;
7 LOGFONTW lf;
8 RECT rect;
9 static HBITMAP bmp;
10 static BYTE * img;
11 static HDC hdc = NULL;
12 static BITMAPINFO bi;
13 SIZE sz;
14 static EGLint width, height;
15
16 if ( ! fontname || ! string )
17 return ;
18 if ( ! string [ 0 ])
19 return ;
20
21 if ( ! hdc)
22 {
23 hdc = CreateCompatibleDC(GetDC(hWnd));
24
25 eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, & width);
26 eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, & height);
27
28
29 ZeroMemory( & bi, sizeof (BITMAPINFO));
30 bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
31 bi.bmiHeader.biWidth = width;
32 bi.bmiHeader.biHeight = height;
33 bi.bmiHeader.biBitCount = 8 ;
34 bi.bmiHeader.biPlanes = 1 ;
35 bi.bmiHeader.biCompression = BI_RGB;
36
37 bmp = CreateDIBSection(hdc, & bi, DIB_RGB_COLORS, & img, NULL, 0 );
38
39 SelectObject(hdc, bmp);
40
41 SelectObject(hdc, GetStockObject(BLACK_BRUSH));
42
43 SetBkMode(hdc, TRANSPARENT);
44 SetTextColor(hdc, RGB( 255 , 255 , 255 ));
45 }
46
47 Rectangle(hdc, 0 , 0 , width, height);
48 ZeroMemory(img, width * height);
49
50 lf.lfCharSet = DEFAULT_CHARSET;
51 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
52 lf.lfEscapement = 0 ;
53 wcscpy(lf.lfFaceName, fontname);
54 lf.lfHeight = - (fontsize * GetDeviceCaps(GetDC(hWnd), LOGPIXELSY) / 72 );
55 lf.lfItalic = (style & 1 ) ? TRUE : FALSE;
56 lf.lfOrientation = 0 ;
57 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
58 lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
59 lf.lfQuality = DEFAULT_QUALITY;
60 lf.lfStrikeOut = FALSE;
61 lf.lfUnderline = (style & 4 ) ? TRUE : FALSE;
62 lf.lfWidth = 0 ;
63 lf.lfWeight = (style & 2 ) ? FW_BOLD : FW_NORMAL;
64
65 font = CreateFontIndirectW( & lf);
66
67 SelectObject(hdc, font);
68
69 len = wcslen( string );
70
71 GetTextExtentPointW(hdc, string , len, & sz);
72
73 rect.left = max( 0 , min(x, width));
74 rect.top = max( 0 , min(y, height));
75 rect.right = min(rect.left + sz.cx, width);
76 rect.bottom = min(rect.top + sz.cy, height);
77
78 DrawTextW(hdc, string , len, & rect, DT_LEFT | DT_BOTTOM);
79
80 points = (GLshort * )malloc(sz.cx * sz.cy * 2 * sizeof ( short ));
81
82 for (yy = rect.top; yy < rect.bottom; yy ++ )
83 {
84 for (xx = rect.left; xx < rect.right; xx ++ )
85 {
86 if (img[xx + (height - yy) * width] != 0 )
87 {
88 points[nbpoints * 2 + 0 ] = xx - x;
89 points[nbpoints * 2 + 1 ] = ( short )(rect.top + sz.cy - (yy - rect.top)) - y;
90 nbpoints ++ ;
91 }
92 }
93 }
94 DeleteObject(font);
95
96 indices = (GLushort * )malloc(nbpoints * sizeof (GLushort));
97 for (i = 0 ; i < nbpoints; i ++ )
98 indices[i] = i;
99
100 glMatrixMode(GL_PROJECTION);
101 glPushMatrix();
102 glLoadIdentity();
103
104 glOrthox( 0 , _INT2FIXED(width),
105 0 , _INT2FIXED(height),
106 0 , _INT2FIXED( 1 ));
107
108
109 glMatrixMode(GL_MODELVIEW);
110 glPushMatrix();
111 glLoadIdentity();
112
113 glDisable(GL_DEPTH_TEST);
114
115 glTranslatex(_INT2FIXED(x), _INT2FIXED(y), 0 );
116
117 glEnable(GL_ALPHA_TEST);
118 glAlphaFuncx(GL_NOTEQUAL, 0 );
119 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
120 glDisableClientState(GL_COLOR_ARRAY);
121 glDisableClientState(GL_NORMAL_ARRAY);
122 glEnableClientState (GL_VERTEX_ARRAY);
123 glVertexPointer( 2 , GL_SHORT, 0 , points);
124
125 glDrawElements(GL_POINTS,
126 nbpoints,
127 GL_UNSIGNED_SHORT,
128 indices);
129
130 glDisable(GL_ALPHA_TEST);
131
132 glEnable(GL_DEPTH_TEST);
133
134 glPopMatrix();
135 glMatrixMode(GL_PROJECTION);
136 glPopMatrix();
137 glMatrixMode(GL_MODELVIEW);
138
139 free(indices);
140 free(points);
141 }
3 int len, xx = 0 , yy = 0 , nbpoints = 0 , i;
4 GLshort * points;
5 GLushort * indices;
6 HFONT font;
7 LOGFONTW lf;
8 RECT rect;
9 static HBITMAP bmp;
10 static BYTE * img;
11 static HDC hdc = NULL;
12 static BITMAPINFO bi;
13 SIZE sz;
14 static EGLint width, height;
15
16 if ( ! fontname || ! string )
17 return ;
18 if ( ! string [ 0 ])
19 return ;
20
21 if ( ! hdc)
22 {
23 hdc = CreateCompatibleDC(GetDC(hWnd));
24
25 eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, & width);
26 eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, & height);
27
28
29 ZeroMemory( & bi, sizeof (BITMAPINFO));
30 bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
31 bi.bmiHeader.biWidth = width;
32 bi.bmiHeader.biHeight = height;
33 bi.bmiHeader.biBitCount = 8 ;
34 bi.bmiHeader.biPlanes = 1 ;
35 bi.bmiHeader.biCompression = BI_RGB;
36
37 bmp = CreateDIBSection(hdc, & bi, DIB_RGB_COLORS, & img, NULL, 0 );
38
39 SelectObject(hdc, bmp);
40
41 SelectObject(hdc, GetStockObject(BLACK_BRUSH));
42
43 SetBkMode(hdc, TRANSPARENT);
44 SetTextColor(hdc, RGB( 255 , 255 , 255 ));
45 }
46
47 Rectangle(hdc, 0 , 0 , width, height);
48 ZeroMemory(img, width * height);
49
50 lf.lfCharSet = DEFAULT_CHARSET;
51 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
52 lf.lfEscapement = 0 ;
53 wcscpy(lf.lfFaceName, fontname);
54 lf.lfHeight = - (fontsize * GetDeviceCaps(GetDC(hWnd), LOGPIXELSY) / 72 );
55 lf.lfItalic = (style & 1 ) ? TRUE : FALSE;
56 lf.lfOrientation = 0 ;
57 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
58 lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
59 lf.lfQuality = DEFAULT_QUALITY;
60 lf.lfStrikeOut = FALSE;
61 lf.lfUnderline = (style & 4 ) ? TRUE : FALSE;
62 lf.lfWidth = 0 ;
63 lf.lfWeight = (style & 2 ) ? FW_BOLD : FW_NORMAL;
64
65 font = CreateFontIndirectW( & lf);
66
67 SelectObject(hdc, font);
68
69 len = wcslen( string );
70
71 GetTextExtentPointW(hdc, string , len, & sz);
72
73 rect.left = max( 0 , min(x, width));
74 rect.top = max( 0 , min(y, height));
75 rect.right = min(rect.left + sz.cx, width);
76 rect.bottom = min(rect.top + sz.cy, height);
77
78 DrawTextW(hdc, string , len, & rect, DT_LEFT | DT_BOTTOM);
79
80 points = (GLshort * )malloc(sz.cx * sz.cy * 2 * sizeof ( short ));
81
82 for (yy = rect.top; yy < rect.bottom; yy ++ )
83 {
84 for (xx = rect.left; xx < rect.right; xx ++ )
85 {
86 if (img[xx + (height - yy) * width] != 0 )
87 {
88 points[nbpoints * 2 + 0 ] = xx - x;
89 points[nbpoints * 2 + 1 ] = ( short )(rect.top + sz.cy - (yy - rect.top)) - y;
90 nbpoints ++ ;
91 }
92 }
93 }
94 DeleteObject(font);
95
96 indices = (GLushort * )malloc(nbpoints * sizeof (GLushort));
97 for (i = 0 ; i < nbpoints; i ++ )
98 indices[i] = i;
99
100 glMatrixMode(GL_PROJECTION);
101 glPushMatrix();
102 glLoadIdentity();
103
104 glOrthox( 0 , _INT2FIXED(width),
105 0 , _INT2FIXED(height),
106 0 , _INT2FIXED( 1 ));
107
108
109 glMatrixMode(GL_MODELVIEW);
110 glPushMatrix();
111 glLoadIdentity();
112
113 glDisable(GL_DEPTH_TEST);
114
115 glTranslatex(_INT2FIXED(x), _INT2FIXED(y), 0 );
116
117 glEnable(GL_ALPHA_TEST);
118 glAlphaFuncx(GL_NOTEQUAL, 0 );
119 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
120 glDisableClientState(GL_COLOR_ARRAY);
121 glDisableClientState(GL_NORMAL_ARRAY);
122 glEnableClientState (GL_VERTEX_ARRAY);
123 glVertexPointer( 2 , GL_SHORT, 0 , points);
124
125 glDrawElements(GL_POINTS,
126 nbpoints,
127 GL_UNSIGNED_SHORT,
128 indices);
129
130 glDisable(GL_ALPHA_TEST);
131
132 glEnable(GL_DEPTH_TEST);
133
134 glPopMatrix();
135 glMatrixMode(GL_PROJECTION);
136 glPopMatrix();
137 glMatrixMode(GL_MODELVIEW);
138
139 free(indices);
140 free(points);
141 }