Подготовка текстуры
Для использования текстуры необходимо сначала загрузить в память нужное изображение и передать его OpenGL. Считывание графических данных из файла и их преобразование можно проводить вручную. Можно также воспользоваться функцией, входящей в состав библиотеки GLAUX (для ее использования надо дополнительно подключить glaux.lib), которая сама проводит необходимые операции. Это функция AUX_RGBImageRec* auxDIBImageLoad (const char *file), где file – название файла с расширением *.bmp или *.dib. Функция возвращает указатель на область памяти, где хранятся преобразованные данные. При создании образа текстуры в памяти следует учитывать следующие требования:
Во-первых, размеры текстуры, как по горизонтали, так и по вертикали должны представлять собой степени двойки. Это требование накладывается для компактного размещения текстуры в текстурной памяти и способствует ее эффективному использованию. Работать только с такими текстурами конечно неудобно, поэтому после загрузки их надо преобразовать. Изменение размеров текстуры можно провести с помощью команды
void gluScaleImage (GLenum format, GLint widthin, GL heightin, GLenum typein,
const void *datain, GLint widthout, GLint heightout, GLenum typeout, void *dataout) В качестве значения параметра format обычно используется значение GL_RGB или GL_RGBA, определяющее формат хранения информации. Параметры widthin, heightin, widhtout, heightout определяют размеры входного и выходного изображений, а с помощью typein и typeout задается тип элементов массивов, расположенных по адресам datain и dataout. Как и обычно, это может быть тип GL_UNSIGNED_BYTE, GL_SHORT, GL_INT и так далее. Результат своей работы функция заносит в область памяти, на которую указывает параметр dataout.
Во-вторых, надо предусмотреть случай, когда объект после растеризации оказывается по размерам значительно меньше наносимой на него текстуры. Чем меньше объект, тем меньше должна быть наносимая на него текстура и поэтому вводится понятие уровней детализации текстуры. (mipmap) Каждый уровень детализации задает некоторое изображение, которое является, как правило, уменьшенной в два раза копией оригинала. Такой подход позволяет улучшить качество нанесения текстуры на объект. Например, для изображения размером 2mx2n можно построить max(m,n)+1 уменьшенных изображений, соответствующих различным уровням детализации. Эти два этапа создания образа текстуры во внутренней памяти OpenGL можно провести с помощью команды
void gluBuild2DMipmaps (GLenum target, GLint components, Glint width,Glint height,GLenum format,GLenum type,const void *data)
где параметр target должен быть равен GL_TEXTURE_2D. Параметр components определяет количество цветовых компонент текстуры и может принимать следующие основные значения:
GL_LUMINANCE одна компонента – яркость. (текстура будет монохромной)
GL_RGB красный, синий, зеленый
GL_RGBA все компоненты
Параметры width, height, data определяют размеры и расположение текстуры соответственно, а format и type имеют аналогичный смысл, что и в команде gluScaleImage().После выполнения этой команды текстура копируется во внутреннюю память OpenGL, и поэтому память, занимаемую исходным изображением, можно освободить. В OpenGL допускается использование одномерных текстур, то есть размера 1xN, однако, это всегда надо указывать, задавая в качестве значения target константу GL_TEXTURE_1D. Полезность одномерных текстур сомнительна, поэтому не будем останавливаться на этом подробно.При использовании в сцене нескольких текстур, в OpenGL применяется подход, напоминающий создание списков изображений (так называемые текстурные объекты). Сначала с помощью команды
void glGenTextures (GLsizei n, GLuint* textures)
надо создать n идентификаторов текстур, которые будут записаны в массив textures. Перед началом определения свойств очередной текстуры следует сделать ее текущей («привязать» текстуру), вызвав команду
void glBindTexture (GLenum target, GLuint texture)
где target может принимать значения GL_TEXTURE_1D или GL_TEXTURE_2D, а параметр texture должен быть равен идентификатору той текстуры, к которой будут относиться последующие команды. Для того, чтобы в процессе рисования сделать текущей текстуру с некоторым идентификатором, достаточно опять вызвать команду glBindTexture() c соответствующим значением target и texture. Таким образом, команда glBindTexture() включает режим создания текстуры с идентификатором texture, если такая текстура еще не создана, либо режим ее использования, то есть делает эту текстуру текущей.
20.Наложение текстуры на объект.
При наложении текстуры, надо учитывать случай, когда размеры текстуры отличаются от оконных размеров объекта, на который она накладывается. При этом возможно как растяжение, так и сжатие изображения, и то, как будут проводиться эти преобразования, может серьезно повлиять на качество построенного изображения. Для определения положения точки на текстуре используется параметрическая система координат (s,t), причем значения s и t находятся в отрезке [0,1] (см. рисунок)
Рис. 8 Текстурные координаты
Для изменения различных параметров текстуры применяются команды:
void glTexParameter[i f] (GLenum target, GLenum pname, GLenum param)
void glTexParameter[if]v (GLenum target,GLenum pname, Glenum* params)
При этом target может принимать значения GL_TEXTURE_1D или GL_TEXTURE_2D, pname определяет, какое свойство будем менять, а с помощью param или params устанавливается новое значение. Возможные значения pname:
GL_TEXTURE_MIN_FILTER параметр param определяет функцию, которая будет использоваться для сжатия текстуры. При значении GL_NEAREST будет использоваться один (ближайший), а при значении GL_LINEAR четыре ближайших элемента текстуры. Значение по умолчанию: GL_LINEAR
GL_TEXTURE_MAG_FILTER параметр param определяет функцию, которая будет использоваться для увеличения (растяжения) текстуры. При значении GL_NEAREST будет использоваться один (ближайший), а при значении GL_LINEAR четыре ближайших элемента текстуры. Значение по умолчанию:GL_LINEAR
GL_TEXTURE_WRAP_S параметр param устанавливает значение координаты s, если оно не входит в отрезок [0,1]. При значении GL_ REPEAT целая часть s отбрасывается, и в результате изображение размножается по поверхности. При значении GL_CLAMP используются краевые значения: 0 или 1, что удобно использовать, если на объект накладывается один образ. Значение по умолчанию: GL_REPEAT.
GL_TEXTURE_WRAP_T аналогично предыдущему значению, только для координаты t
Использование режима GL_NEAREST повышает скорость наложения текстуры, однако при этом снижается качество, так как в отличие от GL_LINEAR интерполяция не производится. Для того чтобы определить, как текстура будет взаимодействовать с материалом, из которого сделан объект, используются команды
void glTexEnv[i f] (GLenum target, GLenum pname, GLtype param)
void glTexEnv[i f]v (GLenum target, GLenum pname, GLtype *params)
Параметр target должен быть равен GL_TEXTURE_ENV, а в качестве pname рассмотрим только одно значение GL_TEXTURE_ENV_MODE, которое наиболее часто применяется. Наиболее часто используемые значения параметра param:
GL_MODULATE конечный цвет находится как произведение цвета точки на поверхности и цвета соответствующей ей точки на текстуре.
GL_REPLACE в качестве конечного цвета используется цвет точки на текстуре.
21. Текстурные координаты.
Перед нанесением текстуры на объект необходимо установить соответствие между точками на поверхности объекта и на самой текстуре. Задавать это соответствие можно двумя методами: отдельно для каждой вершины или сразу для всех вершин, задав параметры специальной функции отображения. Первый метод реализуется с помощью команд
void glTexCoord[1 2 3 4][s i f d] (type coord)
void glTexCoord[1 2 3 4][s i f d]v (type *coord)
Чаще всего используется команды вида glTexCoord2*(type s, type t), задающие текущие координаты текстуры. Понятие текущих координат текстуры аналогично понятиям текущего цвета и текущей нормали, и является атрибутом вершины. Однако даже для куба нахождение соответствующих координат текстуры является довольно трудоемким занятием, поэтому в библиотеке GLU помимо команд, проводящих построение таких примитивов, как сфера, цилиндр и диск, предусмотрено также наложение на них текстур. Для этого достаточно вызвать команду
void gluQuadricTexture (GLUquadricObj* quadObject, GLboolean textureCoords)
с параметром textureCoords равным GL_TRUE, и тогда текущая текстура будет автоматически накладываться на примитив.
Второй метод реализуется с помощью команд
void glTexGen[i f d] (GLenum coord, GLenum pname, GLtype param)
void glTexGen[i f d]v (GLenum coord, GLenum pname, const GLtype *params)
Параметр coord определяет, для какой координаты задается формула, и может принимать значение GL_S,GL_T; pname может быть равен одному из следующих значений:
GL_TEXTURE_GEN_MODE определяет функцию для наложения текстуры.
В этом случае аргумент param принимает значения:
GL_OBJECT_LINEAR значение соответствующей текстурной координаты определяется расстоянием до плоскости, задаваемой с помощью значения pname GL_OBJECT_PLANE (см. ниже). Формула выглядит следующим образом: g=x*xp+y*yp+z*zp+w*wp, где g-соответствующая текстурная координата ( s или p), x, y, z, w – координаты соответствующей точки. xp, yp, zp, wp – коэффициенты уравнения плоскости. В формуле используются координаты объекта.
GL_EYE_LINEAR аналогично предыдущему значению, только в формуле используются видовые координаты. Т.е. координаты текстуры объекта в этом случае зависят от положения этого объекта.
GL_SPHERE_MAP позволяет эмулировать отражение от поверхности объекта. Текстура как бы "оборачивается" вокруг объекта. Для данного метода используются видовые координаты и необходимо задание нормалей.
GL_OBJECT_PLANE позволяет задать плоскость, расстояние до которой будет использоваться при генерации координат, если установлен режим GL_OBJECT_LINEAR. В этом случае параметр params является указателем на массив из четырех коэффициентов уравнения плоскости.
GL_EYE_PLANE аналогично предыдущему значению. Позволяет задать плоскость для режима GL_EYE_LINEAR. Для установки автоматического режима задания текстурных координат необходимо вызвать команду glEnable с параметром GL_TEXTURE_GEN_S или GL_TEXTURE_GEN_P.
22.Смешивание изображений (blending). Прозрачность.
Прозрачность реализуется с помощью специального режима смешения цветов (blending). Алгоритм смешения комбинирует цвета так называемых входящих пикселей (т.е. «кандидатов» на помещение в буфер кадра) с цветами соответствующих пикселей, уже хранящихся в буфере. Для смешения используется четвертая компонента цвета – альфа-компонента, поэтому этот режим называют еще альфа-смешиванием. Программа может управлять интенсивностью альфа-компоненты точно так же, как и интенсивностью основных цветов, т.е. задавать значение интенсивности для каждого пикселя или каждой вершины примитива.
Режим включается с помощью команды glEnable(GL_BLEND).
Определить параметры смешения можно с помощью команды:
void glBlendFunc(enum src,enum dst)
Параметр src определяет, как получить коэффициент k1 исходного цвета пикселя, a dst задает способ получения коэффициента k2 для цвета в буфере кадра. Для получения результирующего цвета используется следующая формула: res=сsrc*k1+cdst*k2, где сsrc – цвет исходного пикселя, cdst – цвет пикселя в буфере кадра (res, k1, k1, сsrc, cdst – четырехкомпонентные RGBA-векторы).
Приведем наиболее часто используемые значения агрументов src и dst.
GL_SRC_ALPHA k=(As,As,As,As)
GL_SRC_ONE_MINUS_ALPHA k=(1,1,1,1)-(As,As,As,As)
GL_DST_COLOR k=(Rd,Gd,Bd)
GL_ONE_MINUS_DST_COLOR k=(1,1,1,1)- (Rd,Gd,Bd,Аd)
GL_DST_ALPHA k=(Ad,Ad,Ad,Ad)
GL_DST_ONE_MINUS_ALPHA k=(1,1,1,1)-(Ad,Ad,Ad,Ad)
GL_SRC_COLOR k=(Rs,Gs,Bs)
GL_ONE_MINUS_SRC_COLOR k=(1,1,1,1)- (Rs,Gs,Bs,As)
Если в сцене есть несколько прозрачных объектов, которые могут перекрывать друг друга, корректный вывод можно гарантировать только в случае выполнения следующих условий:
Все прозрачные объекты выводятся после непрозрачных.
При выводе объекты с прозрачностью должны быть упорядочены по уменьшению глубины, т.е. выводиться, начиная с наиболее отдаленных от наблюдателя.
23.Буфер-накопитель.
Буфер-накопитель (accumulation buffer) – это один из дополнительных буферов OpenGL. В нем можно сохранять визуализированное изображение, применяя при этом попиксельно специальные операции. Буфер-накопитель широко используется для создания различных спецэффектов.Изображение берется из буфера, выбранного на чтение командой void glReadBuffer(enum buf). Аргумент buf определяет буфер для чтения. Значения buf, равные GL_BACK, GL_FRONT, определяют соответствующие буферы цвета для чтения. GL_BACK задает в качестве источника пикселей внеэкранный буфер; GL_FRONT – текущее содержимое окна вывода. Команда имеет значение, если используется дублирующая буферизация. В противном случае используется только один буфер, соответствующий окну вывода (строго говоря, OpenGL имеет набор дополнительных буферов, используемых, в частности, для работы со стереоизображениями, но здесь мы их рассматривать не будем). Буфер-накопитель является дополнительным буфером цвета. Он не используется непосредственно для вывода образов, но они добавляются в него после вывода в один из буферов цвета. Применяя различные операции, описанные ниже, можно понемногу «накапливать» изображение в буфере. Затем полученное изображение переносится из буфера-накопителя в один из буферов цвета, выбранный на запись командой void glDrawBuffer(enum buf). Значение buf аналогично значению соответствующего аргумента в команде glReadBuffer. Все операции с буфером-накопителем контролируются командой
void glAccum(enum op,GLfloat value). Аргумент op задает операцию над пикселями и может принимать следующие значения:
GL_LOAD Пиксель выбирается из буфера, выбранного на чтение, его значение умножается на value и заносится в буфер накопления.
GL_ACCUM Аналогично предыдущему, но полученное после умножения значение складывается с уже имеющимся в буфере.
GL_MULT Эта операция умножает значение каждого пикселя в буфере накопления на value .
GL_ADD Аналогично предыдущему, только вместо умножения используется сложение.
GL_RETURN Изображение переносится из буфера накопления в буфер, выбранный для записи. Перед этим значение каждого пикселя умножается на value.
Следует отметить, что для использования буфера-накопителя нет необходимости вызывать какие-либо команды glEnable. Достаточно инициализировать только сам буфер.
24.Буфер трафарета(маски).
При выводе пикселей в буфер кадра иногда возникает необходимость выводить не все пиксели, а только некоторое подмножество, т.е. наложить трафарет (маску) на изображение. Для этого OpenGL предоставляет так называемый буфер маски (stencil buffer). Кроме наложения маски, этот буфер предоставляет еще несколько интересных возможностей. Прежде чем поместить пиксель в буфер кадра, механизм визуализации OpenGL позволяет выполнить сравнение (тест) между заданным значением и значением в буфере маски. Если тест проходит, пиксель рисуется в буфере кадра. Механизм сравнения весьма гибок и контролируется следующими командами:
void glStencilFunc (enum func, int ref, uint mask)
void glStencilOp (enum sfail, enum dpfail, enum dppass)
Аргумент ref команды glStencilFunc задает значение для сравнения. Он должен принимать значение от 0 до 2s –1. s – число бит на точку в буфере маски.
С помощью аргумента func задается функция сравнения. Он может принимать следующие значения:
GL_NEVER тест никогда не проходит, т.е всегда возвращает false
GL_ALWAYS тест проходит всегда.
GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATE, GL_NOTEQUAL тест проходит в случае, если ref соответственно меньше значения в трафаретном буфере, меньше либо равен, равен, больше, больше либо равен или не равен.
Аргумент mask задает маску для значений. Т.е. в итоге для трафаретного теста получаем следующую формулу: ((ref AND mask) op (svalue AND mask))
Команда StencilOp предназначена для определения действий над пикселем трафаретного буфера в случае положительного или отрицательного результата теста. Аргумент sfail задает действие в случае отрицательного результата теста, и может принимать следующие значения: GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT соответственно сохраняет значение в трафаретном буфере, обнуляет его, заменяет на заданное значение (ref), увеличивает, уменьшает или побитово инвертирует. Аргументы dpfail определяют действия в случае отрицательного результата теста на глубину в z-буфере, а dppass задает действие в случае положительного результата этого теста. Аргументы принимают те же значения, что и аргумент sfail. По умолчанию все три параметра установлены на GL_KEEP. Для включения маскирования необходимо выполнить команду glEnable(GL_STENCIL_TEST). Буфер маски используется при создании таких спецэффектов, как падающие тени, отражения, плавные переходы из одной картинки в другую и пр.
25.Управление растеризацией [glhint].
Способ выполнения растеризации примитивов можно частично регулировать командой glHint (target, mode), где target – вид контролируемых действий, принимает одно из следующих значений
GL_FOG_HINT точность вычислений при наложении тумана. Вычисления могут выполняться по пикселям (наибольшая точность) или только в вершинах. Если реализация OpenGL не поддерживает попиксельного вычисления, то выполняется только вычисление по вершинам
GL_LINE_SMOOTH_HINT управление качеством прямых. При значении mode, равным GL_NICEST, уменьшается ступенчатость прямых за счет большего числа пикселей в прямых
GL_PERSPECTIVE_CORRECTION_HINT точность интерполяции координат при вычислении цветов и наложении текстуры. Если реализация OpenGL не поддерживает режим GL_NICEST, то осуществляется линейная интерполяция координат
GL_POINT_SMOOTH_HINT управление качеством точек. При значении параметра mode равным GL_NICEST точки рисуются как окружности
GL_POLYGON_SMOOTH_HINT управление качеством вывода сторон многоугольника параметра mode интерпретируется следующим образом:
GL_FASTEST используется наиболее быстрый алгоритм
GL_NICEST используется алгоритм, обеспечивающий лучшее качество
GL_DONT_CARE выбор алгоритма зависит от реализации
Важно заметить, что командой glHint() программист может только определить свои пожелания относительно того или иного аспекта растеризации примитивов. Конкретная реализация OpenGL вправе игнорировать данные установки.
Обратите внимание, что glHint() нельзя вызывать между операторными скобками glBegin()/glEnd().
Растровые Графические системы:
26. Дисплеи на ЭЛТ. Растровый дисплей. (км)
ЭЛТ.
В цветном кинескопе обычно используется 3 ЭЛТ, каждая из которых отвечает за вывод одного из 3-х основных цветов (красный, синий, зеленый). Внутренняя поверхность экрана покрыта точками люминофора, сгруппированными в треугольники. Каждая группа из 3-х точек, называемая триадой, содержит по одной точке с люминофором, испускающим при возбуждении соответственно красный, синий и зеленый свет. Триады так малы, что при наблюдении с достаточно большого расстояния свечение их точек воспринимается наблюдателем не как отдельные красные, синие и зеленые точки, а как свечение, полученное при смешивании этих трех цветов. Изменяя степень возбуждения каждой точки, можно в каждой триаде получить широкий спектр цветов.
Непосредственно перед экраном находится маска, в которой каждой триаде соответствует одно маленькое отверстие. Эти отверстия располагаются таким образом, что каждая точка триады доступна электронам только одного луча.
РАСТРОВЫЙ ДИСПЛЕЙ.
Изображение формируется в виде растра, который состоит из горизонтальных строк сканирования. По мере движения луча по строке развертки видеосигнал, подаваемый в схему управления электронным лучом, изменяет яркость каждого пиксела и на экране появляется воспринимаемое человеком изображение. Для получения немерцающего изображения необходимо повторять формирование растра 50-70 раз/с. Такое периодическое сканирование экрана называется регенерацией.
Отклонение луча по горизонтали в течение прямого хода осуществляется сигналом строчной (горизонтальной) развертки, а по вертикали – сигналом кадровой (вертикальной) развертки. Перемещение луча справа налево называется горизонтальным обратным ходом, а снизу вверх – вертикальным обратным ходом.
27. Видеоадаптеры. Определение. Эволюция.
В каждом персональном компьютере семейств PC или PS/2 имеется видеосистема, предназначенная для формирования изображения. Ее основу составляют специализированные схемы для генерирования электрических сигналов, управляющих монитором.
Видеоадаптер представляет собой печатную плату, имеющую разъем для кабеля монитора и два краевых разъема, которые вставляются в один из слотов на материнской плате персонального компьютера. На плате адаптера установлены микросхемы ПЗУ знакогенератора, программируемого контроллера ЭЛТ, видеопамяти (видеобуфера). Схемы адаптера формируют сигналы, управляющие той информацией, которая выводится на экран монитора.
Все видеосистемы содержат электронные компоненты, формирующие сигналы синхронизации, цветности и управляющие генерированием текстовых символов. Кроме того, во всех видеосистемах имеется видеобуфер. Он представляет собой область оперативной памяти, которая предназначена только для хранения текста или графической информации, выводимой на экран. Основная функция видеосистемы заключается в преобразовании данных из видеобуфера в те сигналы, которые управляют монитором и в конце концов формируют наблюдаемое на экране монитора изображение.
Дата добавления: 2016-07-18; просмотров: 1611;