前回質問させていただきました時はご回答くださりありがとうございました。
今回の質問なのですが、
現在DirectXでpmdファイルを読み込みモデルを表示させようとしているのですが、コンパイルした際に
下記2つのエラー文の原因がわからず対処に困っております。
1 error C2065: 'string' : 定義されていない識別子です。
2 error C2039: 'InitPmd' : 'Mesh' のメンバではありません。
記述1(メッシュ関連のヘッダクラス)
#ifndef MESH
#define MESH
#include <d3dx9.h>
#include <mmsystem.h>
#include <Dsound.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <list>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
/// メッシュの頂点データ
struct Vertex {
D3DXVECTOR3 position; // 頂点位置
D3DXVECTOR3 normal; // 法線ベクトル
D3DXVECTOR2 texture; // テクスチャ座標
};
/// メッシュのポリゴンデータ
struct Face {
unsigned short indices[3]; // 3頂点のインデックス
unsigned long material_number; // 材料番号
};
// メッシュデータ一時保存用構造体。独自形式データは一度この構造体に格納し、Mesh::SetMesh()でMesh::pMeshにセットする。
struct MeshData {
std::vector<Vertex> vertices;
std::vector<Face> faces;
std::vector<D3DMATERIAL9> material;
std::vector<string> texture_filename;
};
/// メッシュのベース
class Mesh
{
protected:
LPDIRECT3DDEVICE9 pDevice; // Direct3Dデバイスオブジェクト
LPD3DXMESH pMesh; // メッシュ
D3DMATERIAL9* pMeshMaterials; // マテリアル配列
LPDIRECT3DTEXTURE9* pMeshTextures; // テクスチャ配列
DWORD dwNumMaterials; // マテリアル・テクスチャ配列の大きさ
void AddNormalVector(MeshData& meshData);// MeshDataに法線ベクトルを追加
void SetMesh(MeshData meshData); // MeshDataをpMeshにセット
public:
Mesh();
virtual ~Mesh();
virtual void InitMesh(LPDIRECT3DDEVICE9 pDevice);
virtual void Draw(D3DXVECTOR3 position, D3DXMATRIX rotation);
virtual LPD3DXMESH GetMesh();
virtual int GetNumMaterial();
};
/// Xファイルから読込んだメッシュ
class XFileMesh : public Mesh
{
public:
XFileMesh();
void InitXFile(LPCTSTR filename, LPDIRECT3DDEVICE9 pDevice);
};
/// PMDファイルから読込んだメッシュ
class PmdMesh : public Mesh
{
/// PMD構造体定義
#pragma pack(push,1) //アラインメント制御をオフ
struct PmdHeader
{
unsigned char magic[3];
float version;
unsigned char model_name[20];
unsigned char comment[256];
} pmdHeader;
struct PmdVertex
{
float pos[3];
float normal_vec[3];
float uv[2];
unsigned short bone_num[2];
unsigned char bone_weight;
unsigned char edge_flag;
};
struct PmdMaterial
{
float diffuse_color[3];
float alpha;
float specularity;
float specular_color[3];
float mirror_color[3];
unsigned char toon_index;
unsigned char edge_flag;
unsigned long face_vert_count; // この材料の面頂点数 → 材料番号iのポリゴン番号: pmdMaterial[i - 1].face_vert_count/3 ~ pmdMaterial[i].face_vert_count/3 - 1
char texture_file_name[20];
};
#pragma pack(pop)
void CopyMaterial(D3DMATERIAL9& material, PmdMaterial& pmdMaterial); // PmdMaterialからD3DMATERIAL9にデータをコピー
public:
PmdMesh();
void InitPmd(LPCTSTR filename, LPDIRECT3DDEVICE9 pDevice);
};
#endif
#include "Mesh.h"
#define SAFE_RELEASE(p){if(p) {(p)->Release(); (p) = NULL;}}
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
///// Meshクラス /////
Mesh::Mesh()
{}
Mesh::~Mesh()
{
SAFE_RELEASE(pMesh);
if (pMeshTextures) for (DWORD i = 0; i < dwNumMaterials; ++i) SAFE_RELEASE(pMeshTextures[i]);
SAFE_DELETE_ARRAY(pMeshTextures);
SAFE_DELETE_ARRAY(pMeshMaterials);
}
//------------------------------------------------------------------------------------------------------
void Mesh::InitMesh(LPDIRECT3DDEVICE9 pDev)
{
pDevice = pDev;
pMesh = 0;
pMeshTextures = 0;
pMeshMaterials = 0;
}
//------------------------------------------------------------------------------------------------------
void Mesh::AddNormalVector(MeshData& meshData)
{
for (unsigned int i = 0; i < meshData.vertices.size(); ++i) meshData.vertices[i].normal = D3DXVECTOR3(0, 0, 0);
for (unsigned int i = 0; i < meshData.faces.size(); ++i) {
D3DXVECTOR3 p[3];
for (unsigned int j = 0; j < 3; ++j) p[j] = meshData.vertices[meshData.faces[i].indices[j]].position;
D3DXPLANE plane;
D3DXPlaneFromPoints(&plane, &p[0], &p[1], &p[2]); // 抜き取りで確認する限り、planeは規格化されているっぽい
for (unsigned int j = 0; j < 3; ++j) meshData.vertices[meshData.faces[i].indices[j]].normal += D3DXVECTOR3(plane.a, plane.b, plane.c);
float l = D3DXVec3Length(&D3DXVECTOR3(plane.a, plane.b, plane.c));
}
for (unsigned int i = 0; i < meshData.vertices.size(); ++i) D3DXVec3Normalize(&meshData.vertices[i].normal, &meshData.vertices[i].normal);
}
//------------------------------------------------------------------------------------------------------
void Mesh::SetMesh(MeshData meshData)
{
D3DXCreateMeshFVF(meshData.faces.size(), meshData.vertices.size(), D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1, pDevice, &pMesh);
Vertex* vertexBuffer;
pMesh->LockVertexBuffer(0, (void**)&vertexBuffer);
for (unsigned int ii = 0; ii < meshData.vertices.size(); ii++)
{
vertexBuffer[ii].position = meshData.vertices[ii].position;
vertexBuffer[ii].normal = meshData.vertices[ii].normal;
vertexBuffer[ii].texture = meshData.vertices[ii].texture;
}
pMesh->UnlockVertexBuffer();
unsigned short* indexBuffer;
pMesh->LockIndexBuffer(0, (void**)&indexBuffer);
for (unsigned int ii = 0; ii < meshData.faces.size(); ii++)
{
for (unsigned int jj = 0; jj < 3; jj++)
{
indexBuffer[3*ii + jj] = meshData.faces[ii].indices[jj];
}
}
pMesh->UnlockIndexBuffer();
unsigned long* attributeBuffer;
pMesh->LockAttributeBuffer(0, &attributeBuffer);
for (unsigned int ii = 0; ii < meshData.faces.size(); ii++)
{
attributeBuffer[ii] = meshData.faces[ii].material_number;
}
pMesh->UnlockAttributeBuffer();
dwNumMaterials = meshData.material.size();
pMeshMaterials = new D3DMATERIAL9[dwNumMaterials];
pMeshTextures = new LPDIRECT3DTEXTURE9[dwNumMaterials];
for (DWORD ii = 0; ii < dwNumMaterials; ii++)
{
pMeshTextures[ii] = 0;
}
for (DWORD ii = 0; ii < dwNumMaterials; ii++)
{
pMeshMaterials[ii] = meshData.material[ii];
char tex_filename[256] = {0}; // UNICODE未対応テクスチャファイル名
TCHAR textureFilename[256] = {0}; // UNICODE/マルチバイト両対応テクスチャファイル名
if (strcpy_s(tex_filename, meshData.texture_filename[ii].c_str()))
{
throw TEXT("テクスチャの読み込みに失敗しました");
}
#ifdef UNICODE
if (strlen(tex_filename) > 0) MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, tex_filename, strlen(tex_filename), textureFilename, (sizeof textureFilename)/2);
#else
if (strlen(tex_filename) > 0) strcpy_s(textureFilename, tex_filename);
#endif
if (lstrlen(textureFilename) > 0) // UNICODE/マルチバイト両対応テクスチャファイル名からテクスチャを作成
if(FAILED(D3DXCreateTextureFromFileEx(pDevice, textureFilename, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, 0, 0, &pMeshTextures[ii]))) throw TEXT("テクスチャの読み込みに失敗しました");
}
}
//------------------------------------------------------------------------------------------------------
void Mesh::Draw(D3DXVECTOR3 position, D3DXMATRIX rotation)
{
D3DXMATRIX matWorld, matTrans;
D3DXMatrixTranslation(&matTrans, position.x, position.y, position.z);
matWorld = rotation*matTrans;
pDevice->SetTransform(D3DTS_WORLD, &matWorld);
pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); // ポリゴンのDiffuse色の透明度をテクスチャに反映させる
pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
for (DWORD ii = 0; ii < dwNumMaterials; ii++)
{
pDevice->SetMaterial(&pMeshMaterials[ii]);
pDevice->SetTexture(0, pMeshTextures[ii]);
pMesh->DrawSubset(ii);
}
}
//------------------------------------------------------------------------------------------------------
LPD3DXMESH Mesh::GetMesh()
{
return pMesh;
}
//------------------------------------------------------------------------------------------------------
int Mesh::GetNumMaterial()
{
return dwNumMaterials;
}
//------------------------------------------------------------------------------------------------------
XFileMesh::XFileMesh() : Mesh()
{}
//------------------------------------------------------------------------------------------------------
XFileMesh::InitXFile(LPCTSTR filename, LPDIRECT3DDEVICE9 pDevice)
{
LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
if (FAILED( D3DXLoadMeshFromX(filename, D3DXMESH_SYSTEMMEM, pDevice, NULL, &pD3DXMtrlBuffer, NULL, &dwNumMaterials, &pMesh))) throw TEXT("Xファイルの読み込みに失敗しました");
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
pMeshMaterials = new D3DMATERIAL9[dwNumMaterials];
pMeshTextures = new LPDIRECT3DTEXTURE9[dwNumMaterials];
for (DWORD i = 0; i < dwNumMaterials; ++i) {
pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
pMeshTextures[i] = 0;
TCHAR textureFilename[256] = {0};
#ifdef UNICODE
if (d3dxMaterials[i].pTextureFilename) MultiByteToWideChar(CP_OEMCP,MB_PRECOMPOSED, d3dxMaterials[i].pTextureFilename, strlen(d3dxMaterials[i].pTextureFilename), textureFilename, (sizeof textureFilename)/2);
#else
if (d3dxMaterials[i].pTextureFilename) strcpy_s(textureFilename, d3dxMaterials[i].pTextureFilename);
#endif
if (textureFilename != NULL && lstrlen(textureFilename) > 0)
if(FAILED(D3DXCreateTextureFromFileEx(pDevice, textureFilename, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, 0, 0, &pMeshTextures[i]))) throw TEXT("テクスチャの読み込みに失敗しました");
}
pD3DXMtrlBuffer->Release();
}
/// PmdMeshクラス
PmdMesh::PmdMesh() : Mesh()
{}
void PmdMesh::InitPmd(LPCTSTR filename, LPDIRECT3DDEVICE9 pDev)
{
// PMDファイルからPMDデータを抽出
ifstream ifs(filename, ios::binary);
if (ifs.fail()) throw TEXT("ファイルがありません");
ifs.read((char*)&pmdHeader, sizeof(pmdHeader));
unsigned long numPmdVertex;
ifs.read((char*)&numPmdVertex, sizeof(numPmdVertex));
PmdVertex* pmdVertices = new PmdVertex[numPmdVertex];
ifs.read((char*)pmdVertices, sizeof(PmdVertex)*numPmdVertex);
unsigned long numPmdFace;
ifs.read((char*)&numPmdFace, sizeof(numPmdFace));
unsigned short *pmdFaces = new unsigned short[numPmdFace];
ifs.read((char*)pmdFaces, sizeof(unsigned short)*numPmdFace);
unsigned long numPmdMaterial;
ifs.read((char*)&numPmdMaterial, sizeof(numPmdMaterial));
PmdMaterial* pmdMaterial = new PmdMaterial[numPmdMaterial];
ifs.read((char*)pmdMaterial, sizeof(PmdMaterial)*numPmdMaterial);
// PMDデータからMeshDataにコピー
MeshData meshData;
for (unsigned int i = 0; i < numPmdVertex; ++i) {
Vertex v;
v.position = D3DXVECTOR3(pmdVertices[i].pos[0], pmdVertices[i].pos[1], pmdVertices[i].pos[2]);
v.position *= 0.1f; // 倍率
v.normal= D3DXVECTOR3(pmdVertices[i].normal_vec[0], pmdVertices[i].normal_vec[1], pmdVertices[i].normal_vec[2]);
v.texture = D3DXVECTOR2(pmdVertices[i].uv[0], pmdVertices[i].uv[1]);
meshData.vertices.push_back(v);
}
delete pmdVertices;
Face f;
for (unsigned int i = 0; i < numPmdFace; ++i) {
f.indices[i%3] = pmdFaces[i];
if (i%3 == 2) meshData.faces.push_back(f);
}
delete pmdFaces;
D3DMATERIAL9 material = {0};
unsigned int j = 0, material_end = 0;
for (unsigned int i = 0; i < numPmdMaterial; ++i) {
CopyMaterial(material, pmdMaterial[i]);
meshData.material.push_back(material);
char tex[21] = {0}; // ファイル名が20byteのときのために最後に0を追加
memcpy(tex, pmdMaterial[i].texture_file_name, 20);
string s(tex);
s = s.substr(0, s.find("*")); // temp
meshData.texture_filename.push_back(s);
material_end += pmdMaterial[i].face_vert_count;
for (; j < material_end; ++j) meshData.faces[j/3].material_number = i;
}
delete pmdMaterial;
// MeshDataをグラフィックボードのメモリにセット
SetMesh(meshData);
}
void PmdMesh::CopyMaterial(D3DMATERIAL9& material, PmdMaterial& pmdMaterial)
{
material.Ambient.a = pmdMaterial.alpha;
material.Ambient.r = pmdMaterial.mirror_color[0];
material.Ambient.g = pmdMaterial.mirror_color[1];
material.Ambient.b = pmdMaterial.mirror_color[2];
material.Diffuse.a = pmdMaterial.alpha;
material.Diffuse.r = pmdMaterial.diffuse_color[0];
material.Diffuse.g = pmdMaterial.diffuse_color[1];
material.Diffuse.b = pmdMaterial.diffuse_color[2];
material.Power = pmdMaterial.specularity;
material.Specular.a = pmdMaterial.alpha;
material.Specular.r = pmdMaterial.specular_color[0];
material.Specular.g = pmdMaterial.specular_color[1];
material.Specular.b = pmdMaterial.specular_color[2];
}
include "MyApplication.h"
MyApplication::MyApplication()
{}
MyApplication::~MyApplication(void)
{
delete camera;
delete light;
delete island;
delete yukkuri;
delete directXFramework;
}
//------------------------------------------------------------------------------------
void MyApplication::InitMyApplication(HWND hWnd)
{
directXFramework = new DirectXFramework();
directXFramework->DirectXInit(hWnd);
LPDIRECT3DDEVICE9 pDevice = directXFramework->GetD3DDevice();
light = new Light();
light->LightInit(pDevice);
camera = new Camera();
camera->CameraInit(pDevice);
yukkuri = new PmdMesh();
yukkuri->InitPmd(TEXT("reimu.pmd"), pDevice);
island = new XFileMesh();
island->InitXFile(TEXT("batokin_island5.x"), pDevice);
}
//------------------------------------------------------------------------------------
void MyApplication::Run()
{
directXFramework->BeginScene(0x0F, 0xFF , 0xFF);// シーン開始
static int t;
const D3DXVECTOR3 position(0, 0, 0), zeroVector(0, 0, 0);
D3DXMATRIX rotation, unitMatrix;
D3DXMatrixRotationY(&rotation, 0.01f*(++t));
// D3DXMatrixRotationY(&rotation, D3DX_PI*0.85f);
D3DXMatrixIdentity(&unitMatrix);
// ライト
D3DXVECTOR3 direction(-1, -1, -1); // 光の方向
light->Illume(direction); // 光をあてる
// カメラ
D3DXVECTOR3 eyePoint = D3DXVECTOR3(-0.2f, 0.3f, 1.5f); // 視点
D3DXVECTOR3 lookAtPoint = D3DXVECTOR3(0, 0.4f, 0); // 注視点
//D3DXVECTOR3 eyePoint = D3DXVECTOR3(-0.2f, 1.5f, 1.0f); // 視点
//D3DXVECTOR3 lookAtPoint = D3DXVECTOR3(0, 1.7f, 0); // 注視点
camera->Look(eyePoint, lookAtPoint); // 見る
// 描画
island->Draw(zeroVector, unitMatrix);
yukkuri->Draw(position, rotation);
directXFramework->EndScene(); // シーン終了
}
環境
OS : Windows
コンパイラ名 : VC++ 2008EE
DirectX SDK November2007
型も関数もそれぞれ定義しているのですがなぜこのようなエラー文が出てくるのか原因がわからず困っております。
もしプログラム全体が必要でしたらファイルをアップします。
DirectXで直接読み込ませて表示させたいのはfxファイルを使用したいからです。
DXライブラリではpmdファイルを表示させモーション再生までさせたのですがfxファイルが読み込めないとのことだったのでDirectXで直接読み込ませようとしているところです。