/** * テクニック解析 */ BOOL CShaderConverter::ExportTechnique() { VRETURN(_ExportChunkHeader(m_Out, izanagi::shader::SHD_CHUNK_MAGIC_NUMBER_TECH)); izanagi::shader::S_SHD_TECH_HEADER sTechHeader; FILL_ZERO(&sTechHeader, sizeof(sTechHeader)); // Blank for technique's header. izanagi::tool::CIoStreamSeekHelper cSeekHelper(&m_Out); VRETURN(_BeginExportChunk(sTechHeader, cSeekHelper)); UINT nPassPos = 0; // テクニック取得 CGtechnique tech = ::cgGetFirstTechnique(m_pCgEffect); if (tech != NULL) { while (tech != NULL) { izanagi::shader::S_SHD_TECHNIQUE sTech; { FILL_ZERO(&sTech, sizeof(sTech)); IZ_PCSTR name = ::cgGetTechniqueName(tech); IZ_UINT pos = CStringChunk::GetInstance().Register(name); //sTech.name = *(IZ_PCSTR*)(&pos); sTech.posName = pos; sTech.keyName = izanagi::CKey::GenerateValue(name); sTech.numPass = _GetPassNum(tech); sTech.posPass = nPassPos; } nPassPos += sTech.numPass; // 出力 VRETURN(ExportData(sTech)); tech = ::cgGetNextTechnique(tech); sTechHeader.numTechnique++; } } else { // テクニックは必ず一つはないといけない IZ_ASSERT(FALSE); // TODO return FALSE; } VRETURN(_EndExportChunk(sTechHeader, cSeekHelper)); return TRUE; }
BOOL CShaderConverter::ExportTexture() { VRETURN(_ExportChunkHeader(m_Out, izanagi::shader::SHD_CHUNK_MAGIC_NUMBER_TEX)); izanagi::shader::S_SHD_TEXTRUE_HEADER sTexHeader; FILL_ZERO(&sTexHeader, sizeof(sTexHeader)); // Blank for texture's header. izanagi::tool::CIoStreamSeekHelper cSeekHelper(&m_Out); VRETURN(_BeginExportChunk(sTexHeader, cSeekHelper)); m_TexList.clear(); CGparameter param = ::cgGetFirstEffectParameter(m_pCgEffect); while (param != NULL) { if (CParamUtil::IsTexture(param)) { izanagi::shader::S_SHD_TEXTURE sTex; { FILL_ZERO(&sTex, sizeof(sTex)); CParamUtil::SetNameAndSemantic(sTex, param); #if 0 sTex.type = _GetTexTypeFromSemantic(param); sTex.ann.isRenderTarget = IZ_TRUE; sTex.ann.isDynamic = IZ_FALSE; sTex.ann.typeRsc = izanagi::graph::E_GRAPH_RSC_USAGE_STATIC; VRETURN( CTextureUtil::SetAnnValue( sTex.ann, param)); #endif } m_TexList.push_back(param); // 出力 VRETURN(ExportData(sTex)); sTexHeader.numTexture++; } param = ::cgGetNextParameter(param); } VRETURN(_EndExportChunk(sTexHeader, cSeekHelper)); m_ShdHeader.numTexture = sTexHeader.numTexture; return TRUE; }
/** * パラメータ解析 */ BOOL CPostEffectConverter::ExportParameter() { IZ_UINT nAnnIdx = 0; izanagi::S_PES_PARAM_HEADER paramHader; { paramHader.numParameter = 0; paramHader.numParamAnn = 0; } // Blank for pass's header. izanagi::tool::CIoStreamSeekHelper cSeekHelper(&m_Out); VRETURN(cSeekHelper.Skip(sizeof(paramHader))); // For description. CGparameter param = ::cgGetFirstEffectParameter(m_pCgEffect); while (param != NULL) { if (CParamUtil::IsParameter(param) && !_IgnoreParameter(param)) { // For Debug... IZ_PCSTR name = ::cgGetParameterName(param); VRETURN(CParamUtil::IsValidParameter(param)); izanagi::S_PES_PARAMETER sParam; FILL_ZERO(&sParam, sizeof(sParam)); sParam.DoNotStrip = CParamUtil::DoNotStrip(param); if (sParam.DoNotStrip || DoNotRemoveParam(param)) { CParamUtil::SetNameAndSemantic(sParam, param); VRETURN( CParamUtil::SetDescValue( sParam, param)); if (sParam.hasAnn) { sParam.AnnotationIdx = nAnnIdx++; } // Register initial value. VRETURN( CParamUtil::GetInitValue( sParam, param)); m_ParamList.push_back(param); // 出力 VRETURN(ExportData(sParam)); paramHader.numParameter++; } } param = ::cgGetNextParameter(param); } VRETURN(ExportParamAnn(paramHader, nAnnIdx)); // Export initial value. m_PesHeader.sizeValueBuffer = CDataBuffer::GetInstance().GetBufferSize(); if (m_PesHeader.sizeValueBuffer > 0) { const void* pBuf = CDataBuffer::GetInstance().GetBuffer(); IZ_OUTPUT_WRITE_VRETURN( &m_Out, pBuf, 0, m_PesHeader.sizeValueBuffer); } // Return to paremter's header position with anchor. VRETURN(cSeekHelper.ReturnWithAnchor()); // Export paramter's header. IZ_OUTPUT_WRITE_VRETURN(&m_Out, ¶mHader, 0, sizeof(paramHader)); // Return to anchored position. VRETURN(cSeekHelper.ReturnToAnchor()); return TRUE; }
BOOL CPostEffectConverter::ExportSampler() { izanagi::S_PES_SAMPLER_HEADER smplHeader; { smplHeader.numSampler = 0; } // Blank for pass's header. izanagi::tool::CIoStreamSeekHelper cSeekHelper(&m_Out); VRETURN(cSeekHelper.Skip(sizeof(smplHeader))); // パスを取得 std::vector<CGpass> passList; { CGtechnique tech = ::cgGetFirstTechnique(m_pCgEffect); while (tech != NULL) { CGpass pass = ::cgGetFirstPass(tech); while (pass != NULL) { passList.push_back(pass); pass = ::cgGetNextPass(pass); } tech = ::cgGetNextTechnique(tech); } } CGparameter param = ::cgGetFirstEffectParameter(m_pCgEffect); while (param != NULL) { if (::cgIsParameterUsed(param, m_pCgEffect)) { VRETURN(CParamUtil::IsValidParameter(param)); if (CParamUtil::IsSampler(param)) { // 対象となるパスのインデックスを取得 IZ_INT passIdx = -1; for (IZ_UINT i = 0; i < passList.size(); i++) { if (::cgIsParameterUsed(param, passList[i])) { passIdx = i; break; } } izanagi::S_PES_SAMPLER sSampler; { FILL_ZERO(&sSampler, sizeof(sSampler)); sSampler.state.minFilter = izanagi::graph::E_GRAPH_TEX_FILTER_LINEAR; sSampler.state.magFilter = izanagi::graph::E_GRAPH_TEX_FILTER_LINEAR; sSampler.state.addrU = izanagi::graph::E_GRAPH_TEX_ADDRESS_CLAMP; sSampler.state.addrV = izanagi::graph::E_GRAPH_TEX_ADDRESS_CLAMP; CParamUtil::SetNameAndSemantic(sSampler, param); VRETURN( CSamplerUtil::SetStateValue( sSampler.state, param)); // 対象となるテクスチャとのバインド情報を設定 VRETURN( CSamplerUtil::BindTexture( sSampler.state, param, m_TexList)); if (passIdx >= 0) { // シェーダ定数テーブルを作成 IZ_ASSERT(passIdx < m_CompiledPSList.size()); izanagi::tool::CSimpleMemoryAllocator allocator; izanagi::tool::CShaderConstTableLite* constTbl = izanagi::tool::CShaderConstTableLite::CreateShaderConstTableLite( &allocator, m_CompiledPSList[passIdx]); const char* paramName = ::cgGetParameterName(param); sSampler.resource_id = constTbl->GetSamplerIndex(paramName); SAFE_RELEASE(constTbl); } else { // ある? sSampler.resource_id = -1; } } m_SamplerList.push_back(param); // 出力 VRETURN(ExportData(sSampler)); smplHeader.numSampler++; } } param = ::cgGetNextParameter(param); } // Return to paremter's header position with anchor. VRETURN(cSeekHelper.ReturnWithAnchor()); // Export paramter's header. IZ_OUTPUT_WRITE_VRETURN(&m_Out, &smplHeader, 0, sizeof(smplHeader)); // Return to anchored position. VRETURN(cSeekHelper.ReturnToAnchor()); return TRUE; }
// パス解析 BOOL CShaderConverter::ExportPass(const SShaderConfig& config) { _ExportChunkHeader(m_Out, izanagi::shader::SHD_CHUNK_MAGIC_NUMBER_PASS); izanagi::shader::S_SHD_PASS_HEADER sPassHeader; FILL_ZERO(&sPassHeader, sizeof(sPassHeader)); // Blank for pass's header. izanagi::tool::CIoStreamSeekHelper cSeekHelper(&m_Out); VRETURN(_BeginExportChunk(sPassHeader, cSeekHelper)); IZ_UINT nTechIdx = 0; IZ_UINT nPassIdx = 0; IZ_UINT nConstNum = 0; IZ_UINT nSamplerNum = 0; CGtechnique tech = ::cgGetFirstTechnique(m_pCgEffect); while (tech != NULL) { CGpass pass = ::cgGetFirstPass(tech); while (pass != NULL) { izanagi::shader::S_SHD_PASS sPass; { FILL_ZERO(&sPass, sizeof(sPass)); IZ_PCSTR name = ::cgGetPassName(pass); IZ_UINT pos = CStringChunk::GetInstance().Register(name); //sPass.name = *(IZ_PCSTR*)(&pos); sPass.posName = pos; sPass.keyName = izanagi::CKey::GenerateValue(name); sPass.TechniqueIdx = nTechIdx; sPass.numConst = _GetUsedParamNum(m_ParamList, pass); sPass.numSampler = _GetUsedParamNum(m_SamplerList, pass); sPass.sizeVS = _GetFileSize(config, m_CompiledVSList[nPassIdx]); sPass.sizePS = _GetFileSize(config, m_CompiledPSList[nPassIdx]); nConstNum += sPass.numConst; nSamplerNum += sPass.numSampler; } VRETURN( CPassUtil::SetStateValue( sPass.state, pass)); // 出力 VRETURN(ExportData(sPass)); pass = ::cgGetNextPass(pass); nPassIdx++; IZ_UINT nMax = IZ_MAX(sPass.sizeVS, sPass.sizePS); m_ShdHeader.maxProgamSize = IZ_MAX(m_ShdHeader.maxProgamSize, nMax); sPassHeader.numPass++; } tech = ::cgGetNextTechnique(tech); nTechIdx++; } m_ShdHeader.numPass = sPassHeader.numPass; // NOTE // 全体でのシェーダ定数、サンプラの総数を知りたい m_ShdHeader.numParam = nConstNum; m_ShdHeader.numSmpl = nSamplerNum; VRETURN(ExportUsedParamAndSamplerIdxByPass()); VRETURN(_EndExportChunk(sPassHeader, cSeekHelper)); return TRUE; }
/** * パラメータ解析 */ BOOL CShaderConverter::ExportParameter(const SShaderConfig& config) { _ExportChunkHeader(m_Out, izanagi::shader::SHD_CHUNK_MAGIC_NUMBER_PARAM); izanagi::shader::S_SHD_PARAM_HEADER sParamHeader; FILL_ZERO(&sParamHeader, sizeof(sParamHeader)); // Blank for parameter's header. izanagi::tool::CIoStreamSeekHelper cSeekHelper(&m_Out); VRETURN(_BeginExportChunk(sParamHeader, cSeekHelper)); IZ_UINT nAnnIdx = 0; // For description. CGparameter param = ::cgGetFirstEffectParameter(m_pCgEffect); while (param != NULL) { if (CParamUtil::IsParameter(param)) { // For Debug... IZ_PCSTR name = ::cgGetParameterName(param); VRETURN(CParamUtil::IsValidParameter(param)); izanagi::shader::S_SHD_PARAMETER sParam; FILL_ZERO(&sParam, sizeof(sParam)); sParam.DoNotStrip = CParamUtil::DoNotStrip(param); BOOL bIsUsedInEffect = ::cgIsParameterUsed(param, m_pCgEffect); #if 0 if (sParam.DoNotStrip || DoNotRemoveParam(param)) #else if (bIsUsedInEffect || sParam.DoNotStrip) #endif { CParamUtil::SetNameAndSemantic(sParam, param); VRETURN( CParamUtil::SetDescValue( config, sParam, param)); if (sParam.hasAnn) { sParam.AnnotationIdx = nAnnIdx++; } // Register initial value. VRETURN( CParamUtil::GetInitValue( sParam, param)); if (config.type == izanagi::E_PLATFORM_GLES2) { // For GLES2 #if 0 if (izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT1x1 <= sParam.Type && sParam.Type <= izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT4x4) { // TODO sParam.Type = izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT4; sParam.Elements = (sParam.Elements > 0 ? sParam.Elements * 4 : 4); } #else switch (sParam.Type) { case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT1x1: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT1x2: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT1x3: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT1x4: sParam.Type = izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT; //sParam.Elements = (sParam.Elements > 0 ? sParam.Elements * 1 : 1); break; case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT2x1: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT2x2: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT2x3: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT2x4: sParam.Type = izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT2; //sParam.Elements = (sParam.Elements > 0 ? sParam.Elements * 2 : 2); break; case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT3x1: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT3x2: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT3x3: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT3x4: sParam.Type = izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT3; //sParam.Elements = (sParam.Elements > 0 ? sParam.Elements * 3 : 3); break; case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT4x1: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT4x2: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT4x3: case izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT4x4: sParam.Type = izanagi::shader::E_SHADER_PARAMETER_TYPE_FLOAT4; //sParam.Elements = (sParam.Elements > 0 ? sParam.Elements * 4 : 4); break; } //printf(" Rows(%d) Columns(%d) Elements(%d)\n", sParam.Rows, sParam.Columns, sParam.Elements); #endif } m_ParamList.push_back(param); // 出力 VRETURN(ExportData(sParam)); sParamHeader.numParameter++; } } param = ::cgGetNextParameter(param); } VRETURN(ExportParamAnn(sParamHeader, nAnnIdx)); // Export initial value. sParamHeader.sizeValueBuffer = CDataBuffer::GetInstance().GetBufferSize(); if (sParamHeader.sizeValueBuffer > 0) { const void* pBuf = CDataBuffer::GetInstance().GetBuffer(); IZ_OUTPUT_WRITE_VRETURN( &m_Out, pBuf, 0, sParamHeader.sizeValueBuffer); } //m_ShdHeader.numParam = sParamHeader.numParameter; VRETURN(_EndExportChunk(sParamHeader, cSeekHelper)); return TRUE; }
BOOL CShaderConverter::ExportSampler(const SShaderConfig& config) { VRETURN(_ExportChunkHeader(m_Out, izanagi::shader::SHD_CHUNK_MAGIC_NUMBER_SMPL)); izanagi::shader::S_SHD_SAMPLER_HEADER sSmplHeader; FILL_ZERO(&sSmplHeader, sizeof(sSmplHeader)); // Blank for texture's header. izanagi::tool::CIoStreamSeekHelper cSeekHelper(&m_Out); VRETURN(_BeginExportChunk(sSmplHeader, cSeekHelper)); CGparameter param = ::cgGetFirstEffectParameter(m_pCgEffect); // パスを取得 std::vector<CGpass> passList; { CGtechnique tech = ::cgGetFirstTechnique(m_pCgEffect); while (tech != NULL) { CGpass pass = ::cgGetFirstPass(tech); while (pass != NULL) { passList.push_back(pass); pass = ::cgGetNextPass(pass); } tech = ::cgGetNextTechnique(tech); } } while (param != NULL) { if (::cgIsParameterUsed(param, m_pCgEffect)) { VRETURN(CParamUtil::IsValidParameter(param)); if (CParamUtil::IsSampler(param)) { // 対象となるパスのインデックスを取得 IZ_INT passIdx = -1; for (IZ_UINT i = 0; i < passList.size(); i++) { if (::cgIsParameterUsed(param, passList[i])) { passIdx = i; break; } } izanagi::shader::S_SHD_SAMPLER sSampler; { FILL_ZERO(&sSampler, sizeof(sSampler)); sSampler.state.minFilter = izanagi::graph::E_GRAPH_TEX_FILTER_LINEAR; sSampler.state.magFilter = izanagi::graph::E_GRAPH_TEX_FILTER_LINEAR; sSampler.state.mipFilter = izanagi::graph::E_GRAPH_TEX_FILTER_LINEAR; sSampler.state.addressU = izanagi::graph::E_GRAPH_TEX_ADDRESS_CLAMP; sSampler.state.addressV = izanagi::graph::E_GRAPH_TEX_ADDRESS_CLAMP; CParamUtil::SetNameAndSemantic(sSampler, param); CGtype type = CParamUtil::GetCgType(param); sSampler.Type = CShaderConvUtil::CgParamTypeToIzanagiShaderParamType(type); VRETURN( CSamplerUtil::SetStateValue( sSampler, param)); // 対象となるテクスチャとのバインド情報を設定 VRETURN( CSamplerUtil::BindTexture( sSampler, param, m_TexList)); if (passIdx >= 0) { // シェーダ定数テーブルを作成 IZ_ASSERT(passIdx < m_CompiledPSList.size()); if (config.type == izanagi::E_PLATFORM_DX9) { izanagi::tool::CSimpleMemoryAllocator allocator; // ピクセルシェーダを読み込む izanagi::tool::CShaderConstTableLite* constTbl = izanagi::tool::CShaderConstTableLite::CreateShaderConstTableLite( &allocator, m_CompiledPSList[passIdx].c_str()); const char* paramName = ::cgGetParameterName(param); // シェーダからサンプラのインデックスを取得 sSampler.resource_id = constTbl->GetSamplerIndex(paramName); SAFE_RELEASE(constTbl); } else if (config.type == izanagi::E_PLATFORM_GLES2) { const char* paramName = ::cgGetParameterName(param); // ShaderCompilerに任せる izanagi::tool::CString command; command.format( "%s --analyze %s %s\0", config.compiler.c_str(), m_CompiledPSList[passIdx].c_str(), paramName); // ShaderCompilerを起動 FILE* fp = _popen(command.c_str(), "r"); VRETURN(fp != NULL); static char buf[4]; // 標準出力に出力された数値を取得 while(fgets(buf, sizeof(buf), fp) != NULL) { int index = ::atoi(buf); sSampler.resource_id = index; } int result = _pclose(fp); VRETURN(result == 0); } else { IZ_ASSERT(IZ_FALSE); } } else { // ある? sSampler.resource_id = -1; } } m_SamplerList.push_back(param); // 出力 VRETURN(ExportData(sSampler)); sSmplHeader.numSampler++; } } param = ::cgGetNextParameter(param); } //m_ShdHeader.numSmpl = sSmplHeader.numSampler; VRETURN(_EndExportChunk(sSmplHeader, cSeekHelper)); return TRUE; }
IZ_BOOL CMdlExporter::Export( IZ_UINT maxJointMtxNum, IZ_PCSTR lpszOutFile, IImporter* pImporter) { IZ_BOOL ret = IZ_TRUE; VRETURN(m_Out.Open(lpszOutFile)); izanagi::S_MDL_HEADER sHeader; { FILL_ZERO(&sHeader, sizeof(sHeader)); sHeader.sizeHeader = sizeof(sHeader); } // Blank for file's header. izanagi::tool::CIoStreamSeekHelper cSeekHelper(&m_Out); VGOTO(ret = cSeekHelper.Skip(sizeof(sHeader)), __EXIT__); #if 0 #if 1 // geometry chunk ret = CGeometryChunk::GetInstance().Export( &m_Out, pImporter); CGeometryChunk::GetInstance().Clear(); VGOTO(ret, __EXIT__); #endif #if 1 // joint chunk ret = CJointChunk::Export( &m_Out, pImporter); VGOTO(ret, __EXIT__); #endif // Export terminater. { izanagi::S_MDL_CHUNK_HEADER sChunkHeader; sChunkHeader.magicChunk = izanagi::MDL_CHUNK_MAGIC_TERMINATE; IZ_OUTPUT_WRITE_VRETURN(&m_Out, &sChunkHeader, 0, sizeof(sChunkHeader)); } // Export files's header. { sHeader.sizeFile = m_Out.GetCurPos(); const izanagi::math::SVector4& vMin = CGeometryChunk::GetInstance().GetMin(); const izanagi::math::SVector4& vMax = CGeometryChunk::GetInstance().GetMax(); sHeader.minVtx[0] = vMin.x; sHeader.minVtx[1] = vMin.y; sHeader.minVtx[2] = vMin.z; sHeader.maxVtx[0] = vMax.x; sHeader.maxVtx[1] = vMax.y; sHeader.maxVtx[2] = vMax.z; VRETURN(cSeekHelper.Return()); IZ_OUTPUT_WRITE_VRETURN(&m_Out, &sHeader, 0, sizeof(sHeader)); } #else // Mesh chunk. { izanagi::S_MDL_CHUNK_HEADER sChunkHeader; sChunkHeader.magicChunk = izanagi::MDL_CHUNK_MAGIC_MESH; ret = IZ_OUTPUT_WRITE(&m_Out, &sChunkHeader, 0, sizeof(sChunkHeader)); VGOTO(ret, __EXIT__); ret = CGeometryChunk::GetInstance().Export( maxJointMtxNum, &m_Out, pImporter); } // Skeleton chunk. { izanagi::S_MDL_CHUNK_HEADER sChunkHeader; sChunkHeader.magicChunk = izanagi::MDL_CHUNK_MAGIC_SKELETON; ret = IZ_OUTPUT_WRITE(&m_Out, &sChunkHeader, 0, sizeof(sChunkHeader)); VGOTO(ret, __EXIT__); ret = CJointChunk::Export( &m_Out, pImporter); } // Export terminater. { izanagi::S_MDL_CHUNK_HEADER sChunkHeader; sChunkHeader.magicChunk = izanagi::MDL_CHUNK_MAGIC_TERMINATE; ret = IZ_OUTPUT_WRITE(&m_Out, &sChunkHeader, 0, sizeof(sChunkHeader)); VGOTO(ret, __EXIT__); } // Export files's header. { sHeader.sizeFile = m_Out.GetCurPos(); VGOTO(ret = cSeekHelper.Return(), __EXIT__); ret = IZ_OUTPUT_WRITE(&m_Out, &sHeader, 0, sizeof(sHeader)); VGOTO(ret, __EXIT__); } #endif __EXIT__: m_Out.Finalize(); return ret; }