2010-10-07 31 views
9

J'essaie actuellement de m'habituer à l'API DirectX et je me demande quelle est l'approche habituelle pour rendre un sprite dans DirectX 11 (par exemple pour un clone de tetris).Quelle est la meilleure pratique pour rendre les sprites dans DirectX 11?

Existe-t-il une interface simmilar comme ID3DX10Sprite, et si ce n'est pas le cas, quelle serait la méthode habituelle pour dessiner des sprites dans DirectX 11?

Edit: Voici le code HLSL qui a fonctionné pour moi (le calcul de la projection coordonnée pourrait être fait mieux):

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; 
} 

Répondre

6

Non il n'y a pas d'équivalent. Méthode habituelle serait de dessiner une bande de triangle formant un quad. Vous pouvez utiliser l'instanciation, vous n'avez donc qu'à mettre à jour un tampon avec des données d'image-objet (position d'écran x, y en pixels, identifiant de la texture à extraire dans un tableau de texture, mise à l'échelle, rotation, etc.) et utilisez des shaders pour rendre tous les sprites en un seul appel draw.

Voici quelques petits morceaux HLSL du haut de ma tête:

//-------------------------------------------------------------------------------------- 
// 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

Pourriez-vous me donner un court exemple de code s'il vous plaît? Je me bats pour commencer avec le tampon. –

+0

Vérifiez tous les échantillons D3D11 de DXSDK, et regardez attentivement comment ils font pour créer des tampons, les lier, les mettre à jour, etc. – Stringer

+0

Wow, merci. Cela m'a vraiment aidé à démarrer :) –