📄 shader_linkerdemo.cpp
字号:
}
LPCREATELINKER pCreate = (LPCREATELINKER)GetProcAddress(m_hLinker, "CreateLinker");
if (!pCreate)
{
m_strLastError = "Could not resolve linker create function in nvlinker.dll";
return E_FAIL;
}
m_pLinker = pCreate();
hr = LoadFragmentFile("miscvertex.nvo");
if (FAILED(hr))
return hr;
hr = LoadFragmentFile("lighting.nvo");
if (FAILED(hr))
return hr;
hr = LoadFragmentFile("objectspace.nvo");
if (FAILED(hr))
return hr;
hr = LoadFragmentFile("eyespace.nvo");
if (FAILED(hr))
return hr;
hr = LoadFragmentFile("basisskinning.nvo");
if (FAILED(hr))
return hr;
// In linker 1.0 we have to do this manually. In version 2 there will be an option to dump a header file
// with a table of #defines and names from the link.exe utility.
// Get the framgent ID's
ZeroMemory(&m_FragmentID, sizeof(m_FragmentID));
m_pLinker->GetFragmentID("set_ambient", &m_FragmentID[F_SET_AMBIENT]);
m_pLinker->GetFragmentID("set_default_texture", &m_FragmentID[F_SET_DEFAULT_TEXTURE]);
m_pLinker->GetFragmentID("xform_worldviewprojection", &m_FragmentID[F_XFORM_WORLDVIEWPROJECTION]);
m_pLinker->GetFragmentID("set_power", &m_FragmentID[F_SET_POWER]);
m_pLinker->GetFragmentID("clamp_diffuse_exponentiate_specular", &m_FragmentID[F_CLAMP_DIFFUSE_EXPONENTIATE_SPECULAR]);
// Point
m_pLinker->GetFragmentID("pointlight_accumulate_diffuse", &m_FragmentID[F_POINTLIGHT_ACCUMULATE_DIFFUSE]);
m_pLinker->GetFragmentID("pointlight_accumulate_diffuse_last", &m_FragmentID[F_POINTLIGHT_ACCUMULATE_DIFFUSE_LAST]);
m_pLinker->GetFragmentID("pointlight_accumulate_specular_first", &m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_FIRST]);
m_pLinker->GetFragmentID("pointlight_accumulate_specular", &m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR]);
m_pLinker->GetFragmentID("pointlight_accumulate_specular_last", &m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_LAST]);
m_pLinker->GetFragmentID("pointlight_accumulate_specular_first_and_last", &m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_FIRST_AND_LAST]);
// Directional
m_pLinker->GetFragmentID("dirlight_accumulate_diffuse", &m_FragmentID[F_DIRLIGHT_ACCUMULATE_DIFFUSE]);
m_pLinker->GetFragmentID("dirlight_accumulate_diffuse_last", &m_FragmentID[F_DIRLIGHT_ACCUMULATE_DIFFUSE_LAST]);
m_pLinker->GetFragmentID("dirlight_accumulate_specular_first", &m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_FIRST]);
m_pLinker->GetFragmentID("dirlight_accumulate_specular", &m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR]);
m_pLinker->GetFragmentID("dirlight_accumulate_specular_last", &m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_LAST]);
m_pLinker->GetFragmentID("dirlight_accumulate_specular_first_and_last", &m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_FIRST_AND_LAST]);
// Eyespace
m_pLinker->GetFragmentID("create_eyespace_vertex", &m_FragmentID[F_CREATE_EYESPACE_VERTEX]);
m_pLinker->GetFragmentID("create_eyespace_eyevector_local_viewer", &m_FragmentID[F_CREATE_EYESPACE_EYEVECTOR_LOCAL_VIEWER]);
m_pLinker->GetFragmentID("create_eyespace_normal", &m_FragmentID[F_CREATE_EYESPACE_NORMAL]);
m_pLinker->GetFragmentID("calculate_eyespace_reflection", &m_FragmentID[F_CALCULATE_EYESPACE_REFLECTION]);
m_pLinker->GetFragmentID("calculate_eyespace_directionallight_diffuse_and_specular_intensity_nonlocalviewer", &m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
m_pLinker->GetFragmentID("calculate_eyespace_directionallight_diffuse_and_specular_intensity_localviewer", &m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
m_pLinker->GetFragmentID("calculate_eyespace_directionallight_diffuse_intensity", &m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_INTENSITY]);
m_pLinker->GetFragmentID("calculate_eyespace_directionallight_diffuse_and_specular_intensity_rdotl", &m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
m_pLinker->GetFragmentID("calculate_eyespace_pointlight_vector", &m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_VECTOR]);
m_pLinker->GetFragmentID("calculate_eyespace_pointlight_diffuse_intensity", &m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_INTENSITY]);
m_pLinker->GetFragmentID("calculate_eyespace_pointlight_diffuse_and_specular_intensity_localviewer", &m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
m_pLinker->GetFragmentID("calculate_eyespace_pointlight_diffuse_and_specular_intensity_nonlocalviewer", &m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
m_pLinker->GetFragmentID("calculate_eyespace_pointlight_diffuse_and_specular_intensity_rdotl", &m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
// Basis skinning
m_pLinker->GetFragmentID("calculate_basis_vectors", &m_FragmentID[F_CALCULATE_BASIS_VECTORS]);
// Object space
m_pLinker->GetFragmentID("create_objectspace_eyevector_local_viewer", &m_FragmentID[F_CREATE_OBJECTSPACE_EYEVECTOR_LOCAL_VIEWER]);
m_pLinker->GetFragmentID("calculate_objectspace_reflection", &m_FragmentID[F_CALCULATE_OBJECTSPACE_REFLECTION]);
m_pLinker->GetFragmentID("calculate_cubereflection_vector", &m_FragmentID[F_CALCULATE_CUBEREFLECTION_VECTOR]);
m_pLinker->GetFragmentID("calculate_linear_range_fog", &m_FragmentID[F_CALCULATE_LINEAR_RANGE_FOG]);
m_pLinker->GetFragmentID("calculate_objectspace_directionallight_diffuse_and_specular_intensity_nonlocalviewer", &m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
m_pLinker->GetFragmentID("calculate_objectspace_directionallight_diffuse_and_specular_intensity_localviewer", &m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
m_pLinker->GetFragmentID("calculate_objectspace_directionallight_diffuse_and_specular_intensity_rdotl", &m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
m_pLinker->GetFragmentID("calculate_objectspace_directionallight_diffuse_intensity", &m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_INTENSITY]);
m_pLinker->GetFragmentID("calculate_objectspace_pointlight_vector", &m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_VECTOR]);
m_pLinker->GetFragmentID("calculate_objectspace_pointlight_diffuse_intensity", &m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_INTENSITY]);
m_pLinker->GetFragmentID("calculate_objectspace_pointlight_diffuse_and_specular_intensity_localviewer", &m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
m_pLinker->GetFragmentID("calculate_objectspace_pointlight_diffuse_and_specular_intensity_nonlocalviewer", &m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
m_pLinker->GetFragmentID("calculate_objectspace_pointlight_diffuse_and_specular_intensity_rdotl", &m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
m_pLinker->GetFragmentID("calculate_basis_vectors", &m_FragmentID[F_CALCULATE_BASIS_VECTORS]);
m_pLinker->GetFragmentID("write_texture", &m_FragmentID[F_WRITE_TEXTURE]);
m_pLinker->GetFragmentID("write_default_diffuse", &m_FragmentID[F_WRITE_DEFAULT_DIFFUSE]);
m_pLinker->GetFragmentID("write_default_texture", &m_FragmentID[F_WRITE_DEFAULT_TEXTURE]);
m_pLinker->GetFragmentID("write_default_specular", &m_FragmentID[F_WRITE_DEFAULT_SPECULAR]);
ZeroMemory(&m_ConstantID, sizeof(m_ConstantID));
m_pLinker->GetConstantID("c_dirlight_halfvector", &m_ConstantID[C_DIRLIGHT_HALFVECTOR]);
m_pLinker->GetConstantID("c_ambient_light", &m_ConstantID[C_AMBIENT_LIGHT]);
m_pLinker->GetConstantID("c_constants", &m_ConstantID[C_CONSTANTS]);
m_pLinker->GetConstantID("c_objectspace_eyevector", &m_ConstantID[C_OBJECTSPACE_EYEVECTOR]);
m_pLinker->GetConstantID("c_objectspace_eyeposition", &m_ConstantID[C_OBJECTSPACE_EYEPOSITION]);
m_pLinker->GetConstantID("c_eyespace_eyevector", &m_ConstantID[C_EYESPACE_EYEVECTOR]);
m_pLinker->GetConstantID("c_worldviewprojection_0", &m_ConstantID[C_WORLDVIEWPROJECTION_0]);
m_pLinker->GetConstantID("c_worldviewprojection_1", &m_ConstantID[C_WORLDVIEWPROJECTION_1]);
m_pLinker->GetConstantID("c_worldviewprojection_2", &m_ConstantID[C_WORLDVIEWPROJECTION_2]);
m_pLinker->GetConstantID("c_worldviewprojection_3", &m_ConstantID[C_WORLDVIEWPROJECTION_3]);
m_pLinker->GetConstantID("c_worldviewit_0", &m_ConstantID[C_WORLDVIEWIT_0]);
m_pLinker->GetConstantID("c_worldviewit_1", &m_ConstantID[C_WORLDVIEWIT_1]);
m_pLinker->GetConstantID("c_worldviewit_2", &m_ConstantID[C_WORLDVIEWIT_2]);
m_pLinker->GetConstantID("c_worldview_0", &m_ConstantID[C_WORLDVIEW_0]);
m_pLinker->GetConstantID("c_worldview_1", &m_ConstantID[C_WORLDVIEW_1]);
m_pLinker->GetConstantID("c_worldview_2", &m_ConstantID[C_WORLDVIEW_2]);
m_pLinker->GetConstantID("c_worldview_3", &m_ConstantID[C_WORLDVIEW_3]);
m_pLinker->GetConstantID("c_worldviewcubemap_0", &m_ConstantID[C_WORLDVIEWCUBEMAP_0]);
m_pLinker->GetConstantID("c_worldviewcubemap_1", &m_ConstantID[C_WORLDVIEWCUBEMAP_1]);
m_pLinker->GetConstantID("c_worldviewcubemap_2", &m_ConstantID[C_WORLDVIEWCUBEMAP_2]);
m_pLinker->GetConstantID("c_cubematrix_0", &m_ConstantID[C_CUBEMATRIX_0]);
m_pLinker->GetConstantID("c_cubematrix_1", &m_ConstantID[C_CUBEMATRIX_1]);
m_pLinker->GetConstantID("c_cubematrix_2", &m_ConstantID[C_CUBEMATRIX_2]);
m_pLinker->GetConstantID("c_dirlight_direction", &m_ConstantID[C_DIRLIGHT_DIRECTION]);
m_pLinker->GetConstantID("c_dirlight_diffuse", &m_ConstantID[C_DIRLIGHT_DIFFUSE]);
m_pLinker->GetConstantID("c_dirlight_specular", &m_ConstantID[C_DIRLIGHT_SPECULAR]);
m_pLinker->GetConstantID("c_pointlight_position", &m_ConstantID[C_POINTLIGHT_POSITION]);
m_pLinker->GetConstantID("c_pointlight_diffuse", &m_ConstantID[C_POINTLIGHT_DIFFUSE]);
m_pLinker->GetConstantID("c_pointlight_specular", &m_ConstantID[C_POINTLIGHT_SPECULAR]);
m_pLinker->GetConstantID("c_mat_power", &m_ConstantID[C_MAT_POWER]);
m_pLinker->GetConstantID("c_fogconst", &m_ConstantID[C_FOGCONST]);
ZeroMemory(&m_VertexID, sizeof(m_VertexID));
//m_pLinker->GetVertexID("v_position", &m_VertexID[V_POSITION]); // Fixed position
m_pLinker->GetVertexID("v_normal", &m_VertexID[V_NORMAL]);
m_pLinker->GetVertexID("v_diffuse", &m_VertexID[V_DIFFUSE]);
m_pLinker->GetVertexID("v_specular", &m_VertexID[V_SPECULAR]);
m_pLinker->GetVertexID("v_sbasis0", &m_VertexID[V_SBASIS0]);
m_pLinker->GetVertexID("v_tbasis0", &m_VertexID[V_TBASIS0]);
m_pLinker->GetVertexID("v_sxtbasis0", &m_VertexID[V_SXTBASIS0]);
//m_pLinker->GetVertexID("v_texture0", &m_VertexID[V_TEXTURE0]); // Fixed texture
m_pLinker->GetVertexID("v_texture1", &m_VertexID[V_TEXTURE1]);
m_pLinker->GetVertexID("v_texture2", &m_VertexID[V_TEXTURE2]);
m_pLinker->GetVertexID("v_texture3", &m_VertexID[V_TEXTURE3]);
m_pLinker->GetVertexID("v_texture4", &m_VertexID[V_TEXTURE4]);
m_pLinker->GetVertexID("v_texture5", &m_VertexID[V_TEXTURE5]);
m_pLinker->GetVertexID("v_texture6", &m_VertexID[V_TEXTURE6]);
m_pLinker->GetVertexID("v_texture7", &m_VertexID[V_TEXTURE7]);
#ifdef _DEBUG
// Verify we pulled out the registers we expected
DWORD i;
DWORD y;
for (i = 1; i < F_NUM_FRAGMENTS; i++)
{
assert(m_FragmentID[i] != 0);
for (y = 1; y < F_NUM_FRAGMENTS; y++)
{
if (i != y)
{
assert(m_FragmentID[i] != m_FragmentID[y]);
}
}
}
for (i = 1; i < C_NUM_CONSTANTS; i++)
{
assert(m_ConstantID[i] != 0);
for (y = 1; y < C_NUM_CONSTANTS; y++)
{
if (i != y)
{
assert(m_ConstantID[i] != m_ConstantID[y]);
}
}
}
#endif
// get the D3D device
m_pD3DDev = pDev;
pDev->AddRef();
g_pNVStateManager = new NVStateManager(m_pD3DDev);
g_pNVResourceManager = new NVResourceManager(m_pD3DDev);
//initialize mouse UI
RECT rect;
rect.left = rect.top = 0;
D3DVIEWPORT8 viewport;
m_pD3DDev->GetViewport(&viewport);
rect.bottom = viewport.Height;
rect.right = viewport.Width;
m_pUI = new MouseUI((const RECT)rect);
m_pUI->SetTranslationalSensitivityFactor(0.1f);
m_Eye = EyeStart;
m_LookAt.x = m_Eye.x;
m_LookAt.y = m_Eye.y;
m_LookAt.z = m_Eye.z + 1.0f;
m_Up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&m_matView, &m_Eye, &m_LookAt, &m_Up);
D3DXMatrixPerspectiveFovLH(&m_matProjection,
D3DXToRadian(60.0f),
1,
0.2f,
50.0f);
NVSTATEMANAGER.SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&m_matProjection);
hr = LoadLightObjects();
if (FAILED(hr))
{
m_strLastError = "Failed to create light objects";
return hr;
}
D3DCAPS8 DeviceCaps;
m_pD3DDev->GetDeviceCaps(&DeviceCaps);
m_bSupportsNormalMap = false;
if(D3DSHADER_VERSION_MAJOR(DeviceCaps.PixelShaderVersion) >= 1)
{
// Create a heightmap resource
NVResourceID HeightMapID = NVRESOURCEMANAGER.AddResource(new NVTextureFileResource(m_pD3DDev,
GetFilePath("bump_map_nvidia.dds"),
NVTextureFileResource::TextureType_2D,
D3DX_DEFAULT,
D3DX_DEFAULT,
0,
0,
D3DFMT_A8R8G8B8), "DefaultHeightMap");
if (NVTextureResource::GetTexture(HeightMapID) == NULL)
{
m_strLastError = "Failed to create HeightMap (bump_map_nvidia.dds)";
return E_FAIL;
}
// Create a normal map resource, based off a height map resource
NVResourceID NormalMapID = NVRESOURCEMANAGER.AddResource(new NVTextureNormalMapFromResource(m_pD3DDev, HeightMapID, (D3DFORMAT)MAKEFOURCC('N', 'V', 'H', 'S'), D3DPOOL_DEFAULT), "DefaultNormalMap");
if (NVTextureResource::GetTexture(NormalMapID) != NULL)
{
m_bSupportsNormalMap = true;
// Pixel shader for bumpmaps
hr = LoadAndCreateShader(GetFilePath("linkerpixels.pso"), NULL, 0, SHADERTYPE_PIXEL, &m_dwBumpPixelShader);
if (FAILED(hr))
{
return NULL;
}
}
}
NVRESOURCEMANAGER.AddResource(new NVTextureFileResource(m_pD3DDev, GetFilePath("gloss_map_nvidia.dds")), "DefaultGlossMap");
if (NVTextureResource::GetTexture("DefaultGlossMap") == NULL)
{
m_strLastError = "Failed to create glossmap (gloss_map_nvidia.dds)";
return E_FAIL;
}
m_bSupportsCubeMap = true;
if (!(DeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
{
m_bSupportsCubeMap = false;
}
if (m_bSupportsCubeMap)
{
NVRESOURCEMANAGER.AddResource(new NVTextureFileResource(m_pD3DDev, GetFilePath("nvlobby_cube_mipmap.dds"), NVTextureFileResource::TextureType_CubeMap), "CubeMap");
if (NVTextureResource::GetTexture("CubeMap") == NULL)
{
m_strLastError = "Failed to create cubemap (nvlobby_cube_mipmap.dds)";
return E_FAIL;
}
}
if (!m_bSupportsNormalMap && (m_Settings.m_TexGen == TEXGEN_BLINNBUMPREFLECTION))
{
m_Settings.m_TexGen = TEXGEN_CAMERASPACEREFLECTION;
}
if (!m_bSupportsCubeMap && (m_Settings.m_TexGen == TEXGEN_CAMERASPACEREFLECTION))
{
m_Settings.m_TexGen = TEXGEN_NONE;
}
m_Settings.m_bEnableBump = m_bSupportsNormalMap;
m_Settings.m_bEnableReflect = m_bSupportsCubeMap;
UpdateLights();
if (m_bSupportsCubeMap)
{
hr = CreateCubeEnvironment();
if (FAILED(hr))
{
if (m_strLastError.empty())
m_strLastError = "Failed to create cube environment";
return hr;
}
}
hr = LoadMesh(m_strFileName.c_str());
if (FAILED(hr))
{
if (m_strLastError.empty())
m_strLastError = "Failed to load " + m_strFileName;
return hr;
}
hr = UpdateShader();
// Don't want culling
NVSTATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
// Setup fogging for potential use by the vertex shader
NVSTATEMANAGER.SetRenderState( D3DRS_FOGCOLOR, 0xFFFFFFFF);
NVSTATEMANAGER.SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
NVSTATEMANAGER.SetRenderState( D3DRS_FOGVERTEXMODE, D3DFOG_NONE );
NVSTATEMANAGER.SetRenderState( D3DRS_RANGEFOGENABLE, FALSE );
m_vecFogData.x = 1.0f; // Fog Start
m_vecFogData.y = 4.0f; // Fog End
m_vecFogData.z = 1.0f / (m_vecFogData.y - m_vecFogData.x); // Fog range
m_vecFogData.w = 255.0f;
// Default stage 0 is to have texture in 0, diffuse in 1.
NVSTATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
NVSTATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
return S_OK;
}
void CShaderLinkerDemo::UpdateMeshVertexSlots()
{
// Fill in the required vertex stream locations
// Here we are doing 2 things.
// We are setting up our declation to match the streams.
// We are telling the mesh object where to put each stream (and therefore 'enabling' that stream)
NVComplexMeshVertexData* pVertexData;
DWORD dwLocation;
DWORD dwStreamPosition = 0;
m_MeshDeclaration.clear();
m_MeshDeclaration.push_back(D3DVSD_STREAM(0));
pVertexData = m_pMesh->FindVertexData("position");
if (pVertexData)
{
// Position data is always in v0, because we want it that way
m_MeshDeclaration.push_back(D3DVSD_REG(FIXED_POSITION_LOCATION, pVertexData->GetDataType()));
pVertexData->SetLocation(dwStreamPosition++);
}
pVertexData = m_pMesh->FindVertexData("normal");
if (pVertexData)
{
m_pLinker->GetVertexSlot(m_VertexID[V_NORMAL], &dwLocation);
if (dwLocation != NVLINK_NOT_USED)
{
m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
pVertexData->SetLocation(dwStreamPosition++);
}
else
{
pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
}
}
pVertexData = m_pMesh->FindVertexData("diffuse");
if (pVertexData)
{
m_pLinker->GetVertexSlot(m_VertexID[V_DIFFUSE], &dwLocation);
if (dwLocation != NVLINK_NOT_USED)
{
m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
pVertexData->SetLocation(dwStreamPosition++);
}
else
{
pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
}
}
pVertexData = m_pMesh->FindVertexData("specular");
if (pVertexData)
{
m_pLinker->GetVertexSlot(m_VertexID[V_SPECULAR], &dwLocation);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -