这学期初接触OpenGL,本来就是要跟图形学同时学的东西,不过本人太懒,并没有把OpenGL跟进上。虽然对于其中的算法算是有所了解,不过细节的东西估计要歇菜了,外加考试那天出了点事故,默哀一下我的图形学(不要挂,不要挂),题外话不多扯了,下面正题。

刚刚开始在配置OpenGL环境的时候,并没有把gluax.h和gluax.dll加入到环境中(本人用的是vs2010),后面到了要加载位图,用到函数auxDIBImageLoad(),这个函数是gluax.dll提供的,因此就想到自己动手写一个加载位图的函数。

首先我们来了解一下位图的格式,位图.BMP格式大体分为两种类型:

一个是位图里面的像素数据直接由RGB三原色组成,每个颜色分量为8bit,即一个像素24bit,这也就是所谓的24位真彩色图片

另一个是位图里面的像素数据由调色板索引组成,每个像素索引为8bit,即所谓的256色图片

24位bmp像素数据
    RGB        RGB       RGB
    RGB     RGB      RGB
    RGB     RGB      RGB
8位bmp调色板
    RGB(还有一个字节的保留区,共四个字节)       RGB       RGB   
    RGB    RGB     RGB
    RGB    RGB     RGB
8位bmp像素数据
8bit索引   8bit索引     8bit索引    
8bit索引  8bit索引  8bit索引
 8bit索引  8bit索引  8bit索引

可见,由于24位的BMP的像素数据为RGB三原色,是可以由像素数据加载到帧缓存中显示的,而8位的BMP则不行,它比需先由这8bit的索引值去调色板中才能得到RGB的真实值

接下来我们来了解一下位图的头,无论是8位的还是24位的BMP,都有固定格式的位图文件头和位图信息头:

位图文件头包含了图像类型、图像大小、图像数据存放地址和两个保留未使用的字段,共14个字节。

第0,1个字节为BM(BMP文件的固定开头)

第2,3,4,5个字节为该文件大小

第6,7,8,9个字节为保留字节,都是0

第10,11,12,13个字节为位图像素数据的开始地址

位图信息头包含了位图信息头的大小、图像的宽高、图像的色深、压缩说明图像数据的大小和其他一些参数,共40个字节。

第14 ,15,16,17个字节为0x28,即40,是位图信息头的大小

第18,19,20,21个字节是位图的宽度,以像素为单位

第22,23,24,25个字节是位图的高度

第26,27个字节为1(目标设备级别?)

第28,29个字节是位图的bit,即位图是多少位的

第30,31,32,33个字节用来表示位图是否经过压缩

第34,35,36,37个字节是位图像素数据的大小

第38,39,40,41水平像素

第42,43,44,45垂直像素

第46,47,48,49位图使用的调色板中的颜色数

第50,51,52,53位图使用的重要颜色数

(注:位图信息头的某些数据的数值并不会对位图本身造成影响,因此数据的填与不填并没硬性规定,这个估计要看生成位图的软件)

然后我们知道要使位图转换成纹理,需要的是包含位图RGB三分量的内存块,和位图的宽、高,然后就可以编写函数了

(要注意的是,无论是调色板还是位图的像素数据,位图存放RGB的顺序都是BGR)

以下为加载BMP

 1 unsigned char* LoadBMP(FILE * img)
 2 {
 3     unsigned long bBMPFormat = 0;
 4     unsigned long bData = 0;
 5     DWORD size = 0;
 6     unsigned char *data;
 7
 8     fseek(img,10,SEEK_SET);
 9     fread(&bData,4,1,img);
10     fseek(img,28,SEEK_SET);
11     fread(&bBMPFormat,2,1,img);
12     fseek(img,0,SEEK_END);
13     size = ftell(img) - bData;
14
15     if(bBMPFormat==24)
16     {
17         data = (unsigned char*)malloc(size);
18         fseek(img,bData,SEEK_SET);
19         fread(data,size,1,img);
20     }
21     else if(bBMPFormat==8)
22     {
23
24         data = (unsigned char*)malloc(size*3);
25         unsigned char* pdata = data;
26
27         unsigned char *ColorBoard = (unsigned char*)malloc(1024);
28         fseek(img,54,SEEK_SET);
29         fread(ColorBoard,1024,1,img);
30
31         unsigned char *ColorIndex = (unsigned char*)malloc(size);
32         fseek(img,1078,SEEK_SET);
33         fread(ColorIndex,size,1,img);
34
35         for(int i=0;i<size;i++)
36         {
37
38             *(pdata) = *(ColorBoard+(*ColorIndex)*4);
39             *(pdata+1) = *(ColorBoard+1+(*ColorIndex)*4);
40             *(pdata+2) = *(ColorBoard+2+(*ColorIndex)*4);
41             ColorIndex++;
42             pdata=pdata+3;
43         }
44     }
45
46     return data;
47 }

以下为加载纹理

 1 unsigned int LoadTex(char* Image)
 2 {
 3     unsigned int Texture=0;
 4
 5                 FILE* img = NULL;
 6                img = fopen(Image,"rb");
 7
 8     unsigned long bWidth = 0;
 9     unsigned long bHeight = 0;
10     unsigned long bdata = 0;
11
12     fseek(img,18L,SEEK_SET);
13     fread(&bWidth,4,1,img);
14     fread(&bHeight,4,1,img);
15
16     unsigned char* data=LoadBMP(img);
17
18     fclose(img);
19
20     glGenTextures(1, &Texture);
21     glBindTexture(GL_TEXTURE_2D, Texture);
22     gluBuild2DMipmaps(GL_TEXTURE_2D, 3, bWidth, bHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, data);
23
24
25     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
26     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
27     //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
28     //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
29     //glTexImage2D(GL_TEXTURE_2D,0,3,bWidth,bHeight,0,GL_RGB,GL_UNSIGNED_BYTE,data);
30
31     if (data)
32         free(data);
33
34     return Texture;
35 }

转载于:https://www.cnblogs.com/TaigaCon/archive/2012/06/24/2559640.html

[OpenGL]自己写的加载位图并转换成纹理的两个函数相关推荐

  1. Windows API(非MFC)编程加载位图

    很久都没写博客了,前段时间ACM那些题都是有空的时候水着玩的,虽然大二的课只有6门,但是作业很多,也一直很忙,刚刚都才完成一个电路设计的实验报告.准备TOEFL,GRE,还要跟着导师做计算机视觉的一些 ...

  2. win32汇编--加载位图(bmp)资源

    本例通过静态(static)控件的SS_BITMAP属性来加载位图: 核心代码如下:(完整工程下载) 转载于:https://www.cnblogs.com/wbbice/archive/2012/0 ...

  3. VC++图片框控件静态和动态加载位图

    win10,vc6:新建一个对话框工程:右击资源文件夹,插入...: 类型,Bitmap:引入:选择一个bmp图片: 插入后如下:自动给了一个id: 图片框属性:类型,下拉选中 位图: 图像属性,选中 ...

  4. 基于对话框的MFC程序加载位图为背景图案

    from: http://rwsk.snnu.edu.cn/?uid-156-action-viewspace-itemid-240 先载入一张图片 ,ID 为 IDB_BITMAP2 TestDlg ...

  5. MFC加载位图和图标

    MFC加载位图和图标 | 火苗999℃的博客 从文件加载位图 #pragma once// ZBitmap从文件加载位图资源 class ZBitmap { private:HBITMAP m_hBi ...

  6. Metal之加载TGA与PNG/JPEG纹理图片

    TGA纹理 ① 效果展示 ② 环境准备 视图控制器类:在 viewDidLoad 函数中创建 MTKView 对象.自定义 render 对象,并设置 view 的代理为 render,其流程请参考: ...

  7. python使用openCV图像加载(转化为灰度图像)、使用filter2D函数对图像进行锐化(Sharpen Images)

    python使用openCV图像加载(转化为灰度图像).使用filter2D函数对图像进行锐化(Sharpen Images) 目录

  8. php 文字图片怎么保存为图片,php技术实现加载字体并保存成图片

    下面通过一段代码给大家详解介绍下php技术实现加载字体并保存成图片. // Set the content-type header("Content-type: image/png" ...

  9. R语言导入数据文件(数据导入、加载、读取)、haven包的read_spss函数导入SPSS中的sav格式文件

    R语言导入数据文件(数据导入.加载.读取).haven包的read_spss函数导入SPSS中的sav格式文件 目录

最新文章

  1. [***]HZOJ 优美序列
  2. 【干货集锦】如何轻松玩转文档管理工具?我们为你精心准备了一份学习大礼包...
  3. Jsoup代码解读之四-parser(上)
  4. js形参(parameter)和实参(argument)
  5. list取数据_Day.5利用Pandas做数据处理(二)
  6. android中画弧函数canvas.drawArc()之理解
  7. 微信小程序API之showModal(Loding...)
  8. 揭秘你不知道的京东管理体系!
  9. pytorch GPU和CPU模型相互加载
  10. 计算机对口升学的专科学校,2014对口升学计算机各地专科大学
  11. Storm集成HBase、JDBC、Kafka、Hive
  12. 有各组方差怎么算组间平方和_方差分析中组内离差平方和,组间离差平方和的意义...
  13. Kaggle提示:TTA(测试时间增加),小,技巧,TTAtesttimeaugmentation,增强
  14. Java使用JAVE获取MP4播放时长
  15. 美国iPS细胞治疗癌症最新进展
  16. 利用Java计算多少次纸才能对折出珠峰高度
  17. 计算电磁学——变分问题
  18. B2型水面线计算(含python代码)
  19. 关于http请求返回code:415的原因
  20. [rust学习笔记]数据类型

热门文章

  1. 寻找电路布线最短路径算法BFS
  2. Linux之特殊权限
  3. 机器学习——基于OpenCV和Python的智能图像处理(一)
  4. [UFLDL] Exercise 1C:Softmax Regression
  5. python基础系列教程——python面向对象编程全解
  6. dell 服务器r410装系统,dell r410安装windows2003系统
  7. Crackeme021
  8. 1.4 高并发之线程和进程
  9. day013内置函数一
  10. 概率论中的一些常见的分布与公式