⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shader_blinnreflect.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            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 + -