TextureDibImage.cpp
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:9k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // TextureDibImage.cpp : implementation file
  3. //
  4. // glOOP (OpenGL Object Oriented Programming library)
  5. // Copyright (c) Craig Fahrnbach 1997, 1998
  6. //
  7. // OpenGL is a registered trademark of Silicon Graphics
  8. //
  9. //
  10. // This program is provided for educational and personal use only and
  11. // is provided without guarantee or warrantee expressed or implied.
  12. //
  13. // Commercial use is strickly prohibited without written permission
  14. // from ImageWare Development.
  15. //
  16. // This program is -not- in the public domain.
  17. //
  18. // This source code has been adapted from the Microsoft Knowledge Base
  19. // for Visual C++ ( GLTEXTUR.EXE )
  20. //
  21. /////////////////////////////////////////////////////////////////////////////
  22. #include "stdafx.h"
  23. #include "glOOP.h"
  24. #include <math.h>
  25. #include "DIBUtil.h"
  26. #ifdef _DEBUG
  27. #define new DEBUG_NEW
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CTextureDibImage
  33. IMPLEMENT_DYNAMIC(CTextureDibImage, CTexture)
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CTextureDibImage construction
  36. CTextureDibImage::CTextureDibImage()
  37. {
  38. // TODO:  ADD ANY CONSTRUCTION CODE HERE
  39. }
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CTextureDibImage Destructor
  42. CTextureDibImage::~CTextureDibImage()
  43. {
  44. // TODO:  ADD ANY DE-CONSTRUCTION CODE HERE
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CTextureDibImage virtual overrides
  48. BOOL CTextureDibImage::OpenTexture(char* pFileName, HPALETTE hPalette)
  49. {
  50. // Get a pointer to our TextureMap
  51. m_pBits = (GLubyte*)OpenDIBFile(pFileName, hPalette);
  52. if(m_pBits)
  53. {
  54. // Now we have a square 32bpp DIB, use it as the texture.
  55. m_bApplyImage = TRUE;
  56. // Save the file name of the texture map
  57. m_szFileName.Format("%s", pFileName);
  58. return TRUE;
  59. }
  60. return FALSE;
  61. }
  62. void CTextureDibImage::Serialize(CArchive& ar, int iVersion)
  63. {
  64. CString szBuffer;
  65. if (ar.IsStoring())
  66. {
  67. // Save the Object Class header...
  68. szBuffer.Format("%sCTextureDibImage {n", szIndent);
  69. ar.WriteString(szBuffer);
  70. // Save the this objects' specific data...
  71. // szBuffer.Format("%stSolid         < %d >n", szIndent, m_bSolid);
  72. // ar.WriteString(szBuffer);
  73. // Save the base class CTexture data...
  74. CTexture::Serialize(ar, iVersion);
  75. szBuffer.Format("%s}n", szIndent); // end of texture map def
  76. ar.WriteString(szBuffer);
  77. }
  78. else
  79. {
  80. // Read the derived class data..
  81. ar.ReadString(szBuffer); // Read the class header
  82. // ar.ReadString(szBuffer);
  83. // szBuffer.TrimLeft(); // Remove leading white spaces
  84. // sscanf(szBuffer, "Solid         < %d >n", &m_bSolid);
  85. // Read the base class CTexture data...
  86. CTexture::Serialize(ar, iVersion);
  87. }
  88. }
  89. /////////////////////////////////////////////////////////////////////////////
  90. // CTextureDibImage function implementation
  91. /////////////////////////////////////////////////////////////////////////////
  92. //
  93. // FUNCTION   : SaveDIBFile(LPSTR pszFileName, BITMAPINFO *pInfo, void *pBits
  94. //
  95. // PURPOSE    : Save the DIB in a Windows Bitmap (*.bmp) compatable file.
  96. //
  97. // INPUTS     : pszFileName - a 32-bit char pointer to the file to open
  98. //  pInfo       - The BITMAPINFO structure of the DIB to save
  99. //  pBits       - A GLubyte pointer to the DIB bits
  100. //
  101. // RETURNS    : 0      - if successful.
  102. //  NonZero - otherwise
  103. //
  104. int CTextureDibImage::SaveDIBFile(LPSTR pszFileName, BITMAPINFO *pInfo, void *pBits)
  105. {
  106. FILE *fp; // Open file pointer
  107. long size, // Size of file
  108. infosize, // Size of bitmap info
  109. bitsize; // Size of bitmap pixels
  110. BITMAPFILEHEADER header; // File header
  111. // Try opening the file; use "wb" mode to write this
  112. // *binary* file.
  113. if ((fp = fopen(pszFileName, "wb")) == NULL)
  114. return (-1);
  115. if (pInfo->bmiHeader.biSizeImage == 0) // Figure out the bitmap size
  116. bitsize = (pInfo->bmiHeader.biWidth *
  117.    pInfo->bmiHeader.biBitCount + 7) / 8 *
  118.    abs(pInfo->bmiHeader.biHeight);
  119. else
  120. bitsize = pInfo->bmiHeader.biSizeImage;
  121. infosize = sizeof(BITMAPINFOHEADER);
  122. switch (pInfo->bmiHeader.biCompression)
  123. {
  124. case BI_BITFIELDS :
  125. infosize += 12; // Add 3 RGB doubleword masks
  126. if (pInfo->bmiHeader.biClrUsed == 0)
  127. break;
  128. case BI_RGB :
  129. if (pInfo->bmiHeader.biBitCount > 8 &&
  130. pInfo->bmiHeader.biClrUsed == 0)
  131. break;
  132. case BI_RLE8 :
  133. case BI_RLE4 :
  134. if (pInfo->bmiHeader.biClrUsed == 0)
  135. infosize += (1 << pInfo->bmiHeader.biBitCount) * 4;
  136. else
  137. infosize += pInfo->bmiHeader.biClrUsed * 4;
  138. break;
  139. }
  140. size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;
  141. // Write the file header, bitmap information, and
  142. // bitmap pixel data...
  143. header.bfType      = 'MB'; // Non-portable... sigh
  144. header.bfSize      = size;
  145. header.bfReserved1 = 0;
  146. header.bfReserved2 = 0;
  147. header.bfOffBits   = sizeof(BITMAPFILEHEADER) + infosize;
  148. if (fwrite(&header, 1, sizeof(BITMAPFILEHEADER), fp) < sizeof(BITMAPFILEHEADER))
  149. {
  150. // Couldn't write the file header - return...
  151. fclose(fp);
  152. return (-1);
  153. }
  154. if (fwrite(pInfo, 1, infosize, fp) < (UINT)infosize)
  155. {
  156. // Couldn't write the bitmap header - return...
  157. fclose(fp);
  158. return (-1);
  159. }
  160. if (fwrite(pBits, 1, bitsize, fp) < (UINT)bitsize)
  161. {
  162. // Couldn't write the bitmap - return...
  163. fclose(fp);
  164. return (-1);
  165. }
  166. // OK, everything went fine - return...
  167. fclose(fp);
  168. return (0);
  169. }
  170. /////////////////////////////////////////////////////////////////////////////
  171. //
  172. // FUNCTION   : OpenDIBFile(LPSTR pszFileName, HPALETTE hPalette)
  173. //
  174. // PURPOSE    : Open a Windows DIB (*.bmp or *.dib) file and convert the file
  175. //  to an OpenGL compatable format.  
  176. //
  177. // INPUTS     : filename - a char pointer to the file to open
  178. //  hPalette - a HANDLE to the palette for mapping our DIB colors
  179. //
  180. // RETURNS    : NULL if unsuccessful, otherwise
  181. //  Pointer (GLubyte*) to our bits
  182. //
  183. void* CTextureDibImage::OpenDIBFile(LPSTR pszFileName, HPALETTE hPalette)
  184. {
  185. HANDLE hDibOriginal; // Handle to original-format memory DIB
  186. void* pScaledBits = NULL; // Pointer to our scaled DIB bits
  187. if (!pszFileName)
  188. return NULL; // No file to open!
  189. // Load the DIB
  190. hDibOriginal = OpenDIB(pszFileName);
  191. if(hDibOriginal)
  192. {
  193. // Convert DIB to a square 32bpp DIB.
  194. pScaledBits = ScaleDIB(hPalette, hDibOriginal); //(HANDLE)m_pBitmapInfo);
  195. if(!pScaledBits)
  196. {
  197. if(the3dEngine.m_bDisplayErrorMessages)
  198. AfxMessageBox("CTextureDibImage::FileOpen - ScaleDIB failed", MB_OK);
  199. return NULL;
  200. }
  201. return pScaledBits;
  202. }
  203. return NULL;
  204. }
  205. /////////////////////////////////////////////////////////////////////////////
  206. //
  207. // FUNCTION   : ReadDIBitmap(BITMAPINFO **info)
  208. //
  209. // PURPOSE    : Read the current OpenGL viewport into a 24-bit RGB bitmap
  210. //
  211. // RETURNS    : A pointer to the bitmap if successful, otherwise
  212. //  NULL
  213. //
  214. // AUTHOR    : This code sample originated from the OpenGL Super Bible
  215. //  chapter 11, page 358
  216. //
  217. void* CTextureDibImage::ReadDIBitmap(BITMAPINFO **info)
  218. {
  219. long i, j, // Looping var
  220. bitsize, // Total size of bitmap
  221. width; // Aligned width of a scanline
  222. GLint viewport[4];// Current viewport
  223. void *bits; // RGB bits
  224. GLubyte *rgb, // RGB looping var
  225. temp; // Temporary var for swapping
  226. // Grab the current viewport...
  227. glGetIntegerv(GL_VIEWPORT, viewport);
  228. // Allocate memory for the header and bitmap...
  229. if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER))) == NULL)
  230. {
  231. // Couldn't allocate memory for bitmap info - return NULL...
  232.     return (NULL);
  233. }
  234. width   = viewport[2] * 3; /* Real width of scanline */
  235. width   = (width + 3) & ~3; /* Aligned to 4 bytes */
  236. bitsize = width * viewport[3]; /* Size of bitmap, aligned */
  237. if ((bits = calloc(bitsize, 1)) == NULL)
  238. {
  239. // Couldn't allocate memory for bitmap pixels - return NULL...
  240. free(*info);
  241. return (NULL);
  242. }
  243. // Read pixels from the framebuffer...
  244. glFinish(); // Finish all OpenGL commands 
  245. glPixelStorei(GL_PACK_ALIGNMENT, 4); // Force 4-byte alignment
  246. glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  247. glPixelStorei(GL_PACK_SKIP_ROWS, 0);
  248. glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
  249. glReadPixels(0, 0, viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE,
  250.  bits);
  251. // Swap red and blue for the bitmap...
  252. for (i = 0; i < viewport[3]; i ++)
  253. {
  254. for (j = 0, rgb = ((GLubyte *)bits) + i * width;
  255.  j < viewport[2]; j ++, rgb += 3)
  256. {
  257. temp   = rgb[0];
  258. rgb[0] = rgb[2];
  259. rgb[2] = temp;
  260. }
  261. }
  262. // Finally, initialize the bitmap header information...
  263. (*info)->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
  264. (*info)->bmiHeader.biWidth         = viewport[2];
  265. (*info)->bmiHeader.biHeight        = viewport[3];
  266. (*info)->bmiHeader.biPlanes        = 1;
  267. (*info)->bmiHeader.biBitCount      = 24;
  268. (*info)->bmiHeader.biCompression   = BI_RGB;
  269. (*info)->bmiHeader.biSizeImage     = bitsize;
  270. (*info)->bmiHeader.biXPelsPerMeter = 2952; // 75 DPI
  271. (*info)->bmiHeader.biYPelsPerMeter = 2952; // 75 DPI
  272. (*info)->bmiHeader.biClrUsed       = 0;
  273. (*info)->bmiHeader.biClrImportant  = 0;
  274. return (bits);
  275. }