Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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++ D3D11:如何绘制简单的像素对齐线?_C++_Directx 11 - Fatal编程技术网

C++ D3D11:如何绘制简单的像素对齐线?

C++ D3D11:如何绘制简单的像素对齐线?,c++,directx-11,C++,Directx 11,我试图用D3D11在两个顶点之间画一条线。我在D3D9和D3D11中有一些经验,但在D3D11中画一条线似乎是个问题,它从一个给定的像素开始,在另一个像素结束 我所做的: 我在每个顶点的像素坐标上添加了0.5f,以适应texel-/像素坐标系(我阅读了Microsoft页面中D3D9和D3D11坐标系之间的差异): f32 fOff=0.5f; 彩色顶点新顶点[2]= { {D3DXVECTOR3(fStartX+fOff,fStartY+fOff,0),veccorrgb}, {D3DXVEC

我试图用D3D11在两个顶点之间画一条线。我在D3D9和D3D11中有一些经验,但在D3D11中画一条线似乎是个问题,它从一个给定的像素开始,在另一个像素结束

我所做的:

  • 我在每个顶点的像素坐标上添加了0.5f,以适应texel-/像素坐标系(我阅读了Microsoft页面中D3D9和D3D11坐标系之间的差异):

    f32 fOff=0.5f; 彩色顶点新顶点[2]= { {D3DXVECTOR3(fStartX+fOff,fStartY+fOff,0),veccorrgb}, {D3DXVECTOR3(fEndX+fOff,fEndY+fOff,0),veccorrgb} };

  • 生成正交投影矩阵以适合渲染目标:

    D3DXMatrixOrthoOffCenterLH(和MatrixOrthoProj,0.0f,(f32)轨道宽度,0.0f,(f32)轨道高度,0.0f,1.0f); D3DXMatrixTranspose(&cbConstant.m_-MatorhoProjection,&MatrixOrthoProj)

  • 设置光栅化状态、混合状态、视口

  • 将顶点绘制为D3D11_基本体_拓扑_线列表
  • 问题: 这条线似乎短了一个像素。它从给定的像素坐标开始,非常适合它。线条的方向看起来是正确的,但我希望线条结束的像素仍然没有着色。这条线看起来只有一个像素短

    有没有任何教程解释这个问题,或者有人有同样的问题?正如我所记得的,在D3D9中没有那么难

    请询问您是否需要进一步的信息

    谢谢,Stefan

    编辑:找到d3d10的光栅化规则(应与d3d11相同):


    我希望这能帮助我理解…

    我不知道D3D11,但是你的问题听起来很像D3D9中的D3DRS\u LASTPIXEL渲染状态-也许你需要研究D3D11的一个等价物。

    根据光栅化规则(上面问题中的链接),我可能已经找到了一个可行的解决方案:

  • 排序顶点StartX
  • 将(0.5/0.5)添加到起始顶点(如我之前所做的),以将顶点移动到像素的中心
  • 将(1.0/1.0)添加到端点顶点以将顶点移动到右下角
  • 这需要告诉光栅化器应该绘制线条的最后一个像素

    f32 fXStartOff = 0.5f;
    f32 fYStartOff = 0.5f;
    f32 fXEndOff = 1.0f;
    f32 fYEndOff = 1.0f;
    
    ColoredVertex newVertices[2] = 
    {
        { D3DXVECTOR3((f32)fStartX + fXStartOff, (f32)fStartY + fYStartOff,0), vecColorRGB },
        { D3DXVECTOR3((f32)fEndX + fXEndOff , (f32)fEndY + fYEndOff,0), vecColorRGB }
    };
    

    如果您知道更好的解决方案,请让我知道。

    我遇到了完全相同的问题,我解决了,感谢这次讨论

    我的顶点存储在D3D11_基本体_拓扑_线列表顶点缓冲区中

    感谢这篇有用的帖子,你让我今天修复了这个bug。 这比我一开始想象的要复杂得多

    这里是我的几行代码

    // projection matrix code
    float width = 1024.0f;
    float height = 768.0f;
    DirectX::XMMATRIX offsetedProj = DirectX::XMMatrixOrthographicRH(width, height, 0.0f, 10.0f);
    DirectX::XMMATRIX proj = DirectX::XMMatrixMultiply(DirectX::XMMatrixTranslation(- width / 2, height / 2, 0), offsetedProj);
    
    // view matrix code
    // screen top left pixel is 0,0 and bottom right is 1023,767
    DirectX::XMMATRIX viewMirrored = DirectX::XMMatrixLookAtRH(eye, at, up);
    DirectX::XMMATRIX mirrorYZ = DirectX::XMMatrixScaling(1.0f, -1.0f, -1.0f);
    DirectX::XMMATRIX view = DirectX::XMMatrixMultiply(mirrorYZ, viewMirrored);
    
    // draw line code in my visual debug tool.
    void TVisualDebug::DrawLine2D(int2 const& parStart,
                                  int2 const& parEnd,
                                  TColor parColorStart,
                                  TColor parColorEnd,
                                  float parDepth)
    
    {
        FLine2DsDirty = true;
    
        // D3D11_PRIMITIVE_TOPOLOGY_LINELIST
        float2 const startFloat(parStart.x() + 0.5f, parStart.y() + 0.5f);
        float2 const endFloat(parEnd.x() + 0.5f, parEnd.y() + 0.5f);
        float2 const diff = endFloat - startFloat;
        // return normalized difference or float2(1.0f, 1.0f) if distance between the points is null. Then multiplies the result by something a little bigger than 0.5f, 0.5f is not enough.
        float2 const diffNormalized =  diff.normalized_replace_if_null(float2(1.0f, 1.0f)) * 0.501f;
    
        size_t const currentIndex = FLine2Ds.size();
        FLine2Ds.resize(currentIndex + 2);
        render::vertex::TVertexColor* baseAddress = FLine2Ds.data() + currentIndex;
        render::vertex::TVertexColor& v0 = baseAddress[0];
        render::vertex::TVertexColor& v1 = baseAddress[1];
        v0.FPosition = float3(startFloat.x(), startFloat.y(), parDepth);
        v0.FColor = parColorStart;
        v1.FPosition = float3(endFloat.x() + diffNormalized.x(), endFloat.y() + diffNormalized.y(), parDepth);
        v1.FColor = parColorEnd;
    }
    

    我测试了几个DrawLine2D调用,它似乎工作得很好。

    您不再需要调整DX10+中的pixle坐标,这只是众多改进中的一个(在驱动程序级别iirc中无法实现)。这个问题让我想起了线列表绘图中存在的一个老OpenGL错误…当我不向坐标添加0.5f时,线变为2px厚,这对我来说意味着,它正好在渲染目标中的2个像素之间渲染目标:20x20px线顶点:(1,1)->(18,1)在渲染目标上,线填充从(1,1)到(18,1)的像素(17,1)添加了0.5f调整,请参见“将纹理映射到像素”。您是否有可能将DX11与DX9接口一起使用(也称为
    D3D_功能级别_9_x
    ?我将D3D_功能级别_11_0与硬件渲染设备(nvidia geforce gtx 580)一起使用。调整在顶点着色器到达像素中心之前完成,因此顶点的坐标为(1.5,1.5)和(18.5,1.5)。因为(渲染目标的)纹理和像素之间没有差异在这之后没有任何调整了,对吧,听起来这就是我需要的。但是d3d11中不再有渲染状态。我会寻找相等的。谢谢:)错误:只需排序StartXfEndY)fYEndOff=0.0f;嗯-你不能只在线条上增加0.5,0.5个额外的坡度,或者你正在更改坡度。要做到这一点,你需要添加0.5*坡度(即使线条延长0.5像素)。你是对的,我的解决方案没有我想要的那么精确,但是在我的测试中(20x20px渲染目标上有几行)结果还可以。我会尝试一下你的建议。谢谢:)你可能想看看
    PrimitiveBatch
    类。