📄 texture.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 + -