📄 shader_blinnreflect.cpp
字号:
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 = 3;
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;
}
}
}
}
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_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);
//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);
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("sky_cube_mipmap.dds").c_str(),
D3DX_DEFAULT,
0,
0,
D3DFMT_UNKNOWN,
D3DPOOL_MANAGED,
D3DX_FILTER_LINEAR,
D3DX_FILTER_LINEAR,
0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -