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



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

5.1 Источники света


Метод Light в OpenGL регулирует параметры источников света

///

/// Устанавливает параметры источника света.

///

///

/// Номер источника света. Допустимы значения LIGHT0+i.

/// Максимальное значение i-1 определяется функцией Get с параметром MAX_LIGHTS.

///

///

/// Определяет параметр источника света. Допустимы значения:

/// AMBIENT - компонента окружения источника (по умолчанию (0, 0, 0, 1)),

/// DIFFUSE - компонента диффузного отражения источника

/// (по умолчанию для источника 0 (1, 1, 1, 1), для других (0, 0, 0, 1)),

/// SPECULAR - компонента зеркального отражения источника

/// (по умолчанию для источника 0 (1, 1, 1, 1), для других (0, 0, 0, 1)),

/// POSITION - положение источника света в объектных координатах

/// (по умолчанию (0, 0, 1, 0)),

/// SPOT_DIRECTION - направление луча источника (по умолчанию (0,0,-1)),

/// SPOT_EXPONENT – степень рассеяния луча света (по умолчанию 0),

/// SPOT_CUTOFF - угол раствора луча в градусах (по умолчанию 180),

/// CONSTANT_ATTENUATION - положительная константа затухания (по умолчанию 1),

/// LINEAR_ATTENUATION – положит. коэффициент линейного затухания (по умолчанию 0),

/// QUADRATIC_ATTENUATION – положит. коэфф. квадратичного затухания (по умолчанию 0).

///

///

/// Массив параметров. Размерность массива зависит от смысла параметра name.

///

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

public static extern void Light(int light, int name, float[] parameter);

Символьная константа параметра light имеет вид

///

/// Параметр, нумерующий первый источник света.

/// Остальные источники нумеруются как LIGHT0+i.

///

public const int LIGHT0 = 0x4000;

Константа максимального числа источников света

///

/// Аргумент Get требует возврата значения 1 параметра - максимального

/// числа источников света.

///

public const int MAX_LIGHTS = 0x0D31;

Для активации источника света следует использовать метод Enable с параметром LIGHT0+i. Текущее состояние активации источника света определяется методом IsEnable или Get с тем же параметром.

Константы параметра name метода Light, относящиеся к цветам, указаны в предыдущих разделах. Оставшиеся константы имеют вид

public const int POSITION = 0x1203;

public const int SPOT_DIRECTION = 0x1204;

public const int SPOT_EXPONENT = 0x1205;

public const int SPOT_CUTOFF = 0x1206;

public const int CONSTANT_ATTENUATION = 0x1207;

public const int LINEAR_ATTENUATION = 0x1208;

public const int QUADRATIC_ATTENUATION = 0x1209;

Для определения текущих значений параметров метода Light следует использовать метод

///

/// Возвращает текущие значения параметров метода Light

///

///

/// Номер источника света в форме LIGHT0+i

///

///

/// Название параметра из числа AMBIENT, DIFFUSE, SPECULAR, POSITION,

/// SPOT_DIRECTION, SPOT_EXPONENT, SPOT_CUTOFF, CONSTANT_ATTENUATION,

/// LINEAR_ATTENUATION, QUADRATIC_ATTENUATION.

///

///

/// Массив возвращаемого значения параметра. Размер массива зависит от типа параметра.

///

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

public static extern void GetLight(int light, int pname, float[] lparams);

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

///

/// Определяет вектор (nx, ny, nz) (не обязательно нормированный) направления

/// нормали в точке положения вершины.

///

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

public static extern void Normal(float nx, float ny, float nz);

Здесь дается редакция методов, создающих списки сферы, тора и усеченного конуса, описанных в классе listMaker библиотеки GL, с учетом нормализации вершин:


  • Сфера (метод Sphere):

    • При формировании северного полюса код принимает вид

gl.Normal(0, 1, 0);

gl.Vertex(0, 1, 0);

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

{

gl.Normal(sinteta[1] * sinfi[slice], costeta[1], sinteta[1] * cosfi[slice]);



gl.Vertex(sinteta[1] * sinfi[slice], costeta[1], sinteta[1] * cosfi[slice]);

}


    • При формировании средней части сферы код принимает вид

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

{

gl.Normal(sinteta[stack] * sinfi[slice], costeta[stack],



sinteta[stack] * cosfi[slice]);

gl.Vertex(sinteta[stack] * sinfi[slice], costeta[stack],

sinteta[stack] * cosfi[slice]);

gl.Normal(sinteta[stack + 1] * sinfi[slice], costeta[stack + 1],

sinteta[stack + 1] * cosfi[slice]);

gl.Vertex(sinteta[stack + 1] * sinfi[slice], costeta[stack + 1],

sinteta[stack + 1] * cosfi[slice]);

}


    • При формировании южного полюса

gl.Normal(0, -1, 0);

gl.Vertex(0, -1, 0);

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

{

gl.Normal(sinteta[stacks - 1] * sinfi[slice], costeta[stacks - 1],



sinteta[stacks - 1] * cosfi[slice]);

gl.Vertex(sinteta[stacks - 1] * sinfi[slice], costeta[stacks - 1],

sinteta[stacks - 1] * cosfi[slice]);

}


  • Тор (метод Torus):

for (int bigSlice = bigSlices; bigSlice >= 0; bigSlice--)

{

gl.Normal(cosBigFi[bigSlice] * cosSmallFi[smallSlice],



cosSmallFi[smallSlice] * sinBigFi[bigSlice], sinSmallFi[smallSlice]);

gl.Vertex(curRad * cosBigFi[bigSlice], curRad * sinBigFi[bigSlice],

smallRadius * sinSmallFi[smallSlice]);

gl.Normal(cosBigFi[bigSlice] * cosSmallFi[smallSlice + 1],

cosSmallFi[smallSlice + 1] * sinBigFi[bigSlice], sinSmallFi[smallSlice + 1]);

gl.Vertex(nextRad * cosBigFi[bigSlice], nextRad * sinBigFi[bigSlice],

smallRadius * sinSmallFi[smallSlice + 1]);

}


  • Усеченный конус (метод Frustum):

    • Добавляется локальная переменная

float zNorm = (float)Math.Cos(Math.Atan2(1, 1 - topRadius));

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

{

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



gl.Normal(x, y, zNorm);

gl.Vertex(x, y, z);

}


    • Цикл основной поверхности конуса принимает вид

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

{

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



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

gl.Normal(x, y, zNorm);

gl.Vertex(x, y, z);

gl.Normal(xNext, yNext, zNorm);

gl.Vertex(xNext, yNext, zNext);

}

Определение текущих значений параметров метода Normal осуществляется методом Get с параметром



///

/// Аргумент Get требует возврата значения трех параметров –

/// текущих значений аргументов метода Normal.

///

public const int CURRENT_NORMAL = 0x0B02;

Для эффективного применения метода Normal следует так же активировать режим нормализации методом Enable с параметром

///

/// Параметр активации нормализации.

/// Используется методами Get, Enable, IsEnabled и Disable.

///

public const int NORMALIZE = 0x0BA1;

Эта активация нормализует векторы нормали, если они не единичные.

Для сохранения флага NORMALIZE в стеке следует использовать метод PushAttrib с параметром ENABLE_BIT.

При включенных источниках света с учетом всех перечисленных выше параметров формула цвета каждой вершины представляет собой сумму



  • интенсивности цвета излучения материи,

  • произведения интенсивностей цветов отражения материей света среды и самого света среды и

  • вклада от каждого активного источника света.

Вклад источника света состоит из трех компонент – компоненты среды, диффузной компоненты и компоненты интенсивности зеркально отражаемого света.

  1. Компонента среды является произведением интенсивностей цвета отраженного материей света среды и света среды, создаваемого данным источником.

  2. Диффузная компонента является произведением интенсивностей цвета диффузного отражения материи, интенсивности цвета диффузной составляющей света источника и скалярного произведения нормали вершины с нормализованным вектором направления от вершины к источнику света.

  3. Компонента зеркально отражаемого света является произведением интенсивности цвета, зеркально отраженного материей света, интенсивности цвета зеркально отражаемой составляющей источника света и скалярного произведения нормали вершины на нормализованный сумму векторов, направленных от вершины к наблюдателю и от вершины к источнику света, возведенного в степень яркости материи. Наблюдатель расположен по умолчанию в положительной бесконечности оси Z, а если параметр LIGHT_MODEL_LOCAL_VIEWER метода LightModel установлен равным единице, то наблюдатель находится в начале системы координат наблюдения.

Все три компоненты умножаются одинаково на множитель, уменьшающий интенсивность и состоящий из двух множителей:

  1. Первый множитель имеет вид 1/ (K0 + K1d + K2d2), где K0, K1 и K2 – соответственно, постоянный коэффициент затухания CONSTANT_ATTENUATION , линейный LINEAR_ATTENUATION и квадратичный QUADRATIC_ATTENUATION, d – расстояние от источника света до вершины. Он равен единице, если источник света находится на бесконечности (w = 0), как по умолчанию.

  2. Второй множитель зависит от направления луча света SPOT_DIRECTION, угла раствора пучка света SPOT_CUTOFF и степени рассеяния луча SPOT_EXPONENT. Он равен

    1. единице, если угол раствора SPOT_CUTOFF равен 1800, как по умолчанию,

    2. нулю, если скалярное произведение единичного вектора от источника света к вершине и единичного вектора направления луча SPOT_DIRECTION меньше косинуса угла раствора SPOT_CUTOFF,

    3. скалярному произведению единичных векторов от источника света к вершине и направления луча SPOT_DIRECTION, возведенному в степень рассеяния луча SPOT_EXPONENT в других случаях.

Все скалярные произведения, которые оказываются отрицательными, заменяются нулями.

Альфа-компонентой результирующего цвета является альфа-компонента диффузной составляющей материи.


Читатель, самостоятельно готовящий приложение, может использовать в нем приведенные методы Light и Normal для наблюдения эффекта от включения источников света и изменения параметров этих источников на примере какого-либо объекта.

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


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

  1. Оформите освещение для часов, которые готовились в предыдущих проектных заданиях.

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


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

  1. Опишите параметры источников света и их значения по умолчанию.

  2. Какой метод активирует источник света?

  3. Какой метод возвращает текущие значения параметров источника света?

  4. Что делает метод Normal?

  5. Какой параметр следует использовать в методе PushAttrib с тем, чтобы сохранить состояние освещенности в стеке?

  6. Опишите формулу цвета вершины при освещении.

  7. Какое значение имеет альфа-компонента вершины при освещении?




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




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

    Басты бет