Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Direct3D11:在3D场景中渲染2D:如何在摄影机更改位置时使2D对象在视口中不移动?_C++_3d_2d_Directx_Direct3d11 - Fatal编程技术网

C++ Direct3D11:在3D场景中渲染2D:如何在摄影机更改位置时使2D对象在视口中不移动?

C++ Direct3D11:在3D场景中渲染2D:如何在摄影机更改位置时使2D对象在视口中不移动?,c++,3d,2d,directx,direct3d11,C++,3d,2d,Directx,Direct3d11,带有问题示例的图像: 嗨, 我需要一些关于在3D场景中使用3D相机渲染2D对象的帮助。我想我设法用LH世界坐标解出了2D坐标。但是,仅当摄影机处于[0.0f,0.0f,0.0f]坐标时,渲染的2D对象才处于正确的位置。在每一个其他位置,场景中2D对象的位置的格式都不正确。我认为我的矩阵是一团糟,但不知道在哪里可以看得更远。我很感激你的好主意,如果你缺少什么,请发表评论,我会编辑主要帖子,为你提供更多信息 我正在使用简单的3D颜色HLSL(VS和PS版本:4.0)着色器,对较大的三角形进行alph

带有问题示例的图像:

嗨, 我需要一些关于在3D场景中使用3D相机渲染2D对象的帮助。我想我设法用LH世界坐标解出了2D坐标。但是,仅当摄影机处于
[0.0f,0.0f,0.0f]
坐标时,渲染的2D对象才处于正确的位置。在每一个其他位置,场景中2D对象的位置的格式都不正确。我认为我的矩阵是一团糟,但不知道在哪里可以看得更远。我很感激你的好主意,如果你缺少什么,请发表评论,我会编辑主要帖子,为你提供更多信息

我正在使用简单的3D颜色HLSL(VS和PS版本:4.0)着色器,对较大的三角形进行alpha混合:

cbuffer ConstantBuffer : register( b0 )
{
    matrix World;
    matrix View;
    matrix Projection;
}
struct VS_INPUT
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
};
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
};

PS_INPUT VS ( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;

    input.Pos.w = 1.0f;

    output.Pos = mul ( input.Pos, World );
    output.Pos = mul ( output.Pos, View );
    output.Pos = mul ( output.Pos, Projection );
    output.Color = input.Color;

    return output;
}

float4 PS ( PS_INPUT input ) : SV_Target
{
    return input.Color;
}
这是我的顶点数据结构:

  struct Vertex
  {
    DirectX::XMFLOAT3 position;
    DirectX::XMFLOAT4 color;

    Vertex() {};

    Vertex(DirectX::XMFLOAT3 aPosition, DirectX::XMFLOAT4 aColor) 
      : position(aPosition)
      , color(aColor) 
    {};
  };
对象的渲染调用:

bool PrimitiveMesh::Draw()
{
  unsigned int stride = sizeof(Vertex);
  unsigned int offset = 0;

  D3DSystem::GetD3DDeviceContext()->IASetVertexBuffers(0, 1, &iVertexBuffer, &stride, &offset);
  D3DSystem::GetD3DDeviceContext()->IASetIndexBuffer(iIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
  D3DSystem::GetD3DDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

  return true;
}
使用初始化绘制调用:

    static PrimitiveMesh* mesh;
    if (mesh == 0)
    {
      std::vector<PrimitiveMesh::Vertex> vertices;
      mesh = new PrimitiveMesh();

      DirectX::XMFLOAT4 color = { 186 / 256.0f, 186 / 256.0f, 186 / 256.0f, 0.8f };
      vertices.push_back({ DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f), color });
      vertices.push_back({ DirectX::XMFLOAT3(0.0f, 600.0f, 0.0f), color });
      vertices.push_back({ DirectX::XMFLOAT3(800.0f, 600.0f, 0.0f), color });

      mesh->SetVerticesAndIndices(vertices);
    }
    // Getting clean matrices here:
    D3D::Matrices(world, view, projection, ortho);
    iGI->TurnZBufferOff();
    iGI->TurnOnAlphaBlending();
    mesh->Draw();
    XMMATRIX view2D = Camera::View2D();

    iColorShader->Render(iGI->GetContext(), 3, &world, &view2D, &ortho);
    iGI->TurnZBufferOn();
我将感谢任何帮助。
亲切问候。

使用着色器,您不必被迫使用矩阵,您可以灵活地简化问题

假设您使用像素坐标渲染二维对象,唯一的要求是将它们缩放回标准化投影空间

顶点着色器可以如此短:

cbuffer ConstantBuffer : register( b0 ) {
    float2 rcpDim; // 1 / renderTargetSize
}
PS_INPUT VS ( VS_INPUT input ) {
    PS_INPUT output;

    output.Pos.xy = input.Pos.xy * rcpDim * 2; // from pixel to [0..2]
    output.Pos.xy -= 1; // to [-1..1]
    output.Pos.y *= -1; // because top left in texture space is bottom left in projective space
    output.Pos.zw = float2(0,1);
    output.Color = input.Color;
    return output;
}

当然,您可以构建一组矩阵,实现与原始着色器相同的结果,只需使用
XMMatrixOrthographicOffCenterLH(0,宽度,0,高度,0,1)
将“世界和视图”设置为“标识”,并将“投影”设置为正交投影。但是,随着你对3D编程的要求越来越高,你很快就必须学会如何处理多个着色器,所以把它作为一种练习。

好吧,我解决了我的问题。出于某种奇怪的原因,DirectXMath生成了错误的XMMATRIX。我的
XMMatrixOrtographicLH()
对于好的参数是完全不正确的。我用Ortographic矩阵的经典定义解决了我的问题(图10中的定义)


galop1n给出了一个很好的解决方案,但在我的系统上

cbuffer-ConstantBuffer:寄存器(b0){
float2 rcpDim;//1/renderTargetSize
}

需要为16的倍数,如此处所示:

struct VS_CONSTANT_BUFFER
{
    DirectX::XMFLOAT2 rcpDim;
    DirectX::XMFLOAT2 rcpDim2;
};

// Supply the vertex shader constant data.
VS_CONSTANT_BUFFER VsConstData;
VsConstData.rcpDim = { 2.0f / w,2.0f / h};

// Fill in a buffer description.
D3D11_BUFFER_DESC cbDesc;
ZeroMemory(&cbDesc, sizeof(cbDesc));
cbDesc.ByteWidth = sizeof(VS_CONSTANT_BUFFER);
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;

// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = &VsConstData;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;

// Create the buffer.
HRESULT hr = pDevice->CreateBuffer(&cbDesc, &InitData,
    &pConstantBuffer11);
或对齐

__declspec(align(16))
struct VS_CONSTANT_BUFFER
{
    DirectX::XMFLOAT2 rcpDim;
};

嗨,谢谢你的回答。我自己设法解决了。出于某种奇怪的原因,无论多么令人难以置信,我的XMMatrixOrtographicsProjectionLH完全不正确,我必须自己制作,完全解决了这个问题。我应用了图9下的矩阵定义。
struct VS_CONSTANT_BUFFER
{
    DirectX::XMFLOAT2 rcpDim;
    DirectX::XMFLOAT2 rcpDim2;
};

// Supply the vertex shader constant data.
VS_CONSTANT_BUFFER VsConstData;
VsConstData.rcpDim = { 2.0f / w,2.0f / h};

// Fill in a buffer description.
D3D11_BUFFER_DESC cbDesc;
ZeroMemory(&cbDesc, sizeof(cbDesc));
cbDesc.ByteWidth = sizeof(VS_CONSTANT_BUFFER);
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;

// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = &VsConstData;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;

// Create the buffer.
HRESULT hr = pDevice->CreateBuffer(&cbDesc, &InitData,
    &pConstantBuffer11);
__declspec(align(16))
struct VS_CONSTANT_BUFFER
{
    DirectX::XMFLOAT2 rcpDim;
};