1

我正在尝试使用 Direct3D 11 在屏幕上渲染一个简单的三角形,但没有任何显示。这是我的顶点:

SimpleVertex vertices[ 3 ] =
{
    { XMFLOAT3( -1.0f, -1.0f, 0.0f ) },
    { XMFLOAT3(  1.0f, -1.0f, 0.0f ) },
    { XMFLOAT3( -1.0f,  1.0f, 0.0f ) },
};

预期的输出是一个三角形,一个点在屏幕的左上角,一个点在屏幕的右上角,一个点在屏幕的左下角。但是,任何地方都没有渲染任何内容。

我没有执行任何矩阵转换,顶点着色器只是将输入直接传递给输出。一切似乎都设置正确,当我在 Visual Studio 2012 中使用图形调试器时,正确的顶点位置被传递给顶点着色器。但是,它直接从顶点着色器阶段跳到管道中的输出合并阶段。我假设这意味着没有任何东西被发送到像素着色器,这再次意味着向量在光栅化阶段被丢弃。为什么会这样?

这是我的光栅化状态:

D3D11_RASTERIZER_DESC rasterizerDesc;
rasterizerDesc.AntialiasedLineEnable = false;
rasterizerDesc.CullMode = D3D11_CULL_NONE;
rasterizerDesc.DepthBias = 0;
rasterizerDesc.DepthBiasClamp = 0.0f;
rasterizerDesc.DepthClipEnable = true;
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.FrontCounterClockwise = false;
rasterizerDesc.MultisampleEnable = false;
rasterizerDesc.ScissorEnable = false;
rasterizerDesc.SlopeScaledDepthBias = 0.0f;

我的视口(宽度/高度是与我的后台缓冲区匹配的窗口客户区,在我的测试设置中设置为 1024x576):

D3D11_VIEWPORT viewport;
viewport.Height = static_cast< float >( height );
viewport.MaxDepth = 1.0f;
viewport.MinDepth = 0.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
viewport.Width = static_cast< float >( width );

谁能看到是什么让光栅化阶段放弃了我的顶点?还是我的 D3D 设置的任何其他部分可能导致此问题?

4

2 回答 2

0

我在互联网上找到了这个..加载需要很长时间,所以我复制并粘贴了我用粗体突出显示的一个有趣点。

第 11 行中定义的 D3D_OVERLOADS 构造函数为 C++ 程序员提供了一种使用 D3DTLVERTEX 创建变换和光照顶点的便捷方式。

_D3DTLVERTEX(const D3DVECTOR& v, float _rhw, D3DCOLOR _color,
         D3DCOLOR _specular, float _tu, float _tv)
{
sx = v.x;
sy = v.y;
sz = v.z;
rhw = _rhw;
color = _color;
specular = _specular;
tu = _tu;
tv = _tv;

}

系统需要一个已经转换的顶点位置。所以 x 和 y 值必须在屏幕坐标中,z 必须是像素的深度值,可以在 z-buffer 中使用(我们这里不会使用 z-buffer)。Z 值的范围可以从 0.0 到 1.0,其中 0.0 是距离观察者最近的可能位置,而 1.0 是在观察区域内仍然可见的最远位置。紧跟该位置,变换和光照顶点必须包含一个 RHW(齐次 W 的倒数)值。

在对顶点进行光栅化之前,必须将它们从同质顶点转换为非同质顶点,因为光栅化器期望它们以这种方式进行。Direct3D 通过将 x、y 和 z 坐标除以 w 坐标将齐次顶点转换为非齐次顶点,并通过反转 w 坐标生成 RHW 值。这仅适用于由 Direct3D 转换和照亮的顶点。RHW 值以多种方式使用:用于计算雾,用于执行透视正确的纹理映射,以及用于 w 缓冲(深度缓冲的另一种形式)。

定义 D3D_OVERLOADS 后,D3DVECTOR 被声明为

_D3DVECTOR(D3DVALUE _x, D3DVALUE _y, D3DVALUE _z);

D3DVALUE 是基本的 Direct3D 分数数据类型。它在 d3dtypes.h 中声明为

 typedef float D3DVALUE, *LPD3DVALUE;

源代码显示 D3DVECTOR 的 x 和 y 值始终为 0.0f(这将在 InitDeviceObjects() 中更改)。rhw 始终为 0.5f,颜色为 0xfffffff,镜面反射设置为 0。只有 tu1 和 tv1 值在四个顶点之间不同。这些是背景纹理的坐标。

为了将纹素映射到图元上,Direct3D 要求所有纹理中的所有纹素都有一个统一的地址范围。因此,它使用了一个通用的寻址方案,其中所有的纹素地址都在 0.0 到 1.0 的范围内。相反,如果您决定分配纹理坐标以使 Direct3D 使用纹理的下半部分,则您的应用程序将分配给本例中图元顶点的纹理坐标为 (0.0,0.0)、(1.0,0.0)、 (1.0,0.5) 和 (0.0,0.5)。Direct3D 将应用纹理的下半部分作为背景。

注意:通过在该范围之外分配纹理坐标,您可以创建某些特殊的纹理效果。

您将在 d3dtextr.cpp 的框架源代码中找到 D3DTextr_CreateTextureFromFile() 的声明。它从传递的文件创建本地位图。可以从 *.bmp 和 *.tga 文件创建纹理。纹理在框架中以链表的形式进行管理,链表保存每个纹理的信息,称为纹理容器。

 struct TextureContainer
{
TextureContainer* m_pNext; // Linked list ptr

TCHAR   m_strName[80];  // Name of texture (doubles as image filename)
DWORD   m_dwWidth;
DWORD   m_dwHeight;
DWORD   m_dwStage;      // Texture stage (for multitexture devices)
DWORD   m_dwBPP;
DWORD   m_dwFlags;
BOOL    m_bHasAlpha;

LPDIRECTDRAWSURFACE7 m_pddsSurface;  // Surface of the texture
HBITMAP m_hbmBitmap;                 // Bitmap containing texture image
DWORD*  m_pRGBAData;

public:
HRESULT LoadImageData();
HRESULT LoadBitmapFile( TCHAR* strPathname );
HRESULT LoadTargaFile( TCHAR* strPathname );
HRESULT Restore( LPDIRECT3DDEVICE7 pd3dDevice );
HRESULT CopyBitmapToSurface();
HRESULT CopyRGBADataToSurface();

TextureContainer( TCHAR* strName, DWORD dwStage, DWORD dwFlags );
~TextureContainer();
};
于 2013-01-19T17:52:24.773 回答
0

问题实际上出在我的渲染逻辑中。我将顶点缓冲区的步幅设置为 0,而不是我的顶点结构的大小。改变了它,它渲染得很好!

于 2013-01-20T10:32:42.610 回答