分享
 
 
 

使用DevIL来加载OpenGL纹理

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

OpenGL本身并没有带图象文件的读取函数,D3DX则有,以前我用的IPicture的接口来加载图象,但是TGA ,MNG PNG 等图象它并不支持.需要其他的代码来加载TGA等,非常不方便,最倒霉的是,代码的问题很多,经常不能成功加载一些图象.早就想把那个该死的库移植到DevIL上了,但是人懒,一直等到今天,呵呵。终于做了个简单的包装了。

代码很乱,只加了读取图象到建立OpenGL纹理,应该还有更广泛的用途的.比如SaveImage等.

回头等有空的时候做一个更好用的。

这里的的代码只有一个文件,是一个dll,自己编译一下就可以了。DevIL当前为1.6.7请到http://www.sourceforge.net/Projects/openil/去下载,说明一下,DevIL原来叫OpenIL,是一个学习了OpenGL的库,因为某些原因,改名为devil了。

/***

Source code for gltexture.h

***/

#ifndef _GL_TEXTURE_H_

#define _GL_TEXTURE_H_

#include <windows.h>

#include <GL\gl.h>

typedef struct ImageSize

{

int width,height;

int bits;

}IMAGESIZE,*PIMAGESIZE;

typedef unsigned char* IMAGEDATA;

typedef struct

{

int width,height;

unsigned char* pdata;

int bits;

GLuint format;

int ImageID;

}DIBTEXDATA,*PDIBTEXDATA;

#ifdef _DEBUG

#pragma comment(lib,"gltextured.lib")

#else

#pragma comment(lib,"gltexture.lib")

#endif

typedef GLuint GLTEXTURE;

extern "C" int FlowToPower2(int w);

extern "C" IMAGEDATA LoadBlankImage(IMAGESIZE size);

extern "C" int SetImagePixel(unsigned char* image,int x,int y,IMAGESIZE size,unsigned char cl[4]);

extern "C" int GetImagePixel(unsigned char* image,int x,int y,IMAGESIZE size,unsigned char cl[4]);

extern "C" void SetKeyColorAlpha(unsigned char* image,IMAGESIZE size,unsigned char cl[4],int r);

extern "C" int IsPowerOfTwo(int n);

extern "C" int RoundFourByte(int n);

extern "C" DIBTEXDATA LoadTexData(char* filename);

extern "C" DIBTEXDATA CreateDibTexData(int w,int h);

extern "C" void FreeDibTexData(DIBTEXDATA dib);

extern "C" void SetTexAlpha(GLubyte color[],GLubyte alpha,DIBTEXDATA dib,int r);

extern "C" void SetTexPixel(int x,int y,GLubyte color[],DIBTEXDATA dib);

extern "C" void GetTexPixel(int x,int y,GLubyte color[],DIBTEXDATA dib);

extern "C" GLuint BuildTexture(char* filename);

extern "C" GLuint BuildTransparencyTexture(char* filename,GLubyte color[],GLubyte alpha,int r);

extern "C" GLuint BuildTextureFromImage(unsigned char* image,IMAGESIZE size);

extern "C" GLuint BuildTextureFromRGBImage(unsigned char* image,IMAGESIZE size);

#endif

/**

以下为.def文件,

**/

EXPORTS

LoadBlankImage

SetImagePixel

GetImagePixel

SetKeyColorAlpha

IsPowerOfTwo

RoundFourByte

LoadTexData

CreateDibTexData

FreeDibTexData

SetTexAlpha

SetTexPixel

GetTexPixel

BuildTexture

BuildTransparencyTexture

BuildTextureFromImage

BuildTextureFromRGBImage

+++++++++++++++++++++++++++++++++++++++++++++++++++++

下面为真正代码

+++++++++++++++++++++++++++++++++++++++++++++++++++++

/**

source code for

gltexture.cpp

**/

// GLTexture.cpp : Defines the entry point for the DLL application.

//

#include "stdafx.h"

#include <fstream>

#include <windows.h>

#include <GL\gl.h>

#include <GL\glu.h>

#include <math.h>

using namespace std;

#include <IL/il.h>

#include <IL/ilu.h>

#pragma comment(lib,"Devil.lib")

#pragma comment(lib,"ILu.lib")

/****

以下内容为需要写到头文件里

****/

typedef struct ImageSize

{

int width,height;

int bits;

}IMAGESIZE,*PIMAGESIZE;

typedef unsigned char* IMAGEDATA;

typedef struct

{

int width,height;

unsigned char* pdata;

int bits;

GLuint format;

int ImageID;

}DIBTEXDATA,*PDIBTEXDATA;

extern "C" IMAGEDATA LoadBlankImage(IMAGESIZE size);

extern "C" int SetImagePixel(unsigned char* image,int x,int y,IMAGESIZE size,unsigned char cl[4]);

extern "C" int GetImagePixel(unsigned char* image,int x,int y,IMAGESIZE size,unsigned char cl[4]);

extern "C" void SetKeyColorAlpha(unsigned char* image,IMAGESIZE size,unsigned char cl[4],int r);

extern "C" int IsPowerOfTwo(int n);

extern "C" int RoundFourByte(int n);

extern "C" DIBTEXDATA LoadTexData(char* filename);

extern "C" DIBTEXDATA CreateDibTexData(int w,int h);

extern "C" void FreeDibTexData(DIBTEXDATA dib);

extern "C" void SetTexAlpha(GLubyte color[],GLubyte alpha,DIBTEXDATA dib,int r);

extern "C" void SetTexPixel(int x,int y,GLubyte color[],DIBTEXDATA dib);

extern "C" void GetTexPixel(int x,int y,GLubyte color[],DIBTEXDATA dib);

extern "C" GLuint BuildTexture(char* filename);

extern "C" GLuint BuildTransparencyTexture(char* filename,GLubyte color[],GLubyte alpha,int r);

extern "C" GLuint BuildTextureFromImage(unsigned char* image,IMAGESIZE size);

extern "C" GLuint BuildTextureFromRGBImage(unsigned char* image,IMAGESIZE size);

/****

以上内容为需要写到头文件里

****/

#pragma comment(lib,"opengl32.lib")

#pragma comment(lib,"glu32.lib")

void FreeImageData(unsigned char* pData);

BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

static bool ilIsInit = false;

if(ul_reason_for_call == DLL_PROCESS_ATTACH)

{

if(ilIsInit == false)

{

// Needed to initialize DevIL.

ilInit();

ilIsInit = true;

}

}

if(ul_reason_for_call == DLL_PROCESS_DETACH)

{

if(ilIsInit == true)

{

// Needed to initialize DevIL.

ilShutDown();

ilIsInit = false;

}

}

return TRUE;

}

extern "C" int FlowToPower2(int w)

{

return 1 << (int)floor((log((double)w)/log(2.0f)) + 0.5f);

}

extern "C" DIBTEXDATA LoadTexData(char* filename)

{

int Width = 0;

int Height = 0;

int Bpp = 0;

int Format = 0;

int Depth = 0;

int NewW = 0;

int NewH = 0;

GLubyte* prgba = NULL;

ILuint ImageID;

ilGenImages(1,&ImageID);

ilBindImage(ImageID);

ILboolean IsLoaded = ilLoadImage(filename);

if(! IsLoaded)

{

goto exit_entry;

}

Width = ilGetInteger(IL_IMAGE_WIDTH);

Height = ilGetInteger(IL_IMAGE_HEIGHT);

Bpp = ilGetInteger(IL_IMAGE_BPP);

Format = ilGetInteger(IL_IMAGE_FORMAT);

Depth = ilGetInteger(IL_IMAGE_DEPTH);

NewW = FlowToPower2(Width);

NewH = FlowToPower2(Height);

if(NewW != Width ||

NewH != Height )

{

iluScale(NewW,NewH,Depth);

}

if(Format != IL_RGBA)

{

ilConvertImage(IL_RGBA,ilGetInteger(IL_IMAGE_TYPE));

}

prgba = ilGetData();

DIBTEXDATA dib;

exit_entry:

//纹理数据已经创建好了,现在可以保存大小后返回

dib.height = NewH;

dib.width = NewW;

dib.pdata = prgba;

dib.bits =32;

dib.format = GL_RGBA;

dib.ImageID = ImageID;

return dib;

}

extern "C" DIBTEXDATA CreateDibTexData(int w,int h)

{

DIBTEXDATA pt;

int size = w * h* 4 ;

pt.height = h;

pt.width = w;

IMAGESIZE isize;

isize.height = h;

isize.width = w;

isize.bits = 32;

pt.pdata = LoadBlankImage(isize);

pt.ImageID = -1;

return pt;

}

extern "C" void FreeDibTexData(DIBTEXDATA dib)

{

if( ilIsImage(dib.ImageID) )

{

ilDeleteImages(1,(const ILuint*)&dib.ImageID);

return ;

}

if (dib.pdata)

{

FreeImageData(dib.pdata);

return ;

}

}

extern "C" void SetTexAlpha(GLubyte color[],GLubyte alpha,DIBTEXDATA dib,int r)

{

int size=dib.height*dib.width*4;

for(int i=0;i<size;i+=4)

{

if(abs(color[0]-dib.pdata[i+2])<=r&&

abs(color[1]-dib.pdata[i+1])<=r&&

abs(color[2]-dib.pdata[i])<=r )

{

dib.pdata[i+3]=alpha;

}

}

}

extern "C" void SetTexPixel(int x,int y,GLubyte color[],DIBTEXDATA dib)

{

GLubyte* pstart = dib.pdata+(dib.height-1-y)*dib.width*4;

pstart += x*4;

pstart[0]=color[2];//r

pstart[1]=color[1];//g

pstart[2]=color[0];//b

pstart[3]=color[3];//a

}

extern "C" void GetTexPixel(int x,int y,GLubyte color[],DIBTEXDATA dib)

{

GLubyte* pstart = dib.pdata+(dib.height-1-y)*dib.width*4;

pstart += x*4;

color[0]=pstart[2];//r

color[1]=pstart[1];//g

color[2]=pstart[0];//b

color[3]=pstart[3];//a

}

extern "C" GLuint BuildTexture(char* filename)

{

GLubyte* prgba;

ILuint ImageID;

ilGenImages(1,&ImageID);

ilBindImage(ImageID);

ILboolean IsLoaded = ilLoadImage(filename);

if(! IsLoaded)

return 0;

int Width = ilGetInteger(IL_IMAGE_WIDTH);

int Height = ilGetInteger(IL_IMAGE_HEIGHT);

int Bpp = ilGetInteger(IL_IMAGE_BPP);

int Format = ilGetInteger(IL_IMAGE_FORMAT);

int Depth = ilGetInteger(IL_IMAGE_DEPTH);

int NewW = FlowToPower2(Width);

int NewH = FlowToPower2(Height);

if(NewW != Width ||

NewH != Height )

{

iluScale(NewW,NewH,Depth);

}

if(Format != IL_RGBA)

{

ilConvertImage(IL_RGBA,ilGetInteger(IL_IMAGE_TYPE));

}

prgba = ilGetData();

IMAGESIZE size;

size.bits = 32;

size.width = NewW;

size.height =NewH;

if(prgba == 0)

{

ilDeleteImages(1,&ImageID);

return 0;

}

GLuint t = BuildTextureFromImage(prgba,size);

ilDeleteImages(1,&ImageID);

return t;

}

extern "C" GLuint BuildTransparencyTexture(char* filename,GLubyte color[],GLubyte alpha,int r)

{

GLuint texture;

DIBTEXDATA dib=LoadTexData(filename);

if(dib.pdata == NULL)

return 0;

glGenTextures(1,&texture);

glBindTexture(GL_TEXTURE_2D,texture);

SetTexAlpha(color,alpha,dib,r);

{

glTexImage2D( GL_TEXTURE_2D,0,4,dib.width,dib.height,0,GL_RGBA,GL_UNSIGNED_BYTE,dib.pdata);

}

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);

glEnable(GL_TEXTURE_2D);

FreeDibTexData(dib);

return texture;

}

extern "C" GLuint BuildTextureFromImage(unsigned char* image,IMAGESIZE size)

{

GLuint texture;

glGenTextures(1,&texture);

glBindTexture(GL_TEXTURE_2D,texture);

if(size.bits == 32)

{

glTexImage2D( GL_TEXTURE_2D,0,4,size.width,size.height,0,GL_RGBA,GL_UNSIGNED_BYTE,image);

}

if(size.bits == 24)

{

glTexImage2D( GL_TEXTURE_2D,0,4,size.width,size.height,0,GL_RGB,GL_UNSIGNED_BYTE,image);

}

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);

glEnable(GL_TEXTURE_2D);

return texture;

}

extern "C" GLuint BuildTextureFromRGBImage(unsigned char* image,IMAGESIZE size)

{

GLuint texture;

glGenTextures(1,&texture);

glBindTexture(GL_TEXTURE_2D,texture);

if(size.bits == 32)

{

glTexImage2D( GL_TEXTURE_2D,0,4,size.width,size.height,0,GL_RGBA,GL_UNSIGNED_BYTE,image);

}

if(size.bits == 24)

{

glTexImage2D( GL_TEXTURE_2D,0,4,size.width,size.height,0,GL_RGB,GL_UNSIGNED_BYTE,image);

}

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);

glEnable(GL_TEXTURE_2D);

return texture;

}

/***************************************************************

检测一个数是不是 2 的 几 次方

输入: n 为待检测的数字

输出: 0 为 不是2的平方数。

1 为 是一个2的平方数

***************************************************************/

extern "C" int IsPowerOfTwo(int n)

{

return !( (( n - 1)& n ) != 0);

}

/**************************************************************

调整一个数到能被 4 整除

**************************************************************/

extern "C" int RoundFourByte(int n)

{

if ( ( n%4)==0 )

return n;

else

return (n+ 4-(n%4));

}

extern "C" unsigned char* LoadBlankImage(IMAGESIZE size)

{

if(size.bits != 24 && size.bits != 32)

return NULL;

int b_len = size.height * size.width * size.bits / 8;

unsigned char* pData = new unsigned char[b_len];

memset((void*)pData,0,b_len);

if(size.bits == 32)

{

for(int i = 0;i<b_len;i+=4)

pData[i+3] = 255;

}

return pData;

}

extern "C" int SetImagePixel(unsigned char* image,int x,int y,IMAGESIZE size,unsigned char cl[4])

{

if(image == NULL)

return 0;

int bpp = size.bits / 8;

unsigned char* pixel = & image[bpp * size.width * y + x * bpp];

if(bpp == 3)

{

pixel[0] = cl[0];

pixel[1] = cl[1];

pixel[2] = cl[2];

return 1;

}

if(bpp == 4)

{

pixel[0] = cl[0];

pixel[1] = cl[1];

pixel[2] = cl[2];

pixel[3] = cl[3];

return 1;

}

return 0;

}

extern "C" int GetImagePixel(unsigned char* image,int x,int y,IMAGESIZE size,unsigned char cl[4])

{

if(image == NULL)

return 0;

int bpp = size.bits / 8;

unsigned char* pixel = & image[bpp * size.width * y + x * bpp];

if(bpp == 3)

{

cl[0] = pixel[0];

cl[1] = pixel[1];

cl[2] = pixel[2];

return 1;

}

if(bpp == 4)

{

cl[0] = pixel[0];

cl[1] = pixel[1];

cl[2] = pixel[2];

cl[3] = pixel[3];

return 1;

}

return 0;

}

extern "C" void SetKeyColorAlpha(unsigned char* image,IMAGESIZE size,unsigned char cl[4],int r)

{

if(image == NULL)

return ;

for(int y =0 ; y<size.height;y++)

for(int x = 0; x < size.width ; x++)

{

unsigned char* pixel = & image[4 * size.width * y + x * 4];

if( abs(cl[0] - pixel[0]) <= r &&

abs(cl[1] - pixel[1]) <= r &&

abs(cl[2] - pixel[2]) <= r )

pixel[3] = cl[3];

}

}

void FreeImageData(unsigned char* pData)

{

if(pData)

delete []pData;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有