📄 shader_linkerdemo.cpp
字号:
else
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
}
}
}
else
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_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_OBJECTSPACE_POINTLIGHT_VECTOR]);
if (bNeedSpecular)
{
if (m_Settings.m_bSpecularRDotL)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
}
else
{
if (m_Settings.m_bLocalViewer)
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
}
else
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
}
}
}
else
{
ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_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]);
}
}
if (!bNeedLighting)
{
// Write out the final values.
ThisShader.push_back(m_FragmentID[F_WRITE_DEFAULT_DIFFUSE]);
}
if (bNeedTexture)
{
// If no texgen mode is on, write the texture coordinates out directly
if(m_Settings.m_TexGen == TEXGEN_NONE)
{
ThisShader.push_back(m_FragmentID[F_WRITE_DEFAULT_TEXTURE]);
}
}
for (i = 0; i < ThisShader.size(); i++)
{
assert(ThisShader[i] != 0);
}
ThisShader.push_back(0);
// Load the shader
NVLinkBuffer* pShader;
// Use this to reserve a range of constant/vertex registers - useful for indexed skinning, for example.
// You can only have one range.
// m_pLinker->ReserveConstantRange(3, 10);
// Our vertex format will contain a position and a tex coord at 0 and 1. To ensure that the linker
// never allocates these registers to fragments that don't ever use FIXED_TEXTURE0, we reserve the 'slots'
m_pLinker->ReserveVertexRange(0, 1);
DWORD dwRet = m_pLinker->CreateBinaryShader(&ThisShader[0], &pShader);
// In the failure case, update the text in the window
if (dwRet != NVLINK_OK)
{
switch (dwRet)
{
case NVLINK_OUT_OF_MEMORY:
m_strLastError = "Linker out of memory";
break;
case NVLINK_TOO_MANY_INSTRUCTIONS:
m_strLastError = "Too many instructions";
break;
case NVLINK_TOO_MANY_ADDRESS_REGISTERS:
m_strLastError = "Too many address registers required";
break;
case NVLINK_TOO_MANY_CONSTANTS:
m_strLastError = "Too many constants required";
break;
case NVLINK_TOO_MANY_VERTICES:
m_strLastError = "Too many vertex slots required";
break;
case NVLINK_TOO_MANY_REGISTERS:
m_strLastError = "Too many temporary registers required";
break;
case NVLINK_NO_FRAGMENTS:
m_strLastError = "Linker has no fragments";
break;
case NVLINK_INVALID_FRAGMENT:
m_strLastError = "Invalid fragment ID passed to linker";
break;
default:
m_strLastError = "Failed to link shader";
break;
}
strOutFile = effect_api::GetModulePath() + "\\" + "output.nvv";
hFile = CreateFile(strOutFile.c_str(), GENERIC_WRITE, 0, NULL, TRUNCATE_EXISTING, 0, NULL);
WriteFile(hFile, const_cast<char*>(m_strLastError.c_str()), m_strLastError.length(), &dwNumWritten, NULL);
CloseHandle(hFile);
if (!m_bSetShaderToShow)
{
m_strEffectVertexShader = GetFilePath("output.nvv");
m_bSetShaderToShow = true;
}
// Dirty the vertex shaders so the effects browser reloads the file
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_VERTEXSHADERS;
return E_FAIL;
}
// Write the created shader's source text to an output file
NVLinkBuffer* pShaderText = NULL;
if (m_pLinker->GetShaderSource(&pShaderText) == NVLINK_OK)
{
strOutFile = effect_api::GetModulePath() + "\\" + "output.nvv";
hFile = CreateFile(strOutFile.c_str(), GENERIC_WRITE, 0, NULL, TRUNCATE_EXISTING, 0, NULL);
WriteFile(hFile, pShaderText->GetPointer(), pShaderText->GetBufferSize(), &dwNumWritten, NULL);
CloseHandle(hFile);
SAFE_RELEASE(pShaderText);
if (!m_bSetShaderToShow)
{
m_strEffectVertexShader = GetFilePath("output.nvv");
m_bSetShaderToShow = true;
}
// Dirty the vertex shaders so the effects browser reloads the file
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_VERTEXSHADERS;
}
UpdateMeshVertexSlots();
// Store a list of constant slots for this shader
for (i = 0; i < C_NUM_CONSTANTS; i++)
{
m_pLinker->GetConstantSlot(m_ConstantID[i], 0, &dwLocation);
m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[i], 0)] = dwLocation;
}
//Special ones with offsets
for (i = 0; i < m_PointLights.size(); i++)
{
m_pLinker->GetConstantSlot(m_ConstantID[C_POINTLIGHT_POSITION], i, &dwLocation);
m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_POINTLIGHT_POSITION], i)] = dwLocation;
m_pLinker->GetConstantSlot(m_ConstantID[C_POINTLIGHT_DIFFUSE], i, &dwLocation);
m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_POINTLIGHT_DIFFUSE], i)] = dwLocation;
m_pLinker->GetConstantSlot(m_ConstantID[C_POINTLIGHT_SPECULAR], i, &dwLocation);
m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_POINTLIGHT_SPECULAR], i)] = dwLocation;
}
for (i = 0; i < m_DirectionalLights.size(); i++)
{
m_pLinker->GetConstantSlot(m_ConstantID[C_DIRLIGHT_DIRECTION], i, &dwLocation);
m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_DIRECTION], i)] = dwLocation;
m_pLinker->GetConstantSlot(m_ConstantID[C_DIRLIGHT_DIFFUSE], i, &dwLocation);
m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_DIFFUSE], i)] = dwLocation;
m_pLinker->GetConstantSlot(m_ConstantID[C_DIRLIGHT_SPECULAR], i, &dwLocation);
m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_SPECULAR], i)] = dwLocation;
m_pLinker->GetConstantSlot(m_ConstantID[C_DIRLIGHT_HALFVECTOR], i, &dwLocation);
m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_HALFVECTOR], i)] = dwLocation;
}
DWORD* pBuff = (DWORD*)pShader->GetPointer();
hr = m_pD3DDev->CreateVertexShader(&m_MeshDeclaration[0], (DWORD*)pShader->GetPointer(), &m_dwPass0Shader, 0);
SAFE_RELEASE(pShader);
if (FAILED(hr))
{
m_strLastError = "Failed CreateVertexShader on linked shader";
return hr;
}
// Get a list of sections for pass 0
tSectionList& Sections = m_pMesh->GetPass(0)->GetSections();
tSectionList::iterator itrSections = Sections.begin();
// Walk all the model sections in this pass
while (itrSections != Sections.end())
{
// Set the constants and vertex shaders in this section
NVMaterialResource* pMaterial = static_cast<NVMaterialResource*>(NVRESOURCEMANAGER.FindResource((*itrSections).GetMaterialID()));
if (pMaterial)
{
NVConstant* pConstant;
tConstantInfoToSlot::iterator itrConstant;
// Make sure we have a specular and a power constant in the mesh
pMaterial->AddConstant("specular", D3DXVECTOR4(0.3f, 0.3f, 0.3f, 0.0f), NV_NO_CONSTANT);
pMaterial->AddConstant("power", D3DXVECTOR4(0.0f, 0.0f, 0.0f, 25.0f), NV_NO_CONSTANT);
// Specular off by default
pMaterial->AddRenderState(D3DRS_SPECULARENABLE, FALSE);
// Tell the mesh where to place it's constants
pConstant = pMaterial->FindConstant("diffuse");
if (pConstant)
{
// Not loading the material into constant memory - we are premodulating it with
// the light color - see the tick function.
pConstant->SetLocation(NV_NO_CONSTANT);
}
pConstant = pMaterial->FindConstant("specular");
if (pConstant)
{
// Not loading the material into constant memory - we are premodulating it with
// the light color - see the tick function.
pConstant->SetLocation(NV_NO_CONSTANT);
if (bNeedSpecular)
{
// If we require any specular at all, enable the specular renderstate
itrConstant = m_ConstantSlots[0].find(CLinkerConstantSlot(m_ConstantID[C_POINTLIGHT_SPECULAR], 0));
assert(itrConstant != m_ConstantSlots[0].end());
if (itrConstant->second != NVLINK_NOT_USED)
{
pMaterial->AddRenderState(D3DRS_SPECULARENABLE, TRUE);
}
itrConstant = m_ConstantSlots[0].find(CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_SPECULAR], 0));
assert(itrConstant != m_ConstantSlots[0].end());
if (itrConstant->second != NVLINK_NOT_USED)
{
pMaterial->AddRenderState(D3DRS_SPECULARENABLE, TRUE);
}
}
}
pConstant = pMaterial->FindConstant("power");
if (pConstant)
{
itrConstant = m_ConstantSlots[0].find(CLinkerConstantSlot(m_ConstantID[C_MAT_POWER], 0));
assert(itrConstant != m_ConstantSlots[0].end());
if (itrConstant->second != NVLINK_NOT_USED)
{
pConstant->SetLocation(itrConstant->second);
}
else
{
pConstant->SetLocation(NV_NO_CONSTANT);
}
}
// Setup the vertex shader, and turn off pixel shader by default
pMaterial->AddVertexShader(m_dwPass0Shader);
pMaterial->AddPixelShader(0);
pMaterial->RestoreTexture(0);
pMaterial->AddTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
pMaterial->AddTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
if(bNeedCubeReflection)
{
pMaterial->AddTexture(0, NVRESOURCEMANAGER.FindResourceID("CubeMap"));
pMaterial->AddTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
pMaterial->AddTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
}
else if (bNeedBasis)
{
string strNormalMapTexture;
LPDIRECT3DBASETEXTURE8 pNormalMapTexture = NULL;
// If the mesh has a texture, add a bumpmap for it
if (NVTextureResource::GetTexture(pMaterial->GetTextureID(0)) != NULL)
{
if (m_GeneratedNormalMapID == NVINVALID_RESOURCEID)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -