OpenGL绘制Bmp图片
opengl学习(三)----绘制简单图形(一)

opengl学习(三)----绘制简单图形(⼀)今天说⼀说⼏种简单的图元。
所有的⼏何图元都是根据它们的顶点来描绘的。
⽽顶点就是它们在屏幕上的坐标位置。
我喜欢把这⼏个简单的图元称为点线⾯。
点,可以看到⼀个顶点;线,就是两个顶点指定的⼀条有限长度的线段;⾯,其实更准确讲是⼀个凸多边形。
opengl⾥所讲的多边形是内部⽤颜⾊填充的,视觉上称为⾯我个⼈认为是更贴近的。
当然,多边形也是由指定的顶点组成的。
需要注意的是,要想被opengl按照设计被绘制必须正确的认识到,所谓的多边形是顶点都处于⼀个平⾯上,凸多边形。
凸多边形不能理解的,请问度娘。
来看⼀个例⼦:C++代码1. glBegin(GL_POLYGON);2. glVertex2f(0.0, 0.0);3. glVertex2f(0.0, 3.0);4. glVertex2f(4.0, 3.0);5. glVertex2f(6.0, 1.5);6. glVertex2f(4.0, 0.0);7. glEnd();先不去关⼼代码本⾝,这段代码最终的结果是要指定5个顶点绘制⼀个凸五边形。
注意,不是5条线段⽽是⼀个凸五边形的平⾯。
不管是点线⾯的哪⼀种,都是需要指定⼀组顶点的。
如何判定顶点指定的开始和结束就是glBegin和glEnd的⼯作。
引⽤void glBegin(Glenum mode);标志着⼀个顶点数据列表的开始,它描述了⼀个⼏何图元。
mode参数指定了图元的类型。
void glEnd(void);标志着⼀个顶点数据列表的结束。
mode设置的不同,代表着将要绘制的图元也不同。
下⾯这个表就是图元的名称和含义:值含义GL_POINTS 单个的点GL_LINES ⼀对顶点被解释为⼀条直线GL_LINE_STRIP ⼀系列的连接直线GL_LINE_LOOP 和上⾯相同,但第⼀个顶点和最后⼀个顶点彼此相连GL_TRIANGLES 3个顶点被解释为⼀个三⾓形GL_TRIANGLES_STRIP 三⾓形的连接串GL_TRIANGLES_FAN 连接成扇形的三⾓形系列GL_QUADS 4个顶点被解释为⼀个四边形GL_QUADS_STRIP 四边形的连接串GL_POLYGON 简单的凸多边形的边界试想着,如果将glBegin(GL_POLYGON)修改为glBegin(GL_POINTS),绘制出来的将是什么图形呢? 哈哈,那就是5个点⽽已么。
OpenGL绘制Bmp图片

二维坐标OpenGL一、定义二维坐标的尺度:void gluOrtho2D(left, right, top, bottom);四个参数分别代表(左下角x坐标,右上角x坐标,左下角y坐标,右上角y坐标)。
例如,对于一个640*480的窗口,可以指定如下的坐标尺度:gluOrtho2D(-320, 320, -240, 240);或者gluOrtho2D(0, 640, 0, 480);等等。
具体的使用为:int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(640, 480);glutCreateWindow("图片显示");gluOrtho2D(0, 640, 0, 480);glutDisplayFunc(&myDisplay);glutMainLoop();return 0;}二、OpenGL颜色的选择void glColor3f(GLfloat red, GLfloat green, GLfloat blue);以1.0表示最大的使用。
void glColor3b(GLbyte red, GLbyte green, GLbyte blue);采用b做后缀的函数,以127表示最大的使用。
void glColor3ub(GLuByte red, GLuByte green, GLuByte blue);采用ub做后缀的函数,以255表示最大的使用。
void glColor3s(GLshort red, GLshort green, GLshort blue);采用s做后缀的函数,以32767表示最大的使用。
void glColor3us(GLuShort red, GLuShort green, GLuShort blue); 采用us做后缀的函数,以65535表示最大的使用。
基于OpenGL的三维图形绘制实验

基于OpenGL的三维图形绘制实验基于OpenGL的三维图形绘制实验⽬录实验题⽬:交互图形程序设计基础实验 (3)1.实验⽬的 (3)2.实验内容 (3)2.1 实验内容 (3)2.2 实验任务 (3)3.实验过程 (4)3.1 预处理 (4)3.3 主要函数说明 (5)3.4 过程描述 (6)3.5 运⾏截图 (7)4.实验结果 (7)5.实验体会 (7)实验题⽬:交互图形程序设计基础实验1.实验⽬的1)理解并掌握三维基本图形数据结构表⽰⽅法。
2)掌握编写OpenGL图形程序的基本⽅法.3)掌握OpenGL基本图形表⽰及绘制。
2.实验内容2.1 实验内容基于OpenGL的三维图形绘制实验⽬的是掌握图形信息的表⽰、数据的组织,在此基础上基于OpenGL绘制出三维图形。
实验内容包括OpenGL编程环境搭建、OpenGL程序结构、基本数据类型、核⼼函数等的使⽤;基本图形的绘制(点、线段、折线、闭合折线、多边形、三⾓形、三⾓扇、三⾓条带、四边形、四边形条带等)及图形属性控制(线宽、颜⾊、线型、填充样式等);对指定的若⼲三维模型进⾏建模、绘制,在⼀个程序框架下实现,提交1次程序,1份实验报告。
2.2 实验任务1、使⽤Visual C++建⽴⼀个单⽂档(SDI)程序,完成OpenGL绘制框架程序的设计。
在此基础上参照提供的资料,定义绘制函数,基于⾃定义的若⼲点坐标与颜⾊,分别绘制绘制点、线段、不闭合折线、闭合折线、多边形、三⾓形、四边形、三⾓扇、三⾓条带、四边形条带。
2、使⽤1中建⽴的程序框架,完成如下任务:(1)绘制正棱柱(底⾯多变形的边数及⾼度可以通过对话框输⼊)(2)正棱锥(底⾯多变形的边数及⾼度可以通过对话框输⼊)(3)正棱台(底⾯多变形的边数、台⾼、锥⾼可以通过对话框输⼊)注意模型坐标系的选择和顶点坐标的计算,每个图形的绘制单独写成函数。
加⼊菜单绘制三、四、五、六边的情况,其他边数情况从弹出对话框中输⼊参数,然后绘制。
基于OpenGL的三维动画效果设计与实现

基于OpenGL的三维动画效果设计与实现OpenGL是一种跨平台的图形库,广泛应用于计算机图形学、游戏开发和虚拟现实等领域。
在OpenGL的基础上,可以实现各种精美的三维动画效果,如逼真的光影效果、自然的物理模拟和华丽的特效等。
本文将介绍如何基于OpenGL实现三维动画效果。
一、OpenGL简介OpenGL(Open Graphics Library)是一种跨平台的图形库,可以用于开发高性能的3D图形应用程序。
它提供了一套标准的API,程序员可以使用OpenGL库里的函数来绘制各种图形,包括点、线、三角形等。
OpenGL的主要优点是跨平台,程序可以在不同的操作系统和硬件上运行,并且不需要对程序做太多的修改。
二、OpenGL开发环境在开始OpenGL开发之前,需要配置正确的开发环境。
OpenGL的开发环境包括编程语言、OpenGL库、窗口系统和OpenGL的开发工具等。
编程语言:OpenGL支持多种编程语言,如C/C++、Java、Python等。
其中,C/C++是最常用的开发语言,因为它可以直接调用OpenGL的函数库。
OpenGL库:OpenGL库是开发OpenGL程序时必须的工具,它包含了OpenGL 的所有函数和常量。
窗口系统:OpenGL需要一个可视化的窗口系统,用来显示图形界面。
常用的窗口系统有Windows、Linux和MacOS等。
开发工具:开发OpenGL程序需要使用各种IDE和编辑器,如Visual Studio、CodeBlocks和Eclipse等。
三、实现三维动画效果的基础知识1.三维坐标系OpenGL使用右手坐标系表示三维坐标系,其中x轴向右,y轴向上,z轴向外。
2.矩阵变换OpenGL可以通过矩阵变换来实现图形的移动、旋转、缩放等操作。
常用的变换矩阵包括平移矩阵、旋转矩阵和缩放矩阵。
3.光照模型光照模型是OpenGL中重要的概念之一,它用来计算光源对物体的影响。
其中,主要包括光源的位置、光线的颜色和强度等因素。
OpenGL图像保存为bmp文件

OpenGL图像保存为bmp文件如果我没理解错的话,您需要的应该就是个“截屏”功能吧?如下这段代码是从OpenGL Super Bible中摘抄出来的,我自己加了个writeBMP函数,可以将front color buffer(也就是当前显示的画面)转存为一张bmp格式图片,默认保存在当前目录下。
bool screenshot(const char* filename){GLenum lastBuffer;GLbyte* pBits = 0; // 图像数据unsigned long lImageSize;GLint iViewport[4]; // 视图大小glGetIntegerv(GL_VIEWPORT, iViewport);lImageSize = iViewport[2] * iViewport[3] * 3;pBits = (GLbyte*)new unsigned char[lImageSize];if (!pBits)return false;// 从color buffer中读取数据glPixelStorei(GL_PACK_ALIGNMENT, 1);glPixelStorei(GL_PACK_ROW_LENGTH, 0);glPixelStorei(GL_PACK_SKIP_ROWS, 0);glPixelStorei(GL_PACK_SKIP_PIXELS, 0);//glGetIntegerv(GL_READ_BUFFER, (GLint*)&lastBuffer);glReadBuffer(GL_FRONT);glReadPixels(0, 0, iViewport[2], iViewport[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, pBits);glReadBuffer(lastBuffer);if (writeBMP(filename, (unsigned char*)pBits, iViewport[2], iViewport[3]))return true;return false;}bool writeBMP(const char filename[], unsigned char* data, unsigned int w, unsigned int h){std::ofstream out_file;/** 检查data */if(!data){std::cerr << "data corrupted! " << std::endl;out_file.close();return false;}/** 创建位图文件信息和位图文件头结构 */BITMAPFILEHEADER header;BITMAPINFOHEADER bitmapInfoHeader;//unsigned char textureColors = 0;/**< 用于将图像颜色从BGR 变换到RGB *//** 打开文件,并检查错误 */out_file.open(filename, std::ios::out | std::ios::binary);if (!out_file){std::cerr << "Unable to open file " << filename << std::endl;return false;}/** 填充BITMAPFILEHEADER */header.bfType = BITMAP_ID;header.bfSize = w*h*3 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);header.bfReserved1 = 0;header.bfReserved2 = 0;header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);/** 写入位图文件头信息 */out_file.write((char*)&header, sizeof(BITMAPFILEHEADER));/** 填充BITMAPINFOHEADER */bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);bitmapInfoHeader.biWidth = w;bitmapInfoHeader.biHeight = h;bitmapInfoHeader.biPlanes = 1;bitmapInfoHeader.biBitCount = 24;bitmapInfoHeader.biCompression = BI_RGB; // BI_RLE4 BI_RLE8bitmapInfoHeader.biSizeImage = w * h * 3; // 当压缩类型为BI_RGB是也可以设置为0bitmapInfoHeader.biXPelsPerMeter = 0;bitmapInfoHeader.biYPelsPerMeter = 0;bitmapInfoHeader.biClrUsed = 0;bitmapInfoHeader.biClrImportant = 0;/** 写入位图文件信息 */out_file.write((char*)&bitmapInfoHeader,sizeof(BITMAPINFOHEADER));/** 将指针移到数据开始位置 */out_file.seekp(header.bfOffBits, std::ios::beg);/** 写入图像数据 */out_file.write((char*)data, bitmapInfoHeader.biSizeImage);out_file.close();return true;}我测试过,工作正常。
BMP图像格式详解

BMP格式图像文件详析首先请注意所有的数值在存储上都是按“高位放高位、低位放低位的原则”,如12345678h放在存储器中就是7856 3412)。
下图是导出来的开机动画的第一张图加上文件头后的16进制数据,以此为例进行分析。
T408中的图像有点怪,图像是在电脑上看是垂直翻转的。
在分析中为了简化叙述,以一个字(两个字节为单位,如424D就是一个字)为序号单位进行,“h”表示是16进制数。
424D 4690 0000 0000 0000 4600 0000 2800 0000 8000 0000 9000 0000 0100*1000 0300 0000 0090 0000 A00F 0000 A00F 0000 0000 0000 0000 0000*00F8 0000 E007 0000 1F00 0000 0000 0000*02F1 84F1 04F1 84F1 84F1 06F2 84F1 06F2 04F2 86F2 06F2 86F2 86F2......BMP文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列,在上图中已用*分隔。
一、图像文件头1)1:图像文件头。
424Dh=’BM’,表示是Windows支持的BMP 格式。
2)2-3:整个文件大小。
4690 0000,为00009046h=36934。
3)4-5:保留,必须设置为0。
4)6-7:从文件开始到位图数据之间的偏移量。
4600 0000,为00000046h=70,上面的文件头就是35字=70字节。
5)8-9:位图图信息头长度。
6)10-11:位图宽度,以像素为单位。
8000 0000,为00000080h=128。
7)12-13:位图高度,以像素为单位。
9000 0000,为00000090h=144。
8)14:位图的位面数,该值总是1。
0100,为0001h=1。
二、位图信息头9)15:每个像素的位数。
使用opengl程序绘制实线虚线和点划线

使用opengl程序绘制实线虚线和点划线OpenGL是一种用于绘制2D和3D图形的跨平台编程接口。
它提供了一套功能强大的函数和工具,可以在各种显示设备上渲染图形。
在OpenGL中,可以使用不同的绘制模式来绘制实线、虚线和点划线。
本文将介绍如何使用OpenGL程序实现这些效果。
在开始之前,我们首先需要安装OpenGL库和开发环境。
OpenGL可以在不同的平台上使用,例如Windows、Linux和macOS。
对于Windows用户,可以使用MinGW或者MSYS2等工具链来配置开发环境。
对于Linux和macOS用户,可以使用GCC和Xcode来配置开发环境。
安装完成后,我们可以开始编写OpenGL程序。
在OpenGL中,绘图是通过一系列函数和状态来实现的。
以下是一个基本的OpenGL程序的框架:```cpp#include <GL/glut.h>void displa//清空屏幕glClear(GL_COLOR_BUFFER_BIT);//设置绘图颜色glColor3f(1.0f, 1.0f, 1.0f);//绘制实线glBegin(GL_LINES);glVertex2f(-0.5f, 0.0f);glVertex2f(0.5f, 0.0f);glEnd(;//绘制虚线//...//绘制点划线//...//刷新缓冲区glutSwapBuffers(;int main(int argc, char** argv)// 初始化窗口和OpenGL环境glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE , GLUT_RGB); glutInitWindowSize(800, 600); glutCreateWindow("OpenGL Program");//注册绘图函数glutDisplayFunc(display);//进入主循环glutMainLoop(;return 0;```在以上程序中,`glClear(GL_COLOR_BUFFER_BIT)`用于清空屏幕,`glColor3f(1.0f, 1.0f, 1.0f)`用于设置绘图颜色。
C语言实现OpenGL渲染

C语言实现OpenGL渲染OpenGL是一种强大的图形渲染API(应用程序接口),它可用于创建高性能的2D和3D图形应用程序。
在本文中,我们将探讨如何使用C语言实现OpenGL渲染。
1. 初始化OpenGL环境在开始之前,我们需要初始化OpenGL环境。
这可以通过以下步骤完成:1.1. 创建窗口使用C语言中的窗口创建库(如GLUT或GLFW)创建一个可见的窗口。
这个窗口将充当我们OpenGL渲染的目标。
1.2. 设置视口使用glViewport函数将窗口的尺寸设置为需要进行渲染的大小。
视口定义了OpenGL将渲染的区域。
1.3. 创建正交投影或透视投影矩阵使用glOrtho或gluPerspective函数创建透视或正交投影矩阵。
投影矩阵将定义OpenGL渲染的视图。
2. 渲染基本图形一旦我们初始化了OpenGL环境,我们可以开始渲染基本图形。
以下是一些常见的基本图形渲染函数:2.1. 绘制点使用glBegin和glEnd函数,以及glVertex函数,可以绘制一个或多个点。
2.2. 绘制线段使用glBegin和glEnd函数,以及glVertex函数,可以绘制一条或多条线段。
2.3. 绘制三角形使用glBegin和glEnd函数,以及glVertex函数,可以绘制一个或多个三角形。
2.4. 绘制多边形使用glBegin和glEnd函数,以及glVertex函数,可以绘制一个或多个多边形。
3. 设置光照效果为了给渲染的图形添加逼真感,可以设置光照效果。
以下是一些常见的光照函数:3.1. 设置光源使用glLight函数,可以设置光源的位置、光照颜色等参数。
3.2. 设置材质属性使用glMaterial函数,可以设置渲染对象的表面材质属性,如漫反射、镜面反射等。
3.3. 使用光照模型使用glShadeModel函数,可以选择光照模型,如平滑光照模型或平面光照模型。
4. 纹理映射纹理映射能够使渲染的图形更逼真。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
二维坐标OpenGL一、定义二维坐标的尺度:void gluOrtho2D(left, right, top, bottom);四个参数分别代表(左下角x坐标,右上角x坐标,左下角y坐标,右上角y坐标)。
例如,对于一个640*480的窗口,可以指定如下的坐标尺度:gluOrtho2D(-320, 320, -240, 240);或者gluOrtho2D(0, 640, 0, 480);等等。
具体的使用为:int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(640, 480);glutCreateWindow("图片显示");gluOrtho2D(0, 640, 0, 480);glutDisplayFunc(&myDisplay);glutMainLoop();return 0;}二、OpenGL颜色的选择void glColor3f(GLfloat red, GLfloat green, GLfloat blue);以1.0表示最大的使用。
void glColor3b(GLbyte red, GLbyte green, GLbyte blue);采用b做后缀的函数,以127表示最大的使用。
void glColor3ub(GLuByte red, GLuByte green, GLuByte blue);采用ub做后缀的函数,以255表示最大的使用。
void glColor3s(GLshort red, GLshort green, GLshort blue);采用s做后缀的函数,以32767表示最大的使用。
void glColor3us(GLuShort red, GLuShort green, GLuShort blue); 采用us做后缀的函数,以65535表示最大的使用。
例如:表示不使用绿、蓝色,而将红色使用最多可以调用如下的函数之一glColor3f(1.0f, 0.0f, 0.0f);glColor3ub(255, 0, 0);等等。
实验五 BMP文件BMP 文件是一种像素文件,它保存了一幅图像中所有的像素。
这种文件格式可以保存单色位图、16色或256色索引模式像素图、24位真彩色图像,每种模式种单一像素的大小分别为1/8字节,1/2字节,1字节和3字节。
目前最常见的是256色BMP和24位色BMP。
这种文件格式还定义了像素保存的几种方法,包括不压缩、RLE压缩等。
常见的BMP文件大多是不压缩的。
BMP文件具有如下格式:1:BMP由四部分组成:位图文件头(14字节)、位图信息头(40字节)、颜色表(可选)、位图数据。
2:位图文件头(14字节)格式:struct tagBmpFileHeader_T{unsigned short bfType; // 位图文件的类型,必须为BMP(0-1字节)unsigned int bfSize; // 位图文件的大小,以字节为单位(2-5字节)unsigned short bfReserved1; // 位图文件保留字,必须为0(6-7字节)unsigned short bfReserved2; // 位图文件保留字,必须为0(8-9字节)unsigned int bfOffBits; // 位图数据的起始位置(10-13字节),以相对于位图// 文件头的偏移量表示,以字节为单位};3:位图信息头(40字节)struct tagBmpInfoHeader_T{unsigned int biSize; // 本结构所占用字节数(14-17字节)unsigned int biWidth; // 位图的宽度,以像素为单位(18-21字节)unsigned int biHeight; // 位图的高度,以像素为单位(22-25字节)unsigned short biPlanes; // 目标设备的级别,必须为1(26-27字节)unsigned short biBitCount;// 每个像素所需的位数(28-29字节),必须是1(双色)、(28-29字节)、4(16色)、8(256色)或24(真彩色)之一unsigned int biCompression; // 位图压缩类型,必须是 0(不压缩),(30-33字节)// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一unsigned int biSizeImage; // 位图的大小,以字节为单位(34-37字节)unsigned int biXPelsPerMeter; // 位图水平分辨率,每米像素数(38-41字节)unsigned int biYPelsPerMeter; // 位图垂直分辨率,每米像素数(42-45字节)unsigned int biClrUsed;// 位图实际使用的颜色表中的颜色数(46-49字节)unsigned int biClrImportant;// 位图显示过程中重要的颜色数(50-53字节) };4:颜色表这里为了简单起见,我们仅讨论24位色、不使用压缩的BMP。
因此,位图文件中不包含有颜色表,跳过不处理。
5:位图数据位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上【即第一个像素为左下角的像素,最后一个为右上角的像素】。
每个像素存储的颜色顺序为Blue,Green,Red(即BGR,刚好与我们熟悉的RGB相反)。
struct tagRgbQuad_T {unsigned char rgbBlue;// 蓝色的亮度(值范围为-255)unsigned char rgbGreen; // 绿色的亮度(值范围为-255)unsigned char rgbRed; // 红色的亮度(值范围为-255)};这里为了简单起见,我们仅讨论24位色。
位图的一个像素值占3个字节(每三个字节表示一个像素的颜色)。
于是,一行像素所占的有效..字节数为:int effectiveLen = 一行的像素数量*3;但是,Windows规定一个扫描行.....所占的字节数必须是4的倍数(即以long为单位),不足的以0填充。
需要注意的地方是:像素的数据量并不一定完全等于图像的高度乘以宽度乘以每一像素的字节数,而是可能略大于这个值。
原因是BMP文件采用了一种“对齐”的机制,每一行像素数据的长度若不是4的倍数,则填充一些数据使它是4的倍数。
这样一来,一个17*15的24位BMP大小就应该是834字节(每行17 个像素,有51字节,补充为52字节,乘以15得到像素数据总长度780,再加上文件开始的54字节,得到834字节)。
因此,文件中存储一行像素所占的实际..字节数为:int rowLen = (effectiveLen +3)&~3; //即不小于effectiveLen且能被4整除的最小整数。
例如,若effectiveLen=51,则rowLen=52。
我们可以读取一个具体的BMP文件内容来进一步了解其格式:void main(){FILE *fp;fp = fopen("test.bmp", "rb"); //一定记得以二进制文件形式打开unsigned char b1;for(unsigned int i=0; i<60; i++) //只显示前面60个字节的内容{printf("%d: ", i);fread(&b1, 1, 1, fp);printf("0x%x\n", b1);}fclose(fp);}因此,在程序中,我们可以按照BMP文件头部的格式来进行文件的读取。
程序部分代码如下:tagBmpFileHeader_T bmpFileHdr; //定义为全局变量tagBmpInfoHeader_T bmpInfoHdr;tagRgbQuad_T *p;tagRgbQuad_T *pBmpData;void main(){FILE *fp;fp = fopen("test.bmp", "rb"); //一定记得以二进制文件形式打开fread(&bmpFileHdr, 1, sizeof(tagBmpFileHeader_T), fp);fread(&bmpInfoHdr, 1, sizeof(tagBmpInfoHeader_T), fp);//分配pBmpData空间,用于保存位图所有像素的RGB数据//分配的大小 = 行宽*列高*每像素所占字节数pBmpData = (tagRgbQuad_T *)malloc(bmpInfoHdr.biWidth *bmpInfoHdr.biHeight * sizeof(tagRgbQuad_T));//从文件中读取位图像素的颜色信息//记录顺序是在扫描行内是从左到右,扫描行之间是从下到上//【即第一个像素为左下角的像素,最后一个为右上角的像素】。
//每个像素存储的颜色顺序为Blue,Green,Red//读取完一行的像素信息后,注意使用 fseek(fp, rowLen - effectiveLen, SEEK_CUR)函数跳过BMP文件每行像素因4字节“对齐”而可能填充进来的数据int effectiveLen = bmpInfoHdr.biWidth * 3;int rowLen = (effectiveLen +3)&~3; //即不小于effectiveLen且能被4整除的最小整数。
p = pBmpData;for(unsigned int iRow=0; iRow<bmpInfoHdr.biHeight; iRow++){for(unsigned int iCol=0; iCol<bmpInfoHdr.biWidth; iCol++){fread(p, sizeof(tagRgbQuad_T), 1, fp);p++;}fseek(fp, rowLen - effectiveLen, 1);}fclose(fp);//此处自行添加OpenGL的代码,显示保存在pBmpData中的像素glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(bmpInfoHdr.biWidth, bmpInfoHdr.biHeight);glutCreateWindow("图片显示");gluOrtho2D(0, bmpInfoHdr.biWidth, 0, bmpInfoHdr.biHeight);//set coordinate system glutDisplayFunc(&myDisplay);glutMainLoop();return 0;}/************************************************************* 把下面的这个函数放在main()函数的上面!!!!!! **************************************************************/ void myDisplay(void){glClear(GL_COLOR_BUFFER_BIT);glPointSize(1.0);glBegin(GL_POINTS);p = pBmpData;for(unsigned int i=0; i<bmpInfoHdr.biHeight; i++){for(unsigned int j=0; j<bmpInfoHdr.biWidth; j++){glColor3ub(p->rgbRed, p->rgbGreen, p->rgbBlue);glVertex2i(j, i);p++;}}glEnd();glFlush();}其实,位图像素也可以用二维数组来进行保存tagRgbQuad_T **pBmpData2D; //定义一个指针的指针,相当于二维数组pBmpData2D = malloc(bmpInfoHdr.biHeight*sizeof(tagRgbQuad_T *));pBmpData2D = (tagRgbQuad_T **)malloc( bmpInfoHdr.biHeight *sizeof(tagRgbQuad_T *)); //分配行数for(unsigned int i=0; i<bmpInfoHdr.biHeight; i++){pBmpData2D[i] = (tagRgbQuad_T *) malloc( bmpInfoHdr.biWidth * sizeof(tagRgbQuad_T)); //分配每一行的元素}for(unsigned int iRow=0; iRow<bmpInfoHdr.biHeight; iRow++){for(unsigned int iCol=0; iCol<bmpInfoHdr.biWidth; iCol++){fread(&(pBmpData2D[iRow][iCol]), sizeof(tagRgbQuad_T), 1, fp);}fseek(fp, rowLen - tempLen, 1);}//void myDisplay(void) 函数自己完成。