Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник по GLScene.doc
Скачиваний:
255
Добавлен:
16.12.2018
Размер:
7.18 Mб
Скачать

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, которая удалит не только родителя, но и всех наследников.

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