Bitmap Fonts位图字体的添加.doc_第1页
Bitmap Fonts位图字体的添加.doc_第2页
Bitmap Fonts位图字体的添加.doc_第3页
Bitmap Fonts位图字体的添加.doc_第4页
Bitmap Fonts位图字体的添加.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

字体的绘制Bitmap Fonts位图字体的绘制1 在初始化场景函数(如Initialize)中调用CreateFont()建立位图字体由于还要用glGenLists()创建空显示列表以存储字符、用SelectObject()选进或恢复设备描述表、用DeleteObject()删除新建字体,所以实际上不是直接在初始化函数中调CreateFont,而是自定义一个函数BuildFont调用CreateFont()、glGenLists()、SelectObject()、DeleteObject()等,然后在初始化场景函数(如Initialize)中调用BuildFont。2 在退出前的扫尾函数(如Deinitialize)中调用glDeleteLists删除保存字体的显示列表该函数有参数:glDeleteLists(base,256)3 自定义函数Print用来在窗口中显示字符串,并在场景绘制函数(如DrawScene)中调用(1) 用glColor设置文字颜色;(2) 用glRasterPos设置文字显示的位置;(3) 调用Print显示文字附1 BuildFont的定义GLvoid BuildFont(GLvoid)/ 建立位图字体(Bitmap Fonts)HFONTnewFont;/ 用以保存新的字体对象HFONToldFont;/ 用以保存原字体对象base = glGenLists(256);/ 存储256个字符/上句需要定义GLuintbase;newFont = CreateFont(-18,/ 字体的高度0,/ 字体的宽度0,/ 旋转的角度0,/ 定位角度FW_THIN,/ 字体的粗细FALSE,/ 斜体?FALSE,/ 下划线?FALSE,/ 删除线?ANSI_CHARSET,/ 字符集OUT_TT_PRECIS,/ 输出精度CLIP_DEFAULT_PRECIS,/ 裁减精度ANTIALIASED_QUALITY,/ 输出质量FF_DONTCARE|DEFAULT_PITCH,/ 间距和字体族Tahoma);/ 字体名称oldFont = (HFONT)SelectObject(OGL_window-hDC, newFont); / 选进设备描述表 wglUseFontBitmaps(OGL_window-hDC, 0, 256, base);/ 建立256个字符SelectObject(OGL_window-hDC, oldFont);/ 恢复设备描述表DeleteObject(newFont);/ 删除新字体附2 Print的定义GLvoid Print(const char *fmt, .)/ 建立Print函数chartext256;/ 用以保存格式化后的字符串va_listap;/ 指向参数列表的指针if (fmt = NULL)/ 没有可输出的字符?return;/ 返回va_start(ap, fmt);/ 遍历字符串,查找变量vsprintf(text, fmt, ap);/ 将变量转换为显示的数字/上句需要添加#include / 标准输入/输出库va_end(ap);/ 结果保存在text内glPushAttrib(GL_LIST_BIT);/ 显示表状态入栈glListBase(base);/ 显示表偏移量glCallLists(int)strlen(text), GL_UNSIGNED_BYTE, text);/ 绘制字符串glPopAttrib();/ 显示表状态出栈附3 一个简单的完整例子(1) word.cpp/ 在此处引用程序要求的附加头文件:#include / 标准输入/输出库#include word.h/ 在此处加入程序要求的库到链接器中:#pragma comment(lib, opengl32.lib)#pragma comment(lib, glu32.lib)#pragma comment(lib, glaux.lib)/ 在此处定义全局变量:GL_Window*OGL_window;Keys*OGL_keys;GLuintbase;GLvoid BuildFont(GLvoid)/ 建立位图字体(Bitmap Fonts)HFONTnewFont;/ 用以保存新的字体对象HFONToldFont;/ 用以保存原字体对象base = glGenLists(256);/ 存储256个字符/上句需要定义GLuintbase;newFont = CreateFont(-18,/ 字体的高度0,/ 字体的宽度0,/ 旋转的角度0,/ 定位角度FW_THIN,/ 字体的粗细FALSE,/ 斜体?FALSE,/ 下划线?FALSE,/ 删除线?ANSI_CHARSET,/ 字符集OUT_TT_PRECIS,/ 输出精度CLIP_DEFAULT_PRECIS,/ 裁减精度ANTIALIASED_QUALITY,/ 输出质量FF_DONTCARE|DEFAULT_PITCH,/ 间距和字体族Tahoma);/ 字体名称oldFont = (HFONT)SelectObject(OGL_window-hDC, newFont); / 选进设备描述表 wglUseFontBitmaps(OGL_window-hDC, 0, 256, base);/ 建立256个字符SelectObject(OGL_window-hDC, oldFont);/ 恢复设备描述表DeleteObject(newFont);/ 删除新字体GLvoid Print(const char *fmt, .)/ 建立Print函数chartext256;/ 用以保存格式化后的字符串va_listap;/ 指向参数列表的指针if (fmt = NULL)/ 没有可输出的字符?return;/ 返回va_start(ap, fmt);/ 遍历字符串,查找变量vsprintf(text, fmt, ap);/ 将变量转换为显示的数字/上句需要添加#include / 标准输入/输出库va_end(ap);/ 结果保存在text内glPushAttrib(GL_LIST_BIT);/ 显示表状态入栈glListBase(base);/ 显示表偏移量glCallLists(int)strlen(text), GL_UNSIGNED_BYTE, text);/ 绘制字符串glPopAttrib();/ 显示表状态出栈BOOL Initialize(GL_Window* window, Keys* keys)/ 初始化场景/ 设置全局变量OGL_window= window;OGL_keys= keys;/在此处初始化绘制场景/ glClearColor(0.0f, 0.0f, 0.0f, 0.5f);/ 清屏为黑色/ glClearDepth(1.0f);/ 设置深度缓存/ glDepthFunc(GL_LEQUAL);/ 选择深度测试方式/ glEnable(GL_DEPTH_TEST);/ 开启深度测试/ glShadeModel(GL_SMOOTH);/ 阴暗处理采用平滑方式/ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);/ 最精细的透视计算BuildFont();return TRUE;/ 初始化成功返回TRUEvoid DrawSceneGL(void)/ 绘制场景glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/ 清除场景和深度缓存glLoadIdentity();/ 重置当前矩阵/ 在此处添加代码进行绘制:glColor3f(1.0f,0.0f,0.0f);glRasterPos3f(0.0f,0.0f,-3.0f);Print(hello world!);glFlush();/ 刷新GL命令队列void Update(void)/ 在此处更新对消息的动作if (OGL_keys-keyDownVK_ESCAPE = TRUE)/ 判断ESC键是否按下TerminateApplication(OGL_window);/ 结束程序if (OGL_keys-keyDownVK_F1 = TRUE)/ 判断F1是否按下PostMessage(OGL_window-hWnd, WM_TOGGLEFULLSCREEN, 0, 0);/ 在全屏窗口模式间切换void Deinitialize(void)/ 在此处做退出前扫尾工作glDeleteLists(base,256);(2) wordwindow.h#ifndef _WORD_WINDOW_H#define _WORD_WINDOW_H#include / Windows的头文件#include / OpenGL32库的头文件#include / Glu32库的头文件#define WM_TOGGLEFULLSCREEN (WM_USER + 1)/ 定义全屏/窗口模式切换消息#define TITLE5DGS Bitmapfonts/ 定义窗口标题#define CLASSNAME5DG_OPENGL/ 定义窗口类名#defineWIDTH640/ 定义窗口宽度#define HEIGHT480/ 定义窗口高度#define BPP16/ 定义每象素的位数/ 在此处定义与窗口相关的结构体:typedef struct / 定义处理键盘的结构体BOOL keyDown 256;/ 存储键盘按键状态的数组 Keys;typedef struct / 定义存储应用程序实例的结构体HINSTANCEhInstance;/ 应用程序实例const char*className;/ 应用程序类名 Application;typedef struct / 定义初始窗口所需信息Application*application;/ 所属的应用程序char*title;/ 窗口标题intwidth;/ 窗口宽度intheight;/ 窗口高度intbitsPerPixel;/ 每像素的位数BOOLisFullScreen;/ 是否全屏 GL_WindowInit;typedef struct / 定义窗口结构体Keys*keys;/ 窗口的键盘HWNDhWnd;/ 窗口句柄HDChDC;/ 设备描述表HGLRChRC;/ 绘制描述表GL_WindowInitinit;/ Window初始化信息的结构体BOOLisVisible;/ 窗口是否处于活动态 GL_Window;static BOOL g_isProgramLooping;static BOOL g_createFullScreen;/ 此代码模块中包含的函数的前向声明:void TerminateApplication (GL_Window* window);/ 结束程序BOOL Initialize(GL_Window* window, Keys* keys);/ 设置你绘制前的初始化值void DrawSceneGL(void);/ 在这里完成场景的绘制void Update(void);/ 在此处更新对消息的动作void Deinitialize(void);/ 在此处做退出前扫尾工作#endif/ _WORD_WINDOW_H(3) wordwindow.cpp#include wordwindow.hvoid TerminateApplication(GL_Window* window)/ 结束程序PostMessage(window-hWnd, WM_QUIT, 0, 0);/ 发送WM_QUIT消息g_isProgramLooping = FALSE;/ 停止程序 void ResizeWindowGL(int width, int height)/ 重新设置窗口大小glViewport(0, 0, (GLsizei)(width), (GLsizei)(height);/ 重置当前视口大小glMatrixMode(GL_PROJECTION);/ 切换到投影矩阵模式glLoadIdentity();/ 重置投影矩阵gluPerspective(45, (float)width/(float)height, 0.1, 100);/ 设置透视投影glMatrixMode(GL_MODELVIEW);/ 切换到模型视图矩阵glLoadIdentity();/ 重置模型视图矩阵BOOL ChangeScreenResolution(int width, int height, int bitsPerPixel)/ 修改屏幕分辨率DEVMODE dmScreenSettings;/ 设备设置模式 ZeroMemory(&dmScreenSettings, sizeof(DEVMODE);/ 清空dmScreenSettings.dmSize= sizeof(DEVMODE);/ Devmode结构的大小dmScreenSettings.dmPelsWidth= width;/ 设置为屏幕宽度dmScreenSettings.dmPelsHeight= height;/ 设置为屏幕高度dmScreenSettings.dmBitsPerPel= bitsPerPixel;/ 设为指定位长dmScreenSettings.dmFields= DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;/ 尝试设置显示模式并返回结果。注: CDS_FULLSCREEN 移去了状态栏if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)return FALSE;/ 分辨率修改失败,返回 FALSEreturn TRUE;/ 分辨率修改成功,返回 TRUEBOOL CreateWindowGL(GL_Window* window)/ 建立OpenGL窗口DWORD windowStyle = WS_OVERLAPPEDWINDOW;/ 设置窗口样式DWORD windowExtendedStyle = WS_EX_APPWINDOW;/ 设置窗口扩展样式PIXELFORMATDESCRIPTOR pfd =/ 像素格式描述符(pfd)的设置sizeof(PIXELFORMATDESCRIPTOR),/ 像素的尺寸1,/ 版本号PFD_DRAW_TO_WINDOW |/ pfd必须支持窗口绘制PFD_SUPPORT_OPENGL |/ pfd必须支持OpenGLPFD_DOUBLEBUFFER,/ pfd必须支持双缓存PFD_TYPE_RGBA,/ 像素格式为RGBAwindow-init.bitsPerPixel,/ 设置颜色深度0, 0, 0, 0, 0, 0,/ 忽略颜色位数0,/ 无Alpha缓存0,/ 忽略偏移位0,/ 无累积缓存0, 0, 0, 0,/ 忽略累积缓存位 16,/ 深度缓存为16位 0,/ 无模板缓存0,/ 无辅助缓存PFD_MAIN_PLANE,/ 主要绘制层0,/ 保留位0, 0, 0/ 忽略层遮罩;RECT windowRect = 0, 0, window-init.width, window-init.height;/ 定义窗口大小GLuint PixelFormat;/ 保存像素格式if (window-init.isFullScreen = TRUE)/ 切换全屏if (ChangeScreenResolution(window-init.width, window-init.height, window-init.bitsPerPixel) = FALSE)/ 全屏切换失败MessageBox(HWND_DESKTOP, 无法切换到全屏模式,在窗口模式下运行.nMode Switch Failed,Running In Windowed Mode., Error, MB_OK | MB_ICONEXCLAMATION);window-init.isFullScreen = FALSE;/ 设置 isFullscreen 为FALSEelse/ 全屏切换成功ShowCursor (FALSE);/ 隐藏鼠标windowStyle = WS_POPUP;/ 设置窗口样式windowExtendedStyle |= WS_EX_TOPMOST;/ 设置窗口扩展样式else/ 调整窗口大小,包括窗口边界AdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle);/ 开始创建 OpenGL 窗口window-hWnd = CreateWindowEx(windowExtendedStyle,/ 窗口扩展样式window-init.application-className,/ 应用程序类名window-init.title,/ 窗口标题windowStyle,/ 窗口样式0, 0,/ 窗口的 X,Y 坐标位置windowRect.right - windowRect.left,/ 窗口宽度windowRect.bottom - windowRect.top,/ 窗口高度HWND_DESKTOP,/ 父窗口为桌面0,/ 无菜单window-init.application-hInstance,/ 传入应用程序实例 window);if (window-hWnd = 0)/ 窗口是否成功创建return FALSE;/ 若失败,则返回FALSEwindow-hDC = GetDC(window-hWnd);/ 取得当前窗口的设备描述表if (window-hDC = 0)/ 若未得到设备描述表DestroyWindow(window-hWnd);/ 销毁该窗口window-hWnd = 0;/ 窗口句柄清零return FALSE;/ 返回FALSEPixelFormat = ChoosePixelFormat(window-hDC, &pfd);/ 选择兼容的像素格式if (PixelFormat = 0)/ 若选择失败ReleaseDC(window-hWnd, window-hDC);/ 释放设备描述表window-hDC = 0;/ 将设备描述表清零DestroyWindow(window-hWnd);/ 销毁窗口window-hWnd = 0;/ 窗口句柄清零return FALSE;/ 返回FALSEif (SetPixelFormat(window-hDC, PixelFormat, &pfd) = FALSE)/ 设置像素格式并判断是否失败ReleaseDC(window-hWnd, window-hDC);/ 释放设备描述表window-hDC = 0;/ 将设备描述表清零DestroyWindow(window-hWnd);/ 销毁窗口window-hWnd = 0;/ 窗口句柄清零return FALSE;/ 返回FALSEwindow-hRC = wglCreateContext(window-hDC);/ 取得绘制描述表if (window-hRC = 0)/ 若未得到绘制描述表ReleaseDC(window-hWnd, window-hDC);/ 释放设备描述表 window-hDC = 0;/ 将设备描述表清零DestroyWindow(window-hWnd);/ 销毁窗口window-hWnd = 0;/ 窗口句柄清零return FALSE;/ 返回FALSEif (wglMakeCurrent(window-hDC, window-hRC) = FALSE)/ 设置绘制描述表并判断是否失败wglDeleteContext(window-hRC);/ 删除绘制描述表window-hRC = 0;/ 将绘制描述表清零ReleaseDC(window-hWnd, window-hDC);/ 释放设备描述表window-hDC = 0;/ 将设备描述表清零DestroyWindow(window-hWnd);/ 销毁窗口window-hWnd = 0;/ 窗口句柄清零return FALSE;/ 返回FALSEShowWindow(window-hWnd, SW_NORMAL);/ 显示窗口ResizeWindowGL(window-init.width, window-init.height);/ 重设窗口ZeroMemory(window-keys, sizeof(Keys);/ 清空键盘缓冲区return TRUE;/ 窗口创建成功BOOL DestroyWindowGL(GL_Window* window)/ 销毁窗口并释放程序所用的资源if (window-hWnd != 0)/ 窗口有句柄?if (window-hDC != 0)/ 窗口是否有得到绘制描述表?wglMakeCurrent(window-hDC, 0);/ 将当前描述表指针置为0if (window-hRC != 0)/ 该窗口是否有绘制描述表wglDeleteContext(window-hRC);/ 释放绘制描述表window-hRC = 0;/ 将绘制描述表清零ReleaseDC(window-hWnd, window-hDC);/ 释放设备描述表window-hDC = 0;/ 将设备描述表清零DestroyWindow(window-hWnd);/ 销毁窗口window-hWnd = 0;/ 将窗口句柄清零if (window-init.isFullScreen)/ 若窗口在全屏模式下ChangeDisplaySettings(NULL, 0);/ 切换为桌面分辨率ShowCursor(TRUE);/ 显示鼠标return TRUE;/ 返回TRUELRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)GL_Window* window = (GL_Window*)(GetWindowLong(hWnd, GWL_USERDATA);switch (uMsg)/ 取得Window的消息值case WM_SYSCOMMAND:/ 截取系统命令switch (wParam)/ 监听系统调用case SC_SCREENSAVE:/ 要运行屏保(Screensaver)?case SC_MONITORPOWER:/ 显示器进入节电模式(Powersave)?return 0;/ 提前返回0,防止系统调用执行break;/ 退出case WM_CREATE:/ 创建WindowCREATESTRUCT* creation = (CREATESTRUCT*)(lParam);/ 保存窗口结构指针window = (GL_Window*)(creation-lpCreateParams);SetWindowLong(hWnd, GWL_USERDATA, (LONG)(window);/ 改变窗口属性return 0;/ 返回case WM_CLOSE:/ 关闭窗口PostMessage(window-hWnd, WM_QUIT, 0, 0);/ 结束程序g_isProgramLooping = FALSE;return 0;case WM_SIZE:/ WM_SIZE消息处理switch (wParam)/ 判断消息句柄case SIZE_MINIMIZED:/ 窗口最小化?window-isVisible = FALSE;/ 设置isVisible 为 FALSEreturn 0;case SIZE_MAXIMIZED:/ 窗口最大化?window-isVisible = TRUE;/ 设置isVisible 为 TRUEResizeWindowGL (LOWORD (lParam), HIWORD (lParam);/ 修改窗口大小为 Width=LoWord, Height=HiWordreturn 0;/ 返回case SIZE_RESTORED:/ 窗口还原?window-isVisible = TRUE;/ 设置isVisible 为 TRUEResizeWindowGL (LOWORD (lParam), HIWORD (lParam);/ 修改窗口大小为 Width=LoWord, Height=HiWordreturn 0;/ 返回break;/ 退出case WM_KEYDOWN:/ 更新键盘缓冲区if (wParam = 0) & (wParam keys-keyDownwParam = TRUE;/ 设相应键为 TRUE (被按下的键)return 0;/ 返回break;/ 退出case WM_KEYUP:/ 松开按键的时候更新键盘缓冲if (wParam = 0) & (wParam keys-keyDownwParam = FALSE;/ 设相应键为 FALSE (被释放的键)return 0;/ 返回break;/ 退出case WM_TOGGLEFULLSCREEN:/ 切换全屏/窗口模式g_createFullScreen = !g_createFullScreen;PostMessage(hWnd, WM_QUIT, 0, 0);break;/ 退出default:break;return DefWindowProc(hWnd, uMsg, wParam, lParam);/ 将本程序不处理的消息传给 DefWindowProc BOOL RegisterWindowClass(Application* application)/ 为本应用程序注册一个类.WNDCLASSEX windowClass;/ 窗口类ZeroMemory(&windowClass, sizeof(WNDCLASSEX);/ 清空内存windowClass.cbSize= sizeof(WNDCLASSEX);/ 窗口类的大小windowClass.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;/ 在移动,改变大小的时候重绘 windowClass.lpfnWndProc= (WNDPROC)(WindowProc);/ 用WindowProc函数处理消息windowClass.hInstance= application-hInstance;/ 设置实例windowClass.hbrBackground= (HBRUSH)(COLOR_APPWORKSPACE);/ 类背景的画刷颜色windowClass.hCursor= LoadCursor(NULL, IDC_ARROW);/ 载入箭头光标windowClass.lpszClassName= application-className;/ 设置应用程序的类名if (RegisterClassEx(&windowClass) = 0)/ 注册类失败?MessageBox(HWND_DESKTOP, 应用程序类注册失败!nRegisterClassEx Failed!, Error, MB_OK | MB_ICONEXCLAMATION);return FALSE;/ 返回FALSE (注册失败)return TRUE;/ 返回TRUE(注册成功)/ 应用程序的入口 (WinMain)int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)Applicationapplication;/ 应用程序GL_Windowwindow;/ 窗口Keyskeys;/ 键盘按键MSGmsg;/ Window消息BOOLisMessagePumpActive;/ 给应用程序赋值application.className = CLASSNAME;/ 程序类名字application.hInstance = hInstance;/ 程序入口/ 窗口相关信息设置ZeroMemory(&window, sizeof(GL_Window);/ 清零窗口变量的内存空间window.keys= &keys;/ 设置按键window.init.application= &application;/ 设置窗口程序window.init.title= TITLE;/ 设置标题window.init.width= WIDTH;/ 设置窗口宽度window.init.height= HEIGHT;/ 设置窗口高度window.init.bitsPerPixel= BPP;/ 设置每像素的位数window.init.isFullScreen= FALSE;/ 设置初始窗口是否全屏否(FALSE)ZeroMemory(&keys, sizeof(Keys);/ 键盘缓冲清零if (RegisterWindowClass(&application) = FALSE)/ 注册类是否失败MessageBox(HWND_DESKTOP, 窗口类注册失败!nError Registering Window Class!, Error, MB_OK | MB_ICONEXCLAMATION);return -1;/ 结束程序g_isProgramLooping = TRUE;/ 将g_isProgramLooping设TRUEg_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论