请问在OpenGL里如何显示中文?

tlovexyj 2002-06-12 11:59:49
照下面的代码,显示中文失败,是乱码。
void tl_Font::
DrawString(float x, float y, float z, const unsigned char *str)
{
HDC hDC = wglGetCurrentDC();
DWORD dwChar;
int ListNum;
for(size_t i=0; i<strlen((char *)str); i++)
{
if (IsDBCSLeadByte(str[i]))
{
dwChar = (DWORD)((str[i]<<8) | str[i+1]);
i++;
}
else
dwChar = str[i];

glDisable(GL_TEXTURE_2D);
glRasterPos3f(x, y-_nHeight, z);

ListNum = glGenLists(1);
wglUseFontBitmaps(hDC, dwChar, 1, ListNum);
glCallList(ListNum);
glDeleteLists(ListNum, 1);

glEnable(GL_TEXTURE_2D);
}
}

请问各位高手,我哪里错了:)
谢谢!

在OpenGL中显示中文通常是用什么办法呢?
请教!
...全文
473 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
tlovexyj 2002-06-17
  • 打赏
  • 举报
回复
小弟已经解决,方法与楼上的兄台类似,直接用GetDiBits,然后修改局部纹理,建一个纹理cache。

谢谢大家的回答。散分!
chenlee 2002-06-14
  • 打赏
  • 举报
回复
需要说明的是,上面的函数只能处理UNICODE的字符

用如下的方式定义UNICODE的字符串:
wchar_t * msg1 = L"你好";
~~~C++中定义UNICODE字符串的前缀

注意:这里强制类型转换是行不通的:
wchar_t * msg2 = (wchar_t*)"你好"; //会显示乱码

chenlee 2002-06-14
  • 打赏
  • 举报
回复
下面是我在一个程序中用来生成单个汉字显示列表的程序段


struct glchar_s
{
GLuint _dlist; // display list use to display the char
int _chwidth; // width of the char ( in pixels )
};


bool init_wchar( wchar_t c, glchar_s & glch )
{
// generate display lists
GLuint l = glGenLists(1);
if ( 0 == l )
{
cerr << "init_wchar() FAILED : fail to generate opengl display list!\n";
return false;
}

// get window DC
HDC dc = GetDC( get_your_main_hwnd() );
if ( 0 == dc )
{
cerr << "init_wchar() FAILED : fail to get window DC!\n";
glDeleteLists(l, 1);
return false;
}

// select default fixed font
HGDIOBJ oldfont = SelectObject( dc, GetStockObject(SYSTEM_FIXED_FONT) );

// get char width
SIZE sz;
if ( !GetTextExtentPoint32W(dc, &c, 1, &sz) )
{
cerr << "init_wchar() FAILED : fail to get wchar's width!\n";
SelectObject(dc, oldfont);
ReleaseDC( get_your_main_hwnd(), dc );
glDeleteLists( l, 1 );
return false;
}

// create font list
if ( !wglUseFontBitmapsW(dc, c, 1, l) )
{
cerr << "init_wchar() FAILED : fail to generate display list!\n";
SelectObject(dc, oldfont);
ReleaseDC( get_your_main_hwnd(), dc );
glDeleteLists( l, 1 );
return false;
}

// success
SelectObject(dc, oldfont);
ReleaseDC( get_your_main_hwnd(), dc );
glch._chwidth = sz.cx;
glch._dlist = l;
return true;
}
tlovexyj 2002-06-13
  • 打赏
  • 举报
回复
那上面的文章我都有看过。
不是实际实现不了,就是不支持汉字。

是否有小的例子(最好带源码)可以参考!
谢谢!
maplez 2002-06-13
  • 打赏
  • 举报
回复
不要全部生成显示列表,下面这篇文章讲了这个问题
http://vip.6to23.com/mays/develop/opengl/200112/CFont.htm
清平布衣 2002-06-12
  • 打赏
  • 举报
回复
//两种方法

void DrawStringOutline(HDC hdc, CString strText, HFONT hFont /* = NULL */)
{
//HDC hdc = wglGetCurrentDC();
//ASSERT(hdc != NULL);

if (hFont == NULL)
{
hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
}

ASSERT(hFont != NULL);
HFONT hOldFont = (HFONT)::SelectObject(hdc, hFont);

UCHAR * pChar= (UCHAR*)strText.GetBuffer(strText.GetLength());
int nListNum;
DWORD dwChar;

glPushMatrix();

for(int i = 0; i < strText.GetLength(); i++)
{
if(IsDBCSLeadByte((BYTE)pChar[i]))
{
dwChar = (WORD)((pChar[i] << 8) | pChar[i+1]);
i++;
}
else
dwChar = pChar[i];
nListNum = glGenLists(1);
GLYPHMETRICSFLOAT pgmf[1];
wglUseFontOutlines(hdc, dwChar, 1, nListNum, 0.0f, 0.1f,WGL_FONT_POLYGONS, pgmf);

glCallList(nListNum);
glDeleteLists(nListNum, 1);
}
glPopMatrix();

strText.ReleaseBuffer();
::SelectObject(hdc,hOldFont);
}


int DrawStringBitmap(HDC hdc, LPCTSTR lpszText, HFONT hFont /* = NULL */, BOOL bUseDisplayList /*= FALSE */)
{
CBitmap bitmap;
BITMAP bm;
SIZE size;
UCHAR* pBmpBits;
HFONT hOldFont;
//HDC hdc = wglGetCurrentDC();

if(!hFont) // use default system font
{
hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
}

hOldFont = (HFONT)SelectObject(hdc, hFont);
::GetTextExtentPoint32(hdc, lpszText, (int)strlen(lpszText), &size);

bitmap.CreateBitmap(size.cx, size.cy, 1, 1, NULL);

HDC hMemDC = ::CreateCompatibleDC(hdc);
if(hMemDC)
{
HBITMAP hPrevBmp = (HBITMAP)SelectObject(hMemDC, bitmap);
HFONT hPrevFont = (HFONT)SelectObject(hMemDC, hFont);

SetBkColor(hMemDC, RGB(0, 0, 0));
SetTextColor(hMemDC, RGB(255, 255, 255));
SetBkMode(hMemDC, OPAQUE);
TextOut(hMemDC, 0, 0, lpszText, (int)strlen(lpszText));

// copy GDI bitmap to DIB
bitmap.GetBitmap(&bm);
size.cx = (bm.bmWidth + 31) & (~31);
size.cy = bm.bmHeight;
int bufsize = size.cy * (((bm.bmWidth + 31) & (~31)) / 8);
pBmpBits = new UCHAR[bufsize];
memset(pBmpBits, 0, sizeof(UCHAR)*bufsize);

struct {
BITMAPINFOHEADER bih;
RGBQUAD col[2];
}bic;
BITMAPINFO *binf = (BITMAPINFO *)&bic;

binf->bmiHeader.biSize = sizeof(binf->bmiHeader);
binf->bmiHeader.biWidth = bm.bmWidth;
binf->bmiHeader.biHeight = bm.bmHeight;
binf->bmiHeader.biPlanes = 1;
binf->bmiHeader.biBitCount = 1;
binf->bmiHeader.biCompression = BI_RGB;
binf->bmiHeader.biSizeImage = bufsize;
binf->bmiHeader.biXPelsPerMeter = 1;
binf->bmiHeader.biYPelsPerMeter = 1;
binf->bmiHeader.biClrUsed = 0;
binf->bmiHeader.biClrImportant = 0;

::GetDIBits(hdc, bitmap, 0, bm.bmHeight, pBmpBits, binf, DIB_RGB_COLORS);

SelectObject(hMemDC, hPrevBmp);
}
::DeleteDC(hMemDC);

// delete font from DC
SelectObject(hdc, hOldFont);

// display text
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

if(bUseDisplayList)
{
m_displist = glGenLists(1);
glNewList(m_displist, GL_COMPILE);
glBitmap(size.cx, size.cy, 0.0, 2.0, size.cx+2.0f, 0.0,pBmpBits);
glEndList();
}
else
glBitmap(size.cx, size.cy, 0.0, 2.0, size.cx+2.0f, 0.0, pBmpBits);

delete pBmpBits;

return m_displist;
}
tlovexyj 2002-06-12
  • 打赏
  • 举报
回复
中文字有6000+个,全生成列表,-_-!
chenlee 2002-06-12
  • 打赏
  • 举报
回复
用wglUseFontBitmapW(...)来生成中文字符的显示列表
tlovexyj 2002-06-12
  • 打赏
  • 举报
回复
非常感谢!
不过OpenGL有一些设置,如果不同,则什么也看不到:( 我现在就是。

可否给一个工程我,一个演示也好!
再谢!

8,325

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧