⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texture.cpp

📁 3D赛车游戏源代码-用Visual Studio 2005
💻 CPP
字号:
#include "StdAfx.h"
#include "OGLutil.h"
#include "Texture.h"

//-------------------------------------------------------------------------------
// 载入图片并转换为纹理
//-------------------------------------------------------------------------------
bool BuildTexture(char *szPathName, GLuint &texid);

//-------------------------------------------------------------------------------
// 纹理载入管理器全局对象
//-------------------------------------------------------------------------------
CTextureManager g_TextureManager;

//-------------------------------------------------------------------------------
// 载入纹理
//-------------------------------------------------------------------------------
bool CTextureManager::LoadTexture(TextureReference *pTexRef)
{
	UINT handle = FindIsLoaded(pTexRef);

	if (handle != 0)
	{
		pTexRef->handle = handle;
		return true;
	}
	else
	{
		if (!BuildTexture(pTexRef->name, handle))
		{
			return false;
		}

		string name(pTexRef->name);
		m_textureFileMap.insert(FileMap::value_type(name, handle));
		pTexRef->handle = handle;
		return true;
	}
}

//-------------------------------------------------------------------------------
// 查找是否载入过这个纹理
//-------------------------------------------------------------------------------
UINT CTextureManager::FindIsLoaded(TextureReference *pTexRef)
{
	string name(strlwr(pTexRef->name));
	FileMap::iterator itr = m_textureFileMap.find(name);

	if (itr != m_textureFileMap.end())
	{
		return itr->second;
	}
	else
	{
		return 0;
	}

}



//-------------------------------------------------------------------------------
// 载入图片并转换为纹理
//-------------------------------------------------------------------------------
bool BuildTexture(char *szPathName, GLuint &texid)
{
	HDC			hdcTemp;								// DC用来保存位图
	HBITMAP		hbmpTemp;								// 保存临时位图
	IPicture	*pPicture;								// 定义IPicture Interface
	OLECHAR		wszPath[MAX_PATH+1];					// 图片的完全路径
	char		szPath[MAX_PATH+1];						// 图片的完全路径
	long		lWidth;									// 图像宽度
	long		lHeight;								// 图像高度
	long		lWidthPixels;							// 图像的宽带(以像素为单位)
	long		lHeightPixels;							// 图像的高带(以像素为单位)
	GLint		glMaxTexDim ;							// 保存纹理的最大尺寸

	if (strstr(szPathName, "http://"))									// 如果路径包含 http:// 则...
	{
		strcpy(szPath, szPathName);										// 把路径拷贝到 szPath
	}
	else																// 否则从文件导入图片
	{
		GetCurrentDirectory(MAX_PATH, szPath);							// 取得当前路径
		strcat(szPath, "\\");											// 添加字符"\"
		strcat(szPath, szPathName);										// 添加图片的相对路径
	}

	MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH);		// 把ASCII码转化为Unicode标准码
	HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture);

	if(FAILED(hr))														// 如果导入失败
	{
		// 图片载入失败出错信息
		MessageBox (HWND_DESKTOP, "图片导入失败!\n(TextureLoad Failed!)", "Error", MB_OK | MB_ICONEXCLAMATION);
		return false;													// 返回 FALSE
	}

	hdcTemp = CreateCompatibleDC(GetDC(0));								// 建立窗口设备描述表
	if(!hdcTemp)														// 建立失败?
	{
		pPicture->Release();											// 释放IPicture
		// 图片载入失败出错信息
		MessageBox (HWND_DESKTOP, "图片导入失败!\n(TextureLoad Failed!)", "Error", MB_OK | MB_ICONEXCLAMATION);
		return false;													// 返回 FALSE
	}

	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim);					// 取得支持的纹理最大尺寸
	
	pPicture->get_Width(&lWidth);										// 取得IPicture 宽度 (转换为Pixels格式)
	lWidthPixels	= MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540);
	pPicture->get_Height(&lHeight);										// 取得IPicture 高度 (转换为Pixels格式)
	lHeightPixels	= MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540);

	// 调整图片到最好的效果
	if (lWidthPixels <= glMaxTexDim)									// 图片宽度是否超过显卡最大支持尺寸
		lWidthPixels = 1 << (int)floor((log((double)lWidthPixels)/log(2.0f)) + 0.5f); 
	else																// 否则,将图片宽度设为显卡最大支持尺寸
		lWidthPixels = glMaxTexDim;
 
	if (lHeightPixels <= glMaxTexDim)									// 图片高度是否超过显卡最大支持尺寸
		lHeightPixels = 1 << (int)floor((log((double)lHeightPixels)/log(2.0f)) + 0.5f);
	else																// 否则,将图片高度设为显卡最大支持尺寸
		lHeightPixels = glMaxTexDim;

	// 建立一个临时位图
	BITMAPINFO	bi = {0};												// 位图的类型
	DWORD		*pBits = 0;												// 指向位图Bits的指针

	bi.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);				// 设置结构大小
	bi.bmiHeader.biBitCount		= 32;									// 32 位
	bi.bmiHeader.biWidth		= lWidthPixels;							// 宽度像素值
	bi.bmiHeader.biHeight		= lHeightPixels;						// 高度像素值
	bi.bmiHeader.biCompression	= BI_RGB;								// RGB 格式
	bi.bmiHeader.biPlanes		= 1;									// 一个位平面

	// 建立一个位图这样我们可以指定颜色和深度 并访问每位的值
	hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0);
	
	if(!hbmpTemp)														// 建立失败?
	{
		DeleteDC(hdcTemp);												// 删除设备描述表
		pPicture->Release();											// 释放IPicture
		// 图片载入失败出错信息
		MessageBox (HWND_DESKTOP, "图片导入失败!\n(TextureLoad Failed!)", "Error", MB_OK | MB_ICONEXCLAMATION);
		return false;													// 返回 FALSE
	}

	SelectObject(hdcTemp, hbmpTemp);									// 选择临时DC句柄和临时位图对象

	// 在位图上绘制IPicture
	pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0);

	// 将BGR转换为RGB 将ALPHA值设为255
	for(long i = 0; i < lWidthPixels * lHeightPixels; i++)				// 循环遍历所有的像素
	{
		BYTE* pPixel	= (BYTE*)(&pBits[i]);							// 获取当前像素
		BYTE  temp		= pPixel[0];									// 临时存储第一个颜色像素(蓝色)
		pPixel[0]		= pPixel[2];									// 将红色值存到第一位
		pPixel[2]		= temp;											// 将蓝色值存到第三位
		pPixel[3]		= 255;											// ALPHA值设为255
	}

	glGenTextures(1, &texid);											// 创建纹理

	// 使用来自位图数据生成 的典型纹理
	glBindTexture(GL_TEXTURE_2D, texid);								// 绑定纹理
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	// 线形滤波
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   // 线形滤波

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	//or GL_CLAMP
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);	//or GL_CLAMP

	// 生成纹理
	glTexImage2D(GL_TEXTURE_2D, 0, 3, lWidthPixels, lHeightPixels, 0, GL_RGBA, GL_UNSIGNED_BYTE, pBits);

	DeleteObject(hbmpTemp);												// 删除对象
	DeleteDC(hdcTemp);													// 删除设备描述表

	pPicture->Release();												// 释放 IPicture

	return true;														// 返回 TRUE
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -