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

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Texture.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. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "glOOP.h"
  21. #include <math.h>
  22. #include "DIBUtil.h"
  23. #ifdef _DEBUG
  24. #define new DEBUG_NEW
  25. #undef THIS_FILE
  26. static char THIS_FILE[] = __FILE__;
  27. #endif
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CTexture
  30. IMPLEMENT_DYNAMIC(CTexture, CObject)
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CTexture construction
  33. BOOL CTexture::CreateTexture(char* pFileName,  HPALETTE hPalette, CTexture **pTexture)
  34. {
  35. int iLength; // Length of pFileName
  36. char szFileExt[4]; // File extension
  37. if (!pFileName)
  38. return FALSE; // No file to open!
  39. // Free all image format pointers before we open a new file.
  40. // This will free all image data..
  41. if(*pTexture)
  42. {
  43. delete *pTexture; // free our DIB image
  44. *pTexture = NULL;
  45. }
  46. // Determine the type of Texture map file to Open
  47. iLength = strlen(pFileName);
  48. // Copy the last 3 characters + the NULL terminating character..
  49. strncpy(&szFileExt[0], pFileName + (iLength-3), 4);
  50. // Is the file a Bitmap or DIB?
  51. if(strcmp(szFileExt, "bmp")==0 || strcmp(szFileExt, "dib")==0)
  52. {
  53. // Create a CTextureDibImage class
  54. *pTexture = new CTextureDibImage;
  55. ASSERT(*pTexture);
  56. }
  57. // Is the file an AVI file?
  58. if(strcmp(szFileExt, "avi")==0)
  59. {
  60. // Create a CTextureAviMovie class
  61. *pTexture = new CTextureAviMovie;
  62. ASSERT(*pTexture);
  63. }
  64. // TODO:  ADD OTHER FILE FORMAT SUPPORT CODE HERE..
  65. // Open the Texture map file
  66. if(!(*pTexture)->OpenTexture(pFileName, hPalette))
  67. {
  68. delete *pTexture; // File NOT Opened!
  69. *pTexture = NULL;
  70. return FALSE;
  71. }
  72. return TRUE;
  73. }
  74. CTexture::CTexture()
  75. {
  76. // Initilize variables
  77. m_pBits    = NULL; // Pointer to scaled 32bpp Texture DIB bits
  78. m_hDibScaled   = NULL; // Handle to scaled 32bpp Texture DIB
  79. m_szFileName   = _T("");
  80. m_iDisplayList = NULL;
  81. m_bCreateList  = TRUE; // Do not create display lists for texture
  82. m_bApplyImage  = TRUE;
  83. m_iEnvmode  = GL_MODULATE; // alt: GL_DECAL -or- GL_BLEND
  84. m_enumHint   = GL_NICEST; // alt: GL_FASTEST
  85. m_iMinfilter = GL_NEAREST;
  86. m_iMagfilter = GL_LINEAR;
  87. m_iWrap_S    = GL_REPEAT;
  88. m_iWrap_T    = GL_REPEAT;
  89. m_bS_Gen  = FALSE;
  90. m_iS_Mode = GL_OBJECT_LINEAR;
  91. m_dS_Coeffs[0] = 1.0;
  92. m_dS_Coeffs[1] = 0.0;
  93. m_dS_Coeffs[2] = 0.0;
  94. m_dS_Coeffs[3] = 0.0;
  95. m_bT_Gen  = FALSE;
  96. m_iT_Mode = GL_OBJECT_LINEAR;
  97. m_dT_Coeffs[0] = 0.0;
  98. m_dT_Coeffs[1] = 1.0;
  99. m_dT_Coeffs[2] = 0.0;
  100. m_dT_Coeffs[3] = 0.0;
  101. m_bTransparent = FALSE;
  102. m_bytTransparent_r = 0;
  103. m_bytTransparent_g = 0;
  104. m_bytTransparent_b = 0;
  105. m_fTransparentVariance = 0.1f;
  106. m_fOrigin[X] = 0.0f;
  107. m_fOrigin[Y] = 0.0f;
  108. m_fOrigin[Z] = 0.0f;
  109. }
  110. /////////////////////////////////////////////////////////////////////////////
  111. // CTexture Destructor
  112. CTexture::~CTexture()
  113. {
  114. // Free the display list
  115. glDeleteLists(m_iDisplayList, 1);
  116. // Free the DIB memory allocated by the operating system for the
  117. // device-independent bitmap bits.  (frees pBits). The operating
  118. // system closes the handle to that memory when you delete the
  119. // device-independent bitmap by calling the DeleteObject function.
  120. if(m_hDibScaled)
  121. {
  122. DeleteObject(m_hDibScaled);
  123. m_hDibScaled = NULL;
  124. }
  125. }
  126. /////////////////////////////////////////////////////////////////////////////
  127. // CTexture virtual methods or functions
  128. BOOL CTexture::OpenTexture(char* pFileName, HPALETTE hPalette)
  129. {
  130. // Virtual prototype function only!  Add specific
  131. // functionality to your derived Texture class!
  132. return FALSE;
  133. }
  134. void CTexture::Serialize(CArchive& ar, int iVersion)
  135. {
  136. CString szBuffer;
  137. CString szName;
  138. CString szTemp;
  139. szBuffer.GetBuffer(256);
  140. szName.GetBuffer(128);
  141. if (ar.IsStoring())
  142. {
  143. // Save the Base Class CTexture Data...
  144. // szBuffer.Format("%stColor         < %f %f %f %f > // RGBAn", szIndent, m_Color.m_fColor[0], m_Color.m_fColor[1], m_Color.m_fColor[2], m_Color.m_fColor[3]);
  145. // ar.WriteString(szBuffer);
  146. }
  147. else
  148. {
  149. // Read the Base Class CTexture data...
  150. // ar.ReadString(szBuffer);
  151. // szBuffer.TrimLeft();
  152. // sscanf(szBuffer, "Color         < %f %f %f %f >n", &m_Color.m_fColor[0], &m_Color.m_fColor[1], &m_Color.m_fColor[2], &m_Color.m_fColor[3]);
  153. // Must remove the derived class defined end marker!
  154. ar.ReadString(szBuffer);
  155. szBuffer.TrimLeft();
  156. sscanf(szBuffer, "}n");
  157. }
  158. }
  159. /////////////////////////////////////////////////////////////////////////////
  160. // CTexture function implementation
  161. void CTexture::SetTexture()
  162. {
  163. if(m_bCreateList)
  164. {
  165. if(m_bApplyImage)
  166. {
  167. if(!m_iDisplayList)
  168. m_iDisplayList = glGenLists(1); // Get a display list name
  169. glNewList(m_iDisplayList, GL_COMPILE_AND_EXECUTE);
  170. // Display as solid
  171. glPolygonMode(GL_FRONT, GL_FILL);
  172.    if(m_pBits)
  173. {
  174. GLfloat fWhiteColor[] = { 1.00f, 1.00f, 1.00f, 1.0f };
  175. // Apply the Dib Image to our shape..
  176. // ** setting color to white so that if
  177. // GL_MODULATE is set we dont moduleate to the 
  178. // last color... should modulate to the light
  179. // color...*****
  180. glColor4fv(fWhiteColor);
  181. ApplyTexture();
  182. }
  183. glEndList();
  184. }
  185. else
  186. glCallList(m_iDisplayList);
  187. }
  188. else
  189. {
  190. GLfloat fWhiteColor[] = { 1.00f, 1.00f, 1.00f, 1.0f };
  191. // Apply the Dib Image to our shape..
  192. // ** setting color to white so that if
  193. // GL_MODULATE is set we dont moduleate to the 
  194. // last color... should modulate to the light
  195. // color...*****
  196. glColor4fv(fWhiteColor);
  197. ApplyTexture();
  198. }
  199. return;
  200. }
  201. BOOL CTexture::ApplyTexture()
  202. {
  203. int iImageSize;
  204. int i;
  205. BYTE *pPixel;
  206. double dDelta;
  207. double dVariance;
  208. // Ensure that we have an Image to texturize
  209.     if(!m_pBits)
  210. return FALSE;
  211. // Set up transparency..
  212. if (m_bApplyImage) {
  213. iImageSize = m_lScaledSizeX * m_lScaledSizeY;
  214. if (m_bTransparent) {
  215. glAlphaFunc(GL_GREATER, 0.0f);
  216. glEnable(GL_ALPHA_TEST);
  217. dVariance = (double)(m_fTransparentVariance) * 195075.0;
  218. for (i = 0, pPixel = m_pBits; i < iImageSize; i++, pPixel+=4) {
  219. dDelta = pow((double)abs((int)(*pPixel) - (int)(m_bytTransparent_b)), 2.0) +
  220.  pow((double)abs((int)(*(pPixel+1)) - (int)(m_bytTransparent_g)), 2.0) +
  221.  pow((double)abs((int)(*(pPixel+2)) - (int)(m_bytTransparent_r)), 2.0);
  222. if (dDelta <= dVariance)
  223. *(pPixel+3) = 0x00;
  224. else
  225. *(pPixel+3) = 0xff;
  226. }
  227. }
  228. else {
  229. glDisable(GL_ALPHA_TEST);
  230. for (i = 0, pPixel = m_pBits; i < iImageSize; i++, pPixel+=4)
  231. *(pPixel+3) = 0xff;
  232. }
  233. m_bApplyImage = FALSE;
  234. }
  235. // Set up texture mapping using our new 32bpp image...
  236.     glEnable(GL_TEXTURE_2D);
  237.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  238. glTexImage2D(GL_TEXTURE_2D, 0, 4, m_lScaledSizeX, m_lScaledSizeY,
  239. 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_pBits);
  240. // Set up texture coordinate generation for S...
  241. if (m_bS_Gen)
  242. {
  243. glEnable(GL_TEXTURE_GEN_S);
  244. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, m_iS_Mode);
  245. if (m_iS_Mode == GL_OBJECT_LINEAR)
  246. glTexGendv(GL_S, GL_OBJECT_PLANE, m_dS_Coeffs);
  247. else if (m_iS_Mode == GL_EYE_LINEAR)
  248. glTexGendv(GL_S, GL_EYE_PLANE, m_dS_Coeffs);
  249. // No coeffs for GL_SPHERE_MAP
  250. }
  251. else
  252. glDisable(GL_TEXTURE_GEN_S);
  253. // Set up texture coordinate generation for T...
  254. if (m_bT_Gen)
  255. {
  256. glEnable(GL_TEXTURE_GEN_T);
  257. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, m_iT_Mode);
  258. if (m_iT_Mode == GL_OBJECT_LINEAR)
  259. glTexGendv(GL_T, GL_OBJECT_PLANE, m_dT_Coeffs);
  260. else if (m_iT_Mode == GL_EYE_LINEAR)
  261. glTexGendv(GL_T, GL_EYE_PLANE, m_dT_Coeffs);
  262. // No coeffs for GL_SPHERE_MAP
  263. }
  264. else
  265. glDisable(GL_TEXTURE_GEN_T);
  266. // Set the texturing function (to decal or modulate.
  267. // blending not used.)...
  268.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_iEnvmode);
  269. // Set wrapping for S and T coordinates to (GL_CLAMP
  270. // or GL_REPEAT)...
  271.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_iWrap_S);
  272.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_iWrap_T);
  273. // Set the minification and magnification filtering methods...
  274. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_iMinfilter);
  275. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_iMagfilter);
  276. // Set the perspective correction hint to fastest or nicest...
  277. glHint(GL_PERSPECTIVE_CORRECTION_HINT, m_enumHint);
  278. m_bApplyImage = FALSE;
  279. return TRUE; // success
  280. } // end ApplySettings
  281. /////////////////////////////////////////////////////////////////////////////
  282. //
  283. // FUNCTION   : ScaleDIB(HPALETTE hPalette, HANDLE hDibOriginal)
  284. //
  285. // PURPOSE    : Converts the loaded DIB (hDibOriginal) into a 32-bpp DIB
  286. //  section with the Width (x) and Height (y) scaled to a power
  287. //  of 2.
  288. //
  289. // RETURNS    : NULL - If unsuccessful, otherwise
  290. //  A pointer to the scaled DIB bits
  291. //
  292. void* CTexture::ScaleDIB(HPALETTE hPalette, HANDLE hDibOriginal)
  293. {
  294. BYTE *abBitmapInfo[sizeof(BITMAPINFOHEADER)];
  295. BITMAPINFOHEADER *pBMIH = (BITMAPINFOHEADER*)abBitmapInfo;
  296. HDC hDC, hMemDC;
  297. HBITMAP hbmOld;
  298. GLint maxsize;
  299. LPBITMAPINFOHEADER lpbi;
  300. void* pBits = NULL;
  301. // Get stats for original dib...
  302. if (!hDibOriginal)
  303. return FALSE;
  304. lpbi = (LPBITMAPINFOHEADER)hDibOriginal;
  305. TRACE("Bitmap Statistics:  (%dbpp   %d x %d)n",
  306. lpbi->biBitCount,
  307. lpbi->biWidth,
  308. lpbi->biHeight);
  309. // Allocate memory for new 32bpp DIB section.
  310. // No color table is needed...
  311. memset(pBMIH, 0, sizeof(BITMAPINFOHEADER));
  312. // Scale dimensions down to a power of 2
  313. m_lScaledSizeX = Scale_down_to_power_of_2(lpbi->biWidth);
  314. m_lScaledSizeY = Scale_down_to_power_of_2(lpbi->biHeight);
  315. //*****  if GL is not enabled when we call this function
  316. // it will return maxsize of very large negative number
  317. // and cause the texture not to load
  318. // glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
  319. // lScaledSize = min(lScaledSize, maxsize);
  320. // Fill in the header info...
  321. pBMIH->biSize         = sizeof(BITMAPINFOHEADER);
  322. pBMIH->biWidth        = m_lScaledSizeX;
  323. pBMIH->biHeight       = m_lScaledSizeY;
  324. pBMIH->biPlanes       = 1;
  325. pBMIH->biBitCount     = 32;
  326. pBMIH->biCompression  = BI_RGB;
  327. // Create the new 32-bpp DIB section...
  328. HWND hwnd = GetActiveWindow();
  329. hDC = GetDC(hwnd);
  330. hMemDC = CreateCompatibleDC(hDC);
  331. ReleaseDC(hwnd, hDC);
  332. if (m_hDibScaled)
  333. {
  334. DeleteObject(m_hDibScaled);
  335. m_hDibScaled = NULL;
  336. }
  337. m_hDibScaled = CreateDIBSection(hMemDC,
  338.    (BITMAPINFO*)pBMIH,
  339.     DIB_RGB_COLORS,
  340.    (VOID**) &pBits,
  341.     NULL,
  342. 0);
  343. // Select new DIB Section into DC... 
  344. hbmOld = (HBITMAP) SelectObject(hMemDC, m_hDibScaled);
  345. // Blt the loaded x-bpp DIB into our new 32bpp DIB...
  346. SelectPalette(hMemDC, hPalette, TRUE);
  347. RealizePalette(hMemDC);
  348. SetStretchBltMode(hMemDC, COLORONCOLOR);
  349. // Set our device context mapping mode.
  350. // Each logical unit is converted to 1 device pixel. Positive x is to
  351. // the right; positive y is down.
  352. SetMapMode(hMemDC, MM_TEXT);
  353. StretchDIBBlt(hMemDC,
  354. 0,
  355. 0,
  356. m_lScaledSizeX,
  357. m_lScaledSizeY,
  358. hDibOriginal,
  359. 0,
  360. 0,
  361. lpbi->biWidth,
  362. lpbi->biHeight,
  363. SRCCOPY);
  364. // Flush the calling thread's current batch. 
  365. GdiFlush();
  366. // Deselect DIB Section and destroy its memory DC...
  367. if (hbmOld)
  368. SelectObject(hMemDC, hbmOld);
  369. DeleteDC(hMemDC);
  370. return pBits;
  371. }
  372. /////////////////////////////////////////////////////////////////////////////
  373. //
  374. // FUNCTION   : Scale_down_to_power_of_2(long x)
  375. //
  376. // PURPOSE    : Utility to scale the number x to the next lower power of 2.
  377. //  For example:  300 would get scaled to 256..
  378. //
  379. // RETURNS    : The scaled value of x
  380. //
  381. GLint CTexture::Scale_down_to_power_of_2(long x)
  382. {
  383. int i;
  384. LONG shifted_x;
  385. shifted_x = x;
  386. for (i = 0; ((i < 16) && (shifted_x != 0)); i++)
  387. shifted_x = shifted_x >> 1;
  388. if (i == 0)
  389. return 0;
  390. else
  391. return ((GLint)(pow((double)2, (double)(i-1))));
  392. }
  393. void CTexture::GetTextureOrigin3f(GLfloat* x, GLfloat* y, GLfloat* z)
  394. {
  395. *x = m_fOrigin[X];
  396. *y = m_fOrigin[Y];
  397. *z = m_fOrigin[Z];
  398. }
  399. void CTexture::SetTextureOrigin3f(GLfloat x, GLfloat y, GLfloat z)
  400. {
  401. m_fOrigin[X] = x;
  402. m_fOrigin[Y] = y;
  403. m_fOrigin[Z] = z;
  404. }
  405. void CTexture::SetTextureCoord3f(GLfloat s, GLfloat t, GLfloat r)
  406. {
  407. glTexCoord3f(m_fOrigin[X]+s, m_fOrigin[Y]+t, m_fOrigin[Z]+r);
  408. }