[DirectX]Programming.Role.Playing.Games:02_02 Draw3D

    Draw3D就跟Programming.Role.Playing.Games.with.DirectX书上的源码不一样,书上的是之前的2D图片带上旋转。我将他改成Cube,还是老规则,左边的是用固定管线实现的,右边是用Shader实现的。右边的明暗变化不是很明显,其实效果是跟Draw2D一样的,因为PixelShader代码是一样的。只是没截好图。

    代码是在之前Draw2D上改的,Cube是用36个顶点构成的,uv想了一会,没有用到索引缓存(IDirect3DIndexBuffer9),如果用索引缓存的话,8个顶点是可以的,但是uv坐标不对,导致有些面上是不正确的。

    来看下渲染的代码:

    固定管线:

void ModelClass::Render(IDirect3DDevice9* device, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix) 
{
	D3DXMATRIX xRotationMatrix, yRotationMatrix;
	D3DXMATRIX translationMatrix;

	// Rotation
	::D3DXMatrixRotationX(&xRotationMatrix, D3DX_PI * 0.25f);
	::D3DXMatrixRotationY(&yRotationMatrix, -(float)::timeGetTime() / 1000.0f);

	// Translate
	::D3DXMatrixTranslation(&translationMatrix, -2.0f, 0.0f, 0.0f);

	::D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &xRotationMatrix);
	::D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &yRotationMatrix);
	::D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &translationMatrix);

	device->SetTransform(D3DTS_WORLD, &worldMatrix);
	device->SetTransform(D3DTS_VIEW, &viewMatrix);
	device->SetTransform(D3DTS_PROJECTION, &projectionMatrix);

	device->SetRenderState(D3DRS_LIGHTING, false);

	device->SetTexture(0, m_texture->GetTexture());

	device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
	device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
	device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

	device->SetStreamSource(0, m_vertexBuffer, 0, sizeof(VertexType));
	device->SetFVF(VERTEX_FVF);

	device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, m_vertexCount / 3);

	device->SetTexture(0, nullptr);
}

    在Draw2D代码上增加了变化矩阵,设置了3个矩阵:世界矩阵,观察矩阵,投影矩阵。世界矩阵,就是将模型从模型坐标转换到世界坐标中,可以根据缩放(Scale),旋转(Roation),平移(Translation)顺序来构成矩阵,算法就是世界矩阵=缩放矩阵*旋转矩阵*平移矩阵=缩放矩阵*x轴旋转矩阵*y轴旋转矩阵*z轴旋转矩阵*平移矩阵

    观察矩阵也可以通过上面的算法进行计算,但顺序是反正的,但是算起来有点累,可以通过dx自带的D3DXMatrixLookAtLH来计算,投影矩阵没什么好说的,就是将3D转换为2D,用dx自带的D3DXMatrixPerspectiveFovLH来计算。

    接着就关闭灯光,用SetRenderState(D3DRS_LIGHTING, false),不然的话,你会看到全黑的Cube。

    Shader渲染:

void ShaderModelClass::Render(IDirect3DDevice9* device, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{
	float time;
	D3DXMATRIX xRotationMatrix, yRotationMatrix;
	D3DXMATRIX translationMatrix;
	bool result;
	UINT passMaxNum;

	time = (float)::timeGetTime() / 1000.0f;

	// Rotation
	::D3DXMatrixRotationX(&xRotationMatrix, D3DX_PI * 0.25f);
	::D3DXMatrixRotationY(&yRotationMatrix, time);

	// Translate
	::D3DXMatrixTranslation(&translationMatrix, 2.0f, 0.0f, 0.0f);

	::D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &xRotationMatrix);
	::D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &yRotationMatrix);
	::D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &translationMatrix);

	device->SetStreamSource(0, m_vertexBuffer, 0, sizeof(VertexType));
	device->SetFVF(VERTEX_FVF);

	result = m_colorShader->Render(device, m_texture->GetTexture(), time, worldMatrix, viewMatrix, projectionMatrix);
	if (!result)
		return;

	m_colorShader->GetEffect()->Begin(&passMaxNum, 0);
	for (UINT pass = 0; pass < passMaxNum; ++pass)
	{
		m_colorShader->GetEffect()->BeginPass(pass);
		device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, m_vertexCount / 3);
		m_colorShader->GetEffect()->EndPass();
	}
	m_colorShader->GetEffect()->End();
}

    跟之前Draw2D上的也差不多,只是把3个矩阵:世界矩阵,观察矩阵,投影矩阵传入到Effect中,用于顶点着色器(VertexShader)阶段进行计算。

     Shader:

texture modelTexture;
float time;
float4x4 worldMatrix;
float4x4 viewMatrix;
float4x4 projectionMatrix;

sampler ModelTextureSampler = sampler_state
{
	Texture = <modelTexture>;
	MipFilter = POINT;
	MinFilter = POINT;
	MagFilter = POINT;
	//MipFilter = LINEAR;
	//MinFilter = LINEAR;
	//MagFilter = LINEAR;
	//MipFilter = ANISOTROPIC;
	//MinFilter = ANISOTROPIC;
	//MagFilter = ANISOTROPIC;
};

struct VertexInputType
{
	float4 vertex : POSITION;
	float2 texcoord : TEXCOORD0;
};

struct PixelInputType
{
	float4 pos : POSITION;
	float2 texcoord : TEXCOORD0;
};

PixelInputType ColorVertexShader(VertexInputType input)
{
	PixelInputType output;

	float4x4 worldViewMaxtrix = mul(worldMatrix, viewMatrix);
	float4x4 worldViewProjectionMatrix = mul(worldViewMaxtrix, projectionMatrix);
	output.pos = mul(input.vertex, worldViewProjectionMatrix);
	output.texcoord = input.texcoord;

	return output;
}

float4 ColorPixelShader(PixelInputType input) : COLOR
{
	float param = max(0.5, cos(time));
	float4 color = tex2D(ModelTextureSampler, input.texcoord) * param;

	return color;
}

technique ColorTechnique
{
	pass pass0
	{
		VertexShader = compile vs_2_0 ColorVertexShader();
		PixelShader = compile ps_2_0 ColorPixelShader();
	}
} 

    不同点就是标红的3句,就是将顶点从模型坐标转换到齐次裁剪空间。

源码下载:下载地址

猜你喜欢

转载自blog.csdn.net/zp288105109a/article/details/80861165
今日推荐