write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
讨论新闻组及文件
Technorati 标签:
OpenGL
,
Bitmap
个人认为《OpenGL Programming Guide
》的第8章是最让人头晕的一章,讲了很多内容,但是很多东西太偏向于纯理论的概念及众多函数参数的详尽阐述,可能因为这个内容本来就比较难,作者也知道,所以为本章配了全书最密集的图示,可是个人感觉那些图实在是没有任何帮助-_-!。
太多的东西和理论我们学不来,本节只搞定一件非常重要但是此书讲了半天却没有触及的事情,从一个bmp文件中读取数据然后显示出来。当然,这也不怪作者,毕竟读取数据不再是属于OpenGL API的一部分,但是仅仅因为这样,就总是用一堆通过野蛮的数组操作生成的恶心黑白图来做演示和教学,是不是也太过了点?
另外,NEHE教程中有载入图形的相关章节,单还是使用glaux这个现在已经不再推荐的过时库,已经有点不合时宜了,我不想使用这些,最好的办法自然是字节弄明白bitmap文件的格式,直接读取相关数据,然后载入自己的结构使用,这样可以作为完全的跨平台(irrlicht的做法),我又没有这样做的决心,既然是Win32下的OpenGL编程学习,Win32 API永远是我先考虑的,同样的简洁。。。只是别和我讨论跨平台的问题。其实这个说法值得探讨。。。。不关心跨平台为啥要用OpenGL了?-_-!
显示简单的内存中的像素数据
GLubyte rasters
[24] = {
0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
0xff, 0xc0, 0xff, 0xc0};
//这里进行所有的绘图工作
void
SceneShow
(GLvoid
)
{
glClear
(GL_COLOR_BUFFER_BIT
); // 清空颜色缓冲区
glColor3f
(1.0, 0.0, 0.0);
glPixelStorei
(GL_UNPACK_ALIGNMENT
, 1); // Pixel Storage Mode (Word Alignment / 1 Bytes)
glRasterPos2f
(0, 0);
glBitmap
(10, 12, 0.0, 0.0, 11.0, 0.0, rasters
);
glBitmap
(10, 12, 0.0, 0.0, 11.0, 0.0, rasters
);
glWindowPos2i
(0, 0);
glBitmap
(10, 12, 0.0, 0.0, 11.0, 0.0, rasters
);
glBitmap
(10, 12, 0.0, 0.0, 11.0, 0.0, rasters
);
glBitmap
(10, 12, 0.0, 0.0, 11.0, 0.0, rasters
);
glFlush
();
}
此时显示的效果如下图:
因为实在太简单了,简单的说明一下代码:
此例中主要有4个OpenGL API,但是都非常简单,因为牵涉的相关概念比较少。
glPixelStore*用于指明像素存储的格式,此例中表示1个字节的一个元素。
《OpenGL Reference Manual
》:
Name
glPixelStore — set pixel storage modes
C Specification
void glPixelStoref( GLenum pname,
GLfloat param);
void glPixelStorei( GLenum pname,
GLint param);
此函数的参数较多,但是使用起来却较简单,具体的解释大家就自己去查了。
glRasterPos* ,glWindowPos* 用于指定开始绘制像素的位置,同时,上例也说明了指明时两个函数的区别,glRasterPos* 确定位置后绘制了2个F,并且都在窗口的正中间,(0,0)位置,此函数的位置就是以普通的OpenGL坐标系为基准的,因此,也会受到OpenGL坐标变换的影响。glWindowPos2i是个比较特殊的函数,因为它完全不考虑OpenGL坐标变换,永远按窗口的坐标系定位,(这点在绘制界面的时候很有用)虽然实际的坐标定位方式与Windows惯用方式有点区别,原点不是在左上角而是在左下角,直观点说,glWindowPos* 是|_型坐标系,坐标系的方向遵循了OpenGL坐标系的方向(也就是普通笛卡尔坐标系的方向)。
《OpenGL Reference Manual
》:
glRasterPos — specify the raster position for pixel operations
glWindowPos — specify the raster position in window coordinates for pixel operations
为了更清楚的看到glWindowPos* 的确定性及glRasterPos* 的可变性,这里我加入glTranslate引入的偏移,(glTranslatef(0.5, 0.0, 0.0);),可以看到glRasterPos* 确定的位置变了,glWindowPos* 的还是老地方。
另外,需要注意的是,上面绘制F的函数调用完全一样,但是绘制并没有重合,因为API中本身就包含了绘制位置的偏移参数。
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的2009-12-28/glPixelDraw 目录,获取方式见文章最后关于获取博客完整源代码的说明。
OpenGL中位图文件的显示
以下图片来自于经典的《windows图形编程》一书。
读取bitmap文件的数据是个问题,其实bitmap文件本身很简单,通过固定的结构完全解析读取也不是太难,LaMothe(《Windows游戏编程大师技巧》《3D 游戏编程大师技巧》 )在书中有介绍,但是,我就不这样做了,与OpenGL学习不是一件事。
如一开始描述的一样,这里通过Windows API来完成,以下是Win32的BITMAP结构:
/* Bitmap Header Definition */
typedef struct
tagBITMAP
{
LONG bmType
;
LONG bmWidth
;
LONG bmHeight
;
LONG bmWidthBytes
;
WORD bmPlanes
;
WORD bmBitsPixel
;
LPVOID bmBits
;
} BITMAP
, *PBITMAP
, NEAR
*NPBITMAP
, FAR
*LPBITMAP
;
我们需要的都有了,长,高,实际的像素。
BITMAP gBmp
;
//OpenGL初始化开始
void
SceneInit
(int
w
,int
h
)
{
GLenum err
= glewInit
();
if
(err
!= GLEW_OK
)
{
MessageBox
(NULL
, _T
("Error"
), _T
("Glew init failed."
), MB_OK
);
exit
(-1);
}
HBITMAP hBmp
=(HBITMAP
)LoadImage
( NULL
, "tiger.bmp"
, IMAGE_BITMAP
, 0, 0, LR_CREATEDIBSECTION
| LR_LOADFROMFILE
);
if
(!hBmp
)
{
exit
(3);
}
GetObject
(hBmp
, sizeof
(gBmp
), &gBmp
);
glClearColor
(0.0, 0.0, 0.0, 0.0);
}
MSDN的函数原型:
HANDLE LoadImage(
HINSTANCE hinst
, LPCTSTR lpszName
, UINT uType
, int cxDesired
, int cyDesired
, UINT fuLoad
);
初始化的时候就将图片读出来了,上面就两个Win32 API,一个LoadImage用于加载图片,GetObject用于获取信息,需要特别说明的是,不要看到有个type指定图片类型就感觉LoadImage很强大。。。。
uType
[in] Specifies the type of image to be loaded. This parameter can be one of the following values.
IMAGE_BITMAP
Loads a bitmap.
IMAGE_CURSOR
Loads a cursor.
IMAGE_ICON
Loads an icon.
错觉吧。。。。。。。。。。。。。。毕竟是Win32 API,你以为D3D API啊。。。。。。。。。。呵呵,即使是MFC中的CImage都是弱的不行,还期望这个函数啊。。。。。。。。。。。。。
有了数据就好说了,显示贝。
//这里进行所有的绘图工作
void
SceneShow
(GLvoid
)
{
glClear
(GL_COLOR_BUFFER_BIT
); // 清空颜色缓冲区
glPixelStorei
(GL_UNPACK_ALIGNMENT
, 4); // Pixel Storage Mode (Word Alignment / 4 Bytes)
glWindowPos2d
( (WIDTH
- gBmp
.bmWidth
) / 2, (HEIGHT
- gBmp
.bmHeight
) / 2 );
glDrawPixels
(gBmp
.bmWidth
, gBmp
.bmHeight
, GL_BGR
, GL_UNSIGNED_BYTE
, gBmp
.bmBits
);
glFlush
();
}
如图,这里利用glWindowPos2d函数并通过图片长宽的计算,将图片显示在窗口的中间。
哈。。。。。。。。。。学习了这么久的OpenGL,还是第一次利用API实现图片的绘制(的确有点晚),看惯了线框和实心体,再看看图片就是不一样。。。。。。。。。。(事实上,这样的绘制过程通过Win32 API来实现实在再简单不过了,但是谁叫我们学习的是OpenGL呢,呵呵)
这里只多了一个函数:glDrawPixels
《OpenGL Reference Manual
》:
glDrawPixels — write a block of pixels to the frame buffer
C Specification
void glDrawPixels( GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const GLvoid * data);
Parameters
width, height : Specify the dimensions of the pixel rectangle to be written into the frame buffer.
format:Specifies the format of the pixel data.
type:Specifies the data type for data.
data:Specifies a pointer to the pixel data.
这里都没有什么好奇怪的,我唯一奇怪的是,对于Windows下的图片来说,OpenGL指定绘制的时候type竟然是GL_BGR而不是GL_RGB。。。有高人出来解释一下。
另外,我们还可以通过glPixelZoom函数来缩放图片,比如下列代码就分别将图片横向扩大2倍,纵向扩大1.5倍。
//这里进行所有的绘图工作
void
SceneShow
(GLvoid
)
{
glClear
(GL_COLOR_BUFFER_BIT
); // 清空颜色缓冲区
glPixelZoom
(2.0, 1.5);
glPixelStorei
(GL_UNPACK_ALIGNMENT
, 4); // Pixel Storage Mode (Word Alignment / 4 Bytes)
glWindowPos2d
( (WIDTH
- gBmp
.bmWidth
) / 2, (HEIGHT
- gBmp
.bmHeight
) / 2 );
glDrawPixels
(gBmp
.bmWidth
, gBmp
.bmHeight
, GL_BGR
, GL_UNSIGNED_BYTE
, gBmp
.bmBits
);
glFlush
();
}
显示效果:
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的2009-12-28/glBitmapTest 目录,获取方式见文章最后关于获取博客完整源代码的说明。
本系列其他文章见OpenGL专题 《Win32 OpenGL系列专题
》
参考资料
1. 《OpenGL Reference Manual
》,OpenGL参考手册
2. 《OpenGL
编程指南》(《OpenGL Programming Guide
》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis
著,徐波译,机械工业出版社
3. 《Nehe OpenGL Tutorials》,Nehe著,在http://nehe.gamedev.net/
上可以找到教程及相关的代码下载,(有PDF版本教程下载)Nehe自己还做了一个面向对象的框架,作为演示程序来说,这样的框架非常合适。也有中文版
,各取所需吧。
4.《[游戏开发]OpenGL中用bmp图片做纹理贴图的三种方法
》
完整源代码获取说明
由于篇幅限制,本文一般仅贴出代码的主要关心的部分,代码带工程(或者makefile)完整版(如果有的话)都能用Mercurial在Google Code中下载。文章以博文发表的日期分目录存放,请直接使用Mercurial克隆下库:
https://blog-sample-code.jtianling.googlecode.com/hg/
Mercurial使用方法见《分布式的,新一代版本控制系统Mercurial的介绍及简要入门
》
要是仅仅想浏览全部代码也可以直接到google code上去看,在下面的地址:
http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code
原创文章作者保留版权 转载请注明原作者 并给出链接
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
分享到:
相关推荐
在Win32程序中应用OpenGL进行多窗口显示是一项复杂但有趣的任务,这涉及到Windows API的深入理解和OpenGL图形库的熟练运用。在这个过程中,开发者需要创建多个窗口,每个窗口都独立地渲染OpenGL图形,并且可能还需要...
"win32 opengl画线"这个主题涉及到了在Microsoft Windows环境下,利用OpenGL库来创建和显示简单的线条。OpenGL是一个跨语言、跨平台的编程接口,用于生成2D和3D图像。在Visual Studio 2012这样的IDE中,我们可以配置...
这个工具包包含了四个重要的库文件:opengl32.lib、glu32.lib、glaux.lib和glew32.lib,它们各自在OpenGL编程中扮演着关键角色。 1. **opengl32.lib**:这是OpenGL的主要库文件,提供了与硬件交互的基本接口,允许...
OpenGL打印支持在Win32环境下是一项重要的技术,它允许开发者利用OpenGL的强大图形处理能力来创建高质量的打印输出。本文将详细解析这个主题,包括OpenGL的基本概念、Win32 API在打印中的作用,以及如何结合两者实现...
### 基于VC++的OpenGL编程讲座知识点详解 #### 一、OpenGL简介与特性 **OpenGL概述:** OpenGL是一种高性能的三维图形标准,由SGI等计算机巨头推动,并成为了一个广泛采用的标准。该标准独立于窗口系统和操作系统...
在IT领域,游戏开发是一项复杂而充满挑战的任务,尤其是在使用像VC++这样的编程语言和Win32 API进行原生Windows应用程序开发时。本教程将深入探讨如何利用这些工具创建有趣的游戏。 **Windows API编程基础** ...
《Win32游戏模板》是一个基础的Windows平台游戏开发示例,主要展示了如何利用Win32 API构建一个简单游戏的基本框架。这个模板包含了图形显示、用户输入处理、音频播放和定时器功能,对于初学者来说,是理解Windows...
在Windows CE平台上进行编程时,...通过上述内容,你可以了解到在Win CE平台下利用C++进行图形显示特效编程的基本概念和方法。深入研究并实践这些知识点,你将能够创建出引人注目的、具有视觉冲击力的嵌入式应用程序。
4. **图形绘制**:Win32 API的`BitBlt`函数用于在窗口的设备上下文中进行位图的复制,这对于绘制游戏板和方块非常有用。每次游戏状态改变时,都需要清除屏幕并重新绘制所有元素。 5. **状态管理**:游戏有多个状态...
Win32 GDI (Graphics Device Interface) 是微软Windows操作系统中的一部分,它提供了基本的图形绘制功能,如绘制线条、形状、文本以及处理位图等。GAPI(Graphics Application Programming Interface)通常指的是...
GDI支持位图操作,可以加载并显示BMP或其他格式的图像资源。同时,通过调用`SelectObject`函数可以选择不同的字体和颜色来展示游戏状态。 为了提高游戏的交互性,开发者可能会使用键盘消息处理,监听用户输入,如...
OpenGL 包含 120 个图形函数,在微机环境下共有 5 种函数:基本(或核心)函数、实用函数、辅助函数、Windows 专用函数和 Win32 API 函数。 OpenGL 特点 1. 跨平台特性:OpenGL 可以独立于硬件、窗口和操作系统,...
这样的项目对于想要学习C++和Win32 API编程的初学者来说,是一个非常有价值的实践案例。 首先,我们要理解C++编程语言的基础。C++是一种静态类型、编译式的通用编程语言,以其高效、灵活和面向对象的特性闻名。它...
- **多功能**:OpenGL 支持七大核心功能,包括建模、变换、颜色模式设置、光照和材质设置、纹理映射、位图显示以及双缓冲动画(Double Buffering)。 - **独立性**:OpenGL 不提供窗口管理、用户交互或文件 I/O 等...
5. **开发环境配置**:在开发环境中,使用OpenGL库需要配置正确的编译器设置,例如设置链接器选项以链接到opengl32.lib、glu32.lib以及上述辅助库的相应lib文件。同时,也需要包含相应的头文件,如、等,以访问...
在Visual C++中新建OpenGL工程,首先需要选择“Win32 Console Application”,然后指定工程存储位置和名称。完成这些设置后,开发者可以开始编写OpenGL代码,利用提供的API函数进行图形绘制和交互。 总之,OpenGL是...
OpenGL是计算机图形学中的一种广泛应用的编程接口,用于在各种操作系统和硬件上生成高质量的2D和3D图像。在本教程中,我们将探讨如何在VC++或Visual Studio环境下配置OpenGL,以及如何将二维图形转换为三维图形。这...
开发者可能使用了MFC(Microsoft Foundation Classes)或者Win32 API来处理窗口创建、消息循环和用户输入,这些都是构建Windows桌面应用的基础。 键盘操作是游戏交互的关键部分。源代码会包含事件处理函数,监听...
例如,可以创建一个简单的Win32控制台程序,包含消息循环,处理WM_PAINT消息时执行上述显示位图的代码。 对于初学者来说,理解并实现这个过程能够深入理解位图文件的结构,同时掌握GDI或GDI+的使用。通过不断的实践...
在OpenGL编程中,首先需要理解的基本概念有: 1. **坐标系统**:OpenGL使用右手坐标系,原点在屏幕中心,x轴向右,y轴向上,z轴指向屏幕内部。 2. **基本几何对象**:OpenGL提供了一系列基本形状,如点、线、...