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

Aktuelle Zeit: Fr Jul 18, 2025 21:08

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 20 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
BeitragVerfasst: Mi Jan 17, 2007 11:57 
Offline
DGL Member

Registriert: Mo Jun 12, 2006 14:47
Beiträge: 75
Programmiersprache: Object FPC
Hallo, Ich Versuche gerade verzweifelt Bilder mit hilfe eines TThread in Delphi zu Laden.

Ich habe es auch schon dahingehend geschafft das Mein Programm alle Daten sammelt und dann mit diversen OpenGl Befehlen die Textur auch Tatsächlich erzeugen kann.

Das Rendern ist dann kein Problem.

Mein Problem ist aber nun , das wenn man die OpenGl Befehle nutzt man den Hauptthread anhalten mus. ( Was man mit Synchronize macht ). Nur hat das dann genau den Effeckt den ich nicht haben will.

Denn dann wird ja die Ganze Anwendung angehalten.

Gibt es also eine Möglichkeit eine Texture ( Bei mir sind das immer JPG Dateien ) so zu laden das ich dann diesen GLuint Wert habe den ich mit

GlBind(GL_texture_2d, wert );

Einbinden kann.

Ohne das ich dazu meine Ganze Hauptanwendung anhalten mus ?

Ich habe auch irgendwo mein Sample mit dem man sehen kann wies nicht geht. Wenn das jemanden Hilft lade ich es noch hoch.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 17, 2007 13:52 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 02, 2002 15:41
Beiträge: 867
Wohnort: nahe Stuttgart
Ohne ehrlich gesagt viel Ahnung von Threads zu haben, vermute ich mal, dass dir Critical Sections:
http://wiki.delphigl.com/index.php/Tuto ... .C3.BCtzen
weiterhelfen könnten. :)

MfG


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 17, 2007 16:12 
Offline
DGL Member

Registriert: Mo Jun 12, 2006 14:47
Beiträge: 75
Programmiersprache: Object FPC
Lieder Nein.

Die Critical Sections sorgen dafür das SICHER nur 1 Thread auf etwas zugreifen kann.

Ich habe aber genau das andere Problem.

Ich will ja das 2 Threads das selbe nutzen, im Prinzip.

Ich habe eich mal mein Demo Programm zu diesem Problem Hochgeladen.

da könnt ihr mein Problem sehen.


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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 17, 2007 16:24 
Offline
DGL Member

Registriert: Sa Okt 22, 2005 20:24
Beiträge: 291
Wohnort: Frauenfeld/CH
OpenGL Befehle in verschiedenen Threads sind relativ gefährlich soviel ich weiss, bzw das geht nicht gut. Weil wenn du dann plötzlich irgendwelche Befehle benutzt während du renderst (im selben context) dann funktioniert das natürlich nicht richtig.

_________________
bester uo-shard: www.uosigena.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 17, 2007 16:40 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
OpenGL Befehle in unterschiedlichen Threads sind nicht nur gefährlich sondern gar nicht gültig. Mit anderen Worten du kannst die Texturdaten zwar laden aber erstellen musst du die Textur immer in dem Thread in dem du auch OpenGL initialisiert hast. Da wirst du auch nichts dran ändern können.

Dein Problem ist die Methode gluBuildMipMaps. Diese ist so etwas von lahm, dass es schon fast nicht mehr geht. Wenn du die Textur mittels glTexImage2D hochlädst (oder einen Loader benutzt der das so macht) dauert das nicht mal 1-2 ms. Dann sollte das auch alles überhaupt kein Thema sein.

Eine CriticalSection würde in dem Falle auch nicht unbedingt etwas nützen, da der die Textur dann immer noch aus dem Thread erstellt werden würde. Also ist das einfachste Synchronize. Das würde dann auch schön sauber zwischen den Idles aufgerufen werden.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 17, 2007 17:08 
Offline
DGL Member

Registriert: Mo Jun 12, 2006 14:47
Beiträge: 75
Programmiersprache: Object FPC
Der Befehl glTexImage2D ist mir Neu,

Gitbs da irgendwo ein Sample, Demo Proggy ?

Da ich die Bidler die ich LAden Will ja Beliebig vorher bearbeiten Kann ( über Delphi Programme die ich dann schreiben müste ) ist das ja kein Problem.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 17, 2007 19:07 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also die gluBuildMipMaps2D benutzt intern auch nur die glTexImage2D. Allerdings berechnet er intern auch die MipMaps auf der CPU. Seit knapp 10 Jahren sind dazu aber die Grafikkarten in der Lage weswegen diese Methode vollkommen unnützt geworden sein sollte. Wie man ja sieht ist sie es leider nicht. ;)

Die Parameter sind bei beiden Methoden relativ gleich weswegen es da nur kleine Probleme geben sollte. Aber im falles des nicht wissen kannst du gerne unser Wiki befragen. glTexImage2D, gluBuild2DMipmaps

Anderenfalls könntest du dir auch mal anschauen wie ich das in meiner glBitmap gemacht habe. Aber da dir glTexImage2D nichts sagt hat denke ich nicht, dass dir das viel helfen wird.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 17, 2007 20:44 
Offline
DGL Member

Registriert: Mo Jun 12, 2006 14:47
Beiträge: 75
Programmiersprache: Object FPC
Ahh du bist also dieser Held ;)

Deine GlBitmap.pas nutze ich auch, aber nur wenn ich Transparente Images Brauche.

In Anlehnung an diese habe ich nun meine Textures.pas umgeschrieben. Im Prinzip ergänzt sich da ja nur diese 2 mal 0

Und er Lädt tatsächlich schneller, nur Lädt er nicht das Bild :(

Egal ob mit oder ohne Synchronized kommt immer nur ein Weises nichts zum Vorschein.

Habe das Traurige Ergebniss wieder in den Anhang gepackt.


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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 17, 2007 20:53 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
Siehe:
Lossy eX hat geschrieben:
OpenGL Befehle in unterschiedlichen Threads sind nicht nur gefährlich sondern gar nicht gültig. Mit anderen Worten du kannst die Texturdaten zwar laden aber erstellen musst du die Textur immer in dem Thread in dem du auch OpenGL initialisiert hast. Da wirst du auch nichts dran ändern können.

Sowie: http://www.delphigl.com/forum/viewtopic.php?t=4751

Hatte damals auch keine Lösung gefunden, habe dann nur die Daten in den Speicher geschoben und im Mainthread sie zu OpenGL geschoben.

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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jan 18, 2007 09:43 
Offline
DGL Member

Registriert: Mo Jun 12, 2006 14:47
Beiträge: 75
Programmiersprache: Object FPC
Hi i0n0s,

Das das nicht Geht ist Mittlerweile leider Klar.

Es geht nun um den Ersatz, bzw das Schnelle Laden, denn der Mipmapp befehl dauert ja definitiv zu lang.

Mein Problem ist nu das ich den Vorschlag von Lossy eX nicht umsetzen kann.

Bei mir lädt er selbst wenn ich Synchronized mache immer nur ne weise Textur.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jan 18, 2007 10:45 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also eine weiße Textur wird nicht hochgeladen. Das bedeutet normal, dass der Texturname zwar erstellt wurde aber beim Hochladen der Daten etwas schief gelaufen ist. gluBuild2DMipMaps ist so frei und verändert von sich aus die Texturdaten falls dessen Größe keine Potenz von 2 ist. Die Methode glTexImage2D hingegen allerdings nicht. Wenn deine Grafikkarte kein OpenGL 2.0 oder Non Power Of Two Texturen unterstützt dann bleibt sie halt einfach weiß. Ändere mal die Größe der Textur auf eine Potenz von 2. (64, 128 256 etc.)

Außerdem werden jetzt zwar keine MipMaps mehr erstellt aber du hast in der Textures immer noch das GL_LINEAR_MIPMAP_LINEAR als MinFilter gesetzt. MipMaps zu benutzen obwohl sie nicht erstellt wurden führt auch dazu, dass du keine Textur siehst. Da hast du jetzt entweder die Möglichkeit deine MipMaps zu deaktivieren oder von der Grafikkarte erstellen zu lassen. Beim Deaktivieren solltest den MinFilter auf GL_LINEAR stellen. Beim automatischen Erstellen genügt es einen zusätzlichen Parameter zu setzen. Allerdings auch nur sobald OpenGL 1.4 oder die Extension GL_SGIS_generate_mipmap unterstützt wird. Hier mal die Pasage aus der glBitmap.
Code:
  1.     if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap)
  2.       then glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)


Danach sollte dein Textur eigentlich sichtbar sein.

Allerdings habe ich mal den Code halbwegs genau angeschaut und da muss ich noch ein paar Anmerkungen zu loswerden. Das hast du jetzt davon. Warum hast du auch Fehler. :-P
1. Du benutzt genau wie auch die original Textures das Texturformat GL_RGBA. Bitmaps befinden sich aber grundsätzlich immer im Format GL_BGRA. Ab OpenGL 1.2 wird dieses auch unterstützt. Was eigentlich nur bedutet, dass du die Umformung der Daten gar nicht selber machen musst sondern einfach das andere Format an OpenGL übergibst. Das ist Code und Zeit die du so sehr einfach einsparen kannst. Abgesehen davon übergibst du auch ein GL_RGBA obwohl du aber gar keinen Alphakanal hast belegt dieser trotzdem Speicher auf der Grafikkarte.
2. Deine Variablen und Objekte sind seltsam. Du benutzt in einem Thread ein globales Bitmap. Was du im Thread erstellst und im Synchronize wieder frei gibst. Das ist nicht sonderlich gut. Besser wäre in etwa so etwas.
Code:
  1.   Tloader = Class(TThread)
  2.     fData: ... ;
  3.     fWidth, fHeight: ... ;
  4.   protected
  5.     proccedure Execute; override; // die hat normal nichts im public zu suchen
  6.   end;
  7.  
  8. Procedure Tloader.Execute;
  9. var
  10.   bmp: TBitmap;
  11. begin
  12.   // Bild laden
  13.  
  14.   // Daten aus Bitmap in internen Speicher kopieren, Größen (fWidth, fHeight) setzen
  15.  
  16.   // Bitmap kann und sollte hier schon wieder frei gegeben werden.
  17.  
  18.   // Synchronize aufrufen und Textur erstellen
  19.  
  20.   // Daten Freigeben
  21. end;

Normal solltest du deine Daten immer dort Frei geben wo du sie erstellst. Dadurch kannst du Fehler vermeiden und es ist nicht so verzwickt/verschachelt. Jeder hätte so seine eigene Aufgabe. Und ich bin überhaupt kein Fan von globalen Variablen. Da käme man leicht in die Versuchung Dinge doppelt zu benutzen etc.
3. Hat es einen tieferen Sinn warum du dein Bild erst einmal in einen MemoryStream kopierst?
4. Beim Erstellen der Textur rufst du "glDeleteTextures(1, @Texture);" auf. Das halte ich für Mutig. Die Variable Textures ist eine Lokale Variable. Sie ist zwar deklariert aber noch nicht initialisiert worden. Somit ist dessen Inhalt nicht vorhersehbar. Es könnte also sein, dass sich dort an der Speicherstelle der Name(ID) einer früheren Textur befinden. Dieses würdest du so mal eben löschen. Ich würde das delete weglassen und als erstes die Variable Textures auf 0 setzen. Damit bist du auf jeden Fall auf der sicheren Seite.

So ich denke das sollte für den Anfang ausreichen.

PS: Als Held würde ich mich jetzt nicht bezeichnen wollen. Ich hatte nur vor einige Missstände aus der Welt zu schaffen. Und das primär in erster Linie auch nur für mich selber. Aber es freut mich zu hören, dass es gefällt. Das interpretiere ich da mal rein. ;)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jan 18, 2007 14:49 
Offline
DGL Member

Registriert: Mo Jun 12, 2006 14:47
Beiträge: 75
Programmiersprache: Object FPC
Hi Lossy eX

Also spätestens jetzt bist du mein held, denn es Funktioniert.

Zu meiner Entschuldigung :

Also wie du richtig bemerkt hast ist da einiges nicht so wie es ein guter Programmierer machen würde. Das ist zum Teil absicht und zum Teil der Grund das ich das Sample mitten in der Nacht ( viel zu müde ) so zusammengehackt habe das es Eben Genau den Fehler Erzeugt den ich gerade habe.

Mit TThread kenn ich mich allerdings wirklich nicht aus.( werde das Execute Protected machen )

In Wirklichkeit ist dieses Problem ein TeilProblem in einem Riesen Programm das ich gerade angefangen habe. Und Tmemorystream ist es weil ich die Bilddaten aus einer Datenbank auslese und sie mir da als Streams übergeben werden. Das in dem Sample hier das natürlich keinen Sinn macht ist mir Klar.

Globale Variablen Kann ich Ebenfalls nicht ausstehen und versuche meistens auch alles nur erdenkliche um sie zu verhindern.

Da ich OpenGL im prinzip als 2D Engine Nutze und die Bilder immer in Maximaler Auflösung darstelle Brauche ich Glaubig das Mipmapping nicht, habe es also Deaktiviert ;)

Was deinen Optimierungsansatz angeht, so hast du mich Echt Neugirig gemacht, Verstehn wies Geht tu ich aber leider net. ( Vorallem wil ich den Alpha Kanal gar nicht vor habe zu nutzen, und wenn ich mir Umrechnungen Sparen kann dann mach ich das doch gern ;) ).

Was Das Restliche Chaos in Textures.pas angeht so mus ich Zugeben habe ich diese Unit von "wo auch immer" her und hatte sie bis vor 2 Tagen nie aufgemacht oder Editiert. Werde aber auch mal einen Kritischen Blick drüber werfen, denn das Freigeben erscheint mir auch ein wenig heftig.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jan 18, 2007 16:25 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Zitat:
Das ist zum Teil absicht und zum Teil der Grund das ich das Sample mitten in der Nacht ( viel zu müde ) so zusammengehackt habe das es Eben Genau den Fehler Erzeugt den ich gerade habe.

Ja so was kenne ich auch. :D

MipMaps: Ja in 2D mit voller Auflösung machen MipMaps keinen wirklichen Sinn. Sie verschwenden nur Speicher. Die habe ich bei mir auch häufiger deaktiviert. Aber sonst sollte man die automatische Generation in jedem Fall der gluBuild2DMipMaps vorziehen. Vor allem wenn man bedenkt, dass bereits meine Uralte TNT2 das konnte. Und sei es nur durch den Treiber emuliert.

Optimierungen: Also wenn du den Alphakanal weglässt dann musst du nichts weiter tun als bei den Daten nur noch 3 Bytes anstelle von 4 Bytes zu sammeln. Also nur noch Rot, Grün und Blau. Entsprechend musst du bei den Formaten die du übergibst dann auch den Alphaanteil weglassen. Der Formatparameter ist der wie es sich in deinen Daten befindet und das interne Format ist das wie es die Grafikkarte intern benutzt.

Wobei RGBA das idealste Format ist. Selbst dann wenn der Alphakanal ungenutzt ist. Aber ATI ist bei RGB etwas langsamer als bei RGBA. NVidia allerdings macht das gar nichts. Aber selbst dann ist ATI immer noch schneller als alles was man in seinem Code machen könnte. Und die Manuelle Umwandlung on BGR in RGB ist mittlerweile absolut nicht mehr notwendig. Aber das hängt von der OpenGL version ab. Aber evtl solltest du dir mal die glBitmap genau anschauen. Denn dort versuche ich schon auf so alles Mögliche zu reagieren bzw übertrage nur das was auch tatsächlich in der Textur vorhanden ist.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jan 18, 2007 16:42 
Offline
DGL Member

Registriert: Mo Jun 12, 2006 14:47
Beiträge: 75
Programmiersprache: Object FPC
Cool thx.

Sag mal das mit dem Power of 2 läst sich nicht irgendwie Umgehen ?

Meine Bilder sind in der Regel 1280*960 das heist ich müste ja dann 2096*1024 nehmen damit das wieder Passt.

von diesen Bildern Lade ich immer so ca. 30 in den Graphikkartenspeicher... ( Wobei wenn das mit dem Laden nun so schnell geht Könnte ich da ja auch nur jeweils 2 haben, das wäre schon mal besser *denk* ... )


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jan 18, 2007 17:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Das ist trotzdem schon ein ganzes Stückchen Holz. Da du die aber nur für 2D zur Darstellung benötigst könntest du auch TextureRectangles benutzen. Dazu gibt es hier auch schon ein paar Themen. Im Groben ist es nur ein anderes Texturetarget und andere Koordinaten. Das Target ist GL_TEXTURE_RECTANGLE_ARB und die Koordinaten sind nicht mehr normalisiert auf 1 sondern gehen nach der Breite und Höhe. Angaben in Pixel sozusagen. Es gibt auch noch jeweils eine Extension von EXT und NV aber die sind fast gleich wie die ARB. Damit hast du keinen Speicherverschnitt mehr.

Du solltest aber Idealerweise non power of two benutzen wenn diese unterstützt werden. OpenGL 2.0 oder die passende Extension.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 20 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 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.009s | 15 Queries | GZIP : On ]