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

Aktuelle Zeit: Di Jul 15, 2025 16:57

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



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 13:44 
Offline
DGL Member
Benutzeravatar

Registriert: So Jan 07, 2007 21:26
Beiträge: 130
Wohnort: mal hier mal da mal irgendwo
Hi Leute,

ich bin zur Zeit total am Verzweifeln.
Ich versuche ein TBitmap in OpenGL als Textur zu laden,
allerdings bekomme ich beim generieren der Textur immer einen Adressfehler :<
Die Bitmap erzeuge ich dynamisch da ich den Bilddaten eines bestimmten Fensters als Textur haben möchte [zu testzwecken hab ich erstmal den ganzen Desktop genommen]

Hier mal die entstandene Prozedur:
Code:
procedure loadScreenTex(var tid: GLuint);
var b: TBitmap;
    d: hdc;
begin
  glGenTextures(1, @tid);
  glBindTexture(GL_TEXTURE_2D, tid);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  b := TBitmap.Create;
  try
    b.Width := 1600;
    b.Height := 900;
    d := getDc(GetDesktopWindow);
    try
      bitBlt(b.canvas.Handle, 0,0,1600,900,d,0,0,srccopy);
    finally
      releasedc(GetDesktopWindow, d);
    end;
    glTexImage2D(GL_TEXTURE_2D, 0, 3, 1600, 900,0, GL_RGB, GL_UNSIGNED_INT, b.ScanLine[0]);
  finally
    b.Free;
  end;
end;


Vorher hab ich das einfach gemacht in dem ich es als Bitmap[Datei] abgespeichert hab und dann einen Loader verwendet hab.
Das ist aber eine äußerst unschöne "Lösung" =/

Was mach ich falsch?

mfg bubble

_________________
Wenn Worte nichts als Worte sind,
dann müssen's Steine sein!
Solange - bis sie pleite sind - schmeißt Fensterscheiben ein!

- Fidl Kunterbunt -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 14:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Auf die schnelle würde ich Tippen das es @b.ScanLine[0] heißen muss. Also du brauchst einen Pointer auf den erste Pixeln, nicht den ersten Pixel.

Aber die Delphi-Experten können da sicher mehr zu sagen. :)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 14:20 
Offline
DGL Member
Benutzeravatar

Registriert: So Jan 07, 2007 21:26
Beiträge: 130
Wohnort: mal hier mal da mal irgendwo
Coolcat hat geschrieben:
Auf die schnelle würde ich Tippen das es @b.ScanLine[0] heißen muss. Also du brauchst einen Pointer auf den erste Pixeln, nicht den ersten Pixel.

ScanLine liefert einen Pointer zurück :)

Was mir grad noch auffällt, was noch erwähnenswert wäre ist, dass jeder Pixel 32bit groß ist.

_________________
Wenn Worte nichts als Worte sind,
dann müssen's Steine sein!
Solange - bis sie pleite sind - schmeißt Fensterscheiben ein!

- Fidl Kunterbunt -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 14:30 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Zitat:
Was mir grad noch auffällt, was noch erwähnenswert wäre ist, dass jeder Pixel 32bit groß ist.
Das solltest du dann deinem Bitmap aber auch sagen. :P

Dein Bitmap benötigt in jedem Fall ein B.PixelFormat := pf32Bit. Ansonsten existieren deine Scanlines nicht, da sonst das Bitmap in irgendeinen grafikspezifischen Format auf der Karte selbst (wenn möglich) abgelegt wird. Scanline ist dann auch nicht zulässig.

Außerdem noch folgende Punkte/Hinweise.
- Scanline[0] ist nicht die oberste Zeile sondern die unterste Zeile. Somit das Ende deines Speichers. Richtig ist Scanline[Height -1]. Wobei es laut Spec auch sein könnte, dass Scanline[0] der Anfang ist (Kam bisher aber nie vor). Du könntest da eventuell sogar beide Pointer auslesen und den kleineren von beiden übergeben.

- UNSIGNED_INT ist falsch, da die Größe deiner einzelnen Texelkomponenten (Rot, Grün und Blau) nicht jeweils 32 Bit groß sind. Also ist UNSIGNED_BYTE das Richtige, da die einzelnen Komponenten jeweils 8 Bit groß sind. Ansonsten würde OpenGL viel mehr Daten lesen wollen als vorhanden.

- Bitmap sind als BGR abgelegt. Also solltest du GL_BGR als Format benutzen.

- Als internes Format für die Textur würde ich lieber GL_RGB8 anstelle von 3 benutzen. Das lässt dem Treiber keinen interpretationsraum. Zu mal ich meine auch irgendwann mit 3 schon mal Probleme bekommen zu haben.

@Coolcat: Das sollte eigentlich nicht nötig sein, da Scanline direkt einen Pointer zurückliefert und glTexImage2D direkt einen Pointer erwartet. Wenn man den Pointer zwischenspeicher ist es sogar nicht nur unnötig sondern falsch, da man dann den Pointer der Variable bekommen würde. Aber dein Post hat mich dazu gebracht, dass ich einen Punkt noch ausführlicher schreiben muss.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 14:58 
Offline
DGL Member
Benutzeravatar

Registriert: So Jan 07, 2007 21:26
Beiträge: 130
Wohnort: mal hier mal da mal irgendwo
Lossy eX hat geschrieben:
Dein Bitmap benötigt in jedem Fall ein B.PixelFormat := pf32Bit. Ansonsten existieren deine Scanlines nicht, da sonst das Bitmap in irgendeinen grafikspezifischen Format auf der Karte selbst (wenn möglich) abgelegt wird. Scanline ist dann auch nicht zulässig.

Pixelformat ist bei der Bitmap pfDevice und da ich ja an sich davon ausgehen kann das Ottonormalverbraucher 32 Bit Farbtiefe eingestellt hat sind es ja 32 Bit :]

Lossy eX hat geschrieben:
- Scanline[0] ist nicht die oberste Zeile sondern die unterste Zeile. Somit das Ende deines Speichers. Richtig ist Scanline[Height -1]. Wobei es laut Spec auch sein könnte, dass Scanline[0] der Anfang ist (Kam bisher aber nie vor). Du könntest da eventuell sogar beide Pointer auslesen und den kleineren von beiden übergeben.

Das erklärt natürlich so einiges, warum ich nie so richtig mit ScanLine klar gekommen bin :roll:

Auf jedenfall funktionierts jetzt. :]

Eine aber noch:
Nun ist es aber so das die einzelnen Kanäle an sich nach ARGB sortiert im Speicher liegen, wie händel ich das am besten? Vorher die Kanäle vertauschen find ich für das was ich machen will zu aufwendig.
Also mein Ziel ist es, über den Fragment Shader einfach nur nach einem bestimmten Muster in der Textur zu suchen und alle Positionen der Vorkommnisse in eine Textur speichern/rendern und das dann wieder auszuwerten.
OpenGL verwände ich in dem Fall nur weil die Grafikkarte das ja eigentlich recht gut parallelisieren können müsste, oder liege ich komplett auf dem Holzweg?
(Transform-Feedback möchte ich nicht verwenden weil ich die Anforderungen recht niedrig halten möchte)

Edit: Noch eine Sache, es ist ja recht selten der Fall, dass die Auflösung der Bilddaten eines Fensters Power of 2 ist, wenn ich nun aber - aus Kompatiblitätsgründen - in OpenGL mit Power of 2 arbeiten will, fehlt mir jeglicher Ansatz. =|
mfg bubble

_________________
Wenn Worte nichts als Worte sind,
dann müssen's Steine sein!
Solange - bis sie pleite sind - schmeißt Fensterscheiben ein!

- Fidl Kunterbunt -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 16:08 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
thebubble hat geschrieben:
Pixelformat ist bei der Bitmap pfDevice und da ich ja an sich davon ausgehen kann das Ottonormalverbraucher 32 Bit Farbtiefe eingestellt hat sind es ja 32 Bit :]

Netter Versuch. Aber nein. Die Farbtiefe die du in deinem Windows eingestellt hast hat damit nur sekundär zu tun. Bitmaps werden in 2 Arten unterschieden. DIB (Geräteunabhängige) und DDB (Geräteabhängige). Geräteunabhängige Bitmaps werden von der GDI komplett verwaltet. Entsprechend liegen die Bitmapdaten komplett im Speicher von Windows/deiner Anwendung. Mit Geräteabhängigen Bitmaps ist es aber so, dass die Bitmaps ein Format von der Grafikkarte bekommen. Alle Zeichenoperationen laufen dann über die Grafikkarte. Das kann das Ganze massiv beschleunigen. Sorgt aber auch dafür, dass die Bitmaps in keinem herkömmlichen Format mehr im Speicher liegen. Teilweise ist es sogar so, dass die Bitmap nicht mehr im RAM sondern im GRAM liegen. DDBs können auch andere Größenbeschränkungen als DIBs haben.
Wenn du ein Bitmap erstellst ist es automatisch DDB/pfDevice. Mit dem Setzen des Bitmap.HandleType kannst du direkt die Art des Bitmaps setzen. Sobald du das Pixelformat auf einen fixen Wert setzt wird es automatisch DIB. Setzt du bei einem Bitmap als HandleType DDB wird das Format wieder pfDevice. Nur weil es bei dir jetzt geht heißt es nicht, dass es überall so sein muss. Es kann auch passieren, dass ein System sich da mehr einmischt als das bei einem anderen der Fall ist.

thebubble hat geschrieben:
Nun ist es aber so das die einzelnen Kanäle an sich nach ARGB sortiert im Speicher liegen, wie händel ich das am besten? Vorher die Kanäle vertauschen find ich für das was ich machen will zu aufwendig.

Die Kanäle werden doch bereits durch glTexImage getauscht. Du beschreibst das interne Format (das der Textur) und das Format + Type (Format der Daten). Je nachdem was du bei dem Texturformat setzt wird es automatisch konvertiert. Wobei die Konvertierung im Treiber durchaus zeit benötigt. Wenn die Farben egal sind, dann kannst du bei glTexImage auch bewusst sagen, dass das Bitmap im Format RGB gespeichert ist. Dann konvertiert der Treiber nicht und du musst es im Shader berücksichtigen. Dem sollte es aber total egal sein wärend der Treiber durchaus etwa Zeit brauchen kann. 32Bit wird normal auch besser verarbeitet als 24Bit. Selbst, wenn der Alpha nicht gesetzt wurde.

thebubble hat geschrieben:
Edit: Noch eine Sache, es ist ja recht selten der Fall, dass die Auflösung der Bilddaten eines Fensters Power of 2 ist, wenn ich nun aber - aus Kompatiblitätsgründen - in OpenGL mit Power of 2 arbeiten will, fehlt mir jeglicher Ansatz. =|

Setz es doch einfach vorraus. Also ich meine es überprüfen und vorhandensein erzwingen. Mittlerweile also nach mehr als 6 Jahren sollte das wirklich jedes System können. Speziell, wenn du auf Mipmaps verzichtest sollten das auch die älteren Modelle hinbekommen. Ansonsten (oder auch, wenn die maximalgröße der Textur überschritten wird) musst du die Textur wohl oder übel zerlegen. Je nachdem wie viel Speicher du benutzen willst können es auch etwas größere Stücke sein.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 16:56 
Offline
DGL Member
Benutzeravatar

Registriert: So Jan 07, 2007 21:26
Beiträge: 130
Wohnort: mal hier mal da mal irgendwo
Aha wieder was dazu gelernt :]

Naja mir ist grad aufgefallen, dass mir das mit OpenGL gar nichts bringt. Meine GDI Variante mit GetPixel(dc, x,y) dauert ~200ms, allein OpenGL zu initialisieren dauert aber schon ~400ms ...
Quasi kann ich das ganze sein lassen =/

Trotzdem Danke für die Hilfe und die Aufklärung!

mfg bubble

_________________
Wenn Worte nichts als Worte sind,
dann müssen's Steine sein!
Solange - bis sie pleite sind - schmeißt Fensterscheiben ein!

- Fidl Kunterbunt -


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 17:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
GetPixel? Also das ist das Letzte was du benutzen solltest. Nimm Scanline dann bist du bei eine Bruchteil der Zeit (je nach Intensität der Nutzung). Wenn du oft zwischen den Zeilen springen musst, dann solltest du die Scanlines in eine Array zwischenspeichern, da Scanlines recht viel macht. Da es aber normal eine ganze Zeile abgearbeitet wird relativiert sich das wieder. Im Zweifel kann man sich auch den Anfangspointer geben lassen und dann die Offsets der Zeilen selber berechnen. Dann spart man noch mal ein paar Millisekunden.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: TBitmap als Textur verwenden
BeitragVerfasst: Di Feb 08, 2011 20:40 
Offline
DGL Member
Benutzeravatar

Registriert: So Jan 07, 2007 21:26
Beiträge: 130
Wohnort: mal hier mal da mal irgendwo
Naja, weil ich halt in ScanLine wie man ja gesehen hat noch nicht wirklich Erfahrung hatte hab ichs erstmal mit den mir vertrauten Methoden gemacht.
Der Umstieg erfolgt gerade :>

_________________
Wenn Worte nichts als Worte sind,
dann müssen's Steine sein!
Solange - bis sie pleite sind - schmeißt Fensterscheiben ein!

- Fidl Kunterbunt -


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 10 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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 15 Queries | GZIP : On ]