Я пытаюсь собрать некоторые компоненты для использования OpenGL в RAD Studio 2009. Я хочу иметь несколько контекстов рендеринга.
Моя идея состоит в том, чтобы иметь что-то вроде «основного компонента OpenGL», называемого GLMaster. Это потомок TFrame, поэтому он должен предоставить мне DC. Также есть компонент для GLMonitor, действующий как камера.
Я создаю OpenGL RC в переопределенном GLMaster.Loaded внутри «если нет (csDesigning в ComponentState) затем» -клаузе. DC для этого я не храню, в справке RAD Studio указано, что вы не должны:
«TWinControl.Handle
Не обращайтесь к свойству Handle во время создания компонента или потоковой передачи. Базовое окно не существует до тех пор, пока не будет использована ссылка на свойство Handle. Когда это происходит, метод HandleNeeded вызывается автоматически. "
Я обрабатываю это с помощью указателей на функции в компонентах, используя GLMaster, указывающий на GLMaster.GetCurrentDC (возвращает HDC).
Во время уничтожения GLMonitor хочет очистить некоторые текстуры рендеринга и другие ресурсы OpenGL. При получении DC для вызова wglMakeActive следует указатель функции, и выполнение переходит к GLMaster.GetCurrentDC. Pointer (Self) говорит мне, что это тот же GLMaster, в котором мы создали «master RC» во время потоковой передачи компонентов. Свойство [GLMaster.] Handle теперь недействительно! Однако если я освобожу GLMonitor в OnClose формы приложения (используя просто GLMonitor_1.Free;), то Handle внутри GLMaster.GetCurrentDC действителен, и все работает.
Мне удалось увидеть, что дескриптор, используемый в GLMaster.Loaded, не такой (!?!?), Как после завершения инициализации и отображения формы приложения для пользователя. Когда я нашел это, я погуглил мою проблему и добавил переопределенный CreateParams, чтобы добавить CS_OWNDC к компоненту GLMaster. Точка останова говорит мне, что она выполняется.
Почему VCL / Delphi тихо предоставляет вновь созданным компонентам другие дескрипторы и тем самым косвенно другие DC, даже если я предоставляю флаг OWNDC? Есть ли способ получить «ВСЕ компоненты теперь загружены, а их свойства считываются из файла .dfm и» -message, чтобы я мог запустить GLMaster.InitEverything внутри компонента?
Сейчас я думаю, что самый быстрый путь вперед - это поместить это InitEverything в обработчик OnShow основной формы. А затем вызов GLMatser.CleanAll в OnClose основной формы. Но я не хочу никакого кода в форме, поэтому я создал компоненты в первую очередь!
P.S.
Не то чтобы я думал, что это имеет значение для этой конкретной проблемы, но я использую профиль ядра OpenGL 3.2.