#include #include #include #include #include #include "main.h" #include "texture2d.h" #include "CSceneFBX.h" void CSceneFBX::Init( void ) { const char* lFilename = "dude/dude.fbx"; FbxManager* lSdkManager = FbxManager::Create(); // Create the IO settings object. FbxIOSettings *ios = FbxIOSettings::Create( lSdkManager, IOSROOT ); lSdkManager->SetIOSettings( ios ); // Create an importer using the SDK manager. FbxImporter* lImporter = FbxImporter::Create( lSdkManager, "" ); // Use the first argument as the filename for the importer. if( !lImporter->Initialize( lFilename, -1, lSdkManager->GetIOSettings() ) ) { char buf[ 256 ]; sprintf( buf, "Call to FbxImporter::Initialize() failed.\nError returned: %s\n\n", lImporter->GetStatus().GetErrorString() ); MessageBox( NULL, buf, "error", MB_OK ); return; } // Create a new scene so that it can be populated by the imported file. FbxScene* lScene = FbxScene::Create( lSdkManager, "myScene" ); // Import the contents of the file into the scene. lImporter->Import( lScene ); FbxGeometryConverter converter( lSdkManager ); // anime int anmimeNum = lImporter->GetAnimStackCount(); //lScene->GetPoseCount(); FbxArray animationNames; lScene->FillAnimStackNameArray( animationNames ); FbxTakeInfo* pTakeInfo = lScene->GetTakeInfo( animationNames[ 0 ]->Buffer() ); // get start time FbxTime startTime = 0; FbxTime endTime = 0; startTime = pTakeInfo->mLocalTimeSpan.GetStart(); endTime = pTakeInfo->mLocalTimeSpan.GetStop(); // 三角ポリゴン化 converter.Triangulate( lScene, true ); // 縮退メッシュを削除 converter.RemoveBadPolygonsFromMeshes( lScene ); // マテリアルごとにメッシュ分離 converter.SplitMeshesPerMaterial( lScene, true ); // 再帰的にノードを漁る m_pTopMyNode = myNode::recursiveNode( lSdkManager, lScene->GetRootNode(), false, startTime, endTime ); lImporter->Destroy(); lScene->Destroy(); lSdkManager->Destroy(); } void CSceneFBX::Uninit( void ) { if( m_pV != NULL ) { delete m_pV; m_pV = NULL; } //if( m_pVt != NULL ) //{ // delete m_pVt; // m_pVt = NULL; //} //if( m_pVn != NULL ) //{ // delete m_pVn; // m_pVn = NULL; //} if( m_pFace != NULL ) { delete m_pFace; m_pFace = NULL; } } void CSceneFBX::Update( void ) { } //void CSceneFBX::Draw( void ) //{ // glPushMatrix(); // //glBindTexture( GL_TEXTURE_2D, m_texture ); // // glBegin( GL_TRIANGLES ); // for( int i = 0; i < m_faceCount; i++ ) // { // //glNormal3fv( ( float* ) &m_pVn[ pFace[ i ].vnIndex ] ); // //glTexCoord2fv( ( float* ) &m_pVt[ pFace[ i ].vtIndex ] ); // glVertex3fv( ( float* ) &m_pV[ m_pFace[ i ].vIndex ] ); // } // glEnd(); // glBindTexture( GL_TEXTURE_2D, 0 ); // // glPopMatrix(); //} /** * Return a string-based representation based on the attribute type. */ std::string myNode::GetttributeTypeName( FbxNodeAttribute::EType type ) { switch( type ) { case FbxNodeAttribute::eUnknown: return "unidentified"; case FbxNodeAttribute::eNull: return "null"; case FbxNodeAttribute::eMarker: return "marker"; case FbxNodeAttribute::eSkeleton: return "skeleton"; case FbxNodeAttribute::eMesh: return "mesh"; case FbxNodeAttribute::eNurbs: return "nurbs"; case FbxNodeAttribute::ePatch: return "patch"; case FbxNodeAttribute::eCamera: return "camera"; case FbxNodeAttribute::eCameraStereo: return "stereo"; case FbxNodeAttribute::eCameraSwitcher: return "camera switcher"; case FbxNodeAttribute::eLight: return "light"; case FbxNodeAttribute::eOpticalReference: return "optical reference"; case FbxNodeAttribute::eOpticalMarker: return "marker"; case FbxNodeAttribute::eNurbsCurve: return "nurbs curve"; case FbxNodeAttribute::eTrimNurbsSurface: return "trim nurbs surface"; case FbxNodeAttribute::eBoundary: return "boundary"; case FbxNodeAttribute::eNurbsSurface: return "nurbs surface"; case FbxNodeAttribute::eShape: return "shape"; case FbxNodeAttribute::eLODGroup: return "lodgroup"; case FbxNodeAttribute::eSubDiv: return "subdiv"; default: return "unknown"; } } //============================================================================= // 描画処理 //============================================================================= void myNode::recursiveDraw( int currentFrame ) { glPushMatrix(); glScalef( scaling.x, scaling.y, scaling.z ); glRotatef( rotation.x, 1, 0, 0 ); glRotatef( rotation.y, 0, 1, 0 ); glRotatef( rotation.z, 0, 0, 1 ); glTranslatef( translation.x, translation.y, translation.z ); for( auto itm = meshes.begin(); itm != meshes.end(); ++itm ) { // テクスチャ設定 if( !textures.empty() ) { glBindTexture( GL_TEXTURE_2D, textures[ itm->materialIndex ] ); } // ポリゴン描画 glBegin( GL_TRIANGLES ); if( itm->matrixes.empty() ) { // 骨なし(つまり剛体の塊) for( size_t i = 0; i < itm->positionIndices.size(); i++ ) { if( !itm->normals.empty() ) glNormal3fv( itm->normals[ itm->normalIndices[ i ] ] ); if( !itm->texcoords.empty() ) glTexCoord2fv( itm->texcoords[ itm->texcoordIndices[ i ] ] ); glVertex3fv( itm->points[ itm->positionIndices[ i ] ].positions ); } } else { // 骨あり(つまりワンスキンなど) // 頂点の座標変換 std::vector positions; positions.reserve( itm->points.size() ); D3DXMATRIX mtx; for( auto it = itm->points.begin(); it != itm->points.end(); ++it ) { ZeroMemory( &mtx, sizeof( D3DXMATRIX ) ); for( auto itb = it->bornRefarences.begin(); itb != it->bornRefarences.end(); ++itb ) { int AllFrame = itm->matrixes[ itb->index ].size(); mtx += itm->matrixes[ itb->index ][ currentFrame % AllFrame ] * itb->weight; } D3DXVECTOR3 pos; D3DXVec3TransformCoord( &pos, &it->positions, &mtx ); positions.push_back( pos ); } for( size_t i = 0; i < itm->positionIndices.size(); i++ ) { if( !itm->normals.empty() ) glNormal3fv( itm->normals[ itm->normalIndices[ i ] ] ); if( !itm->texcoords.empty() ) glTexCoord2fv( itm->texcoords[ itm->texcoordIndices[ i ] ] ); glVertex3fv( positions[ itm->positionIndices[ i ] ] ); } } glEnd(); } std::for_each( children.begin(), children.end(), [ currentFrame ]( myNode* p ) {p->recursiveDraw( currentFrame ); } ); glPopMatrix(); } // Get the geometry offset to a node. It is never inherited by the children. FbxMatrix myNode::GetGeometry( FbxNode* pNode ) { const FbxVector4 lT = pNode->GetGeometricTranslation( FbxNode::eSourcePivot ); const FbxVector4 lR = pNode->GetGeometricRotation( FbxNode::eSourcePivot ); const FbxVector4 lS = pNode->GetGeometricScaling( FbxNode::eSourcePivot ); return FbxAMatrix( lT, lR, lS ); } void myNode::analyzeCluster( FbxMesh* pMesh, FbxTime startTime, FbxTime endTime ) { D3DXMATRIX mtxIdentitiy; D3DXMatrixIdentity( &mtxIdentitiy ); FbxTime oneFrameTime; oneFrameTime.SetTime( 0, 0, 0, 1, 0, 0, FbxTime::eFrames60 ); // スキンの数を取得 int skinCount = pMesh->GetDeformerCount( FbxDeformer::eSkin ); for( int skinNum = 0; skinNum < skinCount; skinNum++ ) { // スキンを取得 FbxSkin* pSkin = ( FbxSkin* ) pMesh->GetDeformer( skinNum, FbxDeformer::eSkin ); // クラスターの数を取得 int clusterCount = pSkin->GetClusterCount(); for( int clusterNum = 0; clusterNum < clusterCount; clusterNum++ ) { meshes.back().matrixes.emplace_back( 0 ); // クラスタを取得 FbxCluster* pCluster = pSkin->GetCluster( clusterNum ); // このクラスタが影響を及ぼす頂点インデックスの個数を取得 int pointIndexCount = pCluster->GetControlPointIndicesCount(); if( !pointIndexCount ) { // このメッシュにおいて、このクラスタは無視していいと思う... meshes.back().matrixes.back().push_back( mtxIdentitiy ); continue; } // 初期姿勢行列の取得 FbxAMatrix lReferenceGlobalInitPosition; FbxAMatrix lReferenceGlobalCurrentPosition; FbxAMatrix lReferenceGeometry; FbxAMatrix lClusterGlobalInitPosition; FbxAMatrix lClusterGlobalCurrentPosition; FbxAMatrix lClusterRelativeInitPosition; FbxAMatrix lClusterRelativeCurrentPositionInverse; pCluster->GetTransformMatrix( lReferenceGlobalInitPosition ); // lReferenceGlobalCurrentPosition = pGlobalPosition; // <- たぶんワールド座標変換行列ではないかと // Multiply lReferenceGlobalInitPosition by Geometric Transformation ( FbxMatrix ) lReferenceGeometry = GetGeometry( pMesh->GetNode() ); lReferenceGlobalInitPosition *= lReferenceGeometry; // Get the link initial global position and the link current global position. pCluster->GetTransformLinkMatrix( lClusterGlobalInitPosition ); // lClusterGlobalCurrentPosition = GetGlobalPosition(pCluster->GetLink(), pTime, pPose); // <- ポーズ行列の取り方??? // 指定時間のボーン姿勢の取得 // フレーム単位の時間(1/60s)を入れていく for( FbxTime currentTime = startTime; currentTime < endTime; currentTime += oneFrameTime ) { lClusterGlobalCurrentPosition = pCluster->GetLink()->EvaluateGlobalTransform( currentTime ); // Compute the initial position of the link relative to the reference. lClusterRelativeInitPosition = lClusterGlobalInitPosition.Inverse() * lReferenceGlobalInitPosition; // Compute the current position of the link relative to the reference. lClusterRelativeCurrentPositionInverse = lReferenceGlobalCurrentPosition.Inverse() * lClusterGlobalCurrentPosition; // Compute the shift of the link relative to the reference. FbxAMatrix VertexTransformMatrix = lClusterRelativeCurrentPositionInverse * lClusterRelativeInitPosition; // ↑ 初期姿勢行列も考慮されたモーションボーン行列なので、これで頂点座標を変換するだけで良い D3DXMATRIX d3dMtx; for( int y = 0; y < 4; y++ ) { for( int x = 0; x < 4; x++ ) { d3dMtx( x, y ) = ( float ) VertexTransformMatrix.Get( x, y ); } } //meshes.back().matrixes.emplace_back( d3dMtx ); // vector型最後尾要素 meshes.back().matrixes.back().push_back( d3dMtx ); } int* pointIndexArray = pCluster->GetControlPointIndices(); double* weightArray = pCluster->GetControlPointWeights(); for( int i = 0; i < pointIndexCount; i++ ) { meshes.back().points[ pointIndexArray[ i ] ].bornRefarences.push_back( BornRefarence( clusterNum, static_cast< float >( weightArray[ i ] ) ) ); } } } } myNode* myNode::recursiveNode( FbxManager* pManager, FbxNode* pNode, bool bTexcoordVReverse, FbxTime startTime, FbxTime endTime ) { myNode* p = NULL; if( pNode ) { p = new myNode; p->name = pNode->GetName(); p->translation.x = static_cast< float >( pNode->LclTranslation.Get()[ 0 ] ); p->translation.y = static_cast< float >( pNode->LclTranslation.Get()[ 1 ] ); p->translation.z = static_cast< float >( pNode->LclTranslation.Get()[ 2 ] ); p->rotation.x = static_cast< float >( pNode->LclRotation.Get()[ 0 ] ); p->rotation.y = static_cast< float >( pNode->LclRotation.Get()[ 1 ] ); p->rotation.z = static_cast< float >( pNode->LclRotation.Get()[ 2 ] ); p->scaling.x = static_cast< float >( pNode->LclScaling.Get()[ 0 ] ); p->scaling.y = static_cast< float >( pNode->LclScaling.Get()[ 1 ] ); p->scaling.z = static_cast< float >( pNode->LclScaling.Get()[ 2 ] ); for( int i = 0; i < pNode->GetNodeAttributeCount(); i++ ) { FbxNodeAttribute::EType type = pNode->GetNodeAttributeByIndex( i )->GetAttributeType(); p->attributeNames.push_back( GetttributeTypeName( type ) ); if( type == FbxNodeAttribute::eMesh ) { // マテリアル情報の解析(マテリアルリスト化) p->analyzeMaterial( pNode ); p->meshes.push_back( Mesh() ); // メッシュ情報の取得 FbxMesh* pMesh = FbxCast( pNode->GetNodeAttributeByIndex( i ) ); // 頂点座標解析 p->analyzePosition( pMesh ); // 法線解析 p->analyzeNormal( pMesh ); // UV解析 p->analyzeTexcoord( pMesh, bTexcoordVReverse ); // マテリアル解析(参照情報の取得) p->analyzeMaterial( pMesh ); //ボーン解析 p->analyzeCluster(pMesh, startTime, endTime); } //else //{ // // メッシュではないアトリビュート // MessageBoxA( NULL, GetttributeTypeName( type ).c_str(), "アトリビュート", MB_OK ); //} } for( int i = 0; i < pNode->GetChildCount(); i++ ) { p->children.push_back( recursiveNode( pManager, pNode->GetChild( i ), bTexcoordVReverse, startTime, endTime ) ); } } return p; } void myNode::analyzePosition( FbxMesh* pMesh ) { // コントロールポイント数の取得 int controlPointsCount = pMesh->GetControlPointsCount(); // 頂点座標用コンテナの領域予約 meshes.back().points.reserve( controlPointsCount ); // 頂点データの取得 FbxVector4* pP = pMesh->GetControlPoints(); for( int i = 0; i < pMesh->GetControlPointsCount(); i++ ) { meshes.back().points.push_back( D3DXVECTOR3( static_cast< float >( pP[ i ][ 0 ] ), static_cast< float >( pP[ i ][ 1 ] ), static_cast< float >( pP[ i ][ 2 ] ) ) ); } /* 頂点インデックスの取得 */ // インデックス数を取得 int polygonVertexCount = pMesh->GetPolygonVertexCount(); // 頂点座標インデックス用コンテナの領域予約 meshes.back().positionIndices.reserve( polygonVertexCount ); // インデックスバッファの取得 for( int i = 0; i < polygonVertexCount; i++ ) { meshes.back().positionIndices.push_back( static_cast< unsigned short >( pMesh->GetPolygonVertices()[ i ] ) ); } } void myNode::analyzeNormal( FbxMesh* pMesh ) { // レイヤー数の取得 int layerCount = pMesh->GetLayerCount(); for( int layer = 0; layer < layerCount; layer++ ) { // 法線の取得 FbxLayerElementNormal* pElementNormal = pMesh->GetElementNormal( layer ); if( !pElementNormal ) { continue; } // 法線数の取得 int normalCount = pElementNormal->GetDirectArray().GetCount(); // 法線格納用コンテナの領域予約 meshes.back().normals.reserve( normalCount ); // 法線データの取得 for( int i = 0; i < normalCount; i++ ) { meshes.back().normals.push_back( D3DXVECTOR3( static_cast< float >( pElementNormal->GetDirectArray()[ i ][ 0 ] ), static_cast< float >( pElementNormal->GetDirectArray()[ i ][ 1 ] ), static_cast< float >( pElementNormal->GetDirectArray()[ i ][ 2 ] ) ) ); } // マッピングモード・リファレンスモード取得 FbxLayerElement::EMappingMode mappingMode = pElementNormal->GetMappingMode(); FbxLayerElement::EReferenceMode referenceMode = pElementNormal->GetReferenceMode(); switch( mappingMode ) { case FbxLayerElement::eNone: MessageBox( NULL, "Normal MappingMode = mappingMode", "未実装", MB_OK ); break; case FbxLayerElement::eByControlPoint: // 頂点バッファと同じインデックスを使用 if( referenceMode == FbxLayerElement::eDirect ) { // 法線インデックス格納用コンテナの領域予約 meshes.back().normalIndices.reserve( meshes.back().points.size() ); // 頂点バッファと同じインデックスをコピー meshes.back().normalIndices.assign( meshes.back().positionIndices.begin(), meshes.back().positionIndices.end() ); } else if( referenceMode == FbxLayerElement::eIndexToDirect || referenceMode == FbxLayerElement::eIndex ) { MessageBox( NULL, "Normal ReferenceMode = eIndexToDirect or eIndex, MappingMode = eByControlPoint", "未実装", MB_OK ); } break; case FbxLayerElement::eByPolygonVertex: /* 法線独自のインデックスを使用 */ if( referenceMode == FbxLayerElement::eDirect ) { // インデックス参照の必要なし => インデックスを作成 // 法線インデックス格納用コンテナの領域予約 meshes.back().normalIndices.reserve( normalCount ); // 法線インデックスの作成 for( int i = 0; i < normalCount; i++ ) { meshes.back().normalIndices.push_back( i ); } } else if( referenceMode == FbxLayerElement::eIndexToDirect || referenceMode == FbxLayerElement::eIndex ) { // 独自インデックスを所持 // インデックス数の取得 int normalIndexCount = pElementNormal->GetIndexArray().GetCount(); // 法線インデックス格納用コンテナの領域予約 meshes.back().normalIndices.reserve( normalIndexCount ); // 法線インデックスの取得 for( int i = 0; i < normalIndexCount; i++ ) { meshes.back().normalIndices.push_back( pElementNormal->GetIndexArray()[ i ] ); } } break; case FbxLayerElement::eByPolygon: MessageBox( NULL, "Normal MappingMode = eByPolygon", "未実装", MB_OK ); break; case FbxLayerElement::eByEdge: MessageBox( NULL, "Normal MappingMode = eByEdge", "未実装", MB_OK ); break; case FbxLayerElement::eAllSame: MessageBox( NULL, "Normal MappingMode = eAllSame", "未実装", MB_OK ); break; default: MessageBox( NULL, "Normal ???", "未実装", MB_OK ); break; } } } void myNode::analyzeTexcoord( FbxMesh* pMesh, bool bRevers ) { int layerCount = pMesh->GetLayerCount(); if( !layerCount ) { MessageBox( NULL, "レイヤーを持っていないメッシュを確認", "Analyze Texcoord", MB_OK ); return; } for( int layer = 0; layer < layerCount; layer++ ) { // UVの取得 FbxLayerElementUV* pElementUV = pMesh->GetLayer( layer )->GetUVs(); if( !pElementUV ) { MessageBox( NULL, "...UVのないメッシュレイヤーを確認", "Analyze Texcoord", MB_OK ); continue; } // UVセット名を取得 // = pElementUV->GetName(); // マッピングモード・リファレンスモード取得 FbxLayerElement::EMappingMode mappingMode = pElementUV->GetMappingMode(); FbxLayerElement::EReferenceMode referenceMode = pElementUV->GetReferenceMode(); if( mappingMode == FbxLayerElement::eByPolygonVertex ) { if( referenceMode == FbxLayerElement::eIndexToDirect || referenceMode == FbxLayerElement::eIndex ) { int uvIndexCount = pElementUV->GetIndexArray().GetCount(); meshes.back().texcoordIndices.reserve( uvIndexCount ); for( int i = 0; i < uvIndexCount; i++ ) { meshes.back().texcoordIndices.push_back( pElementUV->GetIndexArray().GetAt( i ) ); } int uvCount = pElementUV->GetDirectArray().GetCount(); meshes.back().texcoords.reserve( uvCount ); for( int i = 0; i < uvCount; i++ ) { meshes.back().texcoords.push_back( D3DXVECTOR2( static_cast< float >( pElementUV->GetDirectArray().GetAt( i )[ 0 ] ), static_cast< float >( bRevers ? 1 - pElementUV->GetDirectArray().GetAt( i )[ 1 ] : pElementUV->GetDirectArray().GetAt( i )[ 1 ] ) ) ); } } else { MessageBox( NULL, "Texcoord::未対応のリファレンスモードを取得", "FbxLayerElement::eByPolygonVertex", MB_OK ); break; } } else if( mappingMode == FbxLayerElement::eByControlPoint ) { MessageBox( NULL, "...未対応マッピングモード[eByControlPoint]を取得した", "Analyze Texcoord", MB_OK ); } else if( mappingMode == FbxLayerElement::eByPolygon ) { MessageBox( NULL, "...未対応マッピングモード[eByPolygon]を取得した", "Analyze Texcoord", MB_OK ); } else if( mappingMode == FbxLayerElement::eByEdge ) { MessageBox( NULL, "...未対応マッピングモード[eByEdge]を取得した", "Analyze Texcoord", MB_OK ); } else { MessageBox( NULL, "...知らないマッピングモードを取得した", "Analyze Texcoord", MB_OK ); } break; // とりあえず1個めだけ } } void myNode::analyzeMaterial( FbxNode* pNode ) { // マテリアル数の取得 int materialCount = pNode->GetMaterialCount(); textures.reserve( materialCount ); for( int i = 0; i < materialCount; i++ ) { // マテリアル情報の取得 FbxSurfaceMaterial* pMaterial = pNode->GetMaterial( i ); // ディフューズ情報の取得 FbxProperty diffuseProperty = pMaterial->FindProperty( FbxSurfaceMaterial::sDiffuse ); // プロパティが持っているレイヤードテクスチャの枚数をチェック int layeredTextureCount = diffuseProperty.GetSrcObjectCount(); // レイヤードテクスチャが無ければ通常テクスチャ if( layeredTextureCount == 0 ) { // 通常テクスチャの枚数をチェック int textureCount = diffuseProperty.GetSrcObjectCount(); // 各テクスチャについてテクスチャ情報をゲット for( int i = 0; i < textureCount; i++ ) { // i番目のテクスチャオブジェクト取得 FbxFileTexture* pTexture = diffuseProperty.GetSrcObject( i ); // テクスチャファイル名の取得 // std::string fileName = pTexture->GetFileName(); std::string relFileName = pTexture->GetRelativeFileName(); // UVSet名の取得 std::string uvSetName = pTexture->UVSet.Get().Buffer(); // 辞書登録 // texfile2UVset[relFileName] = uvSetName; std::string strPathName = "data/" + relFileName; // テクスチャの読み込みと管理 textures.push_back( Texture2D::LoadTGA( strPathName.c_str() ) ); } } else { // レイヤードテクスチャあり MessageBox( NULL, "レイヤードテクスチャ", "マテリアルの取得", MB_OK ); } } } void myNode::analyzeMaterial( FbxMesh* pMesh ) { int layerCount = pMesh->GetLayerCount(); for( int layer = 0; layer < layerCount; layer++ ) { FbxLayerElementMaterial* pElementMaterial = pMesh->GetLayer( layer )->GetMaterials(); if( !pElementMaterial ) { continue; } int materialIndexCount = pElementMaterial->GetIndexArray().GetCount(); if( materialIndexCount == 0 ) { continue; } FbxLayerElement::EMappingMode mappingMode = pElementMaterial->GetMappingMode(); FbxLayerElement::EReferenceMode referenceMode = pElementMaterial->GetReferenceMode(); if( mappingMode == FbxLayerElement::eAllSame ) { if( referenceMode == FbxLayerElement::eIndexToDirect ) { // メッシュ全部がこのマテリアルインデックス meshes.back().materialIndex = pElementMaterial->GetIndexArray().GetAt( 0 ); } else { MessageBox( NULL, "...未対応のリファレンスモードを取得した", "Material MappingMode = eAllSame", MB_OK ); } } else if( mappingMode == FbxLayerElement::eByControlPoint ) { MessageBox( NULL, "...未対応のマッピングモード[eByControlPoint]を取得した", "Material MappingMode", MB_OK ); } else if( mappingMode == FbxLayerElement::eByPolygon ) { // マテリアル分割されているはずだから、一番はじめのだけでいい meshes.back().materialIndex = pElementMaterial->GetIndexArray().GetAt( 0 ); } else if( mappingMode == FbxLayerElement::eByEdge ) { MessageBox( NULL, "...未対応のマッピングモード[eByEdge]を取得した", "Material MappingMode", MB_OK ); } else { MessageBox( NULL, "...未対応のマッピングモードを取得した", "Material MappingMode", MB_OK ); } } } void CSceneFBX::Draw( int currentFrame ) { // マトリクス退避 glMatrixMode( GL_MODELVIEW ); glPushMatrix(); // マテリアル設定 MATERIAL material; material.Diffuse.r = 1.0f; material.Diffuse.g = 1.0f; material.Diffuse.b = 1.0f; material.Diffuse.a = 1.0f; material.Ambient.r = 1.0f; material.Ambient.g = 1.0f; material.Ambient.b = 1.0f; material.Ambient.a = 1.0f; material.Specular.r = 1.0f; material.Specular.g = 1.0f; material.Specular.b = 1.0f; material.Specular.a = 1.0f; material.Emission.r = 0.0f; material.Emission.g = 0.0f; material.Emission.b = 0.0f; material.Emission.a = 1.0f; material.Shininess = 0.5f; glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ( float* ) &material.Ambient ); glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, ( float* ) &material.Diffuse ); glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, ( float* ) &material.Specular ); glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, ( float* ) &material.Emission ); glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, material.Shininess ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); // glScalef(0.1f, 0.1f, 0.1f); glPushMatrix(); m_pTopMyNode->recursiveDraw( currentFrame ); glPopMatrix(); glPopMatrix(); }