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


Класс команд OpenGL. Очистка буфера цвета



бет3/15
Дата29.05.2016
өлшемі1.07 Mb.
#100718
1   2   3   4   5   6   7   8   9   ...   15

Класс команд OpenGL. Очистка буфера цвета


В этом разделе

  • Создается класс команд OpenGL, методы которого будут служить оболочками процедур и функций библиотеки OpenGL.

  • Применяются команды очистки буфера цвета ClearColor и Clear.

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

Откройте библиотеку классов GL и опишите новый статический класс с именем gl, в который будут помещаться методы, отвечающие командам OpenGL. Поместите в класс gl члены, регулирующие цвет заполнения буфера цвета. Эти члены будут объединены областью, названной "Очистка буферов". Описание класса gl примет вид

public static class gl

{

#region Очистка буферов



///

/// Определяет значения цветов в буферах цвета.

/// По умолчанию все 4 составляющих цвета равны нулю

///

///

/// количество красного от 0 до 1

///

///

/// количество зеленого от 0 до 1

///

///

/// количество синего от 0 до 1

///

///

/// количество альфа-компоненты от 0 до 1, участвующей в определении эффекта прозрачности

///

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

public static extern void ClearColor(float red, float green, float blue, float alpha);

///

/// Идентифицирует буфер цвета в методах Clear и PushAttrib.

///

public const int COLOR_BUFFER_BIT = 0x00004000;

///

/// Очищает буферы внутри порта вывода изображения

///

///

/// Выражение, идентифицирующее буферы, которые должны быть очищены.

/// Четыре маски COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT,

/// ACCUM_BUFFER_BIT и STENCIL_BUFFER_BIT могут быть связаны оператором | (или)

///

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

public static extern void Clear(int mask);

#endregion

}

Везде в дальнейшем методы и постоянные, относящиеся к командам OpenGL, будут размещаться в этом классе



В классе формы f3D опишите постоянную цвета, которым будет очищаться буфер цвета

#region Constants

///

/// Хранит цвет фона - цвет очистки буфера цвета (темно-синий)

///

static Color clearColor = Color.FromArgb(0, 0, 51);

#endregion

Опишите так же два новых метода InitGL и BuildFrame. Метод InitGL поместите в раздел "Ctr" следом за описанием конструктора и в него поместите вызов метода, который устанавливает цвет очистки сцены, ее фон

///

/// Инициализирует некоторые атрибуты OpenGL.

///

void InitGL()

{

// Цвет фона темно синий



gl.ClearColor((float)clearColor.R / 255, (float)clearColor.G / 255,

(float)clearColor.B / 255, (float)clearColor.A / 255);

}

Метод BuildFrame будет воспроизводить команды OpenGL, формирующие изображение. Добавьте описание метода BuildFrame к разделу "Методы воспроизведения". Поместите в него команду очистки буфера цвета



///

/// Устанавливает воспроизводимую сцену с помощью команд OpenGL

///

void BuildFrame()

{

// Очистка буферов



gl.Clear(gl.COLOR_BUFFER_BIT);

}

В тело конструктора формы f3D после создания объекта класса glPort добавьте оператор вызова метода InitGL так, что тело конструктора примет вид



public f3D()

{

InitializeComponent();



// Операторы, делающие форму квадратной со стороной side,

// равной минимальной стороне дисплея.

// Класс Screen представляет дисплей или несколько дисплеев.

// Статическое свойство PrimaryScreen класса Screen возвращает главный дисплей

// Свойство Bounds возвращает прямоугольник границ дисплея

int side = Math.Min(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);

Size = new Size(side, side);

port = new glPort(panelGL);

InitGL();

}

В тело метода RenderFrame() перед командой обмена буферов SwapBuffers добавьте вызов метода BuildFrame() так, что тело метод RenderFrame() примет вид



void RenderFrame()

{

BuildFrame();



if (!port.SwapBuffers())

throw new Exception("Не выполнен обмен буферов.");

}

Убедитесь, что после этой редакции панель стала темно синей. Пройдите пошагово код проекта, уяснив последовательность выполнения операторов.


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

  1. Для чего служит описанный класс gl?

  2. Какой метод определяет цвет фона изображения?

  3. Какой метод очищает буфер цвета, заполняя его заданным фоном?

  4. В какой последовательности следует использовать методы ClearColor, Clear, SwapBuffers?

Структура буферов. Методы Get


В этом разделе Вы узнаете

  • О структуре буферов, хранящих информацию о пикселях экрана

  • О том, как считывать информацию о состоянии OpenGL

Информация о каждом пикселе хранится в различных областях памяти – буферах цвета, глубины, трафарета, буфере-аккумуляторе. Каждый буфер имеет стандартную структуру. Он состоит из битовых плоскостей. В каждой битовой плоскости хранится часть информации обо всех пикселях, выводимых на экран. На битовой плоскости столько же ячеек, сколько пикселей на экране. В каждой ячейке битовой плоскости может храниться только единичка или ноль – один бит информации. Отсюда название плоскости. Сколько битовых плоскостей в конкретном буфере, столько битов информации о каждом пикселе содержит буфер. Так, если в буфере две битовые плоскости, то на каждый пиксель приходится два бита информации, т.е. может быть 4 типа пикселей, отличающихся числами-индексами 0, 1, 2, 3. В общем случае в буфере с n битовыми плоскостями каждый пиксель может иметь 2n индексов со значениями от 0 до 2n – 1. К примеру, если в буфере красного цвета (Red) 8 битовых плоскостей, то каждый пиксель может иметь 28 = 256 интенсивностей красного в своем цвете.

Метод Get. Получение информации о состоянии OpenGL


Ответы на любые вопросы о текущем состоянии настроек OpenGL можно получить, используя метод Get из библиотеки OpenGL.

Метод Get позволяет получить, в частности, информацию об объеме всех буферов, на которые рассчитан формат пикселя. Добавьте в класс gl библиотеки GL раздел "Методы Get и их аргументы" со следующим содержанием

#region Методы Get и их аргументы

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

// в буферах цвета RED,GREEN,BLUE,ALPHA

public const int RED_BITS = 0x0D52;

public const int GREEN_BITS = 0x0D53;

public const int BLUE_BITS = 0x0D54;

public const int ALPHA_BITS = 0x0D55;

// Аргумент метода Get, для определения числа битовых плоскостей в буфере глубины

public const int DEPTH_BITS = 0x0D56;

// Аргумент метода Get, для определения числа битовых плоскостей в буфере трафарета

public const int STENCIL_BITS = 0x0D57;

// Аргументы метода Get для определения числа битовых плоскостей в буфере-аккумуляторе

public const int ACCUM_RED_BITS = 0x0D58;

public const int ACCUM_GREEN_BITS = 0x0D59;

public const int ACCUM_BLUE_BITS = 0x0D5A;

public const int ACCUM_ALPHA_BITS = 0x0D5B;

///

/// Возвращает значения параметра с именем prmName в виде массива типа float.

///

[DllImport("OPENGL32.DLL")]

static extern void glGetFloatv(int prmName, float[] parameters);

///

/// Возвращает одно или несколько значений, отвечающих указанному типу параметра.

///

///

/// Символьная постоянная, обозначающая имя параметра,

/// значения которого следует возвратить.

///

///

/// Длина массива возвращаемых значений

///

///

/// Массив значений

///

public static float[] Get(int prmName, int arrayLength)

{

float[] resultArray = new float[arrayLength];



glGetFloatv(prmName, resultArray);

return resultArray;

}

#endregion



Добавьте в метод InitGL формы f3D оператор вывода в строку статуса информации о числе битовых плоскостей буферов цвета, глубины, трафарета и аккумулятора

// Сведения о буферах

stLabel.Text = stLabel.Text +

" Color: Red: " + gl.Get(gl.RED_BITS, 1)[0] +

" Green: " + gl.Get(gl.GREEN_BITS, 1)[0] +

" Blue: " + gl.Get(gl.BLUE_BITS, 1)[0] +

" Alpha: " + gl.Get(gl.ALPHA_BITS, 1)[0] +

" Depth: " + gl.Get(gl.DEPTH_BITS, 1)[0] +

" Stencil: " + gl.Get(gl.STENCIL_BITS, 1)[0] +

" Acc: Red: " + gl.Get(gl.ACCUM_RED_BITS, 1)[0] +

" Green: " + gl.Get(gl.ACCUM_GREEN_BITS, 1)[0] +

" Blue: " + gl.Get(gl.ACCUM_BLUE_BITS, 1)[0];

Посмотрите результат.

Метод GetString.


В библиотеке OpenGL есть метод GetString, позволяющий, в частности, получить сведения о версии библиотеки, установленной на компьютере, ее производителе и микросхеме, ответственной за визуализацию команд OpenGL (так называемый Renderer). Добавьте в раздел "Методы Get и их аргументы" класса gl библиотеки GL описание

///

/// Имя объекта-аргумента GetString для определения версии OpenGL.

///

public const int VERSION = 0x1F02;

///

/// Имя объекта-аргумента GetString для определения производителя OpenGL.

///

public const int VENDOR = 0x1F00;

///

/// Имя объекта-аргумента GetString для определения имени визуализатора OpenGL.

/// Возвращаемое имя специфично для конкретной аппаратной платформы компьютера.

///

public const int RENDERER = 0x1F01;

///

/// Возвращает указатель на объект с именем name.

///

[DllImport("OPENGL32.DLL")]

static extern IntPtr glGetString(int name);

///

/// Возвращает строку с объектом с именем name.

///

public static string GetString(int name)

{

IntPtr i = glGetString(name);



return Marshal.PtrToStringAnsi(i);

}

Добавьте к предыдущей редакции метода InitGL оператор вывода в строку статуса информации о версии, производителе и визуализаторе так, что метод InitGL примет вид



void InitGL()

{

// Цвет фона синий



gl.ClearColor((float)clearColor.R / 255, (float)clearColor.G / 255,

(float)clearColor.B / 255, (float)clearColor.A / 255);

// Вывод результатов работы методов Get и GetString

stLabel.Text +=

" Color: Red: " + gl.Get(gl.RED_BITS, 1)[0] +

" Green: " + gl.Get(gl.GREEN_BITS, 1)[0] +

" Blue: " + gl.Get(gl.BLUE_BITS, 1)[0] +

" Alpha: " + gl.Get(gl.ALPHA_BITS, 1)[0] +

" Depth: " + gl.Get(gl.DEPTH_BITS, 1)[0] +

" Stencil: " + gl.Get(gl.STENCIL_BITS, 1)[0] +

" Acc: Red: " + gl.Get(gl.ACCUM_RED_BITS, 1)[0] +

" Green: " + gl.Get(gl.ACCUM_GREEN_BITS, 1)[0] +

" Blue: " + gl.Get(gl.ACCUM_BLUE_BITS, 1)[0] +

"; Version: " + gl.GetString(gl.VERSION) +

"; Vendor: " + gl.GetString(gl.VENDOR) +

"; Renderer: " + gl.GetString(gl.RENDERER);

}

Две последние строки – имя производителя (Vendor) и тип схемы воспроизведения команд OpenGL (Renderer) являются решающими в определении особенностей работы команд библиотеки OpenGL, установленной на компьютере.


Методы GetError и gluErrorString


Метод GetError из библиотеки opengl32.dll и метод gluErrorString из библиотеки glu32.dll позволяют получить информацию об ошибке, допущенной при обращении к командам OpenGL или при выполнении этих команд.

Для использования этих методов добавьте в раздел "Методы Get и их аргументы" класса gl библиотеки GL описание кодов возможных ошибок в форме констант и описание методов, используемых для регистрации ошибок. Комментарии, дающиеся в описании, позволяют понять смысл этих новых членов класса gl.

///

/// Код отсутствии ошибки.

/// Используется как результат вызова GetError.

///

const int NO_ERROR = 0;

///

/// Код ошибки "Недопустимое значение перечислимого аргумента".

/// Используется как результат вызова GetError.

///

const int INVALID_ENUM = 0x0500;

///

/// Код ошибки "Численное значение аргумента выходит за границы допустимых значений".

/// Используется как результат вызова GetError.

///

const int INVALID_VALUE = 0x0501;

///

/// Код ошибки "Указанная операция недопустима в данном состоянии".

/// Используется как результат вызова GetError.

///

const int INVALID_OPERATION = 0x0502;

///

/// Код ошибки "Стек переполнен".

/// Используется как результат вызова GetError.

///

const int STACK_OVERFLOW = 0x0503;

///

/// Код ошибки "Недостаточно данных в стеке".

/// Используется как результат вызова GetError.

///

const int STACK_UNDERFLOW = 0x0504;

///

/// Код ошибки "Не хватает памяти для выполнения команды".

/// Используется как результат вызова GetError.

///

const int OUT_OF_MEMORY = 0x0505;

///

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

///

///

/// Целое число (код ошибки), указывающее на отсутствие или наличие ошибки

/// в выполненных командах OpenGL.

/// Может иметь одно из 7-ми значений из числа NO_ERROR, INVALID_ENUM, INVALID_VALUE,

/// INVALID_OPERATION, STACK_OVERFLOW, STACK_UNDERFLOW, OUT_OF_MEMORY.

///

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

static extern int GetError();

///

/// Используется для определения строки, описывающей ошибку в OpenGL.

///

///

/// Код ошибки.

///

///

/// Указатель на строку, описывающую ошибку.

///

[DllImport("GLU32.DLL")]

static extern IntPtr gluErrorString(int errCode);

///

/// Используется для определения строки, описывающей ошибку в OpenGL.

///

///

/// Код ошибки.

///

///

/// Строка, описывающая ошибку.

///

public static string getErrorString(int errCode)

{

return Marshal.PtrToStringAnsi(gluErrorString(errCode));



}

///

/// Порождает объект исключительной ситуации в случае возникновения ошибки

/// при выполнении команд OpenGL.

/// Сообщение объекта исключительной ситуации содержит описание ошибки.

///

public static void ErrorException()

{

int error = GetError();



if (NO_ERROR != error)

throw new Exception("OpenGL error: " + getErrorString(error));

}
Внутри метода RenderFrame() формы f3D (после вызова BuildFrame()) добавьте вызов

gl. ErrorException();

Этот вызов будет предохранять код метода BuildeFrame() от возможных ошибок.

Посмотрите результат работы приложения. Активируйте для сравнения авторское приложение.


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

  1. Что такое битовая плоскость буфера?

  2. Сколько различных чисел могут определять один и тот же пиксель в буфере, состоящем из 8 битовых плоскостей?

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

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

  5. Для чего служат методы GetError и gluErrorString?

Что дальше.

Как изобразить одну точку? Что такое примитивы?



Достарыңызбен бөлісу:
1   2   3   4   5   6   7   8   9   ...   15




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

    Басты бет