Advertisement

use Ole load jpg,bmp,gif for OpenGL texture

Started by October 25, 2001 01:58 AM
-1 comments, last by 613129 23 years, 4 months ago
this is my load texture code ^^ [img]http://mopsite.haobang.net/new/face/190.gif[/img]
  
/// GLTexture.cpp: implementation of the CGLTexture class.

//

//////////////////////////////////////////////////////////////////////


#include "stdafx.h"
#include "MapEdit.h"
#include "GLTexture.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define HIMETRIC_INCH	2540
//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////


CGLTexture::CGLTexture()
{
	m_uWidth		= 0;
	m_uHeight		= 0;
	m_uTextureID	= 0;
	m_dwMask		= 0;
}

CGLTexture::~CGLTexture()
{

}

BOOL CGLTexture::LoadFormFile(LPCTSTR lpszfile,BOOL bList)
{
	if(!lpszfile)return FALSE;

	CFile		hFile;
	RECT		rc;
	HBITMAP		hBmp;
	BITMAP		bm;
	DWORD		dwSize;
	LPVOID		pvData = NULL;
	DWORD		dwRead = 0;
	PALETTEENTRY	Palette[256];

	if(!hFile.Open(lpszfile,CFile::modeRead))
	{
        TRACE("Could not open file <%s>.\n",lpszfile);   // process error 

		return FALSE;
	} 
	
	if( hFile.GetLength() == 0)
	{
		hFile.Close();
		return FALSE;
	}


	switch(GetImageType(&hFile))
	{
	case IMAGE_UNKOWN:return FALSE;
	case IMAGE_BMP:if(!ReadBmpPalette(&hFile,Palette))return FALSE;break;
	case IMAGE_JPG:if(!ReadJpgPalette(&hFile,Palette))return FALSE;break;
	case IMAGE_GIF:if(!ReadGifPalette(&hFile,Palette))return FALSE;break;
	}

	TRACE("Load Palette  Ok!\n");
	dwSize = hFile.GetLength();
	// alloc memory based on file size

	HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwSize);
	if(!hGlobal)
	{
		hFile.Close();
		return FALSE;
	}
	pvData = GlobalLock(hGlobal);

	// read file and store in global memory

	hFile.SeekToBegin();
	hFile.Read(pvData,dwSize);
	GlobalUnlock(hGlobal);
	hFile.Close();

	LPSTREAM pstm = NULL;
	// create IStream* from global memory

	HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
	if ( (!SUCCEEDED(hr)) || (pstm == NULL))
	{
		TRACE("CreateStreamOnHGlobal failed!\n");
		return NULL;
	}

	// Create IPicture from image file

	LPPICTURE gpPicture=NULL;
	hr = ::OleLoadPicture(pstm, dwSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
	if ( (!SUCCEEDED(hr)) || (gpPicture == NULL))
	{
		TRACE("OleLoadPicture failed!\n");
		return NULL;
	}

	pstm->Release();
	
	// get width and height of picture

	long hmWidth;
	long hmHeight;
	gpPicture->get_Width(&hmWidth);
	gpPicture->get_Height(&hmHeight);

	HDC Screen = ::CreateDC("Display", NULL, NULL, NULL);

	// convert himetric to pixels

	int nWidth	= MulDiv(hmWidth,
		GetDeviceCaps(Screen, LOGPIXELSX), HIMETRIC_INCH);
	int nHeight	= MulDiv(hmHeight,
		GetDeviceCaps(Screen, LOGPIXELSY), HIMETRIC_INCH);

	
	if(Screen)DeleteDC(Screen);
	
	rc.left = 0;
	rc.top = 0;
	rc.right = nWidth;
	rc.bottom = nHeight;

	gpPicture->get_Handle((OLE_HANDLE FAR *)&hBmp);
	if(hBmp)
	{
		GetObject(hBmp,sizeof(bm),&bm);
		TRACE("Width = %d\nHeight = %d\nPlanes = %d\n\
			bmBitsPixel=%d\nbmWidthBytes= %d\n\
			nWidth = %d\nnHeight=%d\n",
			bm.bmWidth,bm.bmHeight,bm.bmPlanes,
			bm.bmBitsPixel,bm.bmWidthBytes,
			nWidth,nHeight);
		dwSize = bm.bmHeight*bm.bmWidthBytes;
		BYTE* lpData = new BYTE[bm.bmHeight*bm.bmWidth*3];
		if(lpData)
		{
			ChangeColorDepthTo24(hBmp,&lpData,Palette);			
			glGenTextures(1, &m_uTextureID);
			glBindTexture(GL_TEXTURE_2D, m_uTextureID);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	// Linear Filtering

			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	// Linear Filtering

				
			glTexImage2D(GL_TEXTURE_2D, 0, 3, nWidth,
				nHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,lpData);
			
			delete[] lpData; 
		}
		m_uWidth = bm.bmWidth;
		m_uHeight=	bm.bmHeight;
	}
		
	if(hBmp)DeleteObject(hBmp);
	if (gpPicture)gpPicture->Release();
	
	if(bList)
	{
		BuildList();
		AddMask(TEXTURE_LIST);
	}
	return TRUE;
}


BOOL CGLTexture::LoadFormRes(UINT uID)
{
	return TRUE;
}

BOOL CGLTexture::LoadFormRes(LPCTSTR lpszName)
{
	return TRUE;
}

BOOL CGLTexture::LoadBmp(LPCTSTR lpszfile)
{
	int   len;
	AUX_RGBImageRec *lpTextureImage;

	lpTextureImage = NULL;

	FILE *pf=NULL;

	pf = fopen(lpszfile,"r");
	if(pf)
	{
		fclose(pf);
		lpTextureImage = auxDIBImageLoad(lpszfile);
	}

	if(lpTextureImage)
	{
		glGenTextures(1, &m_uTextureID);					// Create The Texture

		// Typical Texture Generation Using Data From The Bitmap

		glBindTexture(GL_TEXTURE_2D, m_uTextureID);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	// Linear Filtering

		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	// Linear Filtering

		glTexImage2D(GL_TEXTURE_2D, 0, 3, lpTextureImage->sizeX,
			lpTextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
			lpTextureImage->data);
	
		m_uWidth = lpTextureImage->sizeX;
		m_uHeight=	lpTextureImage->sizeY;
		if (lpTextureImage)							// If Texture Exists

		{
			if (lpTextureImage->data)					// If Texture Image Exists

			{
				free(lpTextureImage->data);				// Free The Texture Image Memory

			}
			
			free(lpTextureImage);						// Free The Image Structure

		}

		return TRUE;
	}

	return FALSE;
}

BOOL CGLTexture::ChangeColorDepthTo24(
	HBITMAP	hbm,BYTE** lpData,PALETTEENTRY* lpPalette)
{
	if(!hbm||!*lpData)return FALSE;
	
	BITMAP				bm;
	BITMAPINFOHEADER*	lpHead = (BITMAPINFOHEADER*)hbm;
	BYTE*				lpSrc = NULL,*lpDest = *lpData;
	LONG				x,y,i;
	BYTE*				lpTemp;

	GetObject(hbm,sizeof(bm),&bm);

	lpTemp = new BYTE[bm.bmHeight*bm.bmWidthBytes];
	if(!lpTemp)return TRUE;
	GetBitmapBits(hbm,bm.bmHeight*bm.bmWidthBytes,lpTemp);
	lpSrc = lpTemp+bm.bmHeight*bm.bmWidthBytes;

	try
	{
		switch(bm.bmBitsPixel)
		{
		case 1:
			TRACE("1 bit\n");
			for(y=0;y<bm.bmHeight;y++)
			{
				lpSrc  -= bm.bmWidthBytes;	
				for(x=0;x<bm.bmWidth;x++)
				{
					if(lpSrc[(x>>3)] & (128 >> (x % 8)))
					{
						lpDest[x*3+2] = 0xFF;
						lpDest[x*3+1] = 0xFF;
						lpDest[x*3+0] = 0xFF;
					}
					else
					{
						lpDest[x*3+2] = 0;
						lpDest[x*3+1] = 0;
						lpDest[x*3+0] = 0;
					}
				}
				lpDest += bm.bmWidth*3;
			}
			break;
		case 4:
			{
				TRACE("4 bit\n");
				DWORD	color1,color2;
				if(lpPalette)
				{
					for(y=0;y<bm.bmHeight;y++)
					{
						lpSrc  -= bm.bmWidthBytes;	
						for(x=0;x<bm.bmWidth/2;x++)
						{
							color1 = ((lpSrc[x]&0xF0)>>4);
							color2 = (lpSrc[x]&0x0F);
							if(color2>=16)TRACE("color error!\n");
							
							*lpDest++	= lpPalette[color1].peBlue;
							*lpDest++	= lpPalette[color1].peGreen;
							*lpDest++	= lpPalette[color1].peRed;
							
							*lpDest++	= lpPalette[color2].peBlue;
							*lpDest++	= lpPalette[color2].peGreen;
							*lpDest++	= lpPalette[color2].peRed;
						}
					}
				}
			}
			break;
		case 8:
			{
				TRACE("8 bit\n");
				if(lpPalette)
				{
					for(y=0;y<bm.bmHeight;y++)
					{
						lpSrc  -= bm.bmWidthBytes;	
						for(x=0;x<bm.bmWidth;x++)
						{
							lpDest[x*3+2]	= lpPalette[lpSrc[x]].peRed;
							lpDest[x*3+1]	= lpPalette[lpSrc[x]].peGreen;
							lpDest[x*3]		= lpPalette[lpSrc[x]].peBlue;
						}
						lpDest += bm.bmWidth*3;
					}
				}
			}
			break;
		case 16:
			{
				for(y=0;y<bm.bmHeight;y++)
				{
					lpSrc  -= bm.bmWidthBytes;
					for(x=0;x<bm.bmWidth;x++)
					{
						lpDest[x*3]		= ((lpSrc[x*2+1]<<1)&0xF8);
						lpDest[x*3+1]	= ((lpSrc[x*2+1]>>5)&0x04) | 
							((lpSrc[x*2+1]<<6)&0xc0) | 
							((lpSrc[x*2]>>2)&0x38);
						lpDest[x*3+2]	= (lpSrc[x*2]<<3)&0xF8;
					}
					lpDest += bm.bmWidth*3;
				}
			}
			break;
		case 24:
			{
				for(y=0;y<bm.bmHeight;y++)
				{
					lpSrc  -= bm.bmWidthBytes;	
					for(x=0;x<bm.bmWidth;x++)
					{
						lpDest[x*3]		= lpSrc[x*3+2];
						lpDest[x*3+1]	= lpSrc[x*3+1];
						lpDest[x*3+2]	= lpSrc[x*3];
					}
					lpDest += bm.bmWidth*3;
				}
			}
			break;
		}
	}
	catch(...)
	{
		if(lpTemp)delete[] lpTemp;
		return FALSE;
	}

	if(lpTemp)delete[] lpTemp;
	return TRUE;
}

DWORD CGLTexture::GetImageType(CFile* lpFile)
{
	TRACE("CGLTexture::GetImageType\n");
	lpFile->SeekToBegin();
	BYTE	szFlag[32];

	if(lpFile->Read(szFlag,sizeof(szFlag))!=sizeof(szFlag))
		return IMAGE_UNKOWN;
	
	if(szFlag[0]==''B''&&szFlag[1]==''M'')return IMAGE_BMP;
	if(szFlag[0]==''G''&&szFlag[1]==''I''&&szFlag[2]==''F'')return IMAGE_GIF;
	if(szFlag[7]==''J''&&szFlag[8]==''F''&&
	   szFlag[9]==''I''&&szFlag[10]==''F'')return IMAGE_JPG;
	
	return IMAGE_UNKOWN;
}

BOOL CGLTexture::ReadGifPalette(CFile* lpFile, PALETTEENTRY *lpPal)
{
	TRACE("CGLTexture::ReadGifPalette\n");
	if(!lpFile||!lpPal)return FALSE;

	BYTE	szHeader[13];
	BYTE	rgb[3];
	DWORD	bpp;

	lpFile->SeekToBegin();
	lpFile->Read(szHeader,sizeof(szHeader));
	
	bpp = (2 << (szHeader[10]&0x07));
	for(DWORD i=0;i<bpp;i++)
	{
		lpFile->Read(rgb,3);
		lpPal[i].peRed	= rgb[0];
		lpPal[i].peGreen = rgb[1];
		lpPal[i].peBlue	= rgb[2];
	}
	
	return TRUE;
}

BOOL CGLTexture::ReadBmpPalette(CFile *lpFile, PALETTEENTRY *lpPal)
{
	TRACE("CGLTexture::ReadBmpPalette\n");
	if(!lpFile||!lpPal)return FALSE;

	BYTE				rgb[3];
	BITMAPINFOHEADER	bm;

	lpFile->Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
	lpFile->Read(&bm,sizeof(bm));
	if(bm.biBitCount>8)return TRUE;

	lpFile->Read(lpPal,sizeof(PALETTEENTRY)*(1<<bm.biBitCount));

	TRACE("Bmp palette = %d\n",(1<<bm.biBitCount));
	return TRUE;
}

BOOL CGLTexture::ReadJpgPalette(CFile *lpFile, PALETTEENTRY *lpPal)
{
	TRACE("CGLTexture::ReadJpgPalette\n");
	return TRUE;
}

void CGLTexture::Draw(int x, int y)
{
	BindTexture();

	glPushMatrix();
	glTranslatef(x,y,0.0f);
	if(IsMask(TEXTURE_LIST))
	{
		glCallList(m_uListName);
	}
	else
	{
		
		glBegin(GL_QUADS);
		glTexCoord2d(0.0f,1.0f);glVertex2i(0,0);
		glTexCoord2d(1.0f,1.0f);glVertex2i(Width(),0); 
		glTexCoord2d(1.0f,0.0f);glVertex2i(Width(),Height());
		glTexCoord2d(0.0f,0.0f);glVertex2i(0,Height());
		glEnd();	
	}
	glPopMatrix();
}

void CGLTexture::BuildList()
{
	m_uListName = glGenLists(1);
	glNewList(m_uListName,GL_COMPILE);
	BindTexture();
	glBegin(GL_QUADS);
		glTexCoord2d(0.0f,1.0f);glVertex2i(0,0);
		glTexCoord2d(1.0f,1.0f);glVertex2i(Width(),0); 
		glTexCoord2d(1.0f,0.0f);glVertex2i(Width(),Height());
		glTexCoord2d(0.0f,0.0f);glVertex2i(0,Height());
	glEnd();	
	glEndList();
}
  

This topic is closed to new replies.

Advertisement