WINCE 下 Opengles 纹理的创建 (Opengl ES笔记)

          Wince下 Opengl ES 纹理的创建 

    This article describes how to create textures in Opengl ES application development. I list three methods and give an simple introduction only according to my experience .Only the key codes are given in this article and I shall not have any liability for its content.

1、BMP图片文件中创建纹理,这是实现2维纹理最简单的方法,但是Bmp的存储要占大量的空间。这里要注意图片的格式是24-Bitmap.如果是16-Bitmap还要作转化。关键是要得到一张图片的每一个像素点的各个通道的值。

bool COpenGLES::LoadBMPTexture(char* filename,GLuint *texture)

{

BITMAPINFOHEADER* bmpInfo=new (BITMAPINFOHEADER);

FILE *file;

BITMAPFILEHEADER bmpFile;

unsigned char *bmpImage = NULL;

unsigned char tmpRGB ;

file = fopen(filename,"rb");

if (!file)

    return false;

fread(&bmpFile,sizeof(BITMAPFILEHEADER),1,file);

if (bmpFile.bfType != 0x4D42)

{

fclose(file);

return false;

}

fread(bmpInfo,sizeof(BITMAPINFOHEADER),1,file);

fseek(file,bmpFile.bfOffBits,SEEK_SET);

bmpImage = new unsigned char[bmpInfo->biSizeImage];

if (!bmpImage)

{

MessageBox(NULL, L"Out of Memory", L"Error", MB_OK)

delete[] bmpImage;

fclose(file);

return false;

}

fread(bmpImage,1,bmpInfo->biSizeImage,file);

if (!bmpImage)

{

MessageBox(NULL, L"Error reading bitmap", L"Error", MB_OK);

fclose(file);

return false;

}

for (unsigned int i = 0; i < bmpInfo->biSizeImage; i+=3)

{

tmpRGB = bmpImage[i];

bmpImage[i] = bmpImage[i+2];

bmpImage[i+2] = tmpRGB;

}

fclose(file);

glGenTextures(1, texture);

glBindTexture(GL_TEXTURE_2D, *tex ture);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bmpInfo->biWidth, bmpInfo->biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bmpImage);  

delete [] bmpImage;

delete bmpInfo;

return true;

}

2. 使用MS提供的处理图片对象的Com接口IImage,可以方便地进行对图片的解码和访问图片的属性和数据。只要在BSP包里添加了相应图片格式的解码组件,就可以使用这个Com接口来实现把诸如PNG/GIF/JPG等格式的图片创建成2维纹理。

bool COpenGLES::LoadBMPTexture(FILE* pFile,GLuint *id)

{

//获取图像大小信息

ImageInfo ImgInfo;

pImage->GetImageInfo(&ImgInfo);

int sizeX = ImgInfo.Width;

int sizeY = ImgInfo.Height;

if (FAILED(hr = pImgFactory->CreateBitmapFromImage(

pImage,sizeX,sizeY,PixelFormat24bppRGB,

InterpolationHintDefault,&pBmpImg)))

{

return false;

}

CRect rect(0,0,sizeX,sizeY);

BitmapData *BmpData = new BitmapData;

if (FAILED(hr = pBmpImg->LockBits(rect,

ImageLockModeRead|ImageLockModeRead,

PixelFormat24bppRGB,BmpData)))

{

return false;

}

int line = BmpData->Stride;

LPBYTE lpData, lpLine, lpCurPixel;

lpData = lpLine = (LPBYTE)BmpData->Scan0;   //获取BMP位图实际值的地址指针

//若为Bottom-Up(从下到上)的位图,则指向buffer的结尾

//若为Top-Down(从上到下)的位图,则指向buffer的开头

// int nBytesPP = nBPP >> 3;     //左移三位即除以8,获取图像每像素字节数

GLubyte* pTexture = new GLubyte[sizeX * sizeY * 3];

if (line>0)

{

int pos = sizeX * sizeY * 3-1;

for(int i = 0; i

{

lpLine = lpData + i * line;     //获取图像每一行地址指针

for(int j = sizeX-1; j>-1; j--)   //

{

lpCurPixel = lpLine + j * 3;          //获取每行每像素地址指针

pTexture[pos--] = *lpCurPixel ;     //R

pTexture[pos--] = *(lpCurPixel + 1);     //G

pTexture[pos--] = *(lpCurPixel + 2);           //B

}

}

}

else

{

int pos = 0 ;

for(int i = sizeY-1; i>-1; i--)     //

{

lpLine = lpData + i * line;     //获取图像每一行地址指针

for(int j = 0; j

{

lpCurPixel = lpLine + j * 3;          //获取每行每像素地址指针

pTexture[pos++] = *(lpCurPixel + 2);          //R

pTexture[pos++] = *(lpCurPixel + 1);          //G

pTexture[pos++] = *lpCurPixel;                //B

}

}

}

glGenTextures(1, id);     //绑定纹理

glBindTexture(GL_TEXTURE_2D, *id);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, sizeX, sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, pTexture); 

delete []pTexture;

if (FAILED(hr = pBmpImg->UnlockBits(BmpData)))

{

return false;

}

delete BmpData;

pBmpImg = NULL;

// pImage->Release(); 

// pImgFactory->Release(); 

return true;

}

3、使用第三方图片操作类库CXimage,CxImage类可以快捷地存取、显示、转换各种图像,是免费的开源代码,很容易获得利用这个类库也能轻易地创建纹理。

bool COpenGLES::LoadTexture(byte* pbuf,DWORD size,int format,GLuint *id)

{  

DWORD imgformat = 0;

switch (format)

{

case 1:

imgformat = CXIMAGE_FORMAT_PNG;

break;

case 2:

imgformat = CXIMAGE_FORMAT_JPG;

break;

case 3:

imgformat = CXIMAGE_FORMAT_BMP;

default:

break;

}

CxImage img(pbuf,size,imgformat);

if(!img.IsValid())

return false;

int nBPP = img.GetBpp();

if(!((nBPP == 24)||(nBPP == 32))) //只支持2432

{

img.Clear();

img.Destroy();

img.SelectionClear();

return false;

}

int nWidth = img.GetWidth();

int nHeight = img.GetHeight();

int nTexWidth = nWidth;

int nTexHeight = nHeight;

if ( 0 != nWidth%2)

{

nTexWidth = nWidth + 1;

}

if (0 != nHeight%2)

{

nTexHeight = nHeight +1;

}

GLubyte* pTexture = new GLubyte[nTexWidth * nTexHeight * 3];

int nPitch = img.GetEffWidth();

LPBYTE lpData, lpLine, lpCurPixel;

lpData = lpLine = (LPBYTE)img.GetBits();

int nBytesPP = nBPP >> 3;//左移三位即除以8,获取图像每像素字节数

for(int i = 0; i < nHeight; i++)

{

lpLine = lpData + i * nPitch;

for(int j = 0; j < nWidth; j++)

{

lpCurPixel = lpLine + j * nBytesPP;

pTexture[(i * nTexWidth + j)*3] = *(lpCurPixel + 2);     //R

pTexture[(i * nTexWidth + j)*3 + 1] = *(lpCurPixel + 1); //G

pTexture[(i * nTexWidth + j)*3 + 2] = *lpCurPixel;       //B

    //pTexture[(i * nTexWidth + j)*4 + 3] = 255; //A

}

for (int j = nWidth;j< nTexWidth;j++)

{

pTexture[(i * nTexWidth + j)*3] = 0;     //R

pTexture[(i * nTexWidth + j)*3 + 1] = 0; //G

pTexture[(i * nTexWidth + j)*3 + 2] = 0; //B

   //pTexture[(i * nTexWidth + j)*4 + 3] = 0; //A

}

}

glGenTextures(1, id);     //绑定纹理

glBindTexture(GL_TEXTURE_2D, *id);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glPixelStorei (GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nTexWidth, nTexHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pTexture); 

delete []pTexture;

free(pTexture);

img.Clear();

img.Destroy();

img.SelectionClear();

// fseek(pFile,0L,0);

return true;

你可能感兴趣的:(Opengles)