Texture.cpp
资源名称:gloop.zip [点击查看]
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:13k
源码类别:
OpenGL
开发平台:
Visual C++
- /////////////////////////////////////////////////////////////////////////////
- // Texture.cpp : implementation file
- //
- // glOOP (OpenGL Object Oriented Programming library)
- // Copyright (c) Craig Fahrnbach 1997, 1998
- //
- // OpenGL is a registered trademark of Silicon Graphics
- //
- //
- // This program is provided for educational and personal use only and
- // is provided without guarantee or warrantee expressed or implied.
- //
- // Commercial use is strickly prohibited without written permission
- // from ImageWare Development.
- //
- // This program is -not- in the public domain.
- //
- /////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "glOOP.h"
- #include <math.h>
- #include "DIBUtil.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CTexture
- IMPLEMENT_DYNAMIC(CTexture, CObject)
- /////////////////////////////////////////////////////////////////////////////
- // CTexture construction
- BOOL CTexture::CreateTexture(char* pFileName, HPALETTE hPalette, CTexture **pTexture)
- {
- int iLength; // Length of pFileName
- char szFileExt[4]; // File extension
- if (!pFileName)
- return FALSE; // No file to open!
- // Free all image format pointers before we open a new file.
- // This will free all image data..
- if(*pTexture)
- {
- delete *pTexture; // free our DIB image
- *pTexture = NULL;
- }
- // Determine the type of Texture map file to Open
- iLength = strlen(pFileName);
- // Copy the last 3 characters + the NULL terminating character..
- strncpy(&szFileExt[0], pFileName + (iLength-3), 4);
- // Is the file a Bitmap or DIB?
- if(strcmp(szFileExt, "bmp")==0 || strcmp(szFileExt, "dib")==0)
- {
- // Create a CTextureDibImage class
- *pTexture = new CTextureDibImage;
- ASSERT(*pTexture);
- }
- // Is the file an AVI file?
- if(strcmp(szFileExt, "avi")==0)
- {
- // Create a CTextureAviMovie class
- *pTexture = new CTextureAviMovie;
- ASSERT(*pTexture);
- }
- // TODO: ADD OTHER FILE FORMAT SUPPORT CODE HERE..
- // Open the Texture map file
- if(!(*pTexture)->OpenTexture(pFileName, hPalette))
- {
- delete *pTexture; // File NOT Opened!
- *pTexture = NULL;
- return FALSE;
- }
- return TRUE;
- }
- CTexture::CTexture()
- {
- // Initilize variables
- m_pBits = NULL; // Pointer to scaled 32bpp Texture DIB bits
- m_hDibScaled = NULL; // Handle to scaled 32bpp Texture DIB
- m_szFileName = _T("");
- m_iDisplayList = NULL;
- m_bCreateList = TRUE; // Do not create display lists for texture
- m_bApplyImage = TRUE;
- m_iEnvmode = GL_MODULATE; // alt: GL_DECAL -or- GL_BLEND
- m_enumHint = GL_NICEST; // alt: GL_FASTEST
- m_iMinfilter = GL_NEAREST;
- m_iMagfilter = GL_LINEAR;
- m_iWrap_S = GL_REPEAT;
- m_iWrap_T = GL_REPEAT;
- m_bS_Gen = FALSE;
- m_iS_Mode = GL_OBJECT_LINEAR;
- m_dS_Coeffs[0] = 1.0;
- m_dS_Coeffs[1] = 0.0;
- m_dS_Coeffs[2] = 0.0;
- m_dS_Coeffs[3] = 0.0;
- m_bT_Gen = FALSE;
- m_iT_Mode = GL_OBJECT_LINEAR;
- m_dT_Coeffs[0] = 0.0;
- m_dT_Coeffs[1] = 1.0;
- m_dT_Coeffs[2] = 0.0;
- m_dT_Coeffs[3] = 0.0;
- m_bTransparent = FALSE;
- m_bytTransparent_r = 0;
- m_bytTransparent_g = 0;
- m_bytTransparent_b = 0;
- m_fTransparentVariance = 0.1f;
- m_fOrigin[X] = 0.0f;
- m_fOrigin[Y] = 0.0f;
- m_fOrigin[Z] = 0.0f;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CTexture Destructor
- CTexture::~CTexture()
- {
- // Free the display list
- glDeleteLists(m_iDisplayList, 1);
- // Free the DIB memory allocated by the operating system for the
- // device-independent bitmap bits. (frees pBits). The operating
- // system closes the handle to that memory when you delete the
- // device-independent bitmap by calling the DeleteObject function.
- if(m_hDibScaled)
- {
- DeleteObject(m_hDibScaled);
- m_hDibScaled = NULL;
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // CTexture virtual methods or functions
- BOOL CTexture::OpenTexture(char* pFileName, HPALETTE hPalette)
- {
- // Virtual prototype function only! Add specific
- // functionality to your derived Texture class!
- return FALSE;
- }
- void CTexture::Serialize(CArchive& ar, int iVersion)
- {
- CString szBuffer;
- CString szName;
- CString szTemp;
- szBuffer.GetBuffer(256);
- szName.GetBuffer(128);
- if (ar.IsStoring())
- {
- // Save the Base Class CTexture Data...
- // 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]);
- // ar.WriteString(szBuffer);
- }
- else
- {
- // Read the Base Class CTexture data...
- // ar.ReadString(szBuffer);
- // szBuffer.TrimLeft();
- // 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]);
- // Must remove the derived class defined end marker!
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- sscanf(szBuffer, "}n");
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // CTexture function implementation
- void CTexture::SetTexture()
- {
- if(m_bCreateList)
- {
- if(m_bApplyImage)
- {
- if(!m_iDisplayList)
- m_iDisplayList = glGenLists(1); // Get a display list name
- glNewList(m_iDisplayList, GL_COMPILE_AND_EXECUTE);
- // Display as solid
- glPolygonMode(GL_FRONT, GL_FILL);
- if(m_pBits)
- {
- GLfloat fWhiteColor[] = { 1.00f, 1.00f, 1.00f, 1.0f };
- // Apply the Dib Image to our shape..
- // ** setting color to white so that if
- // GL_MODULATE is set we dont moduleate to the
- // last color... should modulate to the light
- // color...*****
- glColor4fv(fWhiteColor);
- ApplyTexture();
- }
- glEndList();
- }
- else
- glCallList(m_iDisplayList);
- }
- else
- {
- GLfloat fWhiteColor[] = { 1.00f, 1.00f, 1.00f, 1.0f };
- // Apply the Dib Image to our shape..
- // ** setting color to white so that if
- // GL_MODULATE is set we dont moduleate to the
- // last color... should modulate to the light
- // color...*****
- glColor4fv(fWhiteColor);
- ApplyTexture();
- }
- return;
- }
- BOOL CTexture::ApplyTexture()
- {
- int iImageSize;
- int i;
- BYTE *pPixel;
- double dDelta;
- double dVariance;
- // Ensure that we have an Image to texturize
- if(!m_pBits)
- return FALSE;
- // Set up transparency..
- if (m_bApplyImage) {
- iImageSize = m_lScaledSizeX * m_lScaledSizeY;
- if (m_bTransparent) {
- glAlphaFunc(GL_GREATER, 0.0f);
- glEnable(GL_ALPHA_TEST);
- dVariance = (double)(m_fTransparentVariance) * 195075.0;
- for (i = 0, pPixel = m_pBits; i < iImageSize; i++, pPixel+=4) {
- dDelta = pow((double)abs((int)(*pPixel) - (int)(m_bytTransparent_b)), 2.0) +
- pow((double)abs((int)(*(pPixel+1)) - (int)(m_bytTransparent_g)), 2.0) +
- pow((double)abs((int)(*(pPixel+2)) - (int)(m_bytTransparent_r)), 2.0);
- if (dDelta <= dVariance)
- *(pPixel+3) = 0x00;
- else
- *(pPixel+3) = 0xff;
- }
- }
- else {
- glDisable(GL_ALPHA_TEST);
- for (i = 0, pPixel = m_pBits; i < iImageSize; i++, pPixel+=4)
- *(pPixel+3) = 0xff;
- }
- m_bApplyImage = FALSE;
- }
- // Set up texture mapping using our new 32bpp image...
- glEnable(GL_TEXTURE_2D);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexImage2D(GL_TEXTURE_2D, 0, 4, m_lScaledSizeX, m_lScaledSizeY,
- 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_pBits);
- // Set up texture coordinate generation for S...
- if (m_bS_Gen)
- {
- glEnable(GL_TEXTURE_GEN_S);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, m_iS_Mode);
- if (m_iS_Mode == GL_OBJECT_LINEAR)
- glTexGendv(GL_S, GL_OBJECT_PLANE, m_dS_Coeffs);
- else if (m_iS_Mode == GL_EYE_LINEAR)
- glTexGendv(GL_S, GL_EYE_PLANE, m_dS_Coeffs);
- // No coeffs for GL_SPHERE_MAP
- }
- else
- glDisable(GL_TEXTURE_GEN_S);
- // Set up texture coordinate generation for T...
- if (m_bT_Gen)
- {
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, m_iT_Mode);
- if (m_iT_Mode == GL_OBJECT_LINEAR)
- glTexGendv(GL_T, GL_OBJECT_PLANE, m_dT_Coeffs);
- else if (m_iT_Mode == GL_EYE_LINEAR)
- glTexGendv(GL_T, GL_EYE_PLANE, m_dT_Coeffs);
- // No coeffs for GL_SPHERE_MAP
- }
- else
- glDisable(GL_TEXTURE_GEN_T);
- // Set the texturing function (to decal or modulate.
- // blending not used.)...
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_iEnvmode);
- // Set wrapping for S and T coordinates to (GL_CLAMP
- // or GL_REPEAT)...
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_iWrap_S);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_iWrap_T);
- // Set the minification and magnification filtering methods...
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_iMinfilter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_iMagfilter);
- // Set the perspective correction hint to fastest or nicest...
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, m_enumHint);
- m_bApplyImage = FALSE;
- return TRUE; // success
- } // end ApplySettings
- /////////////////////////////////////////////////////////////////////////////
- //
- // FUNCTION : ScaleDIB(HPALETTE hPalette, HANDLE hDibOriginal)
- //
- // PURPOSE : Converts the loaded DIB (hDibOriginal) into a 32-bpp DIB
- // section with the Width (x) and Height (y) scaled to a power
- // of 2.
- //
- // RETURNS : NULL - If unsuccessful, otherwise
- // A pointer to the scaled DIB bits
- //
- void* CTexture::ScaleDIB(HPALETTE hPalette, HANDLE hDibOriginal)
- {
- BYTE *abBitmapInfo[sizeof(BITMAPINFOHEADER)];
- BITMAPINFOHEADER *pBMIH = (BITMAPINFOHEADER*)abBitmapInfo;
- HDC hDC, hMemDC;
- HBITMAP hbmOld;
- GLint maxsize;
- LPBITMAPINFOHEADER lpbi;
- void* pBits = NULL;
- // Get stats for original dib...
- if (!hDibOriginal)
- return FALSE;
- lpbi = (LPBITMAPINFOHEADER)hDibOriginal;
- TRACE("Bitmap Statistics: (%dbpp %d x %d)n",
- lpbi->biBitCount,
- lpbi->biWidth,
- lpbi->biHeight);
- // Allocate memory for new 32bpp DIB section.
- // No color table is needed...
- memset(pBMIH, 0, sizeof(BITMAPINFOHEADER));
- // Scale dimensions down to a power of 2
- m_lScaledSizeX = Scale_down_to_power_of_2(lpbi->biWidth);
- m_lScaledSizeY = Scale_down_to_power_of_2(lpbi->biHeight);
- //***** if GL is not enabled when we call this function
- // it will return maxsize of very large negative number
- // and cause the texture not to load
- // glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
- // lScaledSize = min(lScaledSize, maxsize);
- // Fill in the header info...
- pBMIH->biSize = sizeof(BITMAPINFOHEADER);
- pBMIH->biWidth = m_lScaledSizeX;
- pBMIH->biHeight = m_lScaledSizeY;
- pBMIH->biPlanes = 1;
- pBMIH->biBitCount = 32;
- pBMIH->biCompression = BI_RGB;
- // Create the new 32-bpp DIB section...
- HWND hwnd = GetActiveWindow();
- hDC = GetDC(hwnd);
- hMemDC = CreateCompatibleDC(hDC);
- ReleaseDC(hwnd, hDC);
- if (m_hDibScaled)
- {
- DeleteObject(m_hDibScaled);
- m_hDibScaled = NULL;
- }
- m_hDibScaled = CreateDIBSection(hMemDC,
- (BITMAPINFO*)pBMIH,
- DIB_RGB_COLORS,
- (VOID**) &pBits,
- NULL,
- 0);
- // Select new DIB Section into DC...
- hbmOld = (HBITMAP) SelectObject(hMemDC, m_hDibScaled);
- // Blt the loaded x-bpp DIB into our new 32bpp DIB...
- SelectPalette(hMemDC, hPalette, TRUE);
- RealizePalette(hMemDC);
- SetStretchBltMode(hMemDC, COLORONCOLOR);
- // Set our device context mapping mode.
- // Each logical unit is converted to 1 device pixel. Positive x is to
- // the right; positive y is down.
- SetMapMode(hMemDC, MM_TEXT);
- StretchDIBBlt(hMemDC,
- 0,
- 0,
- m_lScaledSizeX,
- m_lScaledSizeY,
- hDibOriginal,
- 0,
- 0,
- lpbi->biWidth,
- lpbi->biHeight,
- SRCCOPY);
- // Flush the calling thread's current batch.
- GdiFlush();
- // Deselect DIB Section and destroy its memory DC...
- if (hbmOld)
- SelectObject(hMemDC, hbmOld);
- DeleteDC(hMemDC);
- return pBits;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // FUNCTION : Scale_down_to_power_of_2(long x)
- //
- // PURPOSE : Utility to scale the number x to the next lower power of 2.
- // For example: 300 would get scaled to 256..
- //
- // RETURNS : The scaled value of x
- //
- GLint CTexture::Scale_down_to_power_of_2(long x)
- {
- int i;
- LONG shifted_x;
- shifted_x = x;
- for (i = 0; ((i < 16) && (shifted_x != 0)); i++)
- shifted_x = shifted_x >> 1;
- if (i == 0)
- return 0;
- else
- return ((GLint)(pow((double)2, (double)(i-1))));
- }
- void CTexture::GetTextureOrigin3f(GLfloat* x, GLfloat* y, GLfloat* z)
- {
- *x = m_fOrigin[X];
- *y = m_fOrigin[Y];
- *z = m_fOrigin[Z];
- }
- void CTexture::SetTextureOrigin3f(GLfloat x, GLfloat y, GLfloat z)
- {
- m_fOrigin[X] = x;
- m_fOrigin[Y] = y;
- m_fOrigin[Z] = z;
- }
- void CTexture::SetTextureCoord3f(GLfloat s, GLfloat t, GLfloat r)
- {
- glTexCoord3f(m_fOrigin[X]+s, m_fOrigin[Y]+t, m_fOrigin[Z]+r);
- }