texture0.cpp
Upload User: xuczgm
Upload Date: 2022-04-25
Package Size: 8601k
Code Size: 13k
Category:

Special Effects

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #include "texture0.h"
  3. // LoadBitmapFile
  4. // desc: Returns a pointer to the bitmap image of the bitmap specified
  5. //       by filename. Also returns the bitmap header information.
  6. //  No support for 8-bit bitmaps.
  7. unsigned char *CTexture::LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
  8. {
  9. FILE *filePtr; // the file pointer
  10. BITMAPFILEHEADER bitmapFileHeader; // bitmap file header
  11. unsigned char *bitmapImage; // bitmap image data
  12. int imageIdx = 0; // image index counter
  13. unsigned char tempRGB; // swap variable
  14. // open filename in "read binary" mode
  15. filePtr = fopen(filename, "rb");
  16. if (filePtr == NULL)
  17. return NULL;
  18. // read the bitmap file header
  19. fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
  20. // verify that this is a bitmap by checking for the universal bitmap id
  21. if (bitmapFileHeader.bfType != BITMAP_ID)
  22. {
  23. fclose(filePtr);
  24. return NULL;
  25. }
  26. // read the bitmap information header
  27. fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
  28. // move file pointer to beginning of bitmap data
  29. fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
  30. // allocate enough memory for the bitmap image data
  31. bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
  32. // verify memory allocation
  33. if (!bitmapImage)
  34. {
  35. free(bitmapImage);
  36. fclose(filePtr);
  37. return NULL;
  38. }
  39. // read in the bitmap image data
  40. fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);
  41. // make sure bitmap image data was read
  42. if (bitmapImage == NULL)
  43. {
  44. fclose(filePtr);
  45. return NULL;
  46. }
  47. // swap the R and B values to get RGB since the bitmap color format is in BGR
  48. for (imageIdx = 0; imageIdx < (int)bitmapInfoHeader->biSizeImage; imageIdx+=3)
  49. {
  50. tempRGB = bitmapImage[imageIdx];
  51. bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
  52. bitmapImage[imageIdx + 2] = tempRGB;
  53. }
  54. // close the file and return the bitmap image data
  55. fclose(filePtr);
  56. return bitmapImage;
  57. }
  58. /*****************************************************************************
  59.  LoadBitmapFileWithAlpha
  60.  Loads a bitmap file normally, and then adds an alpha component to use for
  61.  blending
  62. *****************************************************************************/
  63. unsigned char *CTexture::LoadBitmapFileWithAlpha(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
  64. {
  65.   unsigned char *bitmapImage = LoadBitmapFile(filename, bitmapInfoHeader);
  66.   unsigned char *bitmapWithAlpha = (unsigned char *)malloc(bitmapInfoHeader->biSizeImage * 4 / 3);
  67.   // loop through the bitmap data
  68.   for (unsigned int src = 0, dst = 0; src < bitmapInfoHeader->biSizeImage; src +=3, dst +=4)
  69.   {
  70.     // if the pixel is black, set the alpha to 0. Otherwise, set it to 255.
  71.     if (bitmapImage[src] == 0 && bitmapImage[src+1] == 0 && bitmapImage[src+2] == 0)
  72.       bitmapWithAlpha[dst+3] = 0;
  73.     else
  74.       bitmapWithAlpha[dst+3] = 0xFF;
  75.     // copy pixel data over
  76.     bitmapWithAlpha[dst] = bitmapImage[src];
  77.     bitmapWithAlpha[dst+1] = bitmapImage[src+1];
  78.     bitmapWithAlpha[dst+2] = bitmapImage[src+2];
  79.   }
  80.   free(bitmapImage);
  81.   return bitmapWithAlpha;
  82. } // end LoadBitmapFileWithAlpha()
  83. // LoadPCXFile()
  84. // desc: loads a PCX file into memory
  85. unsigned char *CTexture::LoadPCXFile(char *filename, PCXHEADER *pcxHeader)
  86. {
  87.      int idx = 0;                  // counter index
  88.      int c;                             // used to retrieve a char from the file
  89.      int i;                             // counter index
  90.      int numRepeat;      
  91.      FILE *filePtr;                // file handle
  92.      int width;                         // pcx width
  93.      int height;                        // pcx height
  94.      unsigned char *pixelData;     // pcx image data
  95.      unsigned char *paletteData;   // pcx palette data
  96.      // open PCX file
  97.      filePtr = fopen(filename, "rb");
  98.      if (filePtr == NULL)
  99.           return NULL;
  100.      // retrieve first character; should be equal to 10
  101.      c = getc(filePtr);
  102.      if (c != 10)
  103.      {
  104.           fclose(filePtr);
  105.           return NULL;
  106.      }
  107.      // retrieve next character; should be equal to 5
  108.      c = getc(filePtr);
  109.      if (c != 5)
  110.      {
  111.           fclose(filePtr);
  112.           return NULL;
  113.      }
  114.      // reposition file pointer to beginning of file
  115.      rewind(filePtr);
  116.      // read 4 characters of data to skip
  117.      fgetc(filePtr);
  118.      fgetc(filePtr);
  119.      fgetc(filePtr);
  120.      fgetc(filePtr);
  121.      // retrieve leftmost x value of PCX
  122.      pcxHeader->xMin = fgetc(filePtr);       // loword
  123.      pcxHeader->xMin |= fgetc(filePtr) << 8; // hiword
  124.      // retrieve bottom-most y value of PCX
  125.      pcxHeader->yMin = fgetc(filePtr);       // loword
  126.      pcxHeader->yMin |= fgetc(filePtr) << 8; // hiword
  127.      // retrieve rightmost x value of PCX
  128.      pcxHeader->xMax = fgetc(filePtr);       // loword
  129.      pcxHeader->xMax |= fgetc(filePtr) << 8; // hiword
  130.      // retrieve topmost y value of PCX
  131.      pcxHeader->yMax = fgetc(filePtr);       // loword
  132.      pcxHeader->yMax |= fgetc(filePtr) << 8; // hiword
  133.      // calculate the width and height of the PCX
  134.      width = pcxHeader->xMax - pcxHeader->xMin + 1;
  135.      height = pcxHeader->yMax - pcxHeader->yMin + 1;
  136.      // allocate memory for PCX image data
  137.      pixelData = (unsigned char*)malloc(width*height);
  138.      // set file pointer to 128th byte of file, where the PCX image data starts
  139.      fseek(filePtr, 128, SEEK_SET);
  140.      
  141.      // decode the pixel data and store
  142.      while (idx < (width*height))
  143.      {
  144.           c = getc(filePtr);
  145.           if (c > 0xbf)
  146.           {
  147.                numRepeat = 0x3f & c;
  148.                c = getc(filePtr);
  149.                for (i = 0; i < numRepeat; i++)
  150.                {
  151.                     pixelData[idx++] = c;
  152.                }
  153.           }
  154.           else
  155.                pixelData[idx++] = c;
  156.           fflush(stdout);
  157.      }
  158.      // allocate memory for the PCX image palette
  159.      paletteData = (unsigned char*)malloc(768);
  160.      // palette is the last 769 bytes of the PCX file
  161.      fseek(filePtr, -769, SEEK_END);
  162.      // verify palette; first character should be 12
  163.      c = getc(filePtr);
  164.      if (c != 12)
  165.      {
  166.           fclose(filePtr);
  167.           return NULL;
  168.      }
  169.      // read and store all of palette
  170.      for (i = 0; i < 768; i++)
  171.      {
  172.           c = getc(filePtr);
  173.           paletteData[i] = c;
  174.      }
  175.      // close file and store palette in header
  176.      fclose(filePtr);
  177.      pcxHeader->palette = paletteData;
  178.      // return the pixel image data
  179.      return pixelData;
  180. }
  181. // LoadPCXTexture()
  182. // desc: loads a PCX image file as a texture
  183. void CTexture::LoadPCXTexture(char *filename)
  184. {
  185.      PCXHEADER texInfo;            // header of texture
  186. //     texture_t *thisTexture;       // the texture
  187.      unsigned char *unscaledData;// used to calculate pcx
  188.      int i;                             // index counter
  189.      int j;                             // index counter
  190.      int w;                         // width of texture
  191.      int h;                        // height of texture
  192.      // load the PCX file into the texture struct
  193.      data = LoadPCXFile(filename, &texInfo);
  194.      if (data == NULL)
  195.      {
  196.           free(data);
  197.      //     return NULL;
  198.      }
  199.      // store the texture information
  200.      palette = texInfo.palette;
  201.      width = texInfo.xMax - texInfo.xMin + 1;
  202.      height = texInfo.yMax - texInfo.yMin + 1;
  203.      textureType = PCX;
  204. w = width;
  205.      h = height;
  206.      // allocate memory for the unscaled data
  207.      unscaledData = (unsigned char*)malloc(w*h*4);
  208.      // store the unscaled data via the palette
  209.      for (j = 0; j < h; j++) 
  210.      {
  211.           for (i = 0; i < w; i++) 
  212.           {
  213.                unscaledData[4*(j*w+i)+0] = (unsigned char)palette[3*data[j*w+i]+0];
  214.                unscaledData[4*(j*w+i)+1] = (unsigned char)palette[3*data[j*w+i]+1];
  215.                unscaledData[4*(j*w+i)+2] = (unsigned char)palette[3*data[j*w+i]+2];
  216.                unscaledData[4*(j*w+i)+3] = (unsigned char)255;
  217.           }
  218.      }
  219.      // find width and height's nearest greater power of 2
  220.      // find width's
  221.      i = 0;
  222.      while (w)
  223.      {
  224.           w /= 2;
  225.           i++;
  226.      }
  227.      scaledHeight = (long)pow(2, i-1);
  228.      // find height's
  229.      i = 0;
  230.      while (h)
  231.      {
  232.           h /= 2;
  233.           i++;
  234.      }
  235.      scaledWidth = (long)pow(2, i-1);
  236.      // clear the texture data
  237.      if (data != NULL)
  238.      {
  239.           free(data);
  240.           data = NULL;
  241.      }
  242.      // reallocate memory for the texture data
  243.      data = (unsigned char*)malloc(scaledWidth*scaledHeight*4);
  244.      
  245.      // use the GL utility library to scale the texture to the unscaled dimensions
  246.      gluScaleImage(GL_RGBA, this->width, this->height, GL_UNSIGNED_BYTE, unscaledData, scaledWidth, scaledHeight, GL_UNSIGNED_BYTE, data);
  247. free(unscaledData);
  248. //     return thisTexture;
  249. }
  250. // LoadBMPTexture()
  251. // desc: loads a texture of the BMP format
  252. void CTexture::LoadBMPTexture(char *filename)
  253. {
  254. BITMAPINFOHEADER texInfo; // BMP header
  255. // store BMP data in texture
  256. data = LoadBitmapFileWithAlpha(filename, &texInfo);
  257. if (data == NULL)
  258. {
  259. free(data);
  260. }
  261. // store texture information
  262. width = texInfo.biWidth;
  263. height = texInfo.biHeight;
  264. palette = NULL;
  265. scaledHeight = 0;
  266. scaledWidth = 0;
  267. textureType = BMP;
  268. }
  269. // LoadTexture()
  270. // desc: loads a texture given the filename
  271. void CTexture::LoadTexture(char *filename)
  272. {
  273. char *extStr;
  274. // get extension from filename
  275. extStr = strchr(filename, '.');
  276. extStr++;
  277. // set the texture type based on extension of filename
  278. if ((strcmpi(extStr, "BMP") == 0) || (strcmpi(extStr, "bmp") == 0))
  279. LoadBMPTexture(filename);
  280. else if ((strcmpi(extStr, "PCX") == 0) || (strcmpi(extStr, "pcx") == 0) )
  281. LoadPCXTexture(filename);
  282. else if ((strcmpi(extStr, "TGA") == 0) || (strcmpi(extStr, "tga") == 0) )
  283. LoadTGATexture(filename);
  284. }
  285. // LoadTGAFile()
  286. // desc: loads a TGA file defined by filename
  287. unsigned char *CTexture::LoadTGAFile(char *filename, TGAHEADER *tgaHeader)
  288. {
  289. FILE *filePtr;
  290. unsigned char ucharBad; // garbage data
  291. short int sintBad; // garbage data
  292. long imageSize; // size of TGA image
  293. int colorMode; // 4 for RGBA, 3 for RGB
  294. long imageIdx; // counter variable
  295. unsigned char colorSwap; // swap variable
  296. unsigned char *imageData; // the TGA data
  297. // open the TGA file
  298. filePtr = fopen(filename, "rb");
  299. if (!filePtr)
  300. return NULL;
  301. // read first two bytes of garbage
  302. fread(&ucharBad, sizeof(unsigned char), 1, filePtr);
  303. fread(&ucharBad, sizeof(unsigned char), 1, filePtr);
  304. // read in the image type
  305. fread(&tgaHeader->imageTypeCode, sizeof(unsigned char), 1, filePtr);
  306. // for our purposes, the image type should be either a 2 or a 3
  307. if ((tgaHeader->imageTypeCode != 2) && (tgaHeader->imageTypeCode != 3))
  308. {
  309. fclose(filePtr);
  310. return NULL;
  311. }
  312. // read 13 bytes of garbage data
  313. fread(&sintBad, sizeof(short int), 1, filePtr);
  314. fread(&sintBad, sizeof(short int), 1, filePtr);
  315. fread(&ucharBad, sizeof(unsigned char), 1, filePtr);
  316. fread(&sintBad, sizeof(short int), 1, filePtr);
  317. fread(&sintBad, sizeof(short int), 1, filePtr);
  318. // read image dimensions
  319. fread(&tgaHeader->imageWidth, sizeof(short int), 1, filePtr);
  320. fread(&tgaHeader->imageHeight, sizeof(short int), 1, filePtr);
  321. // read bit depth
  322. fread(&tgaHeader->bitCount, sizeof(unsigned char), 1, filePtr);
  323. // read garbage
  324. fread(&ucharBad, sizeof(unsigned char), 1, filePtr);
  325. // colormode -> 3 = BGR, 4 = BGRA
  326. colorMode = tgaHeader->bitCount / 8;
  327. imageSize = tgaHeader->imageWidth * tgaHeader->imageHeight * colorMode;
  328. // allocate memory for image data
  329. imageData = (unsigned char*)malloc(sizeof(unsigned char)*imageSize);
  330. // read image data
  331. fread(imageData, sizeof(unsigned char), imageSize, filePtr);
  332. // change BGR to RGB so OpenGL can use the data
  333. for (imageIdx = 0; imageIdx < imageSize; imageIdx += colorMode)
  334. {
  335. colorSwap = imageData[imageIdx];
  336. imageData[imageIdx] = imageData[imageIdx+2];
  337. imageData[imageIdx + 2] = colorSwap;
  338. }
  339. // close the file
  340. fclose(filePtr);
  341. return imageData;
  342. }
  343. // LoadTGATexture()
  344. // desc: loads a TGA as a texture
  345. void CTexture::LoadTGATexture(char *filename)
  346. {
  347. TGAHEADER tga; // BMP header
  348. // store BMP data in texture
  349. data = LoadTGAFile(filename, &tga);
  350. if (data == NULL)
  351. {
  352. free(data);
  353. }
  354. // store texture information
  355. width = tga.imageWidth;
  356. height = tga.imageHeight;
  357. palette = NULL;
  358. scaledHeight = 0;
  359. scaledWidth = 0;
  360. tgaImageCode = tga.imageTypeCode;
  361. bitDepth = tga.bitCount;
  362. textureType = TGA;
  363. }