Координаты вершин DirectX 11

Я работаю над своим первым проектом на C++ и DirectX 11, где моя текущая цель — нарисовать на экране цветной треугольник. Это работало хорошо без каких-либо проблем. Однако есть одна часть, которую я хотел бы изменить, но не знаю, как. Я пытался найти решение, но пока не нашел его, и я предполагаю, что причина в том, что я действительно не знаю, что мне искать.

В настоящее время я настроил свои треугольники на 3 вершины следующим образом:

VertexPos vertices[] =
{
    { XMFLOAT3(  0.5f,  0.5f, 1.0f )},
    { XMFLOAT3(  0.5f, -0.5f, 1.0f )},
    { XMFLOAT3( -0.5f, -0.5f, 1.0f )},
}

Где VertexPos определяется следующим образом:

struct VertexPos
{
    XMFLOAT3 pos;
};

В настоящее время моя позиция вершин устанавливается в диапазоне от -1.0F до 1.0F, где 0.0F — это центр. Как я могу изменить это, чтобы я мог позиционировать свои вершины, используя «реальные» координаты следующим образом:

VertexPos vertices[] =
{
    { XMFLOAT3(  100.0f,  300.0f, 1.0f )},
    { XMFLOAT3(  200.0f,  200.0f, 1.0f )},
    { XMFLOAT3(  200.0f,  300.0f, 1.0f )},
}

person fighting_falcon93    schedule 07.10.2013    source источник
comment
Вы должны настроить соответствующую матрицу проекции и умножить координаты на матрицу в вершинном шейдере. Если вы только начинаете, пройдите еще несколько руководств, и вы все узнаете.   -  person Nico Schertler    schedule 07.10.2013


Ответы (1)


  1. Обычный способ:

    • create orthogonal projection matrix (XMMatrixOrthographicLH() if you using XMMATH)
    • создать постоянный буфер с этой матрицей на стороне процессора (код C++) и на размере графического процессора (вершинный шейдер)
    • умножить позиции вершин на матрицу ортогональной проекции в вершинном шейдере
  2. Более простой способ (из книги F.Luna):

    XMFLOAT3 SpriteBatch::PointToNdc(int x, int y, float z)
    {
        XMFLOAT3 p;
    
        p.x = 2.0f*(float)x/mScreenWidth - 1.0f;
        p.y = 1.0f - 2.0f*(float)y/mScreenHeight;
        p.z = z;
    
        return p;
    }
    

    Почти то же самое, но на стороне процессора. Конечно, вы можете переместить этот код и в шейдер.

P.S. Возможно, ваша книга/руководство/туториалы узнают об этом чуть позже. Так что вам лучше довериться этому и действовать шаг за шагом.

Удачного кодирования! знак равно

person Ivan Aksamentov - Drop    schedule 07.10.2013
comment
Спасибо за ответ Дроп. Я понимаю. Причина, по которой я запутался, заключается в том, что несколько месяцев назад я делал туториал по DirectX 9, и тогда можно было сделать так: struct CUSTOMVERTEX { FLOAT x, y, z, rhw; DWORD color; } CUSTOMVERTEX OurVertices[] = { {320.0f, 50.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255),}, {520.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0),}, {120.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0),}, }; Итак, они удалили эту функцию из DirectX 11? Если да, то почему? РЕДАКТИРОВАТЬ: Хм, извините, но теги кода не работают:/ - person fighting_falcon93; 08.10.2013
comment
Да, фиксированный конвейер функций и предварительно преобразованные объявления вершин больше не существуют. Теперь вы должны написать свои собственные шейдерные программы и трансформировать в них вершины по своему усмотрению. Почему? Ну, я не знаю ответа. Наверное, потому что большинству разработчиков это было не нужно, а включение этого в новый API усложнило бы реализацию. - person Ivan Aksamentov - Drop; 08.10.2013
comment
Есть ли большой выигрыш в производительности от использования второго метода вместо первого? - person Mike Weir; 23.01.2014
comment
@PhoenixX_2 Стандартный ответ: зависит. По многим факторам. Чтобы быть уверенным, вам действительно нужно попробовать несколько подходов, профилировать и сравнить их. На первый взгляд кажется, что вы экономите на некоторых умножениях, используя функцию типа PointToNdc. Но, вероятно, классические векторно-матричные SIMD-оптимизированные умножения будут быстрее. Трудно сказать, правда. В любом случае, маловероятно, что здесь вы столкнетесь с узким местом в производительности, если только вы не рисуете много объектов с орфографической проекцией. - person Ivan Aksamentov - Drop; 23.01.2014