- •Учебник
- •Оглавление
- •Введение
- •Глава 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
II. Проблема с glWindowsBitmapFont в Windows Vista
Была обнаружена проблема с работой компонента GLWindowsBitmapFont. При запуске программы или открытии сохранённой формы с этим компонентом возникала ошибка “Characters are too large or too many. Unable to create font texture.”
Эта ошибка просходит от того, что не все символы, указанные в наборе Ranges, можно нарисовать. Например, символы от #0 до #31 в старых версиях Windows рисовались либо квадратиками, либо пробелами. Теперь же для таких символов вообще ничего не рисуется. Больше того, теперь не рисуется символ #152. И теперь, как только компонент встретит такой символ, возникает эта ошибка.
Исправить это можно так. В свойстве Ranges нужно указывать только те символы, которые действительно нужно рисовать, или указать номера только тех символов, которые действительно есть. То есть в окошке свойства Ranges нужно отредактировать список так, чтобы там были две строки: со StartASCII и StopASCII от #32 до #151, и от #153 до #255.
Глава 20. Выделение объекта мышкой.
Часто бывает нужно выбрать какой-нибудь объект с экрана. Для этого можно использовать функцию GLSceneViewer1.Buffer.GetPickedObject(x, y), которая возвращает объект, находящийся на экране по координатам (x, y).
Пример выделения объекта мышкой:
procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
pick : TGLCustomSceneObject;
begin
pick:=(GLSceneViewer1.Buffer.GetPickedObject(x, y) as TGLCustomSceneObject);
if Assigned(pick) then pick.Material.FrontProperties.Emission.Color:=clrRed;
end;
Здесь командой (GLSceneViewer1.Buffer.GetPickedObject(x, y) as TGLCustomSceneObject) выполняется преобразование типа выбранного объекта к базовому типу объектов GLScene, а команда Assigned(pick) проверяет выбран ли какой-нибудь объект и возвращает True, если выбран.
Стандартная демка, демонстрирующая описанное, находится по адресу: Demos\interface\fadingintf.
Глава 21. Создание сцены в режиме runtime.
Создавать объекты так же можно и в ходе выполнения программы. Каждый создаваемый объект в
GLScene должен быть привязан к объекту более высокого уровня. Корневой объект самого высокого уровня – glscene1.Objects (если инспектор объектов сцены у вас называется glscene1). Таким образом, создание объекта принадлежащего корневому объекту будет выглядеть так:
Var Object1 : TGLBaseSceneObject ;
Object1 := TGLCube.CreateAsChild(GLScene1.Objects);
Обратите внимание, что переменная Object1 у нас универсальная, поэтому мы можем не меняя типа переменной присвоить ей любой объект (если он ещё не присвоен). А вот так будет выглядеть создание объекта дочернего к уже созданному:
Var GLSphere: TGLSphere;
GLSphere:= TGLSphere.CreateAsChild(Object1);
GLSphere.Position.SetPoint(0,0,1);
Чтобы обратиться к свойству дочернего объекта, можно написать: Object2.Chidren[0].свойство; 0 - это индекс. Хотя можно и сделать это при помощи Object2.свойство. Первый вариант можно использовать в цикле. Второй вариант иногда недоступен. Например, если нужно задать радиус сферы нужно написать:
TGLSphere(GLSphere).Radius := 0.2;
Обратите внимание на то, что отсчет объектов (индекс) начинается с нуля и, если вы создали первый по счету объект, он будет иметь индекс 0. Новый созданный объект имеет тип TGLBaseSceneObject, который не хранит в себе информацию, например о текстуре объекта. Чтобы установить это свойство нужно преобразовать тип нового дочернего объекта. Вот так:
(имя_родителя.Children[индекс] as новый_тип).свойство;
Например:
(Object2.Children[0] as Object1).Material.FrontProperties.Diffuse.Red := 255;
Object1станет красным.
Удалить созданный объект можно процедурой FreeAndNil:
FreeAndNil(Object1);
Или процедурой родительного объекта DeleteChildren, которая удалит не только родителя, но и всех наследников.
После того как объект перестал быть нужным, его нужно уничтожать, а не хранить в памяти, даже если он уже не виден. От этого зависит, насколько быстро будет работать приложение.