Введение в Direct3D8 | страница 7
Следующий код обеспечивает непосредственно отрисовку изображения трехмерной функции:
>hr = m_p3DDevice->SetStreamSource(0, m_pDataVB, sizeof(GRAPH3DVERTEXSTRUCT));
>if (FAILED(hr)) {
> return hr;
>}
>hr = m_p3DDevice->SetVertexShader(D3DFVF_GRAPH3DVERTEX);
>if (FAILED(hr)) {
> return hr;
>}
>hr = m_p3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, m_dwElementsInVB – 2);
>if (FAILED(hr)) {
> return hr;
>}
Переменная m_pDataVB является членом класса C3DGraphic, она содержит указатель на интерфейс IDirect3DVertexBuffer8. В нашем случае содержимое вертекс-буфера представляет из себя массив структур GRAPH3DVERTEXSTRUCT:
>typedef struct {
> FLOAT x, y, z;
> FLOAT nx, ny, nz;
>} GRAPH3DVERTEXSTRUCT;
Здесь x, y и z – координаты точки, nx, ny, nz – компоненты нормали. Вектор нормали используется подсистемой Direct3D, отвечающей за освещение сцены. Чуть позже мы рассмотрим, как можно рассчитать эти компоненты. Перед вызовом функции DrawPrimitive() мы должны указать vertex shader и используемый поток данных. Выбор и установка потока данных производится с помощью функции SetStreamSorce(). Мы передаем ей номер устанавливаемого потока (0, если оспользуется только один поток), указатель на вертекс-буфер, из которого будут браться данные, и размер каждого элемента в потоке (то есть, sizeof(GRAPH3DVERTEXSTRUCT). Vertex shaders – новая возможность Direct3D. Это эдакая абстракция, символизирующая обработку вершин (вертексов). Грубо говоря, vertex shader обеспечивает перевод точки из трехмерного пространства модели в двумерную картинную плоскость. Вы можете написать на особом языке скрипт, обеспечивающий этот перевод, а можете использовать один из поддерживаемых стандартных механизмов, что мы и сделаем. Наш vertex shader D3DFVF_GRAPH3DVERTEX определен как D3DFVF_XYZ | D3DFVF_NORMAL. Это означает, что каждая точка характеризуется 6-ю числами. Первые 3 из них трактуются как координаты вершины, остальные – как компоненты нормали.
После установки необходимых потока данных и вертекс-шейдера мы можем вызвать метод DrawPrimitive(), который отображает данные из вертекс-буфера на плоскость back-буфера. Способ рендеринга данных выбирается первым параметром этого метода – он может быть одним из значений перечисляемого типа D3DPRIMITIVETYPE: D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_LINESTRIP, D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP или D3DPT_TRIANGLEFAN. Я решил, что наиболее подходящим способом для построения графика функции является использование D3DPT_TRIANGLESTRIP, поскольку этот способ требует относительно немного памяти для хранения данных о поверхности. Триангуляции области построения графика осуществляется как показано на следующем рисунке.