Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 00:10

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Zerstörungslos Rendern ?
BeitragVerfasst: Fr Jul 27, 2007 06:52 
Offline
DGL Member

Registriert: Do Jul 26, 2007 14:55
Beiträge: 7
Hi Leute,

bin totaler Neuling in Sachen OpenGL (allerdings nicht in Sachen Programmierung...). Ich habe die Tutorials durchgearbeitet und dabei eine ganze Menge interessante Sachen gelernt. Eine Kleinigkeit an den Tutorials habe ich zu kritisieren, aber das mache ich dann an passender Stelle ;)

Meine Frage: Wie kann ich mit OpenGL auf einen DC rendern, ohne den vorherigen Inhalt zu zerstören ? In meinem Fall wird von einer Routine ein Landkartenausschnitt auf ein TPanel gezeichnet (per GDI). Ich möchte nun mit OpenGL weitere Elemente hinzufügen (Grafiken, Linien und anderes). Das bedingt aber, das OpenGL die Landkarte nicht löscht...

Sofern das nicht möglich ist, gäbe es eine andere Möglichkeit. Ich könnte die Landkarte in ein TBitmap (kein TImage !) zeichnen lassen, dieses TBitmap als (dann recht große und sicherlich nicht 2^n-kompatible) Textur auf mein Panel legen und dann weiterrendern. In den Tutorials wird prima gezeigt, wie man Texturen von der Platte lädt - doch was, wenn sie schon im Speicher vorliegt ? Vielleicht ist meine Idee mit einer Textur auch total hinrissig... :lol:

Gebt mir einen Schubser in die passende Richtung, ich bin willens genug, selbst loszulaufen :mrgreen:

Thx,

Olaf


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 27, 2007 07:48 
Offline
DGL Member

Registriert: Do Mai 30, 2002 18:48
Beiträge: 1617
ganz ohne umweg sehe ich jetzt keinen weg, aber Du könntest z.B. das Bild in den Framebuffer legen (z.B. per http://wiki.delphigl.com/index.php/glCopyPixels ) und dann mit OpenGl das darüber rendern, was Du möchtest.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 27, 2007 08:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Eine solche Möglichkeit (nur 1-2 Elemente mit OpenGL zu zeichnen) wird es nicht geben.

Texturen wären eine andere Möglichkeit. Und ja üblicherweise kommen diese von der Festplatte. Allerdings werden diese vorher in den Speicher geladen und von dort aus an OpenGL übergeben. Also Theoretisch musst du nur das Laden von der Platte sein lassen und statt dessen den Speicher des Bitmaps benutzen. Aber alternativ kannst du auch mal den Textuern Loader anschauen. Mit dem kannst du auch direkt aus einem TBitmap laden.

POT Texturen sind nicht unbedingt zwingend vorrausgesetzt. Je nachdem wie groß deine Texturen sind kannst du auch als Target GL_TEXTURE_RECTANGLE_ARB benutzen. Dann als Texturkoordinaten direkte Pixelangaben. Also nicht zwischen 0 und 1. Wenn deine Anwendung auf älterer Hardware laufen können soll musst du in jedem Falle auch noch überprüfen ob die passende Extension gesetzt ist. Also GL_ARB_texture_rectangle, GL_EXT_texture_rectangle oder GL_NV_texture_rectangle. Das ist 3 Mal das selber bis auf die Unterstützung in Shadern. Aber das ist für dich derzeit egal.

Allerdings solltest du das nur so machen wenn die Texturen nicht größer sind als sagen wir mal 2000 Pixel sind. Ansonsten würde ich in jedem Falle empfehlen die Texturen zu zerschneiden.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 27, 2007 14:40 
Offline
DGL Member

Registriert: Do Jul 26, 2007 14:55
Beiträge: 7
Danke Leute, ihr habt mich echt weitergebracht !

Nachdem meine Landkarte gezeichnet ist, erzeuge ich ein 2^n-TBitmap (in diesem Fall 512x512). Ist das TBitmap größer als das MapSheet, wäre das nicht schlimm - es stünde dann halt nur rechts und unten "über".

Code:
  1. TB:=TBitmap.Create;
  2. TB.Width:=MapSheet.Width;  //MapSheet ist ein 512x512er TTabsheet
  3. TB.Height:=MapSheet.Height;
  4. TB.PixelFormat:=pf24Bit;      //24Bit muß sein, hab ich in einem Tut gelesen


In dieses TBitmap "Blt"e ich per GDI den Inhalt meines TabSheets (und jetzt weiß man auch, warum ein zu großes Bitmap nicht stören würde):

Code:
  1. DC:=GetDC(MapSheet.Handle);
  2. BitBlt(TB.Canvas.Handle,0,0,TB.Width,TB.Height,DC,0,0,SRCCOPY);
  3. ReleaseDC(MapSheet.Handle,DC);


Jetzt noch ne Textur draus machen (mit dieser höchst praktischen glBitmap wirklich kein Problem), das TBitmap brauchen wir anschließend nicht mehr und wir entsorgen es gleich wieder:

Code:
  1. Texture:=TglBitmap2D.Create;
  2. Texture.Format:=tfCompressed;
  3. Texture.AssignFromBitmap(TB);
  4. Texture.GenTexture;
  5. TB.Free;


Anschließend hat mein rotierendes Quadrat plötzlich eine Landkarten-Textur, wie man am anhängenden Screenshot sehen kann 8)

Das Problem ist nun: Lasse ich den OpenGL-Context als sichtbaren Context, dann muß ich alle Funktionen des Kartenmaterial-Controls nachbilden (MouseMove, Zoom-Funktionen, Bewegen mit der Maus etcpp). Aber: Wenn es so herum wie jetzt geht, dann auch bestimmt anders herum ;) Also lasse ich OpenGL in ein TBitmap rendern und das Ergebnis wird per SRCAND auf das Mapsheet ge"Blt"ed.

Aber das versuche ich am Montag, sollte ich dafür Zeit finden.

Euch erstmal Danke für den Schubser in die richtige Richtung !

Olaf


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 27, 2007 15:16 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
tfCompressed würde ich für solche feinen Strukturen wie eine Landkarte nicht empfehlen. Denn dadurch wird die Textur auf der Grafikkarte komprimiert. Außerdem kostet das auch etwas Zeit.

Zum Graben solltest du dir mal die Funktion glReadPixels oder aber die Methode GrabScreen der TglBitmap2D Klasse anschauen. Ich würde dir aber empfehlen sparsam damit umzugehen, denn diese Operationen kosten etwas Zeit.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jul 31, 2007 12:25 
Offline
DGL Member

Registriert: Do Jul 26, 2007 14:55
Beiträge: 7
Da taucht eine interessante Frage auf:

Ich habe es hier mit Landkarten zu tun - ergo auch mit Geo-Koordinaten im Float-Format (53.925°N, 9.815°E)... Diese Koordinaten muß ich nun erstmal in Pixel-Koordinaten umwandeln lassen (ähnlich wie ScreenToClient im GDI), dann weiß ich, wo auf meinem Canvas diese Position liegt (nehmen wir an, X=200, Y=100).

Für OpenGL müßte ich diese Position in einen Wertebereich von 0.0...1.0 umrechnen lassen. Sicherlich nicht sooo schwierig, aber: Ich glaube, OpenGL kann das besser. Wie bringe ich OpenGL dazu, das ich direkt "53.925, 9.815, 0" an glVertex3f() übergeben kann und mein Punkt an der richtigen Stelle landet ?

Habe schon mit glOrtho und glViewport herumgespielt, schaffe es aber irgendwie nicht, "auf den Zug aufzuspringen".

Übrigens: In meinem Anwendungsfalle kommt es nicht auf FPS an. Aber es kann nicht angehen, das ich für das Zeichnen von 2000 Punkten mit den Karteneigenen Routinen fast 15 Sekunden warten muß (und die Dauer nimmt exponentiell mit der Anzahl der Punkte zu).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jul 31, 2007 12:48 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
Brauchst du 3D?
Im 2D ist dies kein Problem, da kannst du dann direkt mit den Pixelwerten arbeiten.
Und wie du auf die grossen Zahlen kommst ist mir auch fraglich. Renderst du die Punkte/Geraden etwa in die Textur ein?

_________________
Steppity,steppity,step,step,step! :twisted:
❆ ❄ ❄ ❄ ❅ ❄ ❆ ❄ ❅ ❄ ❅ ❄ ❅ ❄ ❄
❄ ❄ ❄ ❅ ❄ ❄ ❄ ❅ ❄ ❄ ❆ ❄ ❄


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jul 31, 2007 13:13 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Koordinaten: 53.925, 9.815 kannst du immer an glVertex übergeben. Du musst aber darauf achten, dass der Rest deiner Darstellung auch dazu passt. Achte vor allem darauf, dass du eventuelle Transformationen, Skalierungen oder Rotationen mit berücksichtigst. Mit glOrtho sorgst du lediglich dafür, dass du zum Beispiel den Bereich 53.0 - 55.0 und 9.0 - 11.0 siehst. glViewPort setzt nur den darzustellenden Bereich (auf dem Fenster). Das verändert aber nicht die Darstellung in OpenGL.

Punkte: 2000 Punkte sollten eigentlich nicht so tragisch sein. Da würde mich aber mal interessieren wie du diese zeichnest. Evtl auch Pointsmooth deaktivieren falls du es aktiviert haben solltest. Könnte mir vorstellen, dass das ein oder andere System das nicht so mag. Pointsmooth ist aber per default aus. Also falls du es nicht angemacht hast dann vergiss das was ich darüber gesagt habe.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jul 31, 2007 13:41 
Offline
DGL Member

Registriert: Do Jul 26, 2007 14:55
Beiträge: 7
Haaaaalt :) Hier läuft was mißverständlich...

Ich habe hier das Problem, das die Bibliothek für die Kartendarstellung echt massive Probleme mit größeren Mengen an Punkten hat... Sie besitzt zwar die Möglichkeit, zu sagen "Zeichne an X,Y das Symbol [Bitmap]" - doch bei 2000+ solcher Symbole wird es Laufzeitmäßig echt häßlich, ab 5000+ unzumutbar. Ich tippe mal auf eine höchst unzulängliche interne Listenverwaltung... ;)

Nun, das Kartenzeichnen selbst muß ich weiterhin der Bibliothek zu überlassen - da kann ich ohnehin nicht eingreifen und so lange es dauert, dauert es nun mal. Aber das Zeichnen der Symbole und der Linien zu Verbindung der Punkte, das könnte ich tun. Wie in den Tutorials so schön beschrieben haben Grafikkarten von heute ungeheure Power, was sowas angeht - man wäre dumm, würde man die Leistung nicht nutzen. So kam ich auf OpenGL und ich wurde bisher nicht enttäuscht.

Sorry, wenn mißverständlicherweise 'rüberkam, das das Zeichnen mit OpenGL 15 Sekunden dauern würde.

[Edit]
Die Funktion von glViewPort habe ich jetzt verstanden - die von glOrtho noch nicht. Nehmen wir folgendes Setup an:

Code:
  1.  
  2. glOrtho(9.0, 10.0,52.0,53.0,0.0,1000.0);
  3. glViewPort(0,0,640,480);
  4.  


Zeichne ich mein Quadrat so:
Code:
  1.  
  2. glVertex3f(9.0, 52.0, 0);
  3. glVertex3f(9.0, 53.0, 0);
  4. glVertex3f(10.0, 53.0, 0);
  5. glVertex3f(10.0, 52.0, 0);
  6.  


dann sehe ich nichts. Nehme ich wieder Werte zwischen 0 und 1, ist mein Quadrat zu sehen. Wo mache ich den Denkfehler ?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 02, 2007 12:19 
Offline
DGL Member

Registriert: Do Jul 26, 2007 14:55
Beiträge: 7
Niemand eine Idee ? :( Kann ich kaum glauben :wink:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 02, 2007 12:36 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Deine nahe Clippingplane liegt bei 0.0, und wenn du dein Quadrat bei 0.0 renderst wird dieses geclippt ist also nicht sichtbar. Da Ortho eine 2D-Projektion ist spielt es aber keine Rolle ob du auf der Z-Achse bei 0, 1 oder weiter hinten bzw. vorne renderst solange du in zNear und zFar bleibts.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 02, 2007 12:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Okay. Kleiner Hinweis. Du solltest in einem Edit keine Frage posten. Ich sehe deine Frage nämlich jetzt zum ersten Mal. ;) Sonst hätte ich dazu schon früher was gesagt.

Und sonst würde ich die 52 und die 53 bei glOrtho tauschen. Denn es heißt. Left, Right, Bottom und Top.

Außerdem stelle bitte sicher, dass du dich auch auf der Projectionsmatrix befindest. Und ich würde glViewPort sicherheitshalber vorher aufrufen. Also dann eher so.

Zitat:
glViewport(0, 0, 640, 480);

glMatrixMode(GL_Projection);
glLoadIdentity;
glOrtho(9.0, 10.0, 53.0, 52.0, 0, 1);

glMatrixMode(GL_Modelview);
glLoadIdentity;


Für 2D kannst du auch glVertex2f benutzen damit wird Z intern so gesetzt, dass es immer sichtbar ist.

Ich denke das sollte eigentlich ausreichen.

PS: für später solltest du dann auch noch ein richtiges Seitenverhältniss bei glOrtho angeben. Derzeit sollte das Bild dann in die Breite gezogen werden.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.023s | 17 Queries | GZIP : On ]