📄 shader_blinnreflect.cpp
字号:
pConstVec3Base = (float const *)(&(pControlMesh[i]));
for (j = 0; j < kFloatsInVec; ++j)
column[j] = D3DXVECTOR3( *(pConstVec3Base + kFloatsInVec*4*0 + j),
*(pConstVec3Base + kFloatsInVec*4*1 + j),
*(pConstVec3Base + kFloatsInVec*4*2 + j) );
// elevate
for (j = 0; j < kFloatsInVec; ++j)
D3DXVec3Transform(&(elevColumn[j]), &(column[j]), pElevator);
// and write result back into pControlMesh
pVec3Base = (float *)(&(pControlMesh[i]));
for (j = 0; j < kFloatsInVec; ++j)
{
*(pVec3Base + kFloatsInVec*4*0 + j) = elevColumn[j].x;
*(pVec3Base + kFloatsInVec*4*1 + j) = elevColumn[j].y;
*(pVec3Base + kFloatsInVec*4*2 + j) = elevColumn[j].z;
*(pVec3Base + kFloatsInVec*4*3 + j) = elevColumn[j].w;
}
}
}
}
void CShaderBlinnReflect::ElevateToCubicMesh(D3DXVECTOR4 *pControlMesh,
unsigned int uOrder,
unsigned int vOrder) const
{
// Can transform constant, linear, quadratic, or cubic in either u/v
// to fully cubic in both u and v.
assert(uOrder >= 1 && uOrder <= 4);
assert(vOrder >= 1 && vOrder <= 4);
// mesh is assumed to be a 4x4 grid of D3DXVECTOR3, the upper left
// uOrder by vOrder corner is assumed to be populated with values and
// the elevation result is returned in the full 4x4 mesh.
D3DXMATRIX const allElevators[3] = {D3DXMATRIX(1.0f, 1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f),
D3DXMATRIX(1.0f, 0.75f, 0.25f, 0.0f,
0.0f, 0.25f, 0.75f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f),
D3DXMATRIX(1.0f, 1.f/3.f, 0.0f, 0.0f,
0.0f, 2.f/3.f, 2.f/3.f, 0.0f,
0.0f, 0.0f, 1.f/3.f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f) };
D3DXMATRIX const *pElevator;
float const *pConstVec3Base;
float *pVec3Base;
int const kFloatsInVec = 4;
int i, j;
// elevate in x-direction first (since we are only applying linear equations,
// order don't matter)
if (uOrder < 4)
{
// determine elevation level (and transpose since D3DX uses row-vecs...)
pElevator = &allElevators[uOrder-1];
D3DXVECTOR3 row [kFloatsInVec];
D3DXVECTOR4 elevRow[kFloatsInVec];
for (i = 0; i < vOrder; ++i)
{
// copy the row of points to be elevated
pConstVec3Base = (float const *)(&(pControlMesh[4*i]));
for (j = 0; j < kFloatsInVec; ++j)
row[j] = D3DXVECTOR3( *(pConstVec3Base + j),
*(pConstVec3Base + kFloatsInVec + j),
*(pConstVec3Base + 2*kFloatsInVec + j));
// elevate
for (j = 0; j < kFloatsInVec; ++j)
D3DXVec3Transform(&(elevRow[j]), &(row[j]), pElevator);
// and write result back into pControlMesh
pVec3Base = (float *)(&(pControlMesh[4*i]));
for (j = 0; j < kFloatsInVec; ++j)
{
*(pVec3Base + j + 0*kFloatsInVec) = elevRow[j].x;
*(pVec3Base + j + 1*kFloatsInVec) = elevRow[j].y;
*(pVec3Base + j + 2*kFloatsInVec) = elevRow[j].z;
*(pVec3Base + j + 3*kFloatsInVec) = elevRow[j].w;
}
}
}
// we are now guaranteed that the first vOrder rows are fully populated
// now elevate the v-direction
if (vOrder < 4)
{
// determine elevation level (and transpose since D3DX uses row-vecs...)
pElevator = &allElevators[vOrder-1];
D3DXVECTOR3 column[kFloatsInVec];
D3DXVECTOR4 elevColumn[kFloatsInVec];
for (i = 0; i < 4; ++i)
{
// copy the column of points to be elevated
pConstVec3Base = (float const *)(&(pControlMesh[i]));
for (j = 0; j < kFloatsInVec; ++j)
column[j] = D3DXVECTOR3( *(pConstVec3Base + kFloatsInVec*4*0 + j),
*(pConstVec3Base + kFloatsInVec*4*1 + j),
*(pConstVec3Base + kFloatsInVec*4*2 + j) );
// elevate
for (j = 0; j < kFloatsInVec; ++j)
D3DXVec3Transform(&(elevColumn[j]), &(column[j]), pElevator);
// and write result back into pControlMesh
pVec3Base = (float *)(&(pControlMesh[i]));
for (j = 0; j < kFloatsInVec; ++j)
{
*(pVec3Base + kFloatsInVec*4*0 + j) = elevColumn[j].x;
*(pVec3Base + kFloatsInVec*4*1 + j) = elevColumn[j].y;
*(pVec3Base + kFloatsInVec*4*2 + j) = elevColumn[j].z;
*(pVec3Base + kFloatsInVec*4*3 + j) = elevColumn[j].w;
}
}
}
}
HRESULT CShaderBlinnReflect::Initialize(IDirect3DDevice8* pDev)
{
HRESULT hr;
vector<DWORD> Declaration, PatchDeclaration;
m_pD3DDev = pDev;
pDev->AddRef();
m_bDrawing = false;
m_bDrawModeOn = true;
//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);
assert( m_pUI != NULL );
// Must Reset BEFORE setting translatin sens factor
m_pUI->Reset();
m_pUI->Translate( 0.0f, 0.0f, -0.25f );
m_pUI->OnLButtonDown( 50, 50 );
m_pUI->OnMouseMove( 68, 62 );
m_pUI->OnLButtonUp( 68, 62 );
m_pUI->SetTranslationalSensitivityFactor( 0.1f );
//////////////////////////////////////////////////////
// allocate class for creating dynamic normal maps
assert( m_pCA_Water == NULL );
m_pCA_Water = new CA_Water( this );
assert( m_pCA_Water != NULL );
m_pCA_Water->Initialize( this, pDev );
//////////////////////////////////////////////////////
m_bShowProceduralMaps = false;
m_pNVDevice = new NVBlinnReflectDevice(pDev, this);
m_pLightMesh = new NVMesh();
hr = m_pLightMesh->Create(m_pNVDevice, GetFilePath("arrow.x"));
if (FAILED(hr))
{
m_strLastError = "Could not load arrow.x";
return hr;
}
m_pLightMesh->SetFVF(m_pNVDevice, D3DFVF_NORMAL | D3DFVF_XYZ | D3DFVF_TEX1);
D3DDEVICE_CREATION_PARAMETERS CreationParams;
pDev->GetCreationParameters(&CreationParams);
if (CreationParams.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING)
{
m_bSupportsPatches = false;
m_bUsePatch = false;
}
else
{
m_bSupportsPatches = true;
}
hr = GenerateSplinePatch();
if (FAILED(hr))
{
m_strLastError = "Failed to generate spline patch";
return E_FAIL;
}
hr = GenerateSphere(D3DXVECTOR3(0.0f, 0.0f, 0.0f), 0.5f, 30, 40, 1.0f, 1.0f, 1.0f);
if (FAILED(hr))
{
m_strLastError = "Failed to generate sphere";
return hr;
}
//GenerateQuad(D3DXVECTOR3(0.0f, 0.0f, 0.0f), 1.0f);
PatchDeclaration.clear();
PatchDeclaration.push_back(D3DVSD_STREAM(0));
PatchDeclaration.push_back(D3DVSD_REG(0, D3DVSDT_FLOAT3)); // Position
PatchDeclaration.push_back(D3DVSD_REG(4, D3DVSDT_FLOAT3)); // Normal not used!
PatchDeclaration.push_back(D3DVSD_REG(2, D3DVSDT_FLOAT3)); // Diffuse not used!
PatchDeclaration.push_back(D3DVSD_REG(7, D3DVSDT_FLOAT2)); // Texture not used!
PatchDeclaration.push_back(D3DVSD_REG(5, D3DVSDT_FLOAT3)); // S
PatchDeclaration.push_back(D3DVSD_REG(6, D3DVSDT_FLOAT3)); // T
PatchDeclaration.push_back(D3DVSD_REG(8, D3DVSDT_FLOAT3)); // SxT
PatchDeclaration.push_back(D3DVSD_STREAM_TESS()); // is computed
PatchDeclaration.push_back(D3DVSD_TESSUV( 3 ));
PatchDeclaration.push_back(D3DVSD_END());
Declaration.clear();
Declaration.push_back(D3DVSD_STREAM(0));
Declaration.push_back(D3DVSD_REG(0, D3DVSDT_FLOAT3)); // Position
Declaration.push_back(D3DVSD_REG(1, D3DVSDT_FLOAT3)); // Normal
Declaration.push_back(D3DVSD_REG(2, D3DVSDT_FLOAT3)); // Diffuse
Declaration.push_back(D3DVSD_REG(3, D3DVSDT_FLOAT2)); // Texture
Declaration.push_back(D3DVSD_REG(5, D3DVSDT_FLOAT3)); // S
Declaration.push_back(D3DVSD_REG(6, D3DVSDT_FLOAT3)); // T
Declaration.push_back(D3DVSD_REG(4, D3DVSDT_FLOAT3)); // SxT
Declaration.push_back(D3DVSD_END());
// Create the shaders, 2 versions - one for the sphere, one for the patch
if (m_bSupportsPatches)
{
hr = LoadAndCreateShader(GetFilePath("blinn_reflect.vso"), &PatchDeclaration[0], 0, SHADERTYPE_VERTEX, &m_dwBlinnPatchVertexShader);
if (FAILED(hr))
return hr;
hr = LoadAndCreateShader(GetFilePath("dot3_transform.vso"), &PatchDeclaration[0], 0, SHADERTYPE_VERTEX, &m_dwTransformPatchShader);
if (FAILED(hr))
return hr;
}
hr = LoadAndCreateShader(GetFilePath("blinn_reflect.pso").c_str(), NULL, 0, SHADERTYPE_PIXEL, &m_dwBlinnPixelShader);
if (FAILED(hr))
return hr;
hr = LoadAndCreateShader(GetFilePath("blinn_reflect.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, &m_dwBlinnVertexShader);
if (FAILED(hr))
return hr;
hr = LoadAndCreateShader(GetFilePath("dot3_transform.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, &m_dwTransformShader);
if (FAILED(hr))
return hr;
LPDIRECT3DTEXTURE8 pBumpTexture;
hr = D3DXCreateTextureFromFileEx(m_pD3DDev,
GetFilePath("bump_map_nvidia.dds").c_str(),
D3DX_DEFAULT,
D3DX_DEFAULT,
1,
0,
D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED,
D3DX_FILTER_LINEAR,
D3DX_FILTER_LINEAR,
0,
NULL,
NULL,
&pBumpTexture);
if (FAILED(hr))
{
m_strLastError = "Could not load texture (bump_map_nvidia.dds)";
return hr;
}
m_pBumpMapHILO = NVTexture2::CreateNormalMap(m_pD3DDev, pBumpTexture, (D3DFORMAT)MAKEFOURCC('N', 'V', 'H', 'S'), D3DPOOL_DEFAULT);
m_bSupportsHILO = (m_pBumpMapHILO != NULL);
m_pBumpMapQWVU = NVTexture2::CreateNormalMap(m_pD3DDev, pBumpTexture, D3DFMT_Q8W8V8U8, D3DPOOL_MANAGED);
m_bSupportsQWVU = (m_pBumpMapQWVU != NULL);
if (!m_bSupportsQWVU && !m_bSupportsHILO)
{
m_strLastError = "Could not find suitable bumpmap format!";
return E_FAIL;
}
SAFE_RELEASE(pBumpTexture);
hr = D3DXCreateTextureFromFileEx(m_pD3DDev,
GetFilePath("gloss_map_nvidia.dds").c_str(),
D3DX_DEFAULT,
D3DX_DEFAULT,
0,
0,
D3DFMT_UNKNOWN,
D3DPOOL_MANAGED,
D3DX_FILTER_LINEAR,
D3DX_FILTER_LINEAR,
0,
NULL,
NULL,
&m_pGlossMap);
if (FAILED(hr))
{
m_strLastError = "Could not load texture (gloss_map_nvidia.dds)";
return hr;
}
hr = D3DXCreateCubeTextureFromFileExA( pDev,
GetFilePath("nvlobby_cube_mipmap.dds").c_str(),
D3DX_DEFAULT,
0,
0,
D3DFMT_UNKNOWN,
D3DPOOL_MANAGED,
D3DX_FILTER_LINEAR,
D3DX_FILTER_LINEAR,
0,
NULL,
NULL,
&m_pCubeTexture);
if (FAILED(hr))
{
m_strLastError = "Could not load texture (sky_cube_mipmap.dds)";
return hr;
}
// Setup constants
m_pD3DDev->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1);
m_pD3DDev->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);
// Camera stuff
D3DXMATRIX matProj;
D3DXMATRIX matView;
D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -1.0f );
D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
m_pD3DDev->SetVertexShaderConstant(CV_EYE_WORLD, D3DXVECTOR4(vEyePt.x, vEyePt.y, vEyePt.z, 0.0f), 1);
// View
D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
// Projection
D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(60.0f), 1.0f, 0.1f, 50.0f);
m_pNVDevice->SetViewTransform(&matView);
m_pNVDevice->SetProjectionTransform(&matProj);
m_pD3DDev->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
if (m_pLightMesh)
m_pLightMesh->RestoreDeviceObjects(m_pNVDevice);
// Reset control points for mesh
m_ctrl1 = m_ctrl2 = m_ctrl3 = m_ctrl4 = 0.0f;
// Point at the vertex data
CreateBasisVectors(m_pVertexBuffer, m_pIndexBuffer);
// Point at the index data
hr = m_pD3DDev->SetIndices(m_pIndexBuffer, 0);
if (FAILED(hr))
{
m_strLastError = "Could not set Index source";
return hr;
}
return S_OK;
}
HRESULT CShaderBlinnReflect::Free()
{
SAFE_DELETE( m_pCA_Water );
SAFE_DELETE(m_pLightMesh);
SAFE_RELEASE(m_pPatchBuffer);
SAFE_RELEASE(m_pVertexBuffer);
SAFE_RELEASE(m_pIndexBuffer);
SAFE_RELEASE(m_pBumpMapQWVU);
SAFE_RELEASE(m_pBumpMapHILO);
SAFE_RELEASE(m_pGlossMap);
SAFE_RELEASE(m_pCubeTexture);
SAFE_DELETE(m_pUI);
SAFE_DELETE(m_pNVDevice);
if (m_pD3DDev)
{
if (m_dwBlinnPixelShader)
m_pD3DDev->DeletePixelShader(m_dwBlinnPixelShader);
if (m_dwBlinnVertexShader)
m_pD3DDev->DeleteVertexShader(m_dwBlinnVertexShader);
if (m_dwTransformShader)
m_pD3DDev->DeleteVertexShader(m_dwTransformShader);
if (m_dwBlinnPatchVertexShader)
m_pD3DDev->DeleteVertexShader(m_dwBlinnPatchVertexShader);
if (m_dwTransformPatchShader)
m_pD3DDev->DeleteVertexShader(m_dwTransformPatchShader);
m_dwBlinnPixelShader = 0;
m_dwBlinnVertexShader = 0;
m_dwTransformShader = 0;
m_dwBlinnPatchVertexShader = 0;
m_dwTransformPatchShader = 0;
SAFE_RELEASE(m_pD3DDev);
}
return S_OK;
}
HRESULT CShaderBlinnReflect::Start()
{
m_fAngle = 0.0f;
return S_OK;
}
HRESULT CShaderBlinnReflect::SetTransform()
{
D3DXMATRIX matTemp;
D3DXMATRIX matWorldViewProj;
D3DXMATRIX matWorldView;
D3DXMATRIX matWorldViewI;
D3DXMATRIX matWorldI;
D3DXMATRIX matWorld = m_pNVDevice->GetWorldTransform();
D3DXMATRIX matProj = m_pNVDevice->GetProjectionTransform();
D3DXMATRIX matView = m_pNVDevice->GetViewTransform();
D3DXMatrixMultiply(&matTemp, &matWorld, &matView);
D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProj);
D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
D3DXMatrixInverse(&matWorldI, NULL, &matWorld);
// Create a 3x3 invertse of the worldview for the normal transformation (we transpose it as we load it into
// the constant store)
D3DXMatrixInverse(&matWorldViewI, NULL, &matWorldView);
// Projection to clip space
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
D3DXMatrixTranspose(&matWorld, &matWorld);
m_pD3DDev->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_WORLD_1, &matWorld(1, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_WORLD_2, &matWorld(2, 0), 1);
D3DXMatrixTranspose(&matWorld, &matWorld);
// If you are rotating the cubemap, you need to apply that transform here too
D3DXMATRIX matBasisTransform = matWorld;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -