2010-10-07 122 views
9

我目前正在嘗試使用DirectX API,我想知道在DirectX 11中渲染精靈的常用方法(例如,用於俄羅斯方塊克隆)。在DirectX 11中渲染精靈的最佳實踐是什麼?

是否有一個類似於ID3DX10Sprite的接口?如果沒有,這將是在DirectX 11中繪製精靈的常用方法?

編輯:這是對我工作的HLSL代碼(投影的座標計算可以做的更好):

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

回答

6

沒有沒有等價物。通常的方法是繪製一個形成四邊形的三角形條。你可以使用實例化,所以你只需要更新一個帶有精靈數據的緩衝區(x,y像素的屏幕位置,在紋理數組中獲取紋理的id,縮放,旋轉,圖層等)並使用着色器在一次繪製調用中渲染所有的精靈。

下面是一些HLSL花絮了我的頭頂部:

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

你能給我一個短的代碼示例嗎?我努力開始使用緩衝區。 – 2010-10-07 23:15:59

+0

查看DXSDK中的所有D3D11樣本,並仔細查看它們如何創建緩衝區,綁定它們,更新它們等。 – Stringer 2010-10-08 12:38:39

+0

哇,謝謝。這真的幫助我開始:) – 2010-10-08 21:28:18