//========================================================
/**
* @file 3DSLoader.h
*
* 项目描述: 3DS文件载入
* 文件描述: 3DS文件载入类
* 适用平台: Windows98/2000/NT/XP
*
* 作者: WWBOSS
* 电子邮件: wwboss123@gmail.com
* 创建日期: 2006-12-06
* 修改日期: 2006-12-12
*
*/
//========================================================
#include "stdafx.h"
#include "3DSLoader.h"
#include "BMPLoader.h"
/** 构造函数 */
C3DSLoader::C3DSLoader()
{
m_CurrentChunk = new tChunk; /**< 为当前块分配空间 */
m_TempChunk = new tChunk; /**< 为临时块分配空间 */
m_3DModel.numOfObjects = 0;
m_3DModel.numOfMaterials = 0;
for (int i=0; i<MAX_TEXTURES; i++)
m_textures[i] = 0;
}
/** 释放内存并关闭文件 */
void C3DSLoader::CleanUp()
{
fclose(m_FilePointer); /**< 关闭文件 */
delete m_CurrentChunk; /**< 释放当前块 */
delete m_TempChunk; /**< 释放临时块 */
}
/** 析构函数 */
C3DSLoader::~C3DSLoader()
{
m_3DModel.numOfObjects = 0;
m_3DModel.numOfMaterials = 0;
m_3DModel.pObject.clear();
m_3DModel.pMaterials.clear();
glDeleteTextures(MAX_TEXTURES, m_textures);
}
/** 初时化3DS文件 */
void C3DSLoader::Init(char *filename)
{
/** 将3ds文件装入到模型结构体中 */
Import3DS(&m_3DModel, filename);
for(int i =0; i<m_3DModel.numOfMaterials;i++)
{
if(strlen(m_3DModel.pMaterials[i].strFile)>0) /**< 判断是否是一个文件名 */
LoadTexture(m_3DModel.pMaterials[i].strFile,m_textures, i);/**< 使用纹理文件名称来装入位图 */
/** 设置材质的纹理ID */
m_3DModel.pMaterials[i].texureId = i;
}
}
/** 显示3ds模型 */
void C3DSLoader::Draw()
{
glPushAttrib(GL_CURRENT_BIT); /**< 保存现有颜色属实性 */
glDisable(GL_TEXTURE_2D);
/**< 遍历模型中所有的对象 */
for(int i = 0; i < m_3DModel.numOfObjects; i++)
{
if(m_3DModel.pObject.size() <= 0)
break; /**< 如果对象的大小小于0,则退出 */
t3DObject *pObject = &m_3DModel.pObject[i];/**< 获得当前显示的对象 */
if(pObject->bHasTexture) /**< 判断该对象是否有纹理映射 */
{
glEnable(GL_TEXTURE_2D); /**< 打开纹理映射 */
glBindTexture(GL_TEXTURE_2D, m_textures[pObject->materialID]);
}
else
glDisable(GL_TEXTURE_2D); /**< 关闭纹理映射 */
glColor3ub(100, 100, 100);
/** 开始绘制 */
glBegin(GL_TRIANGLES);
for(int j = 0; j < pObject->numOfFaces; j++) /**< 遍历所有的面 */
{for(int tex = 0; tex < 3; tex++) /**< 遍历三角形的所有点 */
{
int index = pObject->pFaces[j].vertIndex[tex]; /**< 获得面对每个点的索引 */
glNormal3f(pObject->pNormals[index].x,pObject->pNormals[index].y,
pObject->pNormals[index].z); /**< 给出法向量 */
if(pObject->bHasTexture) /**< 如果对象具有纹理 */
{
if(pObject->pTexVerts) /**< 确定是否有UVW纹理坐标 */
glTexCoord2f(pObject->pTexVerts[index].x,pObject->pTexVerts[index].y);
}
else
{
if(m_3DModel.pMaterials.size() && pObject->materialID>= 0)
{
BYTE *pColor = m_3DModel.pMaterials[pObject->materialID].color;
glColor3ub(pColor[0],pColor[1],pColor[2]);
}
}
glVertex3f(pObject->pVerts[index].x,pObject->pVerts[index].y,pObject->pVerts[index].z);
}
}
glEnd(); /**< 绘制结束 */
}
glEnable(GL_TEXTURE_2D);
glPopAttrib(); /**< 恢复前一属性 */
}
/** 转载纹理 */
void C3DSLoader::LoadTexture(char* filename, GLuint textureArray[], GLuint textureID)
{
if(!filename)
return;
/** 载入位图 */
if(!m_BMPTexture.LoadBitmap(filename))
{
MessageBox(NULL,"载入位图失败!","错误",MB_OK);
exit(0);
}
glGenTextures(1,&m_textures[textureID]);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, m_textures[textureID]);
/** 控制滤波 */
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
/** 创建纹理 */
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, m_BMPTexture.imageWidth, m_BMPTexture.imageHeight, GL_RGB,
GL_UNSIGNED_BYTE, m_BMPTexture.image);
}
/** 载入3DS文件到模型结构中 */
bool C3DSLoader::Import3DS(t3DModel *pModel, char *strFileName)
{
char strMessage[255] = {0};
/** 打开一个3ds文件 */
m_FilePointer = fopen(strFileName, "rb");
/**< 检查文件指针 */
if(!m_FilePointer)
{
sprintf(strMessage, "找不到文件: %s!", strFileName);
MessageBox(NULL, strMessage, "Error", MB_OK);
return false;
}
/** 将文件的第一块读出并判断是否是3ds文件 */
ReadChunk(m_CurrentChunk);
/** 确保是3ds文件 */
if (m_CurrentChunk->ID != PRIMARY)
{
MessageBox(NULL, "不能加载主块!", "Error", MB_OK);
return false;
}
/** 递归读出对象数据 */
ReadNextChunk(pModel, m_CurrentChunk);
/** 计算顶点的法线 */
ComputeNormals(pModel);
/** 释放内存空间 */
CleanUp();
return true;
}
/** 读入一个字符串 */
int C3DSLoader::GetString(char *pBuffer)
{
int index = 0;
/** 读入一个字节的数据 */
fread(pBuffer, 1, 1, m_FilePointer);
/** 直到结束 */
while (*(pBuffer + index++) != 0)
{
/** 读入一个字符直到NULL */
fread(pBuffer + index, 1, 1, m_FilePointer);
}
/** 返回字符串的长度 */
return strlen(pBuffer) + 1;
}
/** 读入块的ID号和它的字节长度 */
void C3DSLoader::ReadChunk(tChunk *pChunk)
{
// 读入块的ID号 */
pChunk->bytesRead = fread(&pChunk->ID, 1, 2, m_FilePointer);
/** 读入块占用的长度 */
pChunk->bytesRead += fread(&pChunk->length, 1, 4, m_FilePointer);
}
/** 读出3ds文件的主要部分 */
void C3DSLoader::ReadNextChunk(t3DModel *pModel, tChunk *pPreChunk)
{
t3DObject newObject = {0}; /**< 用来添加到对象链表 */
tMatInfo newTexture = {0}; /**< 用来添加到材质链表 */
unsigned int version = 0; /**< 保存文件版本 */
int buffer[50000] = {0}; /**< 用来跳过不需要的数据 */
m_CurrentChunk = new tChunk; /**< 为新的块分配空间 */
/** 继续读入子块 */
while (pPreChunk->bytesRead < pPreChunk->length)
{
/** 读入下一个块 */
ReadChunk(m_CurrentChunk);
/** 判断块的ID号 */
switch (m_CurrentChunk->ID)
{
/** 文件版本号 */
case VERSION:
/** 读入文件的版本号 */
m_CurrentChunk->bytesRead += fread(&version, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
/** 如果文件版本号大于3,给出一个警告信息 */
if (version > 0x03)
MessageBox(NULL, " 该3DS文件版本大于3.0,可能不能正确读取", "警告", MB_OK);
break;
/** 网格版本信息 */
case OBJECTINFO:
/** 读入下一个块 */
ReadChunk(m_TempChunk);
/** 获得网格的版本号 */
m_TempChunk->bytesRead += fread(&version, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);
/** 增加读入的字节数 */
m_CurrentChunk->bytesRead += m_TempChunk->bytesRead;
/** 进入下一个块 */
ReadNextChunk(pModel, m_CurrentChunk);
break;
/** 材质信息 */
case MATERIAL:
/** 材质的数目递增 */
pModel->numOfMaterials++;
/** 在纹理链表中添加一个空白纹理结构 */
pModel->pMaterials.push_back(newTexture);
/** 进入材质装入函数 */
ReadNextMatChunk(pModel, m_CurrentChunk);
break;
/** 对象名称 */
case OBJECT:
/** 对象数递增 */
pModel->numOfObjects++;
/** 添加一个新的tObject节点到对象链表中 */
pModel->pObject.push_back(newObject);
/** 初始化对象和它的所有数据成员 */
memset(&(pModel->pObject[pModel->numOfObjects - 1]), 0, sizeof(t3DObject));
/** 获得并保存对象的名称,然后增加读入的字节数 */
m_CurrentChunk->bytesRead += GetString(pModel->pObject[pModel->numOfObjects - 1].strName);
/** 进入其余的对象信息的读入 */
ReadNextObjChunk(pModel, &(pModel->pObject[pModel->numOfObjects - 1]), m_CurrentChunk);
break;
/** 关键帧 */
case EDITKEYFRAME:
/
没有合适的资源?快使用搜索试试~ 我知道了~
OpenGL-select.rar_opengl select_opengl 选择
共71个文件
ani:15个
cpp:13个
obj:13个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 96 浏览量
2022-09-19
15:24:54
上传
评论
收藏 1.96MB RAR 举报
温馨提示
通过OpenGL中选择模式,实现在程序中选择物体。
资源推荐
资源详情
资源评论
收起资源包目录
OpenGL-select.rar (71个子文件)
选择2
OpenGL模板
Camera.cpp 6KB
TGALoader.cpp 3KB
GLFont.cpp 4KB
OpenGL.h 914B
Release
Tray.obj 7KB
StdAfx.obj 854B
Camera.obj 10KB
TGALoader.obj 5KB
选择1.exe.intermediate.manifest 145B
BuildLog.htm 10KB
input.exe.intermediate.manifest 145B
Particle.obj 5KB
main.obj 6KB
mt.dep 67B
Vector3.obj 11KB
DrawSence.obj 11KB
vc80.idb 323KB
GLFont.obj 5KB
3DSLoader.obj 95KB
OpenGL.obj 17KB
BMPLoader.obj 4KB
InputSystem.obj 11KB
TGALoader.h 1KB
3DSLoader.cpp 17KB
Tray.h 812B
BMPLoader.h 868B
Vector3.cpp 4KB
OpenGL模板.vcproj 5KB
Particle.cpp 869B
Particle.h 1KB
Tray.cpp 2KB
OpenGL.cpp 6KB
OpenGL模板.vcproj.JXH.吉训宏.user 1KB
3DSLoader.h 4KB
StdAfx.cpp 294B
InputSystem.h 2KB
main.cpp 4KB
DrawSence.h 1KB
StdAfx.h 2KB
Camera.h 2KB
DrawSence.cpp 6KB
InputSystem.cpp 7KB
BMPLoader.cpp 3KB
Vector3.h 4KB
GLFont.h 576B
OpenGL模板.ncb 8.97MB
选择1.exe 116KB
OpenGL模板.sln 901B
cursors
knife.ani 17KB
dig.ani 3KB
key.ani 4KB
hook.ani 8KB
lcross.cur 766B
split.ani 8KB
hammer.ani 4KB
drag.ani 16KB
hand1.ani 13KB
pick.ani 3KB
fire.ani 17KB
hand2.ani 4KB
flag.cur 2KB
hand.cur 3KB
normal.ani 3KB
attack.ani 29KB
talk.cur 3KB
axe.ani 4KB
repair.cur 3KB
gear.ani 4KB
OpenGL模板.suo 98KB
release
选择1.exe 116KB
input.exe 104KB
共 71 条
- 1
资源评论
我虽横行却不霸道
- 粉丝: 73
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功