XNA4 DrawUserIndexedPrimitives中使用的顶点集不正确

时间:2011-10-19 05:40:55

标签: xna xna-4.0

背景:我正在编写一个基于图块的地形渲染器,它使用GPU光线投影渲染高度场。我的图形编码曾经是C ++ / OpenGL,但我决定尝试使用C#/ XNA4(即DirectX9)作为学习经验。

问题:调用DrawUserIndexedPrimitives似乎正在使用先前调用中指定的顶点数组。

详情: 切片渲染器通过栅格化切片边框的背面来工作。像素着色器执行光线投射。绘制框的调用是这样的:

private void RenderTile(GraphicsDevice device)
{
    device.DrawUserIndexedPrimitives(
        PrimitiveType.TriangleList, 
        this.BoundingBoxVertex, 0, 8, 
        this.BoundingBoxIndex, 0, 12);
}

并渲染边界框的线框:

private void RenderBoundingBox(GraphicsDevice d)
{
    d.DrawUserIndexedPrimitives(
        PrimitiveType.LineList, 
        this.BoundingBoxRenderVertex, 0, 8, // vertex format is different here, 
                                            // but the positions are the same.
        this.BoundingBoxRenderIndex, 0, 12);
}

产生这个: screenshot of correct tile render

如果我们自己使用另一个图块(整个地形是2x2图块):

screenshot of correct tile render

但是,如果我们将两者一起渲染,则会转换边界框:

Two tiles - incorrect render

我假设我在XNA代码中犯了一个基本错误,导致使用前一个tile的顶点渲染tile,但我找不到它。

同一组数据(float[])用于创建高度贴图纹理和边界框,因此在边界框创建中似乎不是错误。

1 个答案:

答案 0 :(得分:1)

好的,发现了问题。我在渲染过程中设置效果参数(是的,基本错误)

原始代码:

    foreach (var pass in effect.CurrentTechnique.Passes)
    {
        pass.Apply();
        effect.Parameters["HeightTex"].SetValue(this.HeightTex);
        effect.Parameters["Eye"].SetValue(eyePosTile);
        effect.Parameters["World"].SetValue(this.TileMatrix);
        effect.Parameters["View"].SetValue(viewMatrix);
        effect.Parameters["TexToView"].SetValue(texToViewMatrix);
        effect.Parameters["Projection"].SetValue(projectionMatrix);
        effect.Parameters["LightDir"].SetValue(lightDirection);
        this.RenderTile(device);
    }

修正:

    effect.Parameters["HeightTex"].SetValue(this.HeightTex);
    effect.Parameters["Eye"].SetValue(eyePosTile);
    effect.Parameters["World"].SetValue(this.TileMatrix);
    effect.Parameters["View"].SetValue(viewMatrix);
    effect.Parameters["TexToView"].SetValue(texToViewMatrix);
    effect.Parameters["Projection"].SetValue(projectionMatrix);
    effect.Parameters["LightDir"].SetValue(lightDirection);

    foreach (var pass in effect.CurrentTechnique.Passes)
    {
        pass.Apply();
        this.RenderTile(device);
    }

enter image description here