- •Учебник
- •Оглавление
- •Введение
- •Глава 1
- •I. Установка
- •II. Удаление
- •Глава 2. Первый проект
- •Глава 3. Создание сцены в режиме design time
- •Создание объектов:
- •Глава 4. Примитивные объекты. Вкладка Basic geometry.
- •Глава 5. Ориентация, координаты.
- •Глава 6. Движение.
- •Глава 7. Как узнать, сколько сейчас fps?
- •Глава 8. Полноэкранный режим.
- •Глава 9. Работа с материалами.
- •I. Прямое обращение к .Material
- •Глава 10. Использование 3d моделей.
- •I. Форматы моделей
- •Глава 11. Прокси объекты.
- •Глава 12. Создание земной поверхности с glTerrainRenderer.
- •Глава 13. Создание земной поверхности с glFreeForm.
- •Глава 14. Итоги работы с glTerainrender и glFreeForm.
- •Глава 15. Создание земной поверхности с glHeightField.
- •Глава 15. Создание неба.
- •Глава 16. GlAtmosphere.
- •Глава 17. Спецэффекты.
- •I. Огонь
- •II. Молния
- •III. Дождь
- •IV. Снег
- •VI. Блики от источников света
- •Глава 18. Растительность.
- •I. Деревья и кустарники
- •II. Трава
- •Глава 19. Работа со шрифтами и вывод надписей.
- •I. Вывод текста через компонент glWindowsBitmapFont
- •II. Проблема с glWindowsBitmapFont в Windows Vista
- •Глава 20. Выделение объекта мышкой.
- •Глава 21. Создание сцены в режиме runtime.
- •Глава 22. Тени.
- •Глава 23. Туман.
- •Глава 24. Vbo или расширение arb_vertex_buffer_object в OpenGl.
- •Глава 25. Fbo или расширение ext_framebuffer_object в OpenGl.
- •Глава 26. Рисование на канве.
- •Глава 27. Использование чистого OpenGl.
- •Глава 28. Звуки.
- •I. Проигрывание звуков с помощью bass
- •II. Проигрывание звуков с помощью fmod
- •III. Проигрывание звуков с помощью OpenAl
- •Глава 29. Игровое меню.
- •Глава 30. Примитивная физика dce.
- •Глава 31. Физика ode.
- •II. Основы библиотеки ode(: tglodeManager и tglodeJointList) на примере создания подобия боулинга.
- •Глава 32. Физика Newton.
- •Глава 33. Ручная проверка коллизий.
- •V. Ручная проверка коллизии
- •Глава 34. Шейдеры. Терменология.
- •Глава 35. Шейдеры. История и компоненты.
- •Глава 36. Шейдеры glsl. Введение.
- •Глава 37. Шейдеры glsl. Использование без компонентов. Самый примитивный шейдер.
- •Глава 38. Шейдеры glsl. Немного о спецификации. Типы данных и переменные
- •Стандартные функции
- •Поддерживаемые компоненты векторов
- •Глава 40. Шейдеры glsl. Текстурирование.
- •Глава 41. Шейдеры glsl. Использование без компонентов. Мультитекстурирование. Смешение трёх цветов по базовой карте.
- •Глава 42. Шейдеры glsl. Использование через компонент glslShader. Часть первая – Первые шаги.
- •Глава 43. Шейдеры glsl. Использование через компонент glslShader. Часть вторая – знакомимся со светом. Передача параметров в шейдер.
- •Глава 44. Шейдеры glsl. Использование через компонент glslShader. Часть третья – текстуры.
- •Глава 45. RenderMonkey.
- •Глава 46. Оптимизация программы.
- •Глава 47. Практика. Создание мира
- •Приложение
- •I. Типы векторов и матриц
- •II. Работа с векторами
- •III. Работа с матрицами
- •IV. Методы объектов glScene
- •Предметный указатель по компонентам glScene
Глава 42. Шейдеры glsl. Использование через компонент glslShader. Часть первая – Первые шаги.
Карпенюк Алексей,
karpenyuk@bk.ru
(публикация стилизованная)
В данной статье мы научимся добавлять к нашей программе эффекты созданные при помощи шейдеров.
Итак, создадим простой проект – разместим на форме такие компоненты – из закладки
“GLScene” помещаем редактор GLscene, так же добавим на форму GLSceneViewer,
GLMaterialLibrary и самое главное – из закладки GLScene Shaders поместим на форму компонент GLSLShader.
Теперь выполним стандартные процедуры по созданию сцены – подберем размер формы и
GLSceneViewer1, добавим в GLscene1 камеру и TGLFreeForm в качестве нашего объекта. Не забываем связать нашу камеру с GLSceneViewer1, указав в свойствах последнего Camera = GLCamera1. Теперь немного настроим камеру – для начала стоит ее немного отодвинуть от начала координат, иначе мы не увидим наш объект, для этого просто указываем в свойствах GLCamera1.Position новые координаты (X=0;Y=0;Z=7). На этом подготовительную часть можно считать завершенной.
Переходим к выбору объекта – возьмем один из стандартных объектов, поставляемый вместе со сценой, к примеру «mushroom.3ds».
Для того чтоб загрузить этот объект в нашу сцену нам потребуется выполнить простую операцию – в событии формы onCreate пишем такие вот строчки:
procedure TForm1.FormCreate(Sender: TObject);
begin
GLFreeForm1.ObjectStyle:=[osDirectDraw];
GLFreeForm1.LoadFromFile('mushroom.3ds');
GLFreeForm1.NormalsOrientation:=mnoInvert;
GLFreeForm1.PitchAngle:=90;
end;
Это загрузит наш грибок в сцену (не забываем
указать правильный путь к этому файлу). Гриб
у нас в файле неправильно повернутый, потому мы сразу же это исправили.
Изначально гриб имеет очень большие размеры, потому можете смело выставлять у GLFreeForm1.scale по каждой из осей равным 0.05
Строка GLFreeForm1.ObjectStyle:=[osDirectDraw] избавит нас от проблем на видеокартах производства ATI. Так как изначально нормали у нашего гриба повернуты вовнутрь, то мы их сразу
же вывернем наружу строчкой:
GLFreeForm1.NormalsOrientation:=mnoInvert. Так же не стоит забывать о том, что для использования формата 3ds нам необходимо добавить к проекту соответствующий модуль: Uses GLFile3ds;
Если мы все сделали правильно, то после запуска программы мы увидим вот такой вот черный грибок.
Вы спросите почему он черный? Это потому что мы не создали в сцене никаких источников света, но на данном этапе это нам не важно.
Теперь переходим к самому интересному – подключим к нашему грибу наш шейдер. Весь этап подключения заключается в создании нового материала и связывания его с нашим шейдером и применением его к объекту.
Первым делом создадим новый материал в библиотеке материалов, для этого дважды щелкнем на значке GLMaterialLibrary1 и в появившемся окне создадим новый материал.
Назовем его ShaderMaterial. После этого нам нужно будет связать
данный материал с нашим шейдером, для этого достаточно в инспекторе объектов свойству Shader присвоить значение GLSLShader1 (можно
выбрать из списка)
После того, как мы создали новый материал и указали что за этот материал у нас будет отвечать шейдер, нам нужно применить его к нашему объекту.
Выбираем наш TGLFreeForm1, ищем у него свойство Material,
раскрываем свиток (жмем «+»), выбираем в открывшемся списке MaterialLibrary и указываем там GLMaterialLibrary1. Теперь нам нужно указать какой материал из этой библиотеки у нас будет использован, для этого ищем там же свойство LibMaterialName и указываем там созданный нами материал – ShaderMaterial.
Итак, половина пути пройдена, самое время заняться написанием самого шейдера.
Для того, чтоб подчеркнуть что шейдер это отдельная программа мы будем ее создавать в обычном текстовом редакторе. У такого способа есть как недостаток (нам придется периодически переключаться между окном Delphi и блокнотом, для того чтоб отредактировать код, но зато мы всегда сможем быстро получить наш шейдер. К примеру для
внесения исправлений без запуска Delphi, или вдруг захотим его кому-то передать, или же просто захотим отладить или изменить его в специализированных редакторах, на подобии
RenderMonkey от ATI.
Итак, открываем блокнот и пишем там такие вот строчки:
void main(void)
{
gl_Position = ftransform();
}
И сохраняем этот файл с именем «Shader.Vert», Это и будет наш вершинный шейдер. Как
видите – там пока только одна команда, без которой нам никак не удастся обойтись – оно производит трансформацию координат вершины используя видовую матрицу модели. Теперь создаем новый файл, и помещаем в него такой вот текст:
void main(void)
{
gl_FragColor = vec4( 0.4, 0.0, 0.9, 1.0 );
}
Сохраняем его с именем «Shader.Frag» - это будет наш фрагментный шейдер. Как вы видите
– там пока тоже только одна трока, и тоже обязательная – она возвращает цвет для данной вершины. В нашем примере для всех вершин задан одинаковый цвет, в чем мы скоро
убедимся.
Итак, файлы шейдеров созданы, самое время запустить их. Для этого нам потребуется еще немного изменить обработчик события формы onCreate – допишем туда вот такие строчки:
GLSLShader1.LoadShaderPrograms('Shader.Vert', 'Shader.Frag'); GLSLShader1.Enabled := true;
Целиком эта процедура теперь будет выглядеть как:
procedure TForm1.FormCreate(Sender: TObject);
begin
GLFreeForm1.LoadFromFile('mushroom.3ds');
GLSLShader1.LoadShaderPrograms('Shader.Vert', 'Shader.Frag');
GLSLShader1.Enabled := true;
end;
Данным фрагментом кода мы загрузили обе наших шейдерных программы и активировали шейдер. Теперь можно попробовать запустить программу:
Если вы все сделали правильно, то как я и обещал – вы увидите грибок залитый одним цветом. Который мы указали как: vec4( 0.4, 0.0, 0.9, 1.0 );
Тут стоит немного задержаться и объяснить каким образом
здесь задается цвет – в шейдере цвет задается в виде 4-х компонентного вектора – RGBA, каждая из компонент представлена в нормированном виде (тоесть от [0..1]), причем 1 соответствует в Windows компоненте 255. Нормированное значение цвета легко получить, разделив каждую из компонент на 255. к примеру если в Windows цвет задается как (r=100, g=50; b=150), то в шейдер пойдут
значения (100/255, 50/255, 150/255), что округленно будет соответствовать строчке -
vec4(0.4,0.2,0.6,1.0). Можете проиграться с цветом, изменяя эту величину в фрагментном шейдере, только не забывайте после каждого изменения шейдера перезапускать программу
(можно просто запускать уже откомпилированный ранее файл).