[OpenGL]自己写的加载位图并转换成纹理的两个函数
这学期初接触OpenGL,本来就是要跟图形学同时学的东西,不过本人太懒,并没有把OpenGL跟进上。虽然对于其中的算法算是有所了解,不过细节的东西估计要歇菜了,外加考试那天出了点事故,默哀一下我的图形学(不要挂,不要挂),题外话不多扯了,下面正题。
刚刚开始在配置OpenGL环境的时候,并没有把gluax.h和gluax.dll加入到环境中(本人用的是vs2010),后面到了要加载位图,用到函数auxDIBImageLoad(),这个函数是gluax.dll提供的,因此就想到自己动手写一个加载位图的函数。
首先我们来了解一下位图的格式,位图.BMP格式大体分为两种类型:
一个是位图里面的像素数据直接由RGB三原色组成,每个颜色分量为8bit,即一个像素24bit,这也就是所谓的24位真彩色图片
另一个是位图里面的像素数据由调色板索引组成,每个像素索引为8bit,即所谓的256色图片
RGB | RGB | RGB |
RGB | RGB | RGB |
RGB | RGB | RGB |
RGB(还有一个字节的保留区,共四个字节) | RGB | RGB |
RGB | RGB | RGB |
RGB | RGB | RGB |
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]自己写的加载位图并转换成纹理的两个函数相关推荐
- Windows API(非MFC)编程加载位图
很久都没写博客了,前段时间ACM那些题都是有空的时候水着玩的,虽然大二的课只有6门,但是作业很多,也一直很忙,刚刚都才完成一个电路设计的实验报告.准备TOEFL,GRE,还要跟着导师做计算机视觉的一些 ...
- win32汇编--加载位图(bmp)资源
本例通过静态(static)控件的SS_BITMAP属性来加载位图: 核心代码如下:(完整工程下载) 转载于:https://www.cnblogs.com/wbbice/archive/2012/0 ...
- VC++图片框控件静态和动态加载位图
win10,vc6:新建一个对话框工程:右击资源文件夹,插入...: 类型,Bitmap:引入:选择一个bmp图片: 插入后如下:自动给了一个id: 图片框属性:类型,下拉选中 位图: 图像属性,选中 ...
- 基于对话框的MFC程序加载位图为背景图案
from: http://rwsk.snnu.edu.cn/?uid-156-action-viewspace-itemid-240 先载入一张图片 ,ID 为 IDB_BITMAP2 TestDlg ...
- MFC加载位图和图标
MFC加载位图和图标 | 火苗999℃的博客 从文件加载位图 #pragma once// ZBitmap从文件加载位图资源 class ZBitmap { private:HBITMAP m_hBi ...
- Metal之加载TGA与PNG/JPEG纹理图片
TGA纹理 ① 效果展示 ② 环境准备 视图控制器类:在 viewDidLoad 函数中创建 MTKView 对象.自定义 render 对象,并设置 view 的代理为 render,其流程请参考: ...
- python使用openCV图像加载(转化为灰度图像)、使用filter2D函数对图像进行锐化(Sharpen Images)
python使用openCV图像加载(转化为灰度图像).使用filter2D函数对图像进行锐化(Sharpen Images) 目录
- php 文字图片怎么保存为图片,php技术实现加载字体并保存成图片
下面通过一段代码给大家详解介绍下php技术实现加载字体并保存成图片. // Set the content-type header("Content-type: image/png" ...
- R语言导入数据文件(数据导入、加载、读取)、haven包的read_spss函数导入SPSS中的sav格式文件
R语言导入数据文件(数据导入.加载.读取).haven包的read_spss函数导入SPSS中的sav格式文件 目录
最新文章
- [***]HZOJ 优美序列
- 【干货集锦】如何轻松玩转文档管理工具?我们为你精心准备了一份学习大礼包...
- Jsoup代码解读之四-parser(上)
- js形参(parameter)和实参(argument)
- list取数据_Day.5利用Pandas做数据处理(二)
- android中画弧函数canvas.drawArc()之理解
- 微信小程序API之showModal(Loding...)
- 揭秘你不知道的京东管理体系!
- pytorch GPU和CPU模型相互加载
- 计算机对口升学的专科学校,2014对口升学计算机各地专科大学
- Storm集成HBase、JDBC、Kafka、Hive
- 有各组方差怎么算组间平方和_方差分析中组内离差平方和,组间离差平方和的意义...
- Kaggle提示:TTA(测试时间增加),小,技巧,TTAtesttimeaugmentation,增强
- Java使用JAVE获取MP4播放时长
- 美国iPS细胞治疗癌症最新进展
- 利用Java计算多少次纸才能对折出珠峰高度
- 计算电磁学——变分问题
- B2型水面线计算(含python代码)
- 关于http请求返回code:415的原因
- [rust学习笔记]数据类型