Неправильный набор вершин, используемых в XNA4 DrawUserIndexedPrimitives - PullRequest
1 голос
/ 19 октября 2011

Фон : я пишу рендерер ландшафта на основе тайлов, который использует визуализацию с помощью графического процессора для визуализации поля высоты. Раньше моим графическим кодированием был C ++ / OpenGL, однако я решил попробовать C # / XNA4 (то есть DirectX9) как часть опыта обучения.

Проблема : вызовы DrawUserIndexedPrimitives, по-видимому, используют массивы вершин, которые были указаны в предыдущих вызовах.

Подробнее 1010 *: Средство визуализации плиток работает путем растеризации задних граней ограничительной рамки плитки. Пиксельный шейдер выполняет лучевое вещание. Призыв нарисовать коробку такой:

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, из-за которой листы отображались с вершинами предыдущего фрагмента, но я не могу его найти.

Тот же набор данных (a float[]) используется для создания текстуры карты высот и ограничивающего прямоугольника, поэтому при создании ограничивающего прямоугольника это не является ошибкой.

1 Ответ

1 голос
/ 19 октября 2011

ОК, обнаружена проблема.Я устанавливал параметры эффекта на этапе рендеринга (так что да, основная ошибка)

Оригинальный код:

    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

...