В этом разделе
-
Создается класс команд 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("Не выполнен обмен буферов.");
}
Убедитесь, что после этой редакции панель стала темно синей. Пройдите пошагово код проекта, уяснив последовательность выполнения операторов.
Тест рубежного контроля
-
Для чего служит описанный класс gl?
-
Какой метод определяет цвет фона изображения?
-
Какой метод очищает буфер цвета, заполняя его заданным фоном?
-
В какой последовательности следует использовать методы 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() от возможных ошибок.
Посмотрите результат работы приложения. Активируйте для сравнения авторское приложение.
Тест рубежного контроля
-
Что такое битовая плоскость буфера?
-
Сколько различных чисел могут определять один и тот же пиксель в буфере, состоящем из 8 битовых плоскостей?
-
Какой метод позволяет возвратить текущие значения параметров OpenGL.?
-
Что делает метод GetString?
-
Для чего служат методы GetError и gluErrorString?
Что дальше.
Как изобразить одну точку? Что такое примитивы?
Достарыңызбен бөлісу: |