Глава 23. Использование чистого OpenGL 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Глава 23. Использование чистого OpenGL



 

GLScene является надстройкой над интерфейсом OpenGL, но это не означает, что он может его (интерфейс) полностью заменить. Поэтому существует возможность вставлять фрагменты на чистом OpenGL. Для этой цели служит GLDirectOpenGL .

Сделаем небольшое приложение с использованием чистого OpenGL и GLScene. Создадим стандартный проект (у GLCamera1 Position.Z = 4), а затем создадим в GLScene1 объект GLDirectOpenGL. Строки кода OpenGL нужно вставлять в событие OnRender.

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

procedure TForm1.GLDirectOpenGL1Render(Sender: TObject;

var rci: TRenderContextInfo);

begin

gl.LoadIdentity; // заменяем текущую матрицу на единичную.

gl.Translatef(0.0, 0.0, -8.0);

gl.Begin(GL_POLYGON); // Начало операторный скобки. Она определяет, что вершины будут объединены

gl.Vertex3f(1.0, 1.0, 1.0); //Рисуем вершину

gl.Vertex3f(-1.0, 1.0, 1.0);

gl.Vertex3f(-1.0, -1.0, 1.0);

gl.Vertex3f(1.0, -1.0, 1.0);

gl.End; // Конец операторной скобки

end;

 

Всё! Запускаем и смотрим на эту плоскость.

Когда вы создадите событие OnRender и попробуете туда что-либо написать, компилятор возможно выдаст вам ошибку. Это несложно исправить: подключите к вашему проекту модуль GLRenderContextInfo и всё будет работать.

 

В последних версиях сцены (от мая 2010) появилась полезная особенность. Для предотвращения двойного переключения состояний (state), все состояния OpenGL теперь должны переключаться через

rci.GLStates.SetXXX

где XXX — название вызываемой функции OpenGL без букв «gl».

Приведу пример: чтобы вызвать glBlendFunc (GL_ONE, GL_ONE), вы должны написать в OnRender:

rci.GLState.SetBlendFunc(bfOne, bfOne)

Иногда на GLScene переносят сложные приложения, работающие с текстурами. В таких случаях удобно использовать класс TGLTextureHandle, который предоставляет очень похожий на чистый OpenGL доступ к текстуре. Ниже приведён пример создания и настройки текстуры подобным образом:

var

TH: TGLTextureHandle;

TH:=TGLTextureHandle.Create;

TH.AllocateHandle;

glEnable(GL_TEXTURE_RECTANGLE_ARB);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, dt.Handle);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

 

В новейших версиях GLScene в командах OpenGL после gl ставится точка, после чего пишется остальная часть имени. Такая система позволяет работать с несколькими контекстами. Например, вместо glvertex3f пишется GL.vertex3f, а вместо GLBegin/GLEnd пишеся GL.Begin_/GL.End_. Такая система вызывает необходимость подключать новые, ранее не используемые для вызова OpenGL-команд, модули: вместо OpenGL1x подключается GLContext и либо OpenGLTokens, либо OpenGLAdapter. OpenGLTokens содержит команды OpenGL, они позволяют компилятору понимать текст, идущий за GL.. OpenGLAdapter даёт возможность иметь список расширений и точек входа функций OGL на каждый контекст. Такая система позволяет делать приложение с несколькими окнами, в которых может быть разный формат пикселя.

 

Зачастую необходимо получить объект, который в данный момент времени отрисовывается. Для этого ввели vCurrentRenderingObject: TGLBaseSceneObject; нужно смотреть в цикле, является ли интересующий вас объект vCurrentRenderingObject (IF Obj= vCurrentRenderingObject then …).


Глава 24. VBO
или
расширение ARB_vertex_buffer_object в OpenGL

Начинаем осваивать…

Расширение VBO является лучшим вариантом вывода всей сцены. Однако один только класс MeshObjects из всех классов GLScene использует эту технологию. Большинство компонентов задействуют вершинные массивы.

 

Одним из самых «узких» мест в работе с современным графическим ускорителем является передача ему данных — текстур, вершин, нормалей и т.п. Для повышения быстродействия следует уменьшить количество запросов на передачу данных и передавать их как можно большими частями.

Если с текстурами все достаточно просто — они один раз загружаются в память графического ускорителя и больше не изменяются, то с геометрическими данными (координатами вершин, текстурными координатами, нормалями и т.д.) дело обстоит значительно хуже.

Самый старый способ передачи данных в операторных скобках glBegin()/glEnd является крайне неэффективным, поскольку требует одного вызова функции для каждого атрибута каждой вершины. Ещё одной проблемой glBegin()/glEnd является избыточная обработка вершин, являющихся общими для нескольких смежных полигонов.

Поэтому разработчики пытались улучшить ситуацию. В версии 1.1 были ведены так называемые вершинные массивы (стоит отметить, что некоторые разработчики реализовали вершинные массивы в виде расширений ещё на момент выхода OpenGL 1.0). В них данные хранятся на стороне CPU, а ускорителю передается только указатель на них и их размер. При использовании этого способа передача осуществляется сразу большими блоками, количество обращений к графическому ускорителю (GPU) заметно сокращается. Кроме того, использование вершинных массивов может устранить избыточность при обработке общих вершин. Всё это приводит к гораздо более эффективному использованию GPU и общему повышению быстродействия программы. Однако этот способ требует постоянной передачи массивов данных от CPU к GPU — вызов любого оператора OpenGL с указателем на массив приводит к его передаче графическому ускорителю, даже если передаваемые данные не устарели (т.е. те данные, что содержит GPU, и те, что будут ему присланы, полностью идентичны).

Поэтому было бы гораздо эффективнее сразу загрузить такие данные в память GPU, после чего использование этих данных графическим ускорителем не будет требовать их передачи от CPU.

Именно подобную возможность и предоставляет пользователю расширение ARB_vertex_buffer_object, введенное в ядро начиная с версии 1.5. Использование данного расширения позволяет кэшировать (хранить) различные типы данных в быстрой памяти графического ускорителя. Для такого хранения блоки данных помещаются в так называемые вершинные буферы (vertex buffer objects, VBO), при этом каждый такой буфер представляет собой просто массив байт.

Давайте сделаем приложение, которое будет использовать вершинные буферы. Я надеюсь, многие аспекты реализации после этого отпадут. Мы будем выводить затекстурированную плоскость средствами GLScene и OpenGL.

Поместите на форму компоненты GLScene, GLSceneViewer, GLMaterialLibrary. В инспекторе объектов сцены создайте камеру под именем GLCamera и установите ее вьюверу, свойству Position.Z присвойте значение 2. В GLMaterialLibrary создайте материал и свойству Disabled материала присвойте False. Загрузите в материал любую 2D текстуру. Подключите столь необходимые для работы модули OpenGLTokens и GLContext.

Переходим к коду. Я постараюсь максимально комментировать всё, что мы будем делать.

Создайте массив:

var

vertexBuffers: array[0..1] of GLInt;

Это статический массив — два объекта вершинного буфера. Один для хранения позиций вершин (vertices), другой для текстурных координат (texcoords).

Теперь создайте событие FormCreate. В нем будут проходить все действия по подготовке к рисованию. Первое что мы сделаем — объявим необходимые для работы переменные, отвечающие за положение каждой из 4-х вершин и 4-х текстурных координат.

var

Vertices: array of array[0..1] of GLFloat;

TexCoords: array of array[0..1] of GLFloat;

Код здесь хитрый и требует пояснения. Vertices по факту — конечная точка, из которых будет состоять наша плоскость. Всего будет 4 точки. Они соединёны треугольниками по принципу «две предыдущих точки вместе с третьей образуют новый треугольник».

Красным обозначены точки, на рисунке проставлен порядок их рендеринга — сначала рисуется точка №1, затем №2, №3 и, наконец, №4. Соответственно, сначала рисуется синий прямоугольник, а затем второй — чёрный.

Точка у нас в проекте имеет координаты X и Y, но обращаться мы к ним будем через Vertices[0] и Vertices[1] (как у векторов).

Итак… Возвращаемся к редактору кода и пишем дальше в событие OnCreate формы.

SetLength(Vertices,4*2);

Vertices[0][0]:=1; Vertices[0][1]:=-1;

Vertices[1][0]:=-1; Vertices[1][1]:=-1;

Vertices[2][0]:=1; Vertices[2][1]:= 1;

Vertices[3][0]:=-1; Vertices[3][1]:= 1;

SetLength(TexCoords,4*2);

TexCoords[0][0]:=0; TexCoords[0][1]:=-1;

TexCoords[1][0]:=-1; TexCoords[1][1]:=-1;

TexCoords[2][0]:=0; TexCoords[2][1]:=0;

TexCoords[3][0]:=-1; TexCoords[3][1]:=0;

Напомню, SetLength изменяет размер массива. Размер массива считается как произведение количества координат, передаваемых для одной вершины на количество вершин нашего объекта. Кроме этого, мы задаём позиции каждой вершины и текстурной координаты.

В последних снимках GLScene при работе с OpenGL требуется обязательно активировать контекст. Делается это так:

GLSceneViewer1.Buffer.RenderingContext.Activate;

Если это не прописано, то при запуске вылетает Access violation.

Далее запишите:

gl.GenBuffers(2, @vertexBuffers);

Этим оператором мы сгенерировали два буферных объекта. Далее один мы будем использовать для хранения позиций вершинных координат, второй для текстурных координат. Возможно, в будущее вам понадобятся ещё 4 буфера, но о них позже.

Теперь нужно инициализировать и заполнить буферы данными.:

gl.BufferData(GL_ARRAY_BUFFER, SizeOf(GLFloat)*Length(Vertices), @Vertices[0], GL_STATIC_DRAW);

Первый параметр — данные, которые будет содержать буфер. Это нужно либо для информации о вершинах (позиция, нормаль и т.д.), либо для индексов в другие массивы (об этом позже). Второй параметр задаёт размер буфера. Третий параметр — ссылка на область памяти, где хранится вершинный массив. Четвёртый параметр несёт в себе информацию о предполагаемом назначении буфера. Эта информация является лишь намеком и служит для того, чтобы система могла более эффективно управлять выделением памяти для вершинного буфера. Параметр имеет вид GL_XXX_VVV_ARB.

Значение XXX Описание
STREAM Предполагается, что после каждого вывода данных они будут изменяться.
DYNAMIC Предполагается, что будет частое использование и изменение содержимого буфера.
STATIC Предполагается, что данные будут заданы один раз и потом вообще не будут изменяться.
Значение VVV Описание
DRAW Буфер будет использоваться для передачи данных GPU, например, для вывода объектов.
READ Буфер будет использоваться пользователем для чтения из GPU.
COPY Буфер будет использоваться как для чтения данных из GPU, так и для вывода объектов.

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

Далее мы должны освободить активный вершинный буфер:

gl.BindBuffer(GL_ARRAY_BUFFER, 0);

Первый параметр — данные, которые будет содержать буфер — может иметь всего два очень важных зарезервированных значения, определяющих тип данных: GL_ARRAY_BUFFER и GL_ELEMENTS_ARRAY_BUFFER. Первое задаёт информацию о вершинах, другими словами вершинный атрибут (позиция, нормаль, текстурные координаты). Второе значение сообщает о том, что данные из вершинного буфера будет использоваться как индексы массива с информаций о вершинах, то есть второе значение связано с первым. Второй параметр должен привязывать первый параметр к буферному объекту. Но сами объекты считаются с 1, поэтому если написать 0 во втором параметре и GL_ARRAY_BUFFER в первом, то активный вершинный буфер освободится.

Теперь запишите кодовый блок для использования вершинного буфера для текстуры (аналогичен предыдущему):

gl.BindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);

gl.BufferData(GL_ARRAY_BUFFER, SizeOf(GLFloat)*Length(TexCoords), @TexCoords[0], GL_STATIC_DRAW);

gl.BindBuffer(GL_ARRAY_BUFFER, 0);

Сейчас уже будет попроще… В инспекторе объектов создайте GLDirectOpenGL и в его событии OnRender запишите

GLMaterialLibrary.Materials[0].Apply(rci);

Это делает активной указанную текстуру. В данном случае библиотека материалов это просто список указателей на текстурные дескрипторы, а чтобы текстура применилась к отрисовываемому объекту, её нужно активировать. При отображении стандартных объектов это делается GLScene автоматически, но когда мы используем DirectOpenGL, это нужно делать кодом.

А теперь включите вершинный массив координат вершин и массив координат текстуры

gl.EnableClientState(GL_VERTEX_ARRAY);

gl.EnableClientState(GL_TEXTURE_COORD_ARRAY);

Всего существует 6 таких массивов. Для использования расширения VBO понадобятся только 4:

GL_VERTEX_ARRAY массив координат вершин
GL_COLOR_ARRAY массив цветов в режиме RGBA
GL_NORMAL_ARRAY массив координат векторов нормалей
GL_TEXTURE_COORD_ARRAY массив координат текстуры

 

Далее необходимо сообщить OpenGL, что мы собираемся использовать vertexbuffers[0] и vertexbuffers[1] как вершинные массивы при рисовании. Сделаем мы это через команду glBindBuffer:

gl.BindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);

Следующим оператором мы укажем, какое количество координат будем задавать каждой вершине (две, три или четыре); тип данных для каждой координаты в массиве (GL_SHORT, GL_INT, GL_FLOAT или GL_DOUBLE); нулевой промежуток памяти в байтах между координатами соседних последовательных вершин и отсутствие указателя на область, где содержатся координаты первой вершины (обычно для VBO задаётся именно отсутствие указателя).

glVertexPointer(2, GL_FLOAT, 0, nil);

Всего существует 4 оператора GL…Pointer, используемых с буферами вершинных массивов. Это:

GIVertexPointer задает адрес массива координат вершин;
GINormalPointer задает адрес массива нормалей в вершинах;
GlColorPointer задает адрес массива цветов, связанных с вершинами;
GlTexCoordPointer задает адрес массива координат текстуры материала, задаваемой в вершинах.

 

Пришло время сделать то же для текстурных координат.

gl.BindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);

gl.TexCoordPointer(2, GL_FLOAT, 0, nil);

Ну а теперь рисуем два треугольника

gl.DrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Эта команда конструирует последовательность геометрических примитивов. Параметр mode указывает, какие примитивы следует построить, и принимает те же значения, что и единственный параметр glBegin(). Ниже приведена полная таблица значений. Второй и третий параметры указывают, с какой координаты начинаются координаты, которые читаются из массива и количество точек.

Значение Соответствующие примитивы
GL_POINTS Индивидуальные точки.
GL_LINES Вершины попарно интерпретируются как самостоятельные отрезки.
GL_LINE_STRIP Серия соединенных отрезков (ломаная).
GL_LINE_LOOP Аналогично предыдущему, но, еще автоматически добавляется отрезок, соединяющий первую и последнюю вершины (замкнутая ломаная).
GL_TRIANGLES Каждая тройка вершин интерпретируется как треугольник.
GL_TRIANGLE_STRIP Цепочка соединенных треугольников.
GL_TRIANGLE_FAN Веер из соединенных треугольников.

В старых книгах вы можете встретить так же режимы GL_QUADS, GL_QUAD_STRIP и GL_POLYGON; используйте их только для OpenGL 1.5-2.1.

 

Наконец, выключаем применения массива позиций вершин и массива текстурных координат.

gl.DisableClientState(GL_VERTEX_ARRAY);

gl.DisableClientState(GL_TEXTURE_COORD_ARRAY);

 

И делаем неактивной указанную текстуру:

GLMaterialLibrary.Materials[0].UnApply(rci);

В конце необходимо освободить видеопамять т.к. Delphi за нас это сделать не может. Создайте событие OnDestroy у главной формы приложения и запишите в нем:

gl.DeleteBuffers(1,@vertexBuffers[0]);

gl.DeleteBuffers(1,@vertexBuffers[1]);

Всё. Готовый пример можно посмотреть здесь: http://www.glscene.ru/download.php?view.443.

Хорошая статья о VBO от Алексея Капернюка (aka Fantom):

http://www.glscene.ru/forum_viewtopic.php?6.36114.230

Частично материал позаимствован с сайта А. Берескова, отсюда:

http://steps3d.narod.ru/tutorials/tutorial-VBO.html.

Но я не рекомендую эту статью к прочтению. Множество неточностей делает её трудной для понимания и почти непригодной для использования на практике.

Итак, мы сделали демо проект, который показывает возможности VBO. Мы использовали чистый OpenGL код или, как ещё говорят, OpenGL API. Тоже самое можно было сделать и используя классы GLScene. Я приведу несколько сокращённый код такой программы:

uses

VectorLists;

var

VertexBuffer,TexCoordBuffer: TGLVBOArrayBufferHandle;

 

procedure TForm1.FormCreate(Sender: TObject);

var

Vertices: TTexPointList;

TexCoords: TTexPointList;

begin

Vertices:=TTexPointList.Create;

TexCoords:=TTexPointList.Create;

Vertices.Add(1,-1);

Vertices.Add(-1,-1);

Vertices.Add(1,1);

Vertices.Add(-1,1);

 

TexCoords.Add(0,-1);

TexCoords.Add(-1,-1);

TexCoords.Add(0,0);

TexCoords.Add(-1,0);

 

Form1.GLSceneViewer.Buffer.RenderingContext.Activate;

VertexBuffer:=TGLVBOArrayBufferHandle.CreateFromData(

Vertices.List,SizeOf(GLFLoat)*2*Vertices.Count,GL_STATIC_DRAW);

TexCoordBuffer:=TGLVBOArrayBufferHandle.CreateFromData(TexCoords.List,

SizeOf(GLFLoat)*3*TexCoords.Count, GL_STATIC_DRAW);

gl.EnableClientState(GL_VERTEX_ARRAY);

gl.EnableClientState(GL_TEXTURE_COORD_ARRAY);

end;

 

procedure TForm1.GLDirectOpenGLRender(Sender: TObject;

var rci: TRenderContextInfo);

begin

GLMaterialLibrary.Materials[0].Apply(rci);

gl.BindBuffer(GL_ARRAY_BUFFER, VertexBuffer.Handle);

gl.VertexPointer(2, GL_FLOAT, 0, nil);

gl.BindBuffer(GL_ARRAY_BUFFER, TexCoordBuffer.Handle);

gl.TexCoordPointer(2, GL_FLOAT, 0, nil);

gl.DrawArrays(GL_TRIANGLE_STRIP, 0, 4);

GLMaterialLibrary.Materials[0].UnApply(rci);

end;

 

procedure TForm1.FormDestroy(Sender: TObject);

begin

GLSceneViewer.Buffer.RenderingContext.Activate;

gl.DisableClientState(GL_VERTEX_ARRAY);

gl.DisableClientState(GL_TEXTURE_COORD_ARRAY);

gl.DeleteBuffers(2,@vertexBuffer);

end;

Полный исходник использования VBO через классы GLScene можно скачать здесь: http://narod.ru/...

Не путайте вершинные массивы и буферы вершинных массивов (VBO).

 

Продолжаем OGL изыскания

 

Выше мы изучили использование VBO для видеокарт с OpenGL 1.5 — 2.1. Это не самые последние версии графической библиотеки. Для OpenGL 3 — 4 все трансформации нужно переносить в вершинный шейдер. Есть такое понятие — вершинный атрибут; к нему относятся цвет вершины, текстура, нормаль и другие. В OpenGL 3-4 убрали так называемые «встроенные» вершинные атрибуты, то есть этот самый цвет вершин, эту самую текстуру, нормаль. Поэтому исчезли и все функции glXXXPointer, которые мы использовали выше. Вместо этого нам теперь дают вjзможность самим создавать вершинные атрибуты. Делается это вот так. Этот код нужно положить в FormCreate или в другую процедуру, вызываемую один раз:

var

AttribPosition: GLInt;

AttribPosition:=glGetAttribLocation(ProgramName, 'Position');

Здесь мы получаем адрес новоиспечённого атрибута. Обратите внимание, что для этого необходимо иметь шейдерную программу, её handle передаётся первым параметром, а вторым передаётся произвольное имя атрибута.

В рисующую процедуру нужно добавить такой код:

glBindBuffer(GL_ARRAY_BUFFER, IndicesBuffer);

glVertexAttribPointer(AttribPosition, 2, GL_UNSIGNED_BYTE, False, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glEnableVertexAttribArray(AttribPosition);

glDrawArrays(GL_TRIANGLES, 0, VertexCount);

glDisableVertexAttribArray(AttribPosition);


Глава 25. FBO

Или

расширение EXT_framebuffer_object в OpenGL

 

EXT_framebuffer_object предоставляет очень простую и платформенно-независимую альтернативу использованию р-буферов, которые были непроизводительны и слишком запутаны.

Данное расширение вводит новый тип объекта в OpenGL — фреймбуфер (framebuffer object, FBO). Фреймбуфер состоит из набора отдельных логических буферов (цвета, глубины, трафарета) и параметров состояния.

В качестве логических буферов могут выступать как текстуры подходящих форматов, так и специальные объекты еще одного вводимого типа — рендербуферы (renderbuffer object, RBO). Рендербуфер содержит внутри себя простое двухмерное изображение (без использования пирамидального фильтрования) и может использоваться для хранения результатов рендеринга в качестве одного из логических буферов.

Приложение может использовать много фреймбуферов, но все они разделяются на начальный фреймбуфер, созданный оконной системой для приложения (он имеет идентификатор 0), и созданные самим приложением фреймбуферы (они идентифицируются натуральными числами).

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

Я приведу две ссылки, где описывается процесс создания и использования FBO:

http://steps3d.narod.ru/tutorials/framebuffer-object-tutorial.html

http://www.gamedev.ru/community/opengl/articles/framebuffer_object

GLFBORenderer

 

В GLScene уже есть компонент для FBO — это GLFBORenderer .

Свойство Описание
Camera Ссылка на камеру, с позиции которой будет производиться рендеринг. Если nil, то используется текущая камера.
Aspect Отношение ширины вида к высоте, по умолчанию 1.
BackgroundColor Фоновый цвет.
UseBufferBackground Флаг, который указывает, какой цвет использовать как фоновый — из BackgroundColor или фоновый цвет вьювера.
MaterialLibrary Ссылка на библиотеку материалов.
ColorTextureName Имя библиотечного материала, в текстуру которого будет записываться цвет.
DepthTextureName Имя библиотечного материала, в текстуру которого будет записываться глубина сцены. Для этого в GLScene были введены новые форматы текстур tfDEPTH_COMPONENTXX
EnableRenderBuffer.erbDepth Флаг записи глубины в рендербуфер. Будет использоваться только при отсутствии текстуры глубины.
EnableRenderBuffer.erbStencil Флаг использования записи в буфер трафарета.
StencilPrecesion Точность значений буфера трафарета — 1, 2, 4, 8 и 16 бит.
Width Ширина видового экрана.
Height Высота видового экрана.
ForceTextureDimension Флаг подгонки текстуры под размеры видового экрана. Если флаг сброшен, то необходимо, чтобы размеры текстуры совпадали с размерами видового экрана.
RootObject Объект, рендеринг которого будет осуществляться. Может быть dummy с дочерними объектами или одиночный объект. Этот объект может быть целью нескольких GLFBORenderer, например, HUDSprite на весь вьювер для пинг-понг постэффектов.
SceneScaleFactor Лучше устанавливать в ноль, тогда это свойство не используется. Применяется для присвоения требуемого масштаба сцены, умноженного на ширину видового экрана.
TargetVisibility Флаг, указывающий на то, будет ли виден целевой объект только при работе TGLFBORenderer1 или по свойству Visible объекта. Замечу, что если у объекта это свойство выключено, то он все равно будет рисоваться в текстуру.
UseLibraryAsMultiTarget Флаг, указывающий на то, что все текстуры из подключенной библиотеки материалов будут использоваться как цели для цветовых данных (так называемый режим MRT (Multi Render Target)). Для этого необходимо использовать шейдеры, где во фрагментной программе данные будут записываться, например, так gl_FragData[0] = Color1; gl_FragData[1] = Сolor2; gl_FragData[2] = Сolor3; gl_FragData[3] = Сolor4; и так по количеству текстур. Если в этой же библиотеке есть текстура глубины, то она не будет использоваться для цветовых данных, а только как глубина для буфера.

 

Здесь лежит простая демка: http://glscene.ru/e107_files/public/3800_fboposteffect.rar

Здесь можно скачать демку с использованием технологии MRT:

http://glscene.ru/download.php?view.501



Поделиться:


Последнее изменение этой страницы: 2016-04-19; просмотров: 506; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.144.107.191 (0.128 с.)