3

長年の読者。初めてのポスター。私はここ数時間脳細胞を破壊し、どこにも速くならないという問題を抱えています。だから私はそれをここに押し付けて、それに新鮮な目を向けると思いました...

基本的に、私はC++とDirectX11を使用して2Dゲームを作成しようとしています。以前はC#とXNAを使用し、DirectXでいくつかの3Dを作成しましたが、それほど大きなものはありません。

今のところ、基本的なカメラと基本的なスプライトバッチを使用して画面の中央にスプライトを描画しようとしていますが、何も表示されておらず、その理由を一生理解できません。アイデアを出すためにいくつかのコードを投稿します。

これは、カメラクラスのすべてのマトリックスを設定している場所であり、それらはそのままです(今のところ、後で移動するように変更されます)。

XMStoreFloat4x4(&m_world, XMMatrixIdentity());
XMStoreFloat4x4(&m_proj, XMMatrixOrthographicOffCenterLH(0.0f, width, height, 0.0f, 0.0f, 1.0f));

m_position = XMFLOAT3(width / 2, height / 2, 0);
m_look = XMFLOAT3(0, 0, 1);
m_up = XMFLOAT3(0, 1, 0);

XMVECTOR p = XMLoadFloat3(&m_position);
XMVECTOR l = XMLoadFloat3(&m_look);
XMVECTOR u = XMLoadFloat3(&m_up);

XMStoreFloat4x4(&m_view, XMMatrixLookToLH(p, l, u));

次に、これは、情報をシェーダーに渡すスプライトバッチ開始メソッドに渡されます。

D3D11_MAPPED_SUBRESOURCE data;
ZeroMemory(&data, sizeof(data));
m_deviceContext->Map(m_cBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
ConstantBuffer* cb = (ConstantBuffer*)data.pData;

XMMATRIX w = XMLoadFloat4x4(&world);
XMMATRIX v = XMLoadFloat4x4(&view);
XMMATRIX p = XMLoadFloat4x4(&proj);

w = XMMatrixTranspose(w);
v = XMMatrixTranspose(v);
p = XMMatrixTranspose(p);

XMStoreFloat4x4(&world, w);
XMStoreFloat4x4(&view, v);
XMStoreFloat4x4(&proj, p);

cb->World = world;
cb->View = view;
cb->Proj = proj;

m_deviceContext->Unmap(m_cBuffer, 0);

そして最後に、シェーダー自体:

cbuffer ConstantBuffer : register(b0)
{
    float4x4 World;
    float4x4 View;
    float4x4 Proj;
};

SamplerState sam : register(s0);
Texture2D tex : register(t0);

struct VertexIn
{
    float3 Position : POSITION;
    float2 Texture : TEXCOORD;
    float4 Color : COLOR;
};

struct PixelIn
{
    float4 Position : SV_POSITION;
    float2 Texture : TEXCOORD;
    float4 Color : COLOR;
};

PixelIn VS(VertexIn vin)
{
    float4 position = float4(vin.Position, 1.0f);
    position = mul(position, World);
    position = mul(position, View);
    position = mul(position, Proj);

    PixelIn vout;
    vout.Position = position;
    vout.Texture = vin.Texture;
    vout.Color = vin.Color;

    return vout;
}

float4 PS(PixelIn pin) : SV_Target
{
    float4 textureColor = tex.Sample(sam, pin.Texture);

    return pin.Color * textureColor;   
}

ご覧のとおり、非常に単純なものです。しかし、画面には何も描画されません。私はマトリックスをまったく気にせず、ワールドマトリックスを除外し、透視投影マトリックスを使用し、マトリックスを見るのではなく見るを使用し、XMMatrixOrthographicLHを介して中心として(0、0、0)を使用し、スプライトの位置をに変換しようとしました。画面スペース。

スプライトバッチを大幅に簡略化して、一度に1つのスプライトのみを描画するように制限しました。

不変のインデックスバッファ(0、1、2、0、2、3)と、次のように更新される動的頂点バッファを使用しています。

D3D11_MAPPED_SUBRESOURCE data;
ZeroMemory(&data, sizeof(data));
m_deviceContext->Map(m_vBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
Vertex* vertex = (Vertex*)data.pData;

for(UINT i = 0; i < sprite->Vertices.size(); ++i)
{
    vertex[i] = sprite->Vertices[i];
}

m_deviceContext->Unmap(m_vBuffer, 0);

m_deviceContext->DrawIndexed(6, 0, 0);

3Dモデルのレンダリングにも同様の方法を使用しました。実際、動的インデックスバッファーと、より多くの定数バッファーデータがあり、シェーダーがはるかに複雑だったため、これはより困難でした。

どこかでデータが失われるのは問題かもしれないと思いましたが、DrawIndexedメソッドの呼び出しまですべてが適切に渡されているようです。バッファの作成と状態を再確認し、現在、カリングされていないことを確認するためにCULL_NONEに配置しています。

わかりやすくするために、バッファの作成とスプライトの作成を投稿します。

HRESULT result = S_OK;

device->GetImmediateContext(&m_deviceContext);

D3D11_BUFFER_DESC cbd;
ZeroMemory(&cbd, sizeof(cbd));
cbd.ByteWidth = sizeof(ConstantBuffer);
cbd.Usage = D3D11_USAGE_DYNAMIC;
cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbd.MiscFlags = 0;
cbd.StructureByteStride = 0;

result = device->CreateBuffer(&cbd, 0, &m_cBuffer);

if (FAILED(result))
{
    return 0;
}

vector<short> indices;
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
indices.push_back(0);
indices.push_back(2);
indices.push_back(3);

D3D11_SUBRESOURCE_DATA indexData;
ZeroMemory(&indexData, sizeof(indexData));
indexData.pSysMem = &indices;

D3D11_BUFFER_DESC ibd;
ZeroMemory(&ibd, sizeof(ibd));
ibd.ByteWidth = 6 * sizeof(short);
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;

result = device->CreateBuffer(&ibd, &indexData, &m_iBuffer);

if (FAILED(result))
{
    return 0;
}

D3D11_BUFFER_DESC vbd;
ZeroMemory(&vbd, sizeof(vbd));
vbd.ByteWidth = 4 * sizeof(Vertex);
vbd.Usage = D3D11_USAGE_DYNAMIC;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;

result = device->CreateBuffer(&vbd, 0, &m_vBuffer);

if (FAILED(result))
{
    return 0;
}

return 1;

スプライト:

ID3D11Resource* resource;
ZeroMemory(&resource, sizeof(resource));
texture->GetResource(&resource);

ID3D11Texture2D* tex = (ID3D11Texture2D*)resource;

D3D11_TEXTURE2D_DESC t;
ZeroMemory(&t, sizeof(t));
tex->GetDesc(&t);

Vertex v[4];
ZeroMemory(&v, sizeof(v));

v[0].Position = XMFLOAT3((float)destinationRectangle.value.left, (float)destinationRectangle.value.top, z);
v[1].Position = XMFLOAT3((float)destinationRectangle.value.right, (float)destinationRectangle.value.top, z);
v[2].Position = XMFLOAT3((float)destinationRectangle.value.right, (float)destinationRectangle.value.bottom, z);
v[3].Position = XMFLOAT3((float)destinationRectangle.value.left, (float)destinationRectangle.value.bottom, z);

v[0].Texture = XMFLOAT2((float)(sourceRectangle.value.left / t.Width), (float)(sourceRectangle.value.top / t.Height));
v[1].Texture = XMFLOAT2((float)(sourceRectangle.value.right / t.Width), (float)(sourceRectangle.value.top / t.Height));
v[2].Texture = XMFLOAT2((float)(sourceRectangle.value.right / t.Width), (float)(sourceRectangle.value.bottom / t.Height));
v[3].Texture = XMFLOAT2((float)(sourceRectangle.value.left / t.Width), (float)(sourceRectangle.value.bottom / t.Height));

v[0].Color = color;
v[1].Color = color;
v[2].Color = color;
v[3].Color = color;

Sprite* sprite = new Sprite();
sprite->Vertices.push_back(v[0]);
sprite->Vertices.push_back(v[1]);
sprite->Vertices.push_back(v[2]);
sprite->Vertices.push_back(v[3]);
sprite->Texture = texture;

m_sprites.push_back(sprite);

私は怒っていますか?私はバカですか?それとも、これを行うための簡単な方法はありますか?ありがとう。どんな助けでも大歓迎です!

また、私が描いているスプライトは、800x600の画面上にすべて白色の長方形(左= 300、右= 500、上= 350、下= 450)を持っていることを指摘したいと思います。テクスチャは正しくロードされており、運が悪いことを確認するために、シェーダーに色を出力することも試みました。

ああ、私が描画しようとしているスプライトのZ値は0.5fに設定されていますが、これを別の値に設定しようとしましたが、これは私がそれで動作することを期待していたものです。

4

2 に答える 2

3

別のWebサイトでMJPのおかげで答えを見つけました。問題は次の行でした。

indexData.pSysMem = &indices;

こうあるべきだったので:

indexData.pSysMem = &indices[0];

どうやら、最初のインスタンスではなくベクター全体へのポインターを送信していたので、インデックス バッファーは私が何をしているのかわかりませんでした。

私が言ったように、XNA プログラミングから DirectX プログラミングを始めたばかりです。;)

これが同様の立場にある他の誰かに役立つことを願っています。

于 2013-01-07T01:07:36.467 に答える
0

2D を使用するために DepthStencil を構成しましたか? また、カメラの位置に対して負の Z を試してください。0 にします。

于 2013-01-06T10:14:16.133 に答える