📄 shader_linkerdemo.cpp
字号:
{
m_GeneratedNormalMapID = NVRESOURCEMANAGER.AddResource(new NVTextureNormalMapFromResource(m_pD3DDev, pMaterial->GetTextureID(0), (D3DFORMAT)MAKEFOURCC('N', 'V', 'H', 'S'), D3DPOOL_DEFAULT));
}
pMaterial->AddTexture(0, m_GeneratedNormalMapID);
}
else
{
pMaterial->AddTexture(0, NVRESOURCEMANAGER.FindResourceID("DefaultNormalMap"));
}
pMaterial->AddTexture(3, NVRESOURCEMANAGER.FindResourceID("CubeMap"));
pMaterial->AddPixelShader(m_dwBumpPixelShader);
pMaterial->AddTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
pMaterial->AddTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
}
else
{
pMaterial->RestoreTexture(0);
}
if ((pMaterial->GetTextureID(0) == NVINVALID_RESOURCEID) || !bNeedTexture)
{
pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
}
else
{
pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
}
}
itrSections++;
}
// Find second pass if there is one. The sphere will have done this.
if (m_pMesh->GetPass(1))
{
// Pass 2 is more simple, we just want the transform and the write of the texture coordinates
ThisShader.clear();
if (bNeedTexture)
{
ThisShader.push_back(m_FragmentID[F_WRITE_DEFAULT_TEXTURE]);
}
// Need to fog the decal
if (bNeedFog)
{
// In eye space put the vertex down and calculate the eye vector
if (m_Settings.m_bEyeSpace)
{
ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_VERTEX]);
ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_EYEVECTOR_LOCAL_VIEWER]);
}
// In object space get the eye vector
else
{
ThisShader.push_back(m_FragmentID[F_CREATE_OBJECTSPACE_EYEVECTOR_LOCAL_VIEWER]);
}
// Calculate the fog
ThisShader.push_back(m_FragmentID[F_CALCULATE_LINEAR_RANGE_FOG]);
}
ThisShader.push_back(m_FragmentID[F_XFORM_WORLDVIEWPROJECTION]);
ThisShader.push_back(0);
dwRet = m_pLinker->CreateBinaryShader(&ThisShader[0], &pShader);
pBuff = (DWORD*)pShader->GetPointer();
hr = m_pD3DDev->CreateVertexShader(&m_MeshDeclaration[0], (DWORD*)pShader->GetPointer(), &m_dwPass1Shader, 0);
SAFE_RELEASE(pShader);
if (FAILED(hr))
{
m_strLastError = "Failed CreateVertexShader on linked shader";
return hr;
}
// Store a list of constant slots for this shader
for (i = 0; i < C_NUM_CONSTANTS; i++)
{
DWORD dwLocation;
m_pLinker->GetConstantSlot(m_ConstantID[i], 0, &dwLocation);
m_ConstantSlots[1][CLinkerConstantSlot(m_ConstantID[i], 0)] = dwLocation;
}
// Now setup the mesh
tSectionList& Sections = m_pMesh->GetPass(1)->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)
{
// Setup the vertex shader
pMaterial->AddVertexShader(m_dwPass1Shader);
string strGlossTexture;
LPDIRECT3DTEXTURE8 pGlossTexture = NULL;
pMaterial->AddRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
pMaterial->AddRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
pMaterial->AddRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
// Add the default gloss map
pMaterial->AddTexture(0, NVRESOURCEMANAGER.FindResourceID("DefaultGlossMap"));
// Setup texture properties
pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
}
itrSections++;
}
}
// Prepare the mesh for rendering
m_pMesh->PrepareDeviceObjects(m_pD3DDev);
return S_OK;
}
HRESULT CShaderLinkerDemo::LoadMesh(const string& strFileName)
{
int Pos = strFileName.find_last_of('.', strFileName.size());
string strExtension = strFileName.substr(Pos + 1, strFileName.size() - Pos);
if (m_pMesh)
{
SAFE_DELETE(m_pMesh);
}
if (m_GeneratedNormalMapID != NVINVALID_RESOURCEID)
{
NVRESOURCEMANAGER.RemoveResource(m_GeneratedNormalMapID);
m_GeneratedNormalMapID = NVINVALID_RESOURCEID;
}
m_pMesh = new NVComplexMesh();
bool bOK;
if (strFileName == "")
{
bOK = m_pMesh->CreateFromSphere(1.0f, 40, 80, D3DXVECTOR3(1.0f, 1.0f, 1.0f), D3DXVECTOR2(1.0f, 1.0f));
if (bOK)
{
m_pMesh->DuplicatePass(0, 1);
}
}
else if (strExtension.compare("x") == 0)
{
bOK = m_pMesh->CreateFromXFile(m_pD3DDev, strFileName.c_str());
if (bOK)
{
// If the model has texture coords...
if (m_pMesh->FindVertexData("texture0"))
{
bool bFoundTex = false;
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)
{
if (NVTextureResource::GetTexture(pMaterial->GetTextureID(0)) != NULL)
bFoundTex = true;
}
itrSections++;
}
// This mesh has texture coords, but no texture. We will be using the default NVIDIA bump
// texture
if (!bFoundTex)
{
// Add a second pass for the gloss map
m_pMesh->DuplicatePass(0, 1);
}
}
}
}
else if (strExtension.compare("m") == 0)
{
bOK = m_pMesh->CreateFromMFile(m_pD3DDev, strFileName.c_str());
}
else
{
assert(0);
return E_FAIL;
}
if (!bOK)
{
SAFE_DELETE(m_pMesh);
return E_FAIL;
}
m_strFileName = strFileName;
// We require for the shader that these components are present.
// If they are already there, then these calls won't do anything
if (!m_pMesh->FindVertexData("normal"))
{
m_pMesh->AddVertexData("normal", NVCOMPLEXMESH_FLOAT3);
m_pMesh->GenerateNormals();
}
if (m_pMesh->FindVertexData("texture0"))
{
// Add basis vectors. We use the normal as our SxT vector
m_pMesh->AddVertexData("sbasis0", NVCOMPLEXMESH_FLOAT3);
m_pMesh->AddVertexData("tbasis0", NVCOMPLEXMESH_FLOAT3);
m_pMesh->GenerateBasis(0);
m_bHasTextureCoords = true;
m_Settings.m_bEnableBump = m_bSupportsNormalMap;
m_Settings.m_bEnableTextures = true;
}
else
{
m_bHasTextureCoords = false;
m_Settings.m_bEnableBump = false;
m_Settings.m_bTextures = false;
m_Settings.m_bEnableTextures = false;
m_Settings.m_TexGen = TEXGEN_NONE;
}
// Get the bounding info and scale the model
NVComplexMeshBounds Bounds;
m_pMesh->ComputeBounds(Bounds);
m_pMesh->Translate(-Bounds.m_vecCenter);
m_pMesh->Scale(0.8f / Bounds.m_fRadius);
//m_pMesh->UnIndex();
m_DialogFunc.SetSettings(&m_Settings);
return S_OK;
}
void CShaderLinkerDemo::PropertyUpdateCallback(const EBProperty* pProperty, bool bWritten)
{
if (!bWritten)
return;
if (pProperty->IsKindOf(EBTYPE_TRIGGER_PROP))
{
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
#define PATH_SIZE 2048
char FileName[PATH_SIZE] = "";
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.hInstance = NULL;
ofn.lpstrFilter = "Model Files (*.x, *.m)\0*.x;*.m\0\0";
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = &FileName[0];
ofn.nMaxFile = PATH_SIZE;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
int iSuccess = GetOpenFileName(&ofn);
if (iSuccess > 0)
{
NVRESOURCEMANAGER.DisposeResources();
LoadMesh(&FileName[0]);
}
else
{
// Might be OK if the user hit cancel
DWORD dwErr = CommDlgExtendedError();
}
m_eDisplayOption = DISPLAY_MODEL;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
UpdateShader();
m_pUI->Reset();
}
else
{
EBString strProp = pProperty->GetPropertyName();
if (strProp == EBString(STR_DISPLAYOPTIONS))
{
switch(m_eDisplayOption)
{
case DISPLAY_MODEL:
{
NVRESOURCEMANAGER.DisposeResources();
LoadMesh(GetFilePath("bigship1.x"));
UpdateShader();
m_pUI->Reset();
}
break;
case DISPLAY_SPHERE:
{
NVRESOURCEMANAGER.DisposeResources();
LoadMesh("");
UpdateShader();
m_pUI->Reset();
}
break;
default:
{
assert(0);
}
break;
}
}
}
}
// ------------------------------------------------------------------------------
// CShaderLinkerDemo::Free
//
// Description: Called when we switch away from this demo. Free up all the
// memory that is in use.
// ------------------------------------------------------------------------------
HRESULT CShaderLinkerDemo::Free()
{
m_PointLights.clear();
m_DirectionalLights.clear();
FreeLightObjects();
// Delete mesh
SAFE_DELETE(m_pMesh);
SAFE_RELEASE(m_pWorldBoxVertices);
SAFE_RELEASE(m_pWorldBoxIndices);
if (m_pD3DDev)
{
if (m_dwPass0Shader)
m_pD3DDev->DeleteVertexShader(m_dwPass0Shader);
m_dwPass0Shader = 0;
if (m_dwPass1Shader)
m_pD3DDev->DeleteVertexShader(m_dwPass1Shader);
m_dwPass1Shader = 0;
if (m_dwBumpPixelShader)
m_pD3DDev->DeletePixelShader(m_dwBumpPixelShader);
m_dwBumpPixelShader = 0;
SAFE_RELEASE(m_pD3DDev);
}
// Free the linker and unload the library
SAFE_RELEASE(m_pLinker);
if (m_hLinker)
{
FreeLibrary(m_hLinker);
m_hLinker = NULL;
}
delete m_pUI, m_pUI = 0;
// Check the function pointer to ensure we got as far
// as loading it.
if (m_DialogFunc.Free)
{
m_DialogFunc.Free();
ZeroMemory(&m_DialogFunc, sizeof(m_DialogFunc));
}
if (m_hDialog)
{
FreeLibrary(m_hDialog);
m_hDialog = NULL;
}
// Final step, releas
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -