![]() Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву ![]() Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Глава 36. Шейдеры GLSL. Использование Без компонентов. Самый примитивный шейдерСодержание книги
Поиск на нашем сайте
Все шейдеры в этой главе соответствуют стандартам GLSL 1.00 — 1.20. Это важно.
Сейчас мы сделаем, пожалуй, самый примитивный шейдер — покрасим сферу в красный цвет. Итак, приступим. Поместите на форму GLScene1 (инспектор объектов сцены), GLSceneViewer. В инспекторе объектов создайте камеру, ее свойству Position.Z присвойте 2; свойству GLSceneViewer. Camera присвойте GLCamera. Также в инспекторе объектов создайте GLDirectOpenGL. Последний нужен, поскольку мы будем использовать прямой доступ к OpenGL. Подключите модуль GLContext, иначе компилятор не будет знать о TGLProgramHandle. Так как мы будем тестировать шейдер на сфере, подключите модуль GLObjects. Также нужно подключить OpenGLTokens. Теперь объявите в программе две константы для хранения вершинного (_vp) и фрагментного (_fp) шейдера. Сейчас оба текста мы поместим в код программы для облегчения редактирования. Но учтите, часто их помещают в виде отдельных файлов. const _vp = ‘void main(void)’+ ‘{‘+ ‘gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;’+ ‘}’; Тут требуется пояснение касательно кода шейдеров вообще. В коде шейдера обязательно должна быть функция main(). Это касается всех типов шейдеров. Так же пользователь может объявлять свои функции. Слово void, стоящее в скобках, означает, что эта функция ничего не принимает, перед именем функции — ничего не возвращает (т.е. процедура). float MyMain(float value) { return clamp(value, 0.0, 1.0); }; Возвращаемся к нашему простому шейдеру. Прежде, чем мы сможем работать с вершинами, нам необходимо их трансформировать с учётом глобальной (мировой) матрицы. Это и выполняется командой gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;. По сути, эта команда должна присутствовать во всех вершинных шейдерах, хотя вместо неё иногда можно увидеть и устаревшую запись gl_Position = ftransform(). Ей пользоваться мы не рекомендуем, а при использовании в шейдерах с версией выше 1.20 вообще можно получить ошибку от драйвера. const _fp = ‘void main(void)’+ ‘{‘+ ‘gl_FragColor = vec4(1.0, 0.0, 0.1, 1.0);’+ ‘}’; vec4 — это вектор, состоящий из 4-х компонентов — x,y,z,w. Есть еще vec3 и vec2. Ещё всегда помните, что GLSL различает маленькие и большие буквы.
Иногда программисты задают версию шейдерной программы через зарезервированное в GLSL слово; вот как мы укажем, что будем использовать версию 1.10: ‘#version 110 ‘+#10#13+ ‘void main(void){‘+ … Обритите внимание, что в шейдерной программе версия указывается без точки. Разные версии имеют некоторые отличия и ограничения по железу. Но об этом вы прочитаете много позже.
Подробнее о MRT можете потом почитать здесь: steps3d.narod.ru/tutorials/mrt-tutorial.html. Возвращаемся в Delphi. Объявите глобальную переменную GLSLHandle типа TGLProgramHandle. Она нужна для управления шейдером. Также создадим экземпляр сферы: GLSphere: TGLSphere. Создайте у формы событие OnCreate и запишите в нем GLSphere:=TGLSphere.Create(nil); Читатель меня не простит, если я не расскажу, почему в скобках написано nil, а не GLScene1.Objects и почему мы используем Create, а не CreateAsChild. Дело в том, что инспектор объектов сцены, в который мы наш объект заботливо не поместили, визуализирует свои объекты когда ему и только ему захочется; нам же нужно визуализировать сферу именно после команды UseProgramObject и именно перед EndUseProgramObject. Поэтому мы и не воспользовались инспектором, чтобы не рендить объект дважды. Пришло время задействовать GLDirectOpenGL. Мы будем практиковать нашу очень интересную находку: будем иметь для этого компонента два варианта события OnRender. Первое событие будет называться GLDirectOpenGLInit; второе GLDirectOpenGLRender. Откройте инспеткор объектов сцены, выберите там GLDirectOpenGL; перейдите на вкладку Events; щёлкнув дважды в инспекторе объектов напротив текста OnRender вы создадите второе событие GLDirectOpenGLRender. Теперь создайте первое событие: перейдите в окно редактора кода и в месте объявления формы пропишите рядом с объявлением GLDirectOpenGLRender точно такую же по параметрам процедуру GLDirectOpenGLInit: procedure GLDirectOpenGLRender(Sender: TObject; var rci: TRenderContextInfo); procedure GLDirectOpenGLInit(Sender: TObject; var rci: TRenderContextInfo); Теперь поместите в программу пустое «тело», как говорят, процедуры GLDirectOpenGLInit. В итоге у вас должно получиться:
procedure TForm1.GLDirectOpenGLInit(Sender: TObject; var rci: TRenderContextInfo); begin
end;
procedure TForm1.GLDirectOpenGLRender(Sender: TObject; var rci: TRenderContextInfo); begin
end; В GLDirectOpenGLInit будем проводить всё, что касается инициализации шейдеров, а именно: // Будем проверять поддержку необходимых расширений. Эти
// расширения есть даже на весьма старых компьютерах. if not (GL.ARB_shader_objects and GL.ARB_vertex_program and GL.ARB_vertex_shader and GL.ARB_fragment_shader) then begin ShowMessage(‘Ваша видеокарта не поддерживает GLSL шейдеры!’); Halt; end; // Создаём и распределяем дескриптор. GLSLHandle:=TGLProgramHandle.CreateAndAllocate; // Загружаем вершинный и фрагментный шейдеры. GLSLHandle.AddShader(TGLVertexShaderHandle, _vp); GLSLHandle.AddShader(TGLFragmentShaderHandle, _fp); // Если у драйвера возникли какие-либо нарекания, // он оповестит о них пользователя. if not GLSLHandle.LinkProgram then raise Exception.Create(GLSLHandle.InfoLog); if not GLSLHandle.ValidateProgram then raise Exception.Create(GLSLHandle.InfoLog); Gl.CheckError; // Инициализация закончена, пришло время перейти // к рендингу объекта с шейдером. GLDirectOpenGL.OnRender:=GLDirectOpenGLRender; // Без этой строчки рендинг объекта всё-таки наступит, но только если // на форме есть каденсер и в нём записано GLSceneViewer.Invalidate, // или если опустить форму за край экрана и вытащить обратно. GLDirectOpenGL.BuildList(rci);
Теперь назначьте данное событие как текущее событие OnRender компонента GLDirectOpenGL, прописав в FormCreate: GLDirectOpenGL.OnRender:=GLDirectOpenGLInit; или сделав то же самое в design time. Теперь зададим GLDirectOpenGLRender, где будет проходить применение шейдера к объекту — самая интересная часть: procedure TForm1.GLDirectOpenGLRender(Sender: TObject; var rci: TRenderContextInfo); begin with GLSLHandle do begin UseProgramObject; MySphere.Render(rci); EndUseProgramObject; end; end; Описание вызываемых тут команд потом посмотрите внизу главы. Я лишь скажу, что если вам понадобится когда-нибудь потом использовать шейдер не только для MySphere, но и для каких-то других объектов, вызовите их метод Render рядом с таким же методом MySphere. Например: with GLSLHandle do begin UseProgramObject; MySphere.Render(rci); MyCube.Render(rci); MyFreeForm.Render(rci); EndUseProgramObject; end; Построение примера закончено. Ну, собственно и всё. Запускайте проект и смотрите на работу самого примитивного GLSL шейдера. Думаю, вас удивило то, что шар превратился в круг. Всё дело в том, что чтобы вернуть шару «шарообразный» вид, нужно учитывать освещение, что у нас не делается. Но в этой главе делать мы этого и не будем — этому посвящена другая глава. Небольшое замечание — вы можете иметь столько программ-шейдеров, прилинкованных и готовых к употреблению, сколько хотите, но не больше чем это позволяет GPU. Обычно это очень большое число. Разберём использованные свойства класса TGLProgramHandle.
Готовый пример берите здесь: http://www.glscene.ru/download.php?view.545
|
|||||||||||||||||||||||
Последнее изменение этой страницы: 2016-04-19; просмотров: 547; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.189.171.188 (0.018 с.) |