background_xD.cpp
Upload User: kairuinn
Upload Date: 2009-02-07
Package Size: 2922k
Code Size: 16k
Category:

Graph program

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #include "background_xD.h"
  3. #include "math.h"
  4. #include <io.h>
  5. #include <fcntl.h>
  6. #include <glglu.h>
  7. //-----------------------------------------------------------//
  8. //                         public                            //
  9. //-----------------------------------------------------------//
  10. //-------------------------------------------------------------
  11. //constructor
  12. //public
  13. #define FAR_CLIP 2000.0
  14. CBackground::CBackground()
  15. {
  16.     m_depth = FAR_CLIP;
  17.     m_row_num = 1;
  18.     m_col_num = 1;
  19. m_corners[0].r = 0.2f;
  20. m_corners[0].g = 0.2f;
  21. m_corners[0].b = 0.6f;
  22. m_corners[0].a = 1.0f; 
  23. m_corners[1].r = 0.2f;
  24. m_corners[1].g = 0.2f;
  25. m_corners[1].b = 0.6f;
  26. m_corners[1].a = 1.0f; 
  27.     m_corners[2].r = 0.9f;
  28.     m_corners[2].g = 0.9f;
  29.     m_corners[2].b = 1.0f;
  30.     m_corners[2].a = 1.0f; 
  31.     m_corners[3].r = 0.9f;
  32.     m_corners[3].g = 0.9f;
  33.     m_corners[3].b = 1.0f;
  34.     m_corners[3].a = 1.0f; 
  35.     
  36.     m_mirror_type = MIRROR11;
  37.     m_textureID = 0;
  38.     m_texture_file.Empty();
  39. }
  40. //-------------------------------------------------------------
  41. //destructor
  42. //public
  43. CBackground::~CBackground()
  44. {
  45.     if(m_textureID)
  46.     {
  47.         glDeleteTextures(1, &m_textureID);
  48.         m_textureID = 0;
  49.     }  
  50. }
  51. //-------------------------------------------------------------
  52. //set background params
  53. //public
  54. void CBackground::SetParams(SBACKGROUND_PARAMS *params)
  55. {
  56.     if(!params)        return;
  57.     if(m_textureID)
  58.     {
  59.         glDeleteTextures(1, &m_textureID);
  60.         m_textureID = 0;
  61.     }  
  62.     m_row_num = params->row_num;
  63.     m_col_num = params->col_num;
  64.     m_mirror_type = params->mirror_type;
  65.     m_texture_file = params->texture_file;
  66.     for( int i=0; i<4; i++)
  67.     {
  68.         m_corners[i].r = params->corner[i].r;
  69.         m_corners[i].g = params->corner[i].g;
  70.         m_corners[i].b = params->corner[i].b;
  71.         m_corners[i].a = params->corner[i].a;
  72.     }
  73. }
  74. //-------------------------------------------------------------
  75. //get background params
  76. //public
  77. void CBackground::GetParams(SBACKGROUND_PARAMS *params)
  78. {
  79.     if(!params)        return;
  80.     params->row_num = m_row_num;
  81.     params->col_num = m_col_num;
  82.     params->mirror_type = m_mirror_type;
  83.     params->texture_file = m_texture_file;
  84.     for( int i=0; i<4; i++)
  85.     {
  86.         params->corner[i].r = m_corners[i].r;
  87.         params->corner[i].g = m_corners[i].g;
  88.         params->corner[i].b = m_corners[i].b;
  89.         params->corner[i].a = m_corners[i].a;
  90.     }
  91. }
  92. //-------------------------------------------------------------
  93. //set z coordinate of the background
  94. //this function is called in CScene::SetBackgroung(CBackground *background)
  95. //public
  96. void CBackground::SetDepth(float depth)
  97. {
  98.     m_depth = depth;
  99. }
  100. //-------------------------------------------------------------
  101. //showing background
  102. //called in CScene::Display()
  103. //public
  104. void CBackground::Display()
  105. {
  106.     int i, j;
  107.     if(m_textureID==0 && !m_texture_file.IsEmpty())
  108.     {
  109.         CreateTexture();
  110.         if(m_textureID==0)
  111.         {    
  112.             ASSERT(0);
  113.             return;
  114.         }
  115.     }
  116.     glMatrixMode(GL_MODELVIEW);
  117. glPushMatrix();
  118. glLoadIdentity();
  119. glMatrixMode(GL_PROJECTION);
  120. glPushMatrix();
  121. glLoadIdentity();
  122. glOrtho(0, 1, 0, 1, 0, -(m_depth+1));
  123.     glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT | GL_POLYGON_BIT);
  124.     glDisable(GL_CULL_FACE);
  125.     glDisable(GL_BLEND);  
  126.     glDisable(GL_LIGHTING);
  127.     //if we have texture (*.bmp file) then show texture
  128. if(m_textureID)
  129.     {
  130.         bool vert_mirror_status=false;
  131.     bool hor_mirror_status=true;
  132.         glBindTexture(GL_TEXTURE_2D, m_textureID);
  133.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  134.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  135.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  136.         for(i=0; i<m_col_num; i++)
  137. {
  138. for(j=0; j<m_row_num; j++)
  139. {
  140. glBegin(GL_QUADS);
  141. if(!vert_mirror_status && !hor_mirror_status)
  142. glTexCoord2f(0.f,0.f);
  143. if(vert_mirror_status && !hor_mirror_status)
  144. glTexCoord2f(1.f,0.f);
  145. if(!vert_mirror_status && hor_mirror_status)
  146. glTexCoord2f(0.f,1.f);
  147. if(vert_mirror_status && hor_mirror_status)
  148. glTexCoord2f(1.f,1.f);
  149.                     glVertex3f((float)i/(float)m_col_num, (float)(j+1)/(float)m_row_num, m_depth);
  150.                     
  151. if(!vert_mirror_status && !hor_mirror_status)
  152. glTexCoord2f(1.f,0.f);
  153. if(vert_mirror_status && !hor_mirror_status)
  154. glTexCoord2f(0.f,0.f);
  155. if(!vert_mirror_status && hor_mirror_status)
  156. glTexCoord2f(1.f,1.f);
  157. if(vert_mirror_status && hor_mirror_status)
  158. glTexCoord2f(0.f,1.f);
  159.      glVertex3f((float)(i+1)/(float)m_col_num, (float)(j+1)/(float)m_row_num, m_depth);
  160.                     
  161. if(!vert_mirror_status && !hor_mirror_status)
  162. glTexCoord2f(1.f,1.f);
  163. if(vert_mirror_status && !hor_mirror_status)
  164. glTexCoord2f(0.f,1.f);
  165. if(!vert_mirror_status && hor_mirror_status)
  166. glTexCoord2f(1.f,0.f);
  167. if(vert_mirror_status && hor_mirror_status)
  168. glTexCoord2f(0.f,0.f);
  169.      glVertex3f((float)(i+1)/(float)m_col_num, (float)j/(float)m_row_num, m_depth);
  170. if(!vert_mirror_status && !hor_mirror_status)
  171. glTexCoord2f(0.f,1.f);
  172. if(vert_mirror_status && !hor_mirror_status)
  173. glTexCoord2f(1.f,1.f);
  174. if(!vert_mirror_status && hor_mirror_status)
  175. glTexCoord2f(0.f,0.f);
  176. if(vert_mirror_status && hor_mirror_status)
  177. glTexCoord2f(1.f,0.f);
  178. glVertex3f((float)i/(float)m_col_num, (float)j/(float)m_row_num,m_depth);
  179. glEnd();
  180.     if(m_mirror_type == MIRROR01 || m_mirror_type == MIRROR11)
  181.     hor_mirror_status=!hor_mirror_status;
  182.     }
  183.             if(m_mirror_type == MIRROR10 || m_mirror_type == MIRROR11)
  184.     vert_mirror_status=!vert_mirror_status;
  185.             hor_mirror_status=true;
  186. }
  187. }
  188. else
  189. {
  190.         bool vert_mirror_status=false;
  191.     bool hor_mirror_status=false;
  192.         glEnable(GL_BLEND);
  193. glDisable(GL_TEXTURE_2D);
  194. for(i=0; i<m_col_num; i++)
  195. {
  196. for(j=0; j<m_row_num; j++)
  197. {
  198. glBegin(GL_QUADS);
  199.      if(!vert_mirror_status && !hor_mirror_status)
  200.      glColor4f(m_corners[0].r, m_corners[0].g, m_corners[0].b,1.0f);
  201.      if(vert_mirror_status && !hor_mirror_status)
  202.      glColor4f(m_corners[1].r, m_corners[1].g, m_corners[1].b,1.0f);
  203.      if(vert_mirror_status && hor_mirror_status)
  204.      glColor4f(m_corners[2].r, m_corners[2].g, m_corners[2].b,1.0f);
  205.                     if(!vert_mirror_status && hor_mirror_status)
  206.      glColor4f(m_corners[3].r, m_corners[3].g, m_corners[3].b,1.0f);
  207.                     glVertex3f((float)i/(float)m_col_num, (float)(j+1)/(float)m_row_num,m_depth);
  208.                     //glVertex2f((float)i/(float)m_col_num, (float)(j+1)/(float)m_row_num);
  209.                 
  210.      if(vert_mirror_status && !hor_mirror_status)
  211.      glColor4f(m_corners[0].r, m_corners[0].g, m_corners[0].b,1.0f);
  212.                     if(!vert_mirror_status && !hor_mirror_status)
  213.      glColor4f(m_corners[1].r, m_corners[1].g, m_corners[1].b,1.0f);
  214.      if(!vert_mirror_status && hor_mirror_status)
  215.      glColor4f(m_corners[2].r, m_corners[2].g, m_corners[2].b,1.0f);
  216.      if(vert_mirror_status && hor_mirror_status)
  217.      glColor4f(m_corners[3].r, m_corners[3].g, m_corners[3].b,1.0f);
  218.      glVertex3f((float)(i+1)/(float)m_col_num, (float)(j+1)/(float)m_row_num,m_depth);
  219.                     //glVertex2f((float)(i+1)/(float)m_col_num, (float)(j+1)/(float)m_row_num);
  220.                     
  221.                 
  222.      if(vert_mirror_status && hor_mirror_status)
  223.      glColor4f(m_corners[0].r, m_corners[0].g, m_corners[0].b,1.0f);
  224.      if(!vert_mirror_status && hor_mirror_status)
  225.      glColor4f(m_corners[1].r, m_corners[1].g, m_corners[1].b,1.0f);
  226.                     if(!vert_mirror_status && !hor_mirror_status)
  227.      glColor4f(m_corners[2].r, m_corners[2].g, m_corners[2].b,1.0f);
  228.      if(vert_mirror_status && !hor_mirror_status)
  229.      glColor4f(m_corners[3].r, m_corners[3].g, m_corners[3].b,1.0f);
  230.                     glVertex3f((float)(i+1)/(float)m_col_num, (float)j/(float)m_row_num,m_depth);
  231.                     //glVertex2f((float)(i+1)/(float)m_col_num, (float)j/(float)m_row_num);
  232.                 
  233.      if(!vert_mirror_status && hor_mirror_status)
  234.      glColor4f(m_corners[0].r, m_corners[0].g, m_corners[0].b,1.0f);
  235.      if(vert_mirror_status && hor_mirror_status)
  236.      glColor4f(m_corners[1].r, m_corners[1].g, m_corners[1].b,1.0f);
  237.      if(vert_mirror_status && !hor_mirror_status)
  238.      glColor4f(m_corners[2].r, m_corners[2].g, m_corners[2].b,1.0f);
  239.                     if(!vert_mirror_status && !hor_mirror_status)
  240.      glColor4f(m_corners[3].r, m_corners[3].g, m_corners[3].b,1.0f);
  241.                     glVertex3f((float)i/(float)m_col_num, (float)j/(float)m_row_num,m_depth);
  242.                     //glVertex2f((float)i/(float)m_col_num, (float)j/(float)m_row_num);
  243.          
  244.     glEnd();
  245.     if(m_mirror_type == MIRROR01 || m_mirror_type == MIRROR11)
  246.     hor_mirror_status=!hor_mirror_status;
  247.     }
  248.             if(m_mirror_type == MIRROR10 || m_mirror_type == MIRROR11)
  249.     vert_mirror_status=!vert_mirror_status;
  250.             hor_mirror_status=false;
  251.     }
  252.     }
  253. glPopAttrib();
  254. glPopMatrix();
  255. glMatrixMode(GL_MODELVIEW);
  256. glPopMatrix();
  257. }
  258. //-----------------------------------------------------------//
  259. //                         private                           //
  260. //-----------------------------------------------------------//
  261. //creating background texture from *.bmp file
  262. //private
  263. bool CBackground::CreateTexture()
  264. {
  265.     if(m_texture_file.IsEmpty())
  266.     {
  267.         if(m_textureID)
  268.         {
  269.             glDeleteTextures(1, &m_textureID);
  270.             m_textureID = 0;
  271.         }
  272.         return false;
  273.     }
  274.     if(m_textureID)
  275.         if(m_textureID)
  276.     glDeleteTextures(1, &m_textureID);
  277.   
  278.     //glGenTextures(1, &m_textureID);
  279.         m_textureID = 10067;
  280.     ASSERT(m_textureID>0);
  281.     int textuere_width;
  282.     int texture_height;
  283.     int tmp_width;
  284.     int tmp_height;
  285.     BYTE *pTexture = NULL;
  286.     BYTE *pTmpData = NULL;
  287.     char path[MAX_PATH];
  288.     sprintf(path, "%s", (LPCTSTR) m_texture_file);
  289.     
  290. pTmpData = LoadFromBmp(path, &tmp_width, &tmp_height);
  291. if(pTmpData)
  292. {
  293.      textuere_width=32;
  294. textuere_width = (int)pow((float)2.0f,(float)
  295. ((log((float)tmp_width)/log(2.0f))+
  296. 1.0-
  297. (log((float)m_col_num)/log(2.0f))));
  298. if(textuere_width<32)
  299.     textuere_width=32;
  300. if(textuere_width>1024)
  301. textuere_width=1024;
  302. texture_height=32;
  303. texture_height = (int)pow((float)2.0f,
  304. (float)((log((float)tmp_height)/log(2.0f))+1.0-(log((float)m_row_num)/log(2.0f))));
  305. if(texture_height<32)
  306.     texture_height=32;
  307. if(texture_height>1024)
  308. texture_height=1024;
  309. pTexture = new BYTE[texture_height*textuere_width*3];
  310. if(pTexture)
  311. {
  312.     gluScaleImage(GL_RGB, tmp_width, tmp_height, GL_UNSIGNED_BYTE, pTmpData, textuere_width, texture_height, GL_UNSIGNED_BYTE, pTexture);
  313.             glBindTexture(GL_TEXTURE_2D, m_textureID);
  314.             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textuere_width, texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLubyte*) pTexture);
  315. delete[] pTmpData;
  316.             delete[] pTexture;
  317. }
  318.         else
  319.         {
  320.             return false;
  321.         }
  322.     }
  323.     else
  324.     {
  325.         return false;
  326.     }
  327.     return true;
  328. }
  329. //-------------------------------------------------------------
  330. //this function loads *.bmp file and returns width and height 
  331. //pointer to the picture storage (rgbrgbrgb...), 
  332. //size of this storage is bmpWidth*bmpHeight*3*sizeof(unsigned char)
  333. //this memory shoud be free after using; 
  334. //this function is used in CBackground::CreateTexture()
  335. //private
  336. unsigned char *CBackground::LoadFromBmp(char *filename, int* bmpWidth, int* bmpHeight)
  337. {
  338.     LPRGBQUAD   ptrToPalette;  
  339.     char*       ptrToPixels;   
  340.     long        bitmapRow, bitmapColumn;  
  341. LPBITMAPINFOHEADER PtrToBmpHdr;
  342. LPBITMAPFILEHEADER PtrToFileHdr;
  343. unsigned char *Texels;
  344. unsigned char *texture_pixels;
  345. int    size_texture;
  346. unsigned char *ptex;
  347. int    length;
  348. char  *texture_file;
  349. UINT  nBytesRead;
  350. int    fh;
  351. char errorstr[_MAX_PATH+25]="Can't open bmp file ";
  352.    /* Open file for input: */
  353. if( (fh = _open(filename, _O_RDONLY )) == -1 )  
  354. {
  355. ::MessageBox(NULL, strcat(errorstr,filename),"Error",MB_OK);
  356.         return NULL;
  357. }
  358. length = _filelength(fh);
  359. texture_file = (char*)malloc(length);
  360. if(texture_file == NULL)
  361. ::MessageBox(NULL, "Can not load picture. nPicture is too large.","Error",MB_OK);
  362. if( ( nBytesRead = _read( fh, texture_file, length ) ) <= 0 ) 
  363. {
  364. _close( fh );
  365. ::MessageBox(NULL, "Read texture file","Error",MB_OK);
  366. exit(-3);
  367. }
  368. _close( fh );
  369. PtrToFileHdr = (LPBITMAPFILEHEADER)texture_file;
  370. PtrToBmpHdr = (LPBITMAPINFOHEADER)(texture_file+sizeof(BITMAPFILEHEADER));
  371.   
  372. if (!PtrToBmpHdr) 
  373. {
  374. DWORD err = GetLastError();
  375. goto ErrorExit;
  376. }
  377.     Texels = (unsigned char *)malloc(PtrToBmpHdr->biWidth * 3);
  378.     ptrToPalette = (LPRGBQUAD) ((LPSTR) PtrToBmpHdr + PtrToBmpHdr->biSize);
  379.     ptrToPixels  = (char*) PtrToBmpHdr + (PtrToBmpHdr->biSize + 
  380.                            PtrToBmpHdr->biClrUsed * sizeof(RGBQUAD));
  381. if ( PtrToBmpHdr->biBitCount == 4) 
  382. {
  383.             ptrToPixels += ((PtrToBmpHdr->biHeight - 1) * (long )((PtrToBmpHdr->biWidth/2+3) & ~3));
  384. else 
  385. {
  386. if ( PtrToBmpHdr->biBitCount == 8) 
  387. {
  388.             ptrToPixels += ((PtrToBmpHdr->biHeight - 1) * (long )((PtrToBmpHdr->biWidth+3) & ~3));
  389. else 
  390. {
  391. if ( PtrToBmpHdr->biBitCount == 24) 
  392. {
  393. ptrToPixels += ((PtrToBmpHdr->biHeight - 1) * (long )((PtrToBmpHdr->biWidth*3+3) & ~3));
  394. }
  395. }
  396. }
  397. size_texture = PtrToBmpHdr->biWidth*PtrToBmpHdr->biHeight;
  398. ptex = (unsigned char*)malloc(3*size_texture);
  399. if (ptex == NULL) 
  400. {
  401. goto ErrorExit;
  402. }
  403. *bmpWidth = PtrToBmpHdr->biWidth;
  404. *bmpHeight = PtrToBmpHdr->biHeight;
  405.   /*if ( ((*bmpWidth-1) & *bmpWidth)||((*bmpHeight-1) & *bmpHeight) )
  406.   ::MessageBox(NULL, "Texture dimension has to be power of 2","Error",MB_OK);
  407.   */  
  408. texture_pixels = ptex;
  409.     for (bitmapRow = 0;  bitmapRow < PtrToBmpHdr->biHeight; bitmapRow++) 
  410. {
  411. LPSTR   rowPtr;
  412. rowPtr = (LPSTR)ptrToPixels;
  413.         for (bitmapColumn = 0; bitmapColumn < PtrToBmpHdr->biWidth; ) 
  414. {
  415.             unsigned char p;
  416. if ( PtrToBmpHdr->biBitCount == 4) 
  417. {
  418. p = *rowPtr;
  419. rowPtr++;
  420. Texels[bitmapColumn*3  ] = ptrToPalette[p>>4].rgbRed;
  421. Texels[bitmapColumn*3+1] = ptrToPalette[p>>4].rgbGreen;
  422. Texels[bitmapColumn*3+2] = ptrToPalette[p>>4].rgbBlue;
  423. bitmapColumn++;
  424. Texels[bitmapColumn*3  ] = ptrToPalette[p&0xf].rgbRed;
  425. Texels[bitmapColumn*3+1] = ptrToPalette[p&0xf].rgbGreen;
  426. Texels[bitmapColumn*3+2] = ptrToPalette[p&0xf].rgbBlue;
  427. bitmapColumn++;
  428. else 
  429. if ( PtrToBmpHdr->biBitCount == 8) 
  430. {
  431. p = *rowPtr;
  432. rowPtr++;
  433. Texels[bitmapColumn*3  ] = ptrToPalette[p].rgbRed;
  434. Texels[bitmapColumn*3+1] = ptrToPalette[p].rgbGreen;
  435. Texels[bitmapColumn*3+2] = ptrToPalette[p].rgbBlue;
  436. bitmapColumn++;
  437. else 
  438. if ( PtrToBmpHdr->biBitCount == 24) 
  439. {
  440. Texels[bitmapColumn*3+2] = *rowPtr++;
  441. Texels[bitmapColumn*3+1] = *rowPtr++;
  442. Texels[bitmapColumn*3  ] = *rowPtr++;
  443. bitmapColumn++;
  444. }
  445. }
  446.         
  447. if (PtrToBmpHdr->biBitCount==4) 
  448. {
  449. ptrToPixels -= ((PtrToBmpHdr->biWidth >> 1)+3) & ~3;
  450. else 
  451. {
  452. if(PtrToBmpHdr->biBitCount==8) 
  453. {
  454. ptrToPixels -= (PtrToBmpHdr->biWidth+3) & ~3;
  455. else 
  456. {
  457. if(PtrToBmpHdr->biBitCount==24) 
  458. {
  459. ptrToPixels -= ((PtrToBmpHdr->biWidth*3+3) & ~3);
  460. }
  461. }
  462. }
  463. memcpy( ptex, &Texels[0], 3 * PtrToBmpHdr->biWidth);
  464. ptex += 3 * PtrToBmpHdr->biWidth;
  465.     } 
  466. free(texture_file); 
  467. free(Texels);
  468. return texture_pixels;
  469.     
  470. ErrorExit:
  471. free(texture_file);
  472. return NULL;
  473. }