Опубликован: 08.07.2007 | Доступ: свободный | Студентов: 1432 / 183 | Оценка: 4.43 / 4.02 | Длительность: 13:47:00
Специальности: Программист
Лекция 2:

Двумерная графика с использованием Direct3D

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >

Вообще говоря, функции вывода примитивов DrawPrimitiveUP и DrawIndexedPrimitiveUP являются довольно медленными с эффективной точки зрения, т.к. производят довольно много лишних операций. Для хранения вершин мы использовали обычные переменные (в нашем случае массивы), хотя для таких ситуаций предназначен специальный буфер вершин. Чтобы начать работы с этим буфером вершин необходимо проделать следующие шаги:

  1. Объявить переменную, в которой будет храниться адрес буфера вершин. Программно это будет выглядеть так.
    C++ LPDIRECT3DVERTEXBUFFER9 VBuffer = NULL;
    Pascal var VBuffer: IDirect3DVertexBuffer9;
  2. Воспользовавшись методом CreateVertexBuffer интерфейса IDirect3DDevice9 создать буфер вершин.
  3. Заполнить буфер данными о вершинах. Этот шаг реализуется в три приема. Вначале необходимо запереть буфер, т.к. заполнение его может производиться только в закрытом состоянии. Достигается это вызовом метода Lock интерфейса IDirect3DVertexBuffer9. Второй шаг состоит в непосредственном копировании данных с помощью стандартной функции Win32API – memcpy(). И третий шаг заключается в отпирании буфера вершин с помощью метода Unlock интерфейса IDirect3DVertexBuffer9. Таким образом, этот шаг можно реализовать следующим образом:
    C++
    LPDIRECT3DVERTEXBUFFER9     VBuffer     = NULL;
    VOID* pBuff;
    …
    device->CreateVertexBuffer(sizeof(points), 0, MY_FVF,
                     D3DPOOL_DEFAULT, &VBuffer, NULL );
    VBuffer->Lock( 0, sizeof(points), (void**)&pBuff, 0 );
    memcpy( pBuff, points, sizeof(points) );
    VBuffer-> Unlock();
    Pascal
    var VBuffer: IDirect3DVertexBuffer9;
          pBuff: Pointer;
    …
    device.CreateVertexBuffer(SizeOf(points), 0, MY_FVF,  
                      D3DPOOL_DEFAULT, VBuffer, nil);
    VBuffer.Lock(0, SizeOf(points), pBuff, 0);
    Move( points, pBuff^, SizeOf(points) );
    VBuffer.Unlock;

    Разберем значение параметров метода CreateVertexBuffer(). Первый параметр задает размер буфера вершин в байтах. Второй аргумент определяет параметры работы с буфером и, как правило, всегда это значение выставляется в ноль. Третий параметр задает формат вершин буфера через набор FVF флагов. Четвертый параметр определяет месторасположение буфера вершин. Значение D3DPOOL_DEFAULT говорит о том, что библиотека сама позаботится о размещении буфера в памяти. Пятый аргумент задает адрес переменной, в которую будет помещен результат вызова метода, т.е. эта переменная будет хранить адрес буфера вершин. И Шестой параметр не используется, является зарезервированным в настоящее время и всегда должен быть пустым.

    Рассмотрим теперь значения параметров метода Lock. Первый параметр определяет смещение от начала буфера, с которого будет производиться запирание области (значение 0 указывает на то, что запирается весь буфер с самого начала). Второй аргумент задает размер запираемой области в байтах. Третий параметр возвращает адрес запираемой области. И последний аргумент задает набор флагов способа запирания и, как правило, всегда равен нулю.

  4. И последний шаг – вывод примитивов на экран. Библиотека Direct3D позволяет выводить данные в несколько потоков. Созданный буфер вершин является примером одного такого потока. Вначале вывода сцены на экран необходимо связать наш буфер вершин с одним из потоков данных. Это реализуется с помощью вызова метода SetStreamSource интерфейса IDirect3DDevice9. Этот метод имеет четыре параметра. Первый из них определяет номер потока вывода. Если в программе используется только один буфер вершин, то этот параметр должен быть 0. Второй параметр содержит указатель на переменную, ассоциированную с буфером вершин. Третий – определяет смещение от начала буфера, с которого нужно производить считывание данных. Четвертый параметр задает размер одной вершины в байтах. Далее необходимо указать формат выводимых вершин. Это проделывается с помощью вызова метода SetFVF интерфейса IDirect3DDevice9. И затем производится непосредственный вывод примитивов с помощью функции DrawPrimitive интерфейса IDirect3DDevice9. Метод DrawPrimitive имеет три параметра: первый – тип выводимых примитивов, второй – индекс начальной выводимой вершины и третий определяет количество выводимых примитивов. Программно шаг вывода одного треугольника выглядит так:
    C++
    device->SetStreamSource( 0, VBuffer, 0, sizeof(MYVERTEX) );
    device->SetFVF( MY_FVF );
    device->DrawPrimitive( D3DPT_TRIANGLELIST , 0, 1 );
    Pascal
    device.SetStreamSource(0, VBuffer, 0, SizeOf(MyVertex));
    device.SetFVF(MY_FVF);
    device.DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

Библиотека Direct3D имеет богатый набор по способу отображения выводимых примитивов. Программист может указать нужный ему способ отображения полигонов с помощью задания режима воспроизведения. Существует три режима воспроизведения полигонов:

  1. режим вершинной модели определяет вывод только вершин полигонов без ребер и без закраски внутренних точек примитива и реализуется с помощью вызова метода SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT) интерфейса IDirect3DDevice9 ;
  2. режим каркасной модели задает вывод только ребер полигонов без закраски внутренних точек примитива и реализуется с помощью вызова метода SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME) интерфейса IDirect3DDevice9 ;
  3. режим сплошной модели определяет вывод полигонов с закрашенными внутренними точками и реализуется с помощью вызова метода SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID) интерфейса IDirect3DDevice9.

Кроме того, сплошная модель вывода подразделяется на два вида закрашивания: плоское заполнение либо закрашивание с интерполяцией. Первое реализуется через вызов метода SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT), второе через SetRenderState(D3DRS_SHADEMODE, D3DSHADE_ GOURAUD).

Данные режимы воспроизведения можно представить с помощью следующей схемы.


< Лекция 1 || Лекция 2: 123456 || Лекция 3 >