コンパイルエラーの原因について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
north

コンパイルエラーの原因について

#1

投稿記事 by north » 12年前

こんばんは。
前回質問させていただきました時はご回答くださりありがとうございました。

今回の質問なのですが、
現在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
記述2(メッシュ関連のcppファイル)

コード:

#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];
}
記述3(実際に描画させるプログラム)

コード:

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で直接読み込ませようとしているところです。

旅路のきのこ

Re: コンパイルエラーの原因について

#2

投稿記事 by 旅路のきのこ » 12年前

こんにちは!
stringの方は、std::だと思います。

InitPmdについてですが、MyApplicationについての記述がここにはないような気がするんで当てずっぽうです。
MyApplicationのメンバーyukkuriが、PmdMesh型ではなくMesh型になっていたりするんでしょうか?
違っていたらごめんなさい。

north

Re: コンパイルエラーの原因について

#3

投稿記事 by north » 12年前

早速の回答ありがとうございます。
std::の部分というのはstdがいらないということでしょうか?
stringのエラーは36行目で出ていました。

一応MyApplicationのヘッダの部分も載せておきたいと思います。

コード:

#ifndef MYAPPLICATION
#define MYAPPLICATION


#include "DirectXFramework.h"
#include "Mesh.h"
#include "Camera.h"
#include "Light.h"

/// アプリケーションの統括クラス
class MyApplication 
{
private:
	DirectXFramework* directXFramework;
	Mesh* island;
	Mesh* yukkuri;
	Light* light;
	Camera* camera;

public:
	/// コンストラクタ
	MyApplication();

	/// デストラクタ
	~MyApplication();

	//初期化関数
	void InitMyApplication(HWND hWnd);

	/// 1/60秒毎に行なう処理
	void Run();
};
#endif
本当は使い慣れているDXライブラリを使用したいのですが、そうなるとエフェクト関連でシェーダーを使いたいときに制限が出てくるのでDirectXでpmdとvmdファイルを
読み込ませることにしました。最終的にはMMEのもととなっているfxファイルを利用したゲームを作成する予定です。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: コンパイルエラーの原因について

#4

投稿記事 by みけCAT » 12年前

north さんが書きました:早速の回答ありがとうございます。
std::の部分というのはstdがいらないということでしょうか?
stringのエラーは36行目で出ていました。
逆です。stringにもstd::をつけてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

north

Re: コンパイルエラーの原因について

#5

投稿記事 by north » 12年前

ありがとうございます。
stdをstringの前に記述することで無事に解決できました。
ただ、全部にstdをつけていくと忘れる可能性もあるのでnamespaceを使って書き忘れ防止をすることにしました。
2つ目についてはご指摘された通りMesh型からPmdMesh型に変えることで無事に解決しました。
本当にありがとうございます。ただ、コンパイルは通るようになったのですが、現在ハンドルされていない例外が発生しました。というアクセス違反が
発生してしまうのですが、とりあえずまずは自分で原因を調べてみてどうしてもわからない場合に改めて別のトピックを立てて質問させていただこうと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る