永发信息网

怎样把3DMAX建立的三维模型加入到Vc++工程中并进行驱动?

答案:1  悬赏:0  手机版
解决时间 2021-02-15 23:55
哪位会VC++???
最佳答案
// Load3DS.cpp: implementation of the CLoad3DS class.

#include "stdafx.h"
#include "Load3DS.h"static int gBuffer[50000] = {0};
CLoad3DS::CLoad3DS()
{
m_FilePointer = NULL;
}CLoad3DS::~CLoad3DS()
{
m_FilePointer = NULL;
}

// 打开一个3ds文件,读出其中的内容,并释放内存
bool CLoad3DS::Import3DS(CLoad3DS::t3DModel *pModel, char *strFileName)
{
char strMessage[255] = {0};
tChunk currentChunk = {0};
int i=0; // 打开一个3ds文件
m_FilePointer = fopen(strFileName, "rb");
// 确保所获得的文件指针合法
if(!m_FilePointer)
{
sprintf(strMessage, "找不到文件: %s!", strFileName);
MessageBox(NULL, strMessage, "Error", MB_OK);
return false;
} // 当文件打开之后,首先应该将文件最开始的数据块读出以判断是否是一个3ds文件
// 如果是3ds文件的话,第一个块ID应该是PRIMARY

// 将文件的第一块读出并判断是否是3ds文件
ReadChunk(&currentChunk); // 确保是3ds文件
if (currentChunk.ID != PRIMARY)
{
sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName);
MessageBox(NULL, strMessage, "Error", MB_OK);
return false;
}
// 现在开始读入数据,ProcessNextChunk()是一个递归函数

// 通过调用下面的递归函数,将对象读出
ProcessNextChunk(pModel, &currentChunk);
// 在读完整个3ds文件之后,计算顶点的法线
ComputeNormals(pModel); // 释放内存空间
CleanUp(); return true;
}
// 下面的函数释放所有的内存空间,并关闭文件
void CLoad3DS::CleanUp()
{
if (m_FilePointer)
{
fclose(m_FilePointer); // 关闭当前的文件指针
m_FilePointer = NULL; //文件指针为空
}
}
// 下面的函数读出3ds文件的主要部分(是个递归函数)
void CLoad3DS::ProcessNextChunk(CLoad3DS::t3DModel *pModel, tChunk *pPreviousChunk)
{
t3DObject newObject = {0}; // 用来添加到对象链表
tMaterialInfo newTexture = {0}; // 用来添加到材质链表 tChunk currentChunk = {0}; // 用来添加到当前块链表
tChunk tempChunk = {0}; // 用来添加到临时块链表 // 下面每读一个新块,都要判断一下块的ID,如果该块是需要的读入的,则继续进行
// 如果是不需要读入的块,则略过 // 继续读入子块,直到达到预定的长度
while (pPreviousChunk->bytesRead < pPreviousChunk->length)
{

ReadChunk(&currentChunk); // 读入下一个块 // 判断块的ID号
switch (currentChunk.ID)
{
case VERSION: // 文件版本号
// 在该块中有一个无符号短整型数保存了文件的版本

// 读入文件的版本号,并将字节数添加到bytesRead变量中
currentChunk.bytesRead += fread(gBuffer, 1, currentChunk.length - currentChunk.bytesRead, m_FilePointer);

// 如果文件版本号大于3,给出一个警告信息
if ((currentChunk.length - currentChunk.bytesRead == 4) && (gBuffer[0] > 0x03))
{
MessageBox(NULL, "3DS文件版本号大于3,有可能读取不正确!", "警告", MB_OK);
}
break; case OBJECTINFO: // 网格版本信息

ReadChunk(&tempChunk);// 读入下一个块

// 获得网格的版本号
tempChunk.bytesRead += fread(gBuffer, 1, tempChunk.length - tempChunk.bytesRead, m_FilePointer); // 增加读入的字节数
currentChunk.bytesRead += tempChunk.bytesRead; // 进入下一个块
ProcessNextChunk(pModel, &currentChunk);
break;
case MATERIAL: // 材质信息

// 材质的数目递增
pModel->numOfMaterials++;

// 在纹理链表中添加一个空白纹理结构
pModel->vctMaterials.push_back(newTexture);

// 进入材质装入函数
ProcessNextMaterialChunk(pModel, &currentChunk);

break; case OBJECT: // 对象的名称
// 该块是对象信息块的头部,保存了对象了名称

pModel->numOfObjects++;// 对象数递增

// 添加一个新的tObject节点到对象链表中
pModel->vctObjects.push_back(newObject);

// 初始化对象和它的所有数据成员
memset(&(pModel->vctObjects[pModel->numOfObjects - 1]), 0, sizeof(t3DObject)); // 获得并保存对象的名称,然后增加读入的字节数
currentChunk.bytesRead += GetString(pModel->vctObjects[pModel->numOfObjects - 1].strName);

// 进入其余的对象信息的读入
ProcessNextObjectChunk(pModel, &(pModel->vctObjects[pModel->numOfObjects - 1]), &currentChunk);
break; case EDITKEYFRAME:
// 跳过关键帧块的读入,增加需要读入的字节数
currentChunk.bytesRead += fread(gBuffer, 1, currentChunk.length - currentChunk.bytesRead, m_FilePointer);
break; default:
// 跳过所有忽略的块的内容的读入,增加需要读入的字节数
currentChunk.bytesRead += fread(gBuffer, 1, currentChunk.length - currentChunk.bytesRead, m_FilePointer);
break;
}

// 增加从最后块读入的字节数
pPreviousChunk->bytesRead += currentChunk.bytesRead;
}}// 下面的函数处理所有的文件中对象的信息
void CLoad3DS::ProcessNextObjectChunk(CLoad3DS::t3DModel *pModel, CLoad3DS::t3DObject *pObject, CLoad3DS::tChunk *pPreviousChunk)
{

tChunk currentChunk = {0};// 用来添加到当前块链表
vector<tMatREF*> vctMatIDS;

// 继续读入块的内容直至本子块结束
while (pPreviousChunk->bytesRead < pPreviousChunk->length)
{
// 读入下一个块
ReadChunk(&currentChunk); // 区别读入是哪种块
switch (currentChunk.ID)
{
case OBJECT_MESH: // 正读入的是一个新块

// 使用递归函数调用,处理该新块
ProcessNextObjectChunk(pModel, pObject, &currentChunk);
break; case OBJECT_VERTICES: // 读入是对象顶点
ReadVertices(pObject, &currentChunk);// 读对象顶点
break; case OBJECT_FACES: // 读入的是对象的面
ReadVertexIndices(pObject, &currentChunk);// 读入对象的面
break; case OBJECT_MATERIAL: // 读入的是对象的材质名称
// 该块保存了对象材质的名称,可能是一个颜色,也可能是一个纹理映射。同时在该块中也保存了
// 纹理对象所赋予的面

// 下面读入对象的材质名称
ReadObjectMaterial(pModel, pObject, &currentChunk,&vctMatIDS);
break; case OBJECT_UV: // 读入对象的UV纹理坐标 // 读入对象的UV纹理坐标
ReadUVCoordinates(pObject, &currentChunk);
break;// case 0x4111:
//
// currentChunk.bytesRead += fread(gBuffer, 1, currentChunk.length - currentChunk.bytesRead, m_FilePointer);
// break;
default: // 略过不需要读入的块

currentChunk.bytesRead += fread(gBuffer, 1, currentChunk.length - currentChunk.bytesRead, m_FilePointer);
break;
} // 添加从最后块中读入的字节数到前面的读入的字节中
pPreviousChunk->bytesRead += currentChunk.bytesRead; }
if(pPreviousChunk->ID!=OBJECT_MESH) return;

int size=vctMatIDS.size();
if(size)
{
pObject->numOfMaterials=size; //对象的材质数量
pObject->pMaterialREFS=new tMatREF[size];
for(int i=0;i<size;i++)
{
pObject->pMaterialREFS[i]=*(vctMatIDS[i]);
}
vctMatIDS.clear();
}
}
// 下面的函数处理所有的材质信息
void CLoad3DS::ProcessNextMaterialChunk(CLoad3DS::t3DModel *pModel, CLoad3DS::tChunk *pPreviousChunk)
{

tChunk currentChunk = {0};// 用来添加到当前块链表 // 继续读入这些块,直到该子块结束
while (pPreviousChunk->bytesRead < pPreviousChunk->length)
{
// 读入下一块
ReadChunk(&currentChunk); // 判断读入的是什么块
switch (currentChunk.ID)
{
case MATNAME: // 材质的名称

// 读入材质的名称
currentChunk.bytesRead += fread(pModel->vctMaterials[pModel->numOfMaterials - 1].strName, 1, currentChunk.length - currentChunk.bytesRead, m_FilePointer);
break;

case MAT_AMBIENT: //材质的环境光
ReadColorChunk(&(pModel->vctMaterials[pModel->numOfMaterials - 1]), &currentChunk,MAT_AMBIENT);
break;
case MAT_SPECULAR: //材质的镜面光
ReadColorChunk(&(pModel->vctMaterials[pModel->numOfMaterials - 1]), &currentChunk,MAT_SPECULAR);
break;
case MAT_EMISSIVE: //材质的出射光
ReadColorChunk(&(pModel->vctMaterials[pModel->numOfMaterials - 1]), &currentChunk,MAT_EMISSIVE);
break;
case MATDIFFUSE: //材质的漫反射光
ReadColorChunk(&(pModel->vctMaterials[pModel->numOfMaterials - 1]), &currentChunk,MATDIFFUSE);
break;

case MATMAP: // 纹理信息的头部

// 进入下一个材质块信息
ProcessNextMaterialChunk(pModel, &currentChunk);
break; case MATMAPFILE: // 材质文件的名称 // 读入材质的文件名称
currentChunk.bytesRead += fread(pModel->vctMaterials[pModel->numOfMaterials - 1].strFile, 1, currentChunk.length - currentChunk.bytesRead, m_FilePointer);
break;

default: // 掠过不需要读入的块
currentChunk.bytesRead += fread(gBuffer, 1, currentChunk.length - currentChunk.bytesRead, m_FilePointer);
break;
} // 添加从最后块中读入的字节数
pPreviousChunk->bytesRead += currentChunk.bytesRead;
}
}// 下面函数读入块的ID号和它的字节长度
void CLoad3DS::ReadChunk(CLoad3DS::tChunk *pChunk)
{
// 读入块的ID号,占用了2个字节。块的ID号象OBJECT或MATERIAL一样,说明了在块中所包含的内容
pChunk->bytesRead = fread(&pChunk->ID, 1, 2, m_FilePointer); // 然后读入块占用的长度,包含了四个字节
pChunk->bytesRead += fread(&pChunk->length, 1, 4, m_FilePointer);
}
// 下面的函数读入一个字符串
int CLoad3DS::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;
}
// 下面的函数读入RGB颜色
void CLoad3DS::ReadColorChunk(CLoad3DS::tMaterialInfo *pMaterial, CLoad3DS::tChunk *pChunk,USHORT typeFlag)
{
tChunk tempChunk = {0};
BYTE btmp[3]; // 读入颜色块信息
ReadChunk(&tempChunk);
switch(typeFlag)
{
case MAT_AMBIENT://材质的环境光颜色
tempChunk.bytesRead += fread(btmp, 1, tempChunk.length - tempChunk.bytesRead, m_FilePointer);
Bytes2Floats(btmp,pMaterial->ambient,3,1.0f/256.0f);
pMaterial->ambient[3]=1.0f;
break;
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
笔记本电脑系统8.1的进不了主系统,只进到欢迎
洛龙区洛阳东北手工饺子地址在什么地方,想今
韩国迷你美珠珍珠冰激凌这个地址在什么地方,
电机额定功率不大于20kW的消防水栗机组外轮廓
双环体育在哪里啊,我有事要去这个地方
Born and raised in central Ohio,
英语中的‘过去式’‘过去分式’‘现在进行式
谷城县襄樊食尚地址是什么,有没有知道的
QQ飞车元宵灯谜会怎么获得
双方喝醉酒打架,另一个受了轻微伤,另一个要负
柳芭之家在什么地方啊,我要过去处理事情
越乡龙井专卖店鲁NO.17地址有知道的么?有点
联通办理的业务说是次月生效,请问是次月哪天
小儿身材矮小怎么办;都有哪些
香辣鸡公煲地址在什么地方,想过去办事
推荐资讯
求大神翻译hit and run 的歌词(´・_・`)
查驾前几年驶证扣分记录怎么查询
新野县南阳农家饺子馆地址在哪里啊
如果不买社保,我还能怎么取得养老保障?
庞统冠以什么之称,与他有关的故事是什么
当地时间2009年9月11日,美国总统宣布对从中
车骑王子汽车漆面快修连锁聊城店地址在什么地
杨铭宇黄焖鸡米饭铁塔寺路店在什么地方啊,我
创新Sound Blaster Live! 5.1 的声卡...和创
我们村有一颗皂角树,预计有上百年的历史,请
how long have you been studing english?为
取名邹浩泽名字怎么样
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?