Direct3D 11不会栅格化任何顶点

时间:2013-01-19 14:54:19

标签: directx direct3d directx-11 direct3d11

我正在尝试使用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设置中是否还有其他任何可能导致此问题的部分?

2 个答案:

答案 0 :(得分: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缓冲区中使用(我们不会在这里使用z缓冲区)。 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的Framework源代码中找到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();
};

答案 1 :(得分:0)

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