⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shader_linkerdemo.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}

	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 + -