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

    技术2026-04-20  6

              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<sizeY; 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<sizeX; 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;

    最新回复(0)