Entwickler-Ecke

Multimedia / Grafik - Problem mit dem Fokus auf OpenGL Elemente


Endgegner - Mo 15.03.10 10:38
Titel: Problem mit dem Fokus auf OpenGL Elemente
Liebe Community,

ich hoffe sehr, ihr könnt mir helfen, da ich zwischenzeitlich wie der sprichwörtliche Ochs' vor dem Berg stehe.

Ich entwickle derzeit in Delphi eine Anwendung, in der mehrere, von einander unabhängige, OpenGL-Steuerelemente vorkommen. Ich bin dabei so vorgegangen, dass ich ein bestehendes Steuerelement (TPanel) genommen habe und meine OpenGL-Steuerelemente davon abgeleitet habe (damit ich eine Grundfläche zum Zeichnen habe).

In der Initialisierung des Steuerlements setze ich dann den RenderContext und den DeviceContext, damit OpenGL auch weiß, wo es zu zeichnen hat:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
DC := GetDC(Handle);

pixelFormat := ChoosePixelFormat(DC, @pfd);
SetPixelFormat(DC, pixelFormat, @pfd);

RC := wglCreateContext(DC);
wglMakeCurrent(DC, RC);

In einer Draw-Funktion steht nun, was genau zu zeichnen ist. Zu Beginn der Funktion setze ich den Fokus auf das entsprechende Feld, d.h. ich setze den RenderContext, damit OpenGL weiß, wohin es zu zeichnen hat:

Delphi-Quelltext
1:
2:
3:
wglMakeCurrent(DC, RC);
// ...
SwapBuffers(wglGetCurrentDC);

In der Init- und Draw-Funktion kümmere ich mich selbstverständlich auch um die ganzen OpenGL-Dinge wie ModelViewMatrix, Viewports, Lighting, etc., aber dies ist für mein Problem an der Stelle irrelevant.

Mein Problem ist nun folgendes: wenn ich eines meiner OpenGL-Steuerelemente in meiner Dialog-Anwendung platziere, dann erscheint nur das TPanel, von dem ich abgeleitet habe, aber nicht die OpenGL-Szene. Ich habe meine Initialisierung (Init) in die FormCreate-Methode meiner Anwendung gepackt und das Zeichnen (Draw) steht in FormShow.

Wenn ich nun aber einen Button in meine Anwendung einfüge, welche die Draw-Funktionen meiner Steuerelemente aufruft, erscheinen alle OpenGL-Szenen, wie ich es möchte.

Kann es sein, dass die OpenGL-Szenen erst dann auf das Steuerelement gezeichnet werden können, wenn die Anwendung bereits gestartet ist (also nach FormShow)? Wie kann ich es schaffen, dass die OpenGL-Szenen direkt nach Programmstart gezeichnet werden?

Ich würde mich über eine kurze, helfende Rückmeldung sehr freuen.

Moderiert von user profile iconNarses: Color- in Delphi-Tags gewandelt.


Xion - Mo 15.03.10 11:02

user profile iconEndgegner hat folgendes geschrieben Zum zitierten Posting springen:

Kann es sein, dass die OpenGL-Szenen erst dann auf das Steuerelement gezeichnet werden können, wenn die Anwendung bereits gestartet ist (also nach FormShow)? Wie kann ich es schaffen, dass die OpenGL-Szenen direkt nach Programmstart gezeichnet werden?


Das ist durchaus möglich. Was mich etwas wundert ist, dass du es nur einmal zeichnen lässt. Wenn ich etwas mit OpenGL mache dann immer mit einem timer (ok, bei mir bewegt sich auch immer was ^^).

user profile iconEndgegner hat folgendes geschrieben Zum zitierten Posting springen:

Wie kann ich es schaffen, dass die OpenGL-Szenen direkt nach Programmstart gezeichnet werden?


Um das ganze mal zu überprüfen, mache folgendes: Platziere einen Timer, den stellst auf enabled:=False. Bei OnShow machst du ihn dann an. In den Timer machst du das Draw und stellst ihn wieder ab. Dann hast du das Draw praktisch 1 Sekunde nach Programmstart, dann sieht man, ob es so funktionieren würde.


Endgegner - Mo 15.03.10 12:28

Ich habe, deinem Vorschlag entsprechend, einen Timer eingebaut, der 1ms nach FormShow aktiviert und beim Aufruf die Steuerelemente zeichnet und sich dann selbst ausschaltet.

Vielen dank für den Tipp! Jetzt weiß ich, dass es nicht an meinen Routinen lag.

Aber gibt es auch timerfreie Lösungen? :)


Xion - Mo 15.03.10 13:52

Du könntest es mal mit OnActivate probieren. Ansonsten könntest du dir selbst eine message schicken
(
Tutorial - Kapitel 1 genügt [http://www.delphi-library.de/viewtopic.php?t=97738] Und du brauchst nur ein Programm (Application.Handle)
Im Endeffekt musst du nur 3 Sachen machen:
- Message-Konstante deklarieren
- die Message in OnShow an Application.Handle posten
- eine procedure schreiben, die bei Ankunft der message den Draw ausführt
)