2010-10-07 11 views
9

Actualmente estoy tratando de acostumbrarme a la API de DirectX y me pregunto cuál es el enfoque habitual para representar un sprite en DirectX 11 (por ejemplo, para un clon de tetris).¿Cuál es la mejor práctica para renderizar sprites en DirectX 11?

¿Hay una interfaz similar a ID3DX10Sprite, y si no, cuál sería el método habitual para dibujar sprites en DirectX 11?

Editar: Aquí está el código HLSL que trabajó para mí (el cálculo de la proyección de coordenadas que se podría hacer mejor):

struct SpriteData 
{ 
    float2 position; 
    float2 size; 
    float4 color; 
}; 

struct VSOut 
{ 
    float4 position : SV_POSITION; 
    float4 color : COLOR; 
}; 

cbuffer ScreenSize : register(b0) 
{ 
    float2 screenSize; 
    float2 padding; // cbuffer must have at least 16 bytes 
} 

StructuredBuffer<SpriteData> spriteData : register(t0); 

float2 GetVertexPosition(uint VID) 
{ 
    [branch] switch(VID) 
    { 
     case 0: 
      return float2(0, 0); 
     case 1: 
      return float2(1, 0); 
     case 2: 
      return float2(0, 1); 
     default: 
      return float2(1, 1); 
    } 
} 

float4 ComputePosition(float2 positionInScreenSpace, float2 size, float2 vertexPosition) 
{ 
    float2 origin = float2(-1, 1); 
    float2 vertexPositionInScreenSpace = positionInScreenSpace + (size * vertexPosition); 

    return float4(origin.x + (vertexPositionInScreenSpace.x/(screenSize.x/2)), origin.y - (vertexPositionInScreenSpace.y/(screenSize.y/2)), 1, 1); 
} 

VSOut VShader(uint VID : SV_VertexID, uint SIID : SV_InstanceID) 
{ 
    VSOut output; 

    output.color = spriteData[SIID].color; 
    output.position = ComputePosition(spriteData[SIID].position, spriteData[SIID].size, GetVertexPosition(VID)); 

    return output; 
} 

float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET 
{ 
    return color; 
} 

Respuesta

6

No, no hay un equivalente. El método habitual sería dibujar una franja triangular formando un quad.

Puede hacer uso de instancias, por lo que solo tiene que actualizar un búfer con datos de sprite (x, y posición de pantalla en píxeles, id de la textura a buscar en una matriz de textura, escala, rotación, capa, etc.) y use sombreadores para renderizar todos los sprites en una sola llamada de sorteo.

He aquí algunos datos HLSL de la parte superior de mi cabeza:

//-------------------------------------------------------------------------------------- 
// Shader code for Sprite Rendering 
//-------------------------------------------------------------------------------------- 

struct Sprite { 
    float2 position; // x, y world position 
    float rotation; 
    float scaling; 

    float layer; // if you have multiple layers of sprites (e.g. background sprites) 
    uint textureId; 
}; 

StructuredBuffer<Sprite> SpritesRO : register(t0); 
Texture2DArray<float4> TextureSlices : register (t1); 

cbuffer cbRenderConstants : register(b0) 
{ 
    matrix g_mViewProjection; 
    // other constants 
}; 

struct VSSpriteOut 
{ 
    float3 position : SV_Position; 
    uint textureId; 
}; 

//-------------------------------------------------------------------------------------    
// Sprite Vertex Shader 
//------------------------------------------------------------------------------------- 

VSSpriteOut SpriteVS(uint VID : SV_VertexID, uint SIID : SV_InstanceID) 
{ 
    VSSpriteOut Out = (VSSpriteOut)0; 

    // VID is either 0, 1, 2 or 3 
    // We can map 0 to position (0,0), 1 to (0,1), 2 to (1,0), 3 to (1,1) 

    // We fetch the sprite instance data accord SIID 
    Sprite sdata = SpritesRO[SIID]; 

    // function f computes screen space vertex position 
    float3 pos = f (g_mViewProjection, VID, position, rotation, scaling, layer etc) 

    Out.position = pos; 
    Out.textureId = sdata.textureId; 

    return Out; 
} 

//------------------------------------------------------------------------------------- 
// Sprite Pixel Shader 
//------------------------------------------------------------------------------------- 

float4 SpritePS(VSSpriteOut In) : SV_Target 
{ 
    // use In.textureId to fetch the right texture slice in texture array 
    return color; 
} 
+0

Podría darme un ejemplo de código corto por favor? Me cuesta empezar con el buffer. –

+0

Eche un vistazo a todas las muestras D3D11 de DXSDK, y observe cuidadosamente cómo lo hacen para crear búferes, vincularlos, actualizarlos, etc. – Stringer

+0

Wow, gracias. Esto realmente me ayudó a comenzar :) –

Cuestiones relacionadas