DirectX11 学习笔记9

首先,什么是缓冲区:

缓冲区是.fx文件的影响(.ps .vs还) 一种数据结构,其定义了。为.fx和cpp数据通信文件。

例:

//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
cbuffer ConstantBuffer 
{
	matrix World;
	matrix View;
	matrix Projection;
};
cbuffer LightBuffer
{
    float3 cameraPosition;
    float padding;
};
cbuffer是keyword。  类似于struct 

这里就定义了2个缓冲区。

在程序执行的时候。

效果文件.fx须要获得世界矩阵观察矩阵投影矩阵等等。 因此就须要为这个缓冲区赋值。一方面能够直接写在.fx文件中面。

可是

直接写在效果文件 编译后就不能动态改变了,没有灵活性。

以下说说2种缓冲区

1:静态常量缓冲区

所谓静态就是在渲染器初始化的时候,就为缓冲区赋值好了。不会再变了。

// Create the constant buffer
	D3D11_BUFFER_DESC bd;
	ZeroMemory( &bd, sizeof(bd) );
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(ConstantBuffer);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = 0;
	hr = device->CreateBuffer( &bd, NULL, &m_matrixBuffer );
	if( FAILED( hr ) )
		return hr;
上面就是创建一个静态缓冲区的列子

当中bd.Usage属性  

D3D11_USAGE_DEFAULT
意思是 cpu在执行过程中不可以再读写数据了

bd.COUAccessFlags=0 也得设置为0才行。

定义好缓冲区结构之后就是初始化了

//
	// Update variables
	//
	ConstantBuffer cb;
	cb.mWorld = XMMatrixTranspose( worldMatrix);
	cb.mView = XMMatrixTranspose( viewMatrix );
	cb.mProjection = XMMatrixTranspose( projectionMatrix );
	deviceContext->UpdateSubresource( m_matrixBuffer, 0, NULL, &cb, 0, 0 );
	deviceContext->VSSetConstantBuffers( 0, 1, &m_matrixBuffer );

初始化非常easy 这里拿世界矩阵 视图矩阵 投影矩阵为样例

2:动态顶点缓冲区

和静态缓冲区不同。

动态缓冲区用于每一帧都须要动态改变渲染数据的情况。

比方水波,每一秒他的顶点结构都在变,因此须要用动态缓冲区动态赋值,而不是在初始化赋值

//create the light buffer
	ZeroMemory( &bd, sizeof(bd) );
	bd.Usage = D3D11_USAGE_DYNAMIC;
	bd.ByteWidth = sizeof(LightBuffer);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	hr = device->CreateBuffer( &bd, NULL, &m_lightmaterialBuffer );
	if( FAILED( hr ) )
		return hr;
	return S_OK;

定义基本一样。,仅仅是在Usage 里面要设置为D3D11_USAGE_DYNAMIC  还有CPUAccessFlags也要设置为D3D11_CPU_ACCESS_WRITE

并且在更新数据的时候不一样

必须先用map锁定,防止还没更新好的时候设备就渲染了造成错误数据不一致

D3D11_MAPPED_SUBRESOURCE mappedResource;
	ConstantBuffer *data0;
	LightBuffer *data1;
	//
	// Update variables
	//
	//ConstantBuffer cb;
	//cb.mWorld = XMMatrixTranspose( worldMatrix);
	//cb.mView = XMMatrixTranspose( viewMatrix );
	//cb.mProjection = XMMatrixTranspose( projectionMatrix );
	//锁定常量缓冲区
	HR(deviceContext->Map(m_matrixBuffer,0,D3D11_MAP_WRITE_DISCARD,0,&mappedResource));
	//deviceContext->UpdateSubresource( m_matrixBuffer, 0, NULL, &cb, 0, 0 );
	data0=(ConstantBuffer*)mappedResource.pData;
	data0->mWorld=XMMatrixTranspose( worldMatrix);
	data0->mView=XMMatrixTranspose( viewMatrix );
	data0->mProjection=XMMatrixTranspose( projectionMatrix );
	deviceContext->Unmap(m_matrixBuffer,0);
	deviceContext->VSSetConstantBuffers( 0, 1, &m_matrixBuffer );
	//LightBuffer lb;
	//lb.cameraPosition=cameraPos;
	//锁定光照缓冲区
	HR(deviceContext->Map(m_lightmaterialBuffer,0,D3D11_MAP_WRITE_DISCARD,0,&mappedResource));
	data1=(LightBuffer*)mappedResource.pData;
	data1->cameraPosition=cameraPos;
	deviceContext->Unmap(m_lightmaterialBuffer,0);
	//deviceContext->UpdateSubresource( m_lightmaterialBuffer, 0, NULL, &lb, 0, 0 );
	deviceContext->VSSetConstantBuffers( 1, 1, &m_lightmaterialBuffer );


这里举了2个样例,同一时候渲染了2个缓冲区。

要注意的是,渲染两个缓冲区的时候,不是简单的先写第一个再写第二个。 

有一点小差别。

就是在deviceContext->VSSetConstantBuffers()当要加入的第一参数1. 它代表了一个第二缓冲。其他的都一样。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

原文地址:https://www.cnblogs.com/lcchuguo/p/4647967.html