The following example vertex declaration (HLSL/Cg syntax) is used as a reference to define a series of terms the SDK uses to define supporting data types used in the vertex data accessing functions and classes:
// example vertex declaration, HLSL/Cg syntax struct SVertexDecl { float3 vSlot0 : POSITION; // xyz = position.xyz float4 vSlot1 : TEXCOORD0; // xy = diffuse texcoords, z = amb occ, w = normal.z };
Terms:
The structure SVertexDecl is declared in Core.h and defined in the Core library. Each render state for a given tree defines a single SVertexDecl vertex declaration, which contains a complete vertex declaration organized in a way that makes it easy to access by attribute or by property. To explore the definition by attribute, access the SVertexDecl::m_asAttributes array as in the following example:
/////////////////////////////////////////////////////////////////////// // VertexDecl_ByAttribute void VertexDecl_ByAttribute(void) { const char* pFilename = "example.srt"; CCore* pTree = Internal_LoadSrtFile(pFilename); if (pTree) { const SGeometry* pGeometry = pTree->GetGeometry( ); if (pGeometry->m_nNum3dRenderStates > 0) { // grab the first render state to use for example const SVertexDecl& sDecl = pGeometry->m_p3dRenderStates[SHADER_PASS_LIT][0].m_sVertexDecl; for (int i = 0; i < VERTEX_ATTRIB_COUNT; ++i) { const SVertexDecl::SAttribute& sAttrib = sDecl.m_asAttributes[i]; if (sAttrib.IsUsed( )) { printf("%s in use:\n", SVertexDecl::AttributeName(i)); printf(" Num components: %d\n", sAttrib.NumUsedComponents( )); printf(" Format: %s\n", SVertexDecl::FormatName(sAttrib.m_eFormat)); // print per-componenet info const char* c_apCompNames[ ] = { "x", "y", "z", "w" }; for (int j = 0; j < sAttrib.NumUsedComponents( ); ++j) { printf(" [%s.%s], ", SVertexDecl::AttributeName(i), c_apCompNames[j]); printf("byte offset %d, ", sAttrib.m_auiVertexOffsets[j]); printf("holds [%s.%s]\n", SVertexDecl::PropertyName(sAttrib.m_aeProperties[j]), c_apCompNames[sAttrib.m_aePropertyComponents[j]]); } printf("\n"); } } } st_delete(pTree); } else Error("Failed to load [%s]: %s\n", pFilename, CCore::GetError( )); }
Note that in the output of this example, you may see some “pad.x” entries, which is simply padding the unused parts of some attributes.
To explore the definition by property, access the SVertexDecl::m_asProperties array as in this example:
/////////////////////////////////////////////////////////////////////// // VertexDecl_ByProperty void VertexDecl_ByProperty(void) { const char* pFilename = "example.srt"; CCore* pTree = Internal_LoadSrtFile(pFilename); if (pTree) { const SGeometry* pGeometry = pTree->GetGeometry( ); if (pGeometry && pGeometry->m_nNum3dRenderStates > 0) { // grab the first render state to use for example const SVertexDecl& sDecl = pGeometry->m_p3dRenderStates[SHADER_PASS_LIT][0].m_sVertexDecl; for (int i = 0; i < VERTEX_PROPERTY_COUNT; ++i) { const SVertexDecl::SProperty& sProp = sDecl.m_asProperties[i]; if (sProp.IsPresent( )) { printf("[%s]\n", SVertexDecl::PropertyName(i)); printf(" uses %d %s%s\n", sProp.NumComponents( ), SVertexDecl::FormatName(sProp.m_eFormat), sProp.NumComponents( ) > 1 ? "s" : ""); const char* c_apCompNames[ ] = { "x", "y", "z", "w" }; for (int j = 0; j < sProp.NumComponents( ); ++j) { printf(" [%s.%s] stored in [%s.%s]\n", SVertexDecl::PropertyName(i), c_apCompNames[j], SVertexDecl::AttributeName(sProp.m_aeAttribs[j]), c_apCompNames[sProp.m_aeAttribComponents[j]]); } printf("\n"); } } } st_delete(pTree); } else Error("Failed to load [%s]: %s\n", pFilename, CCore::GetError( )); }