📄 shader_linkerdemo.cpp
字号:
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("sbasis0");
if (pVertexData)
{
m_pLinker->GetVertexSlot(m_VertexID[V_SBASIS0], &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("tbasis0");
if (pVertexData)
{
m_pLinker->GetVertexSlot(m_VertexID[V_TBASIS0], &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("sxtbasis0");
if (pVertexData)
{
m_pLinker->GetVertexSlot(m_VertexID[V_SXTBASIS0], &dwLocation);
if (dwLocation != NVLINK_NOT_USED)
{
m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
pVertexData->SetLocation(dwStreamPosition++);
}
else
{
pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
}
}
for (DWORD i = 0; i < NV_MAX_TEXTURES; i++)
{
string strBuff;
strBuff.resize(2);
ultoa(i, &strBuff[0], 2);
string texname = "texture" + strBuff;
texname = texname.substr(0, strlen(texname.c_str()));
pVertexData = m_pMesh->FindVertexData(texname.c_str());
if (pVertexData)
{
if (i == 0)
{
// We have chosen to place texture 0 at a fixed location.
dwLocation = FIXED_TEXTURE0_LOCATION;
}
else
{
m_pLinker->GetVertexSlot(m_VertexID[V_TEXTURE0 + i], &dwLocation);
}
if (dwLocation != NVLINK_NOT_USED)
{
m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
pVertexData->SetLocation(dwStreamPosition++);
}
else
{
pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
}
}
}
// Finish the decleration and create the shader
m_MeshDeclaration.push_back(D3DVSD_END());
}
HRESULT CShaderLinkerDemo::UpdateShader()
{
HRESULT hr;
std::string strOutFile;
HANDLE hFile;
DWORD dwNumWritten;
DWORD dwLocation;
DWORD i;
if (m_dwPass0Shader)
{
m_pD3DDev->DeleteVertexShader(m_dwPass0Shader);
m_dwPass0Shader = 0;
}
if (m_dwPass1Shader)
{
m_pD3DDev->DeleteVertexShader(m_dwPass1Shader);
m_dwPass1Shader = 0;
}
// Force a change to a default vertex shader because the deletes above will upset us otherwise.
NVSTATEMANAGER.SetVertexShader(D3DFVF_XYZ);
NVSTATEMANAGER.FlushVertexShader();
// Create the required shader.
// ThisShader is an array of DWORDS that can grow. Each push_back call adds another DWORD to the array.
// STL is nice like this because it eliminates stupid errors with over-filling arrays. Of course the drawback
// is dynamic allocation, but this is a demo and I'm going for simple.
// The DWORD's we put in are the ID's of the shader components we want to build.
// You can get as intricate as you like about how the shader is layed out. The linker will automatically remove
// the redundant instructions, but you should make every effort to remove redundant code for speed.
vector<DWORD>ThisShader;
DWORD dwNumLights = m_DirectionalLights.size() + m_PointLights.size();
bool bNeedLighting = m_Settings.m_bLighting && (dwNumLights > 0);
bool bNeedSpecular = m_Settings.m_bSpecular && bNeedLighting;
bool bNeedTexture = m_Settings.m_bTextures && m_bHasTextureCoords;
bool bNeedCubeReflection = (m_Settings.m_TexGen == TEXGEN_CAMERASPACEREFLECTION) && bNeedTexture;
bool bNeedFog = (m_Settings.m_Fog != FOG_NONE);
bool bNeedRDotL = bNeedSpecular && m_Settings.m_bSpecularRDotL;
bool bNeedEyeReflection = bNeedCubeReflection || bNeedRDotL;
bool bNeedNormal = bNeedLighting || bNeedCubeReflection;
bool bNeedVertex = bNeedLighting || bNeedCubeReflection || bNeedFog;
bool bNeedEyeVector = (bNeedSpecular && (m_Settings.m_bLocalViewer || m_Settings.m_bSpecularRDotL)) || (bNeedCubeReflection) || (bNeedFog);
bool bNeedBasis = (m_Settings.m_TexGen == TEXGEN_BLINNBUMPREFLECTION) && bNeedTexture;
bool bNeedLit = true;
bool bFirstLight = true;
bool bLastLight = false;
ThisShader.push_back(m_FragmentID[F_XFORM_WORLDVIEWPROJECTION]);
if (m_Settings.m_bEyeSpace)
{
// Create some things we need
if (bNeedVertex)
ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_VERTEX]);
// Specular and reflections require an eye vector
if (bNeedEyeVector)
ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_EYEVECTOR_LOCAL_VIEWER]);
// Reflections and lights require a normal
if (bNeedNormal)
ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_NORMAL]);
if (bNeedFog)
ThisShader.push_back(m_FragmentID[F_CALCULATE_LINEAR_RANGE_FOG]);
if (bNeedEyeReflection)
{
// Camera space reflection is always done with local viewer. This is practical because it can look
// pretty aweful without it.
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_REFLECTION]);
}
// If texgen is on, apply it
if (bNeedCubeReflection)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_CUBEREFLECTION_VECTOR]);
}
if (bNeedLighting)
{
// Add the ambient color, and setup the specular power if needed
ThisShader.push_back(m_FragmentID[F_SET_AMBIENT]);
if (bNeedSpecular)
{
ThisShader.push_back(m_FragmentID[F_SET_POWER]);
}
tLightList::const_iterator itrLights = m_DirectionalLights.begin();
while (itrLights != m_DirectionalLights.end())
{
if (m_PointLights.empty() && ((itrLights + 1) == m_DirectionalLights.end()))
{
bLastLight = true;
}
// Add a directional light fragment
if (bNeedSpecular)
{
if (m_Settings.m_bSpecularRDotL)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
}
else
{
if (m_Settings.m_bLocalViewer)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
}
else
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
}
}
}
else
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_INTENSITY]);
}
if (bNeedLit)
{
ThisShader.push_back(m_FragmentID[F_CLAMP_DIFFUSE_EXPONENTIATE_SPECULAR]);
}
if (bLastLight)
{
ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_DIFFUSE_LAST]);
}
else
{
ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_DIFFUSE]);
}
if (bNeedSpecular)
{
if (bFirstLight && bLastLight)
{
ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_FIRST_AND_LAST]);
}
else if (bFirstLight)
{
ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_FIRST]);
}
else if (bLastLight)
{
ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_LAST]);
}
else
{
ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR]);
}
}
bFirstLight = false;
itrLights++;
}
itrLights = m_PointLights.begin();
while (itrLights != m_PointLights.end())
{
if ((itrLights + 1) == m_PointLights.end())
{
bLastLight = true;
}
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_VECTOR]);
if (bNeedSpecular)
{
if (m_Settings.m_bSpecularRDotL)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
}
else
{
if (m_Settings.m_bLocalViewer)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
}
else
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
}
}
}
else
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_INTENSITY]);
}
if (bNeedLit)
{
ThisShader.push_back(m_FragmentID[F_CLAMP_DIFFUSE_EXPONENTIATE_SPECULAR]);
}
if (bLastLight)
{
ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_DIFFUSE_LAST]);
}
else
{
ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_DIFFUSE]);
}
if (bNeedSpecular)
{
if (bFirstLight && bLastLight)
{
ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_FIRST_AND_LAST]);
}
else if (bFirstLight)
{
ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_FIRST]);
}
else if (bLastLight)
{
ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_LAST]);
}
else
{
ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR]);
}
}
bFirstLight = false;
itrLights++;
}
}
if (bNeedBasis)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_BASIS_VECTORS]);
}
}
else
// object space
{
if (bNeedEyeVector)
ThisShader.push_back(m_FragmentID[F_CREATE_OBJECTSPACE_EYEVECTOR_LOCAL_VIEWER]);
if (bNeedEyeReflection)
{
// Camera space reflection is always done with local viewer. This is practical because it can look
// pretty aweful without it.
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_REFLECTION]);
}
// If texgen is on, apply it
if (bNeedCubeReflection)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_CUBEREFLECTION_VECTOR]);
}
if (bNeedFog)
ThisShader.push_back(m_FragmentID[F_CALCULATE_LINEAR_RANGE_FOG]);
if (bNeedLighting)
{
// Add the ambient color, and setup the specular power if needed
ThisShader.push_back(m_FragmentID[F_SET_AMBIENT]);
if (bNeedSpecular)
{
ThisShader.push_back(m_FragmentID[F_SET_POWER]);
}
tLightList::const_iterator itrLights = m_DirectionalLights.begin();
while (itrLights != m_DirectionalLights.end())
{
if (m_PointLights.empty() && ((itrLights + 1) == m_DirectionalLights.end()))
{
bLastLight = true;
}
// Add a directional light fragment
if (bNeedSpecular)
{
if (m_Settings.m_bSpecularRDotL)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
}
else
{
if (m_Settings.m_bLocalViewer)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -