Creación de recursos de búfer (Direct3D 10)
La creación de búferes requiere definir los datos que almacenará el búfer, proporcionar datos de inicialización y configurar las marcas de uso y enlace adecuadas. Para crear texturas, consulte Creación de recursos de textura (Direct3D 10).
- Crear un búfer de vértices
- Creación de un búfer de índice
- Crear un búfer de constantes
- Temas relacionados
Crear un búfer de vértices
Los pasos para crear un búfer de vértices son los siguientes.
- Crear una descripción del búfer
- Creación de los datos de inicialización para el búfer
- Creación del búfer
Crear una descripción del búfer
Al crear un búfer de vértices, se usa una descripción del búfer (consulte D3D10_BUFFER_DESC) para definir cómo se organizan los datos dentro del búfer, cómo puede acceder la canalización al búfer y cómo se usará el búfer.
En el ejemplo siguiente se muestra cómo crear una descripción del búfer para un único triángulo con vértices que contienen valores de posición y color.
struct SimpleVertex
{
D3DXVECTOR3 Position;
D3DXVECTOR3 Color;
};
D3D10_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof( SimpleVertex ) * 3;
bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
En este ejemplo, la descripción del búfer se inicializa con casi todas las configuraciones predeterminadas para el uso, el acceso a la CPU y las marcas varias. La otra configuración es para la marca de enlace que identifica el recurso como solo un búfer de vértices y el tamaño del búfer.
Las marcas de uso y acceso de CPU son importantes para el rendimiento. Estas dos marcas juntas determinan la frecuencia con la que se obtiene acceso a un recurso, en qué tipo de memoria se puede cargar el recurso y en qué procesador necesita acceder al recurso. El uso predeterminado de este recurso no se actualizará con mucha frecuencia. Establecer el acceso de CPU a 0 significa que la CPU no necesitará leer o escribir el recurso. En combinación, esto significa que el tiempo de ejecución puede cargar el recurso en la memoria de mayor rendimiento para la GPU, ya que el recurso no requiere acceso a la CPU.
Como se esperaba, hay un equilibrio entre el mejor rendimiento y la accesibilidad en cualquier momento por parte de cualquier procesador. Por ejemplo, el uso predeterminado sin acceso a la CPU significa que el recurso puede estar disponible exclusivamente para la GPU. Esto podría incluir cargar el recurso en memoria no accesible directamente por la CPU. El recurso solo se puede modificar con UpdateSubresource.
Creación de los datos de inicialización para el búfer
Un búfer es simplemente una colección de elementos y se establece como una matriz 1D. Como resultado, el tono de memoria del sistema y el tono de segmento de memoria del sistema son los mismos; el tamaño de la declaración de datos de vértices. Una aplicación puede proporcionar datos de inicialización cuando se crea un búfer mediante una descripción de subrecurso, que contiene un puntero a los datos de recursos reales y contiene información sobre el tamaño y el diseño de esos datos.
Cualquier búfer creado con uso inmutable (consulte D3D10_USAGE_IMMUTABLE) debe inicializarse en el momento de la creación. Los búferes que usan cualquiera de las otras marcas de uso se pueden actualizar después de la inicialización mediante CopyResource, CopySubresourceRegion y UpdateSubresource, o accediendo a su memoria subyacente mediante el método Map.
Creación del búfer
Con la descripción del búfer y los datos de inicialización (que es opcional), llame a CreateBuffer para crear un búfer de vértices. El siguiente fragmento de código muestra cómo crear un búfer de vértices a partir de una matriz de datos de vértices declarados por la aplicación.
struct SimpleVertexCombined
{
D3DXVECTOR3 Pos;
D3DXVECTOR3 Col;
};
ID3D10InputLayout* g_pVertexLayout = NULL;
ID3D10Buffer* g_pVertexBuffer[2] = { NULL, NULL };
ID3D10Buffer* g_pIndexBuffer = NULL;
SimpleVertexCombined verticesCombo[] =
{
D3DXVECTOR3( 0.0f, 0.5f, 0.5f ),
D3DXVECTOR3( 0.0f, 0.0f, 0.5f ),
D3DXVECTOR3( 0.5f, -0.5f, 0.5f ),
D3DXVECTOR3( 0.5f, 0.0f, 0.0f ),
D3DXVECTOR3( -0.5f, -0.5f, 0.5f ),
D3DXVECTOR3( 0.0f, 0.5f, 0.0f ),
};
D3D10_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof( SimpleVertexCombined ) * 3;
bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = verticesCombo;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
hr = g_pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &g_pVertexBuffer[0] );
Creación de un búfer de índice
Crear un búfer de índice es muy similar a crear un búfer de vértices; con dos diferencias. Un búfer de índice contiene solo datos de 16 o 32 bits (en lugar de la amplia gama de formatos disponibles para un búfer de vértices. Un búfer de índice también requiere una marca de enlace de búfer de índice.
En el ejemplo siguiente se muestra cómo crear un búfer de índice a partir de una matriz de datos de índice.
ID3D10Buffer *g_pIndexBuffer = NULL;
// Create indices
unsigned int indices[] = { 0, 1, 2 };
D3D10_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof( unsigned int ) * 3;
bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = indices;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
hr = g_pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &g_pIndexBuffer );
if( FAILED( hr ) )
return hr;
g_pd3dDevice->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
Crear un búfer de constantes
Direct3D 10 presenta un búfer de constantes. Un búfer de constantes de constantes o un búfer de constantes de sombreador es un búfer que contiene constantes del sombreador. Este es un ejemplo de creación de un búfer de constantes, tomado del ejemplo HLSLWithoutFX10.
ID3D10Buffer* g_pConstantBuffer10 = NULL;
struct VS_CONSTANT_BUFFER
{
D3DXMATRIX mWorldViewProj; //mWorldViewProj will probably be global to all shaders in a project.
//It's a good idea not to move it around between shaders.
D3DXVECTOR4 vSomeVectorThatMayBeNeededByASpecificShader;
float fSomeFloatThatMayBeNeededByASpecificShader;
float fTime; //fTime may also be global to all shaders in a project.
float fSomeFloatThatMayBeNeededByASpecificShader2;
float fSomeFloatThatMayBeNeededByASpecificShader3;
};
D3D10_BUFFER_DESC cbDesc;
cbDesc.ByteWidth = sizeof( VS_CONSTANT_BUFFER );
cbDesc.Usage = D3D10_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
hr = g_pd3dDevice->CreateBuffer( &cbDesc, NULL, &g_pConstantBuffer10 );
if( FAILED( hr ) )
return hr;
g_pd3dDevice->VSSetConstantBuffers( 0, 1, g_pConstantBuffer10 );
Tenga en cuenta que cuando se usa la interfaz ID3D10Effect Interface, la instancia de ID3D10Effect Interface controla el proceso de creación, enlace y comitting de un búfer de constantes. En ese caso, solo es necesario obtener la variable del efecto con uno de los métodos GetVariable como GetVariableByName y actualizar la variable con uno de los métodos SetVariable, como SetMatrix. Para obtener un ejemplo del uso de la interfaz ID3D10Effect para administrar un búfer de constantes, consulte Tutorial 7: Asignación de texturas y búferes de constantes.
Temas relacionados