Библиотека трехмерной графики Open gl



бет12/15
Дата29.05.2016
өлшемі1.07 Mb.
#100718
1   ...   7   8   9   10   11   12   13   14   15

Модуль 3. 4-угольники

Комплексной целью модуля является изучение следующих элементов OpenGL



  • Примитив "4-угольник".

  • Типы примитивов, состоящих из 4-угольников – отдельные 4-гольники, 4-угольники, имеющие общие стороны.

  • Атрибуты 4-угольников не отличаются от атрибутов треугольников. Однако, 4-угольники не обязательно являются плоскими фигурами.

  • Из 4-угольников можно формировать различные поверхности. Приводится пример усеченного конуса.



3.0 Примитив QUADS


Примитив QUADS позволяет изображать отдельные 4-угольники. Параметр метода Begin в этом случае имеет вид

///

/// Рассматривает каждую группу из четырех вершин, как независимый четырехугольник.

/// Вершины 4n - 3, 4n - 2, 4n - 1 и 4n определяют четырехугольник n.

/// Изображается N/4 четырехугольника, где N - полное число вершин.

///

public const int QUADS = 0x0007;

Рисунок, иллюстрирующий правило перечисление вершин при построении примитивов QUADS



Читатель, строящий собственное приложение, может добавить в него построение одного или нескольких 4-угольников, применив примитив QUADS. Посмотрите иллюстрацию к этому разделу в авторском приложении. Код этой части авторского приложения можно найти по ссылке.


Примечание.

Если 4-угольник является плоским прямоугольником, то можно воспользоваться методом Rect, имеющимся в библиотеке OpenGL

///

/// Изображает прямоугольник с двумя противоположными вершинами.

///

[DllImport("OPENGL32.DLL", EntryPoint = "glRectf")]

public static extern void Rect(float x1, float y1, float x2, float y2);

3.1 Примитив QUAD STRIP


Для изображения этого примитива параметром метода Begin должна быть константа

///

/// Изображает связанную группу четырехугольников.

/// Один четырехугольник определен для каждой пары вершин после первой пары.

/// Вершины 2n - 1, 2n, 2n+2 и 2n+1 определяют четырехугольник n.

/// Изображается N четырехугольника, где N - полное число вершин.

/// Заметьте, что порядок используемых вершин для построения четырехугольника в данном примитиве

/// отличается от того, что используется при построении независимых четырехугольников.

///

public const int QUAD_STRIP = 0x0008;

Рисунок, иллюстрирующий порядок перечисления вершин при построении примитива QUAD_STRIP

Обратите внимание на порядок перечисления вершин при отображении примитива QUAD_STRIP.

Читатель, строящий собственное приложение, может добавить в него построение 2-ух или нескольких 4-угольников, применив примитив QUAD_STRIP. Посмотрите иллюстрацию к этому разделу в авторском приложении. Код этой части авторского приложения можно найти по ссылке.
Проектные задания


  1. Постройте, применяя QUAD_STRIP, алгоритм изображения кругового цилиндра единичной высоты и радиуса с осью вдоль оси z и основанием на плоскости xy.

  2. Добавьте метод createCylinderList, создающий дисплейный список цилиндра cylinderList с произвольным числом поперечных (stacks) и продольных (slices) фрагментов.

  3. Сделайте стрелки на часах цилиндрическими, используя дисплейный список цилиндра.



3.2 Дисплейный список усеченного конуса


Для иллюстрации применения рассмотренных примитивов посмотрите дисплейный список команд, изображающих усеченный конус (Frustum). Можно добавить в класс listMaker метод создания этого списка

///

/// В режиме COMPILE создает команды дисплейного списка, если список не создан;

/// в режиме COMPILE_AND_EXECUTE создает и, если список создан,

/// вызывает команды дисплейного списка

/// кругового усеченного конуса с единичным базовым радиусом, единичной высотой,

/// с основанием на плоскости xy и осью вдоль оси z.

///

///

/// Режим создания списка COMPILE или COMPILE_AND_EXECUTE

///

///

/// Число продольных, вертикальных сегментов конуса, нарезанных вдоль оси.

///

///

/// Число поперечных, горизонтальных сегментов конуса, нарезанных поперек оси.

///

///

/// Значение радиуса верхней грани конуса по отношению

/// к базовому радиусу (в интервале [0;1]).

///

///

/// Альфа-компонента цвета

///

///

/// Номер созданного списка.

///

public static void Frustum(int mode, int slices, int stacks, float topRadius, float alpha, ref uint frustumList)

{

if (topRadius < 0 || topRadius > 1)



throw new Exception("Параметр topRadius должен лежать в интервале [0;1].");

// Если список создан, то он вызывается

if (frustumList != 0)

{

gl.CallList(frustumList);



return;

}

// Рабочие переменные



float curRadius, radiusNext, curColor, x, y, z, xNext, yNext, zNext;

// Тригонометрические функции углов (рабочие переменные)

float[] sinfi = new float[slices + 1], cosfi = new float[slices + 1];

// Инициализация тригонометрических функций

for (int slice = 0; slice <= slices; slice++)

{

sinfi[slice] = (float)Math.Sin(2.0 * Math.PI * slice / slices);



cosfi[slice] = (float)Math.Cos(2.0 * Math.PI * slice / slices);

}

// Генерируется свободный номер для списка усеченного конуса



frustumList = gl.GenLists(1);

// Создается и выполняется дисплейный список

gl.NewList(frustumList, mode);

gl.PushAttrib(gl.CURRENT_BIT);

for (int stack = 0; stack < stacks; stack++)

{

curRadius = 1.0f - stack * (1.0f - topRadius) / stacks;



radiusNext = 1.0f - (stack + 1) * (1.0f - topRadius) / stacks;

z = 1.0f * stack / stacks;

zNext = 1.0f * (stack + 1) / stacks;

if (stack < stacks / 2)

gl.Color(curColor = 1.0f - 2.0f * stack / stacks, 1.0f - curColor, 0, alpha);

else


gl.Color(0, curColor = 1.0f - 2.0f * (stack - stacks / 2) / stacks, 1.0f - curColor, alpha);

// В случае полного конуса (topRadius=0) последний слой

// создается примитивами TRIANGLE_FUN

if (topRadius == 0 && stack == stacks - 1)

{

gl.Begin(gl.TRIANGLE_FAN);



gl.Vertex(0, 0, 1);

for (int slice = slices; slice >= 0; slice--)

{

x = curRadius * cosfi[slice]; y = curRadius * sinfi[slice];



gl.Vertex(x, y, z);

}

gl.End();



}

else


{

gl.Begin(gl.QUAD_STRIP);

for (int slice = slices; slice >= 0; slice--)

{

x = curRadius * cosfi[slice]; y = curRadius * sinfi[slice];



xNext = radiusNext * cosfi[slice]; yNext = radiusNext * sinfi[slice];

gl.Vertex(x, y, z);

gl.Vertex(xNext, yNext, zNext);

}

gl.End();



}

}

gl.PopAttrib();



gl.EndList();

}

Читатель, строящий собственное приложение, может добавить в него построение усеченного конуса и фигур, перечисленных ниже в проектных заданиях. Посмотрите иллюстрацию к этому разделу в авторском приложении. Код этой части авторского приложения можно найти по ссылке.


Тест рубежного контроля

  1. Опишите соответствие вершин и фигур в примитиве QUADS.

  2. Опишите соответствие вершин и фигур в примитиве QUAD_STRIP.


Проектные задания

  1. Постройте по аналогии с уже рассмотренными методами в классе listMaker библиотеки GL метод

public static void Disk(int mode, int slices, int stacks,

float intRadius, float alpha, ref uint diskList),

создающий список диска diskList с внешним единичным радиусом, лежащим в плоскости xy, с произвольным внутренним радиусом intRadius в интервале [0;1], произвольными числами фрагментов slices и stacks (см., в частности, код конуса) и альфа-компонентой цвета alpha. Проверьте работу метода.


  1. Используя дисплейный списки цилиндра и полного конуса, постройте в классе listMaker библиотеки GL метод

public static void CylinderAxe(float radius,

float pointLength, float pointAngle, char label, uint bmpGlyphsBaseList, ref uint axeList).

Этот метод должен создавать дисплейный список стрелки axeList единичной длины, состоящей из стержня-цилиндра радиуса radius, острия с относительной длиной pointLength, половиной угла раствора pointAngle и метки label – символом из списка битовых карт с базовым номером bmpGlyphsBaseList. Если символ не является буквой или цифрой, он не должен изображаться.


  1. Замените стрелки в часах подобными стрелками, но без символов.

  2. Используя дисплейный список оси CylinderAxe, постройте в классе listMaker библиотеки GL метод изображения осей объектной системы координат с помощью стрелок с названиями осей X, Y, Z.

public static void CylinderAxes(uint bmpGlyphsBaseList, ref uint axesList)

Этот метод должен создавать список осей координат axesList, используя списки символов битовых карт с базовым номером bmpGlyphsBaseList.





Достарыңызбен бөлісу:
1   ...   7   8   9   10   11   12   13   14   15




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет