加载.x文件
.x 文件是由3dsmax导出的,专门被direct3D使用。
一个.x文件包含:n 个 D3DXMATERIAL 类型的数据,每个D3DXMATERIAL包含一个D3DMATERIAL9 和 一个texture文件的路径。也就是说一个.x文件包含n个material 和 n 个texture文件路径。
加载过程如下:
LPD3DXBUFFER pMeshMaterialsBuffer = NULL;
// 先将.x文件的数据存到buffer中,并得到material的个数,即D3DXMATERIAL的个数
if ( FAILED(D3DXLoadMeshFromX(L"rect.x",D3DXMESH_SYSTEMMEM,pd3dDevice,
NULL,&pMeshMaterialsBuffer,NULL,&g_numMaterials,&g_pRectMesh)) )
{
if ( FAILED(D3DXLoadMeshFromX(L"..\\rect.x",D3DXMESH_SYSTEMMEM,pd3dDevice,
NULL,&pMeshMaterialsBuffer,NULL,&g_numMaterials,&g_pRectMesh) ))
{
MessageBoxW(NULL,L"Can't find this .x file",L"rect.exe",MB_OK);
return E_FAIL;
}
}
// 得到buffer的指针
D3DXMATERIAL *pMaterial = (D3DXMATERIAL*)pMeshMaterialsBuffer->GetBufferPointer();
// 为读取material 和texture数据分配空间
g_pRectMeshMaterials = new D3DMATERIAL9[g_numMaterials];
if ( g_pRectMeshMaterials == NULL )
return E_OUTOFMEMORY;
g_pRectMeshTextures = new LPDIRECT3DTEXTURE9[g_numMaterials];
if ( g_pRectMeshTextures == NULL )
return E_OUTOFMEMORY;
for ( DWORD i = 0;i < g_numMaterials ; ++i )
{
// 得到第i个material
g_pRectMeshMaterials[i] = pMaterial[i].MatD3D;
g_pRectMeshMaterials[i].Ambient = g_pRectMeshMaterials[i].Diffuse;
g_pRectMeshTextures[i] = NULL;
// 通过texture文件的路径,得到第i个material 的texture
if ( pMaterial[i].pTextureFilename != NULL &&
lstrlen((LPCWSTR)pMaterial[i].pTextureFilename) > 0 )
{
LPWSTR path = (LPWSTR)_alloca(len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP,0,pMaterial[i].pTextureFileName,
-1,path,len*sizeof(WCHAR));
if ( FAILED(D3DXCreateTextureFromFile(pd3dDevice,
path,&g_pRectMeshTextures[i])) )
{
MessageBoxW(NULL, L"Could not find texture map", L"rect.exe", MB_OK);
}
}
}
pMeshMaterialsBuffer->Release();
// 先将.x文件的数据存到buffer中,并得到material的个数,即D3DXMATERIAL的个数
if ( FAILED(D3DXLoadMeshFromX(L"rect.x",D3DXMESH_SYSTEMMEM,pd3dDevice,
NULL,&pMeshMaterialsBuffer,NULL,&g_numMaterials,&g_pRectMesh)) )
{
if ( FAILED(D3DXLoadMeshFromX(L"..\\rect.x",D3DXMESH_SYSTEMMEM,pd3dDevice,
NULL,&pMeshMaterialsBuffer,NULL,&g_numMaterials,&g_pRectMesh) ))
{
MessageBoxW(NULL,L"Can't find this .x file",L"rect.exe",MB_OK);
return E_FAIL;
}
}
// 得到buffer的指针
D3DXMATERIAL *pMaterial = (D3DXMATERIAL*)pMeshMaterialsBuffer->GetBufferPointer();
// 为读取material 和texture数据分配空间
g_pRectMeshMaterials = new D3DMATERIAL9[g_numMaterials];
if ( g_pRectMeshMaterials == NULL )
return E_OUTOFMEMORY;
g_pRectMeshTextures = new LPDIRECT3DTEXTURE9[g_numMaterials];
if ( g_pRectMeshTextures == NULL )
return E_OUTOFMEMORY;
for ( DWORD i = 0;i < g_numMaterials ; ++i )
{
// 得到第i个material
g_pRectMeshMaterials[i] = pMaterial[i].MatD3D;
g_pRectMeshMaterials[i].Ambient = g_pRectMeshMaterials[i].Diffuse;
g_pRectMeshTextures[i] = NULL;
// 通过texture文件的路径,得到第i个material 的texture
if ( pMaterial[i].pTextureFilename != NULL &&
lstrlen((LPCWSTR)pMaterial[i].pTextureFilename) > 0 )
{
LPWSTR path = (LPWSTR)_alloca(len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP,0,pMaterial[i].pTextureFileName,
-1,path,len*sizeof(WCHAR));
if ( FAILED(D3DXCreateTextureFromFile(pd3dDevice,
path,&g_pRectMeshTextures[i])) )
{
MessageBoxW(NULL, L"Could not find texture map", L"rect.exe", MB_OK);
}
}
}
pMeshMaterialsBuffer->Release();
这里有一个问题折腾了我半天:由于使用DXUT,程序必须使用unicode ,D3dxCreateTextureFromFile 转换为D3DXCreateTextureFromFileW,第2个参数的类型由LPSTR变为LPWSTR。我需要将pTextureFileName的类型由ansi转为unicode 。一上来我用强转的方法:(LPWSTR)pMaterial[i].pTextureFileName,无法得到正确的路径,接着我想到用atl的A2W,但一直没有正确导入a2w的相关文件,总报错。没办法,看看A2W是咋写的。原来A2W先从栈上分配一段内存作为buffer,然后调用MultiByteToWideChar,用buffer得到unicode版的字符串。好了,照猫画猫,一切ok!
posted @ 2007-01-08 11:17 永远自由的心 阅读(242) | 评论 (0) | 编辑
2007年1月4日 #
在c++程序中调用python脚本函数
在c++中调用python脚本函数的代码框架如下: 1 Py_Initialize(); //初始化 python interpreter
2
3 PyObject *pName = PyString_FromString("test1"); // python脚本文件名
5 PyObject *pModule = PyImport_Import(pName); // import 脚本,返回pModule
// pModule指向这个脚本对象
7 if ( !pModule )
8{
9 cout<<"Can't find the file!"<<endl;
10 return 0;
11 }
12
14 cout<<"Get the function in .py"<<endl;
15 PyObject *pDict = PyModule_GetDict(pModule); // 通过pModule得到dictionary
// 的指针pDict
16 PyObject *pFunc = PyDict_GetItemString(pDict,"Add"); // 通过pDict得到你所需的
// function,此处"Add"为test1.py
// 的一个funciton object
17 PyObject *pParam = PyTuple_New(1); // 填写function所需要的参数
18 PyObject *pCurParam = PyInt_FromLong(10);
19 PyTuple_SET_ITEM(pParam,0,pCurParam);
20 PyObject *pAdded = PyObject_CallObject(pFunc,pParam);// 调用此function,并得到
// 返回值
21 int max = PyInt_AsLong(pAdded); // 将返回值转换为c++的数据类型
22 cout<<"after added ,the number is "<<max<<endl;
23
24 Py_XDECREF(pAdded); // 引用计数减一
25 Py_XDECREF(pCurParam);
26 Py_XDECREF(pParam);
27// Py_XDECREF(pFunc);
28// Py_XDECREF(pDict);
29 Py_XDECREF(pModule);
30 Py_XDECREF(pName);
31
32 Py_Finalize(); // 关闭 python interpreter
这里有几个问题,目前还没有解决:2
3 PyObject *pName = PyString_FromString("test1"); // python脚本文件名
5 PyObject *pModule = PyImport_Import(pName); // import 脚本,返回pModule
// pModule指向这个脚本对象
7 if ( !pModule )
8{
9 cout<<"Can't find the file!"<<endl;
10 return 0;
11 }
12
14 cout<<"Get the function in .py"<<endl;
15 PyObject *pDict = PyModule_GetDict(pModule); // 通过pModule得到dictionary
// 的指针pDict
16 PyObject *pFunc = PyDict_GetItemString(pDict,"Add"); // 通过pDict得到你所需的
// function,此处"Add"为test1.py
// 的一个funciton object
17 PyObject *pParam = PyTuple_New(1); // 填写function所需要的参数
18 PyObject *pCurParam = PyInt_FromLong(10);
19 PyTuple_SET_ITEM(pParam,0,pCurParam);
20 PyObject *pAdded = PyObject_CallObject(pFunc,pParam);// 调用此function,并得到
// 返回值
21 int max = PyInt_AsLong(pAdded); // 将返回值转换为c++的数据类型
22 cout<<"after added ,the number is "<<max<<endl;
23
24 Py_XDECREF(pAdded); // 引用计数减一
25 Py_XDECREF(pCurParam);
26 Py_XDECREF(pParam);
27// Py_XDECREF(pFunc);
28// Py_XDECREF(pDict);
29 Py_XDECREF(pModule);
30 Py_XDECREF(pName);
31
32 Py_Finalize(); // 关闭 python interpreter
1). 我使用的是python25_d.dll,无法找到用activepython编辑的*.py文件中的function object 。我的activepython版本为2.4。
2). 程序末尾不能将 function object 和 dictionary object 的引用计数减一,如果执行此操作,程序会crash。
大部分转载 小部分自写