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

Aktuelle Zeit: Fr Jul 18, 2025 21:01

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: Di Jan 30, 2007 15:49 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 15, 2007 16:10
Beiträge: 24
Wohnort: bei Düsseldorf
Hallo , ich mal wieder mit einem Problem:


ich habe es nun soweit ,dass ich ein fbo benutze um dort in eine textur zu rendern, diese soll ausgelesen werden via readpixels (bzw. der buffer) und auf meiner video karte extern ausgegeben werden.

Das klappt leider nicht, und darum habe ich mir eine screenshot funktion gesucht, damit ich kontrollieren kann,ob denn alles richtig ausgelesen wurde und was für daten da sind. (wird als tga gespeichert, funktioniert auch soweit)

Da ich eine Anwendung für TV mache, benötige ich Material im Zeilensprung format.

ich bin dann im wiki über glPixelStorei und dem parameter GL_PACK_SKIP_ROWS gestolpert.

Meine Implementierung sieht wie folgt aus


Zitat:
for (int i=0; i<=iHeight; i=i+2)
{
glPixelStorei(GL_PACK_SKIP_ROWS,i);
}

glReadPixels(0, 0, iWidth, iHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels);


Leider wird eine speicherverletzung verursacht und zwar in meiner glerror check routine.

Nun bin ich mir garnicht mehr sicher, ob es die richtige funktion ist :)

ich möchte jede 2te zeile überspringen, ist dies mit der funktion überhaupt möglich ? sind rows zeilen oder spalten (irgendwie steht beides in leo )? Welche Werte müssen dann in glreadpixels benutz werden für die höhe , der wert des urpsünglichen dimension oder nachdem die zeilen geskippt wurden (also die hälfte?)
wird das auslassen der zeilen vor oder nach dem kopieren gemacht, also werden erstmal alle zeilen kopiert und dann "nachbearbeitet "oder nur die hälfte von vornerein kopiert ?

für Hilfe bin ich wie immer sehr dankbar :)

Grüße

Chris


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 30, 2007 16:16 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Um da mal unser Wiki (Artikel glPixelStore)zu Zitieren.
Zitat:
Diese Werte wurden nur für den Programmierkomfort eingeführt; Sie bieten keine Funktionalität die nicht auch einfach dadurch erreicht werden könnte, indem man den Zeiger erhöht den glReadPixels zurückliefert.


Mit anderen Worten. Das ist lediglich ein Offset in deinem Buffer. Wenn du jetzt also ein Offset setzt aber trotzdem alles (Volle Höhe und volle Breite) liest dürfte es zu Problemen führen, da irgendwo dein Speicher zu kurz ist.

Was die beste Möglichkeit ist um aus FBOs Daten zu ziehen da muss ich passen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 30, 2007 16:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 15, 2007 16:10
Beiträge: 24
Wohnort: bei Düsseldorf
ahh jetzt versteh ich das ganze ! ich habe das ganze wohl falsch verstanden (wollen) . wenn es nur ein anfangs offset ist, ist es wohl nicht zu gebrauchen für mein problem. ich dachte man kann generell sagen welche pixel er lesen soll.


was ist denn (unabhängig von den fbo) die schnellste möglichkeit jede zweite zeile zu lesen?

mehrfaches aufrufen der glReadPixels funktion mit nur einer zeile inhalt ? oder kopieren von alles in ein temporäres array und dann von dort per memcopy kopieren ?


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

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
glReadPixel ist recht langsam. Brauchst du eigentlich die anderen Zeilen aus diesem Bild für das nächste Frame dann eigentlich auch noch? Weil wenn ja. Würde ich sagen. Ganzes Bild lesen und dann entweder so oder so. Wenn du aber dann ein anderes Frame renderst und dann die anderen Zeilen ausließt dann könnte es evtl sogar schon etwas bringen nur jede zweite Zeile zu lesen. Das müsstet du aber mal messen.

Bzw habe ich vor einer Weile etwas gelesen in dem mit PBOs (Pixel Buffer Objects) ein Bild kopiert wurde. Dabei wurden jeweils nur die hälfte der Bilder kopiert um die Asynchronität voll auschöpfen zu könne. Die PBOs kann man auch in den Speicher mappen und dann kann man direkt auf den Speicher zugreifen. Das ist in jedem Falle schneller als glReadPixel. Allerdings habe ich keine Ahnung mehr wo ich das gelesen hatte. Irgendwo bei NVidia. Und ich weiß auch nicht ob das mit FBOs so ohne weiteres geht.

Und ich weiß nicht ob man evtl bei FBOs so etwas in dem Dreh machen kann.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 30, 2007 17:39 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 15, 2007 16:10
Beiträge: 24
Wohnort: bei Düsseldorf
nein ich brauche die zeilen nicht, ist ja beim fernsehen so, PAL hat 50Hz aber 50 mal halbbilder.. also halbe auflösung. für das nächste halbbild werden dann die ungerade zeilen genommen.

es ist die frage ob durch das mehrfache aufrufen der glReadPixels funktion nicht unnötiger overhead ensteht.(habe bisher noch keine dokumentation gefunden)
ich werds mal messen(müssen wenn nicht jemand ne idee hat)...

ich hab zuerst auch PBOs benutzt für das offscreen rendering, allerdings habe ich keine elegante möglichkeit gefunden, das gerenderte auch on-screen anzuzeigen.Darum bin ich zu den FBOs gewechselt.

wobei mir jetzt das WGL_BIND_TO_TEXTURE_RGBA_ARB attribut über den weg gelaufen ist. nur weiß ich nicht wirklich was damit anzufangen. wie spreche ich die gerenderte Textur an... zumal kommt dazu, dass auf jeden fall ein context switch zu meinem haupt rendering context dazu kommt. wenn man das in betracht zieht ist die frage ob es mit fbo oder pbo schneller geht....

wenn dir das paper nochmal über den weg läuft mit dem asynchronen auslesen, dann denk an mich :)

Vielleicht hat noch jemand anregungen odre kommentare ... danke


€dit:

ich habe mal etwas über die GL_INTERLACE_EXT bzw. GL_INTERLACE_READ_I3D gelesen, nur leider nirgendws im internetetwas darüber gefunden. weiß jemand mehr ?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 30, 2007 18:40 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Als erstes Pixel Buffer bitte nicht mit Pixel Buffer Objects verwechseln. PBs sind zum Offscreenrendern. PBOs sind dazu da um Pixeldaten direkt ansprechen zu können. Also wie das bei VBOs der Fall. Nur müssen PBOs immer erst noch und oder von einer Textur kopiert werden.

Also die Daten einer Texture kannst du mittel glGetTexImage abrufen. Wenn das bei einem FBO geht sollte das recht praktisch sein ;)

PS: Die Konstanten von Extension. Ich denke nicht, dass die dir weiterhelfen, da sie sehr exotisch klingen.
OpenGL® Extension Registry Übersicht über alle Extensions
delphi3d.net/hardware Übersicht über Extensions und von welchen Karten sie unterstützt werden.

PPS: Interleace wird nur von Wildcard unterstützt. Aber das klang ziemlich genau nach dem was du sucht aber wie gesagt. Kannste vergessen. ;)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 30, 2007 18:55 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 15, 2007 16:10
Beiträge: 24
Wohnort: bei Düsseldorf
arghs wieder mal geschlampt beim suchen, habs nur in google eingehämmert und nichtmal die liste gecheckt... sorry...

da das wohl wegfällt, habe ich mit der oben erwähnten methode versucht mithilfe von glreadpixels jede 2te zeile zu lesen, aber es kommt ja so wie es kommen muss und ich bekomm wieder ein speicherzugriffsfehler

hier mein code

Zitat:
pixels = new unsigned char[iWidth*(iHeight/2)*4];

for (int i=0;i<iHeight;i=i+2)
{
glReadPixels(0, i, iWidth, i, GL_BGRA, GL_UNSIGNED_BYTE, &pixels[(i/2)*iWidth*4]);
CheckErrorsGL("MIDDLE: After Read Pixels - ScreenshotRGBA");
}



tja was soll ich sagen, bei i=194 bekomm ich den speicherzugriffsfehler.. ich denke es liegt an der falschen adresse in glreadpixels , aber ich find den fehler nicht :(

€dit:

ohh mann so dumm kann man doch echt nicht sein !

man sollte auch richtig lesen können es heißt ja als parameter widht und height "Beschreibt die Dimensionen des Pixelrechtecks" , Dimension und nicht koordinaten!

wäre dann height dann 1 für eine zeile!

vollidiot ....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 31, 2007 12:35 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 15, 2007 16:10
Beiträge: 24
Wohnort: bei Düsseldorf
Hallo zusammen,

ich möchte mal meine Testergebnisse durchführen, für den Fall, dass jemand mal vor einer änhlichen Entscheidung steht.

Das Kopieren des gesamten Bildschirms via glCopyPixels dauerte auf meinem Laptop mit ATI RADION PCIE im Mittel 16 ms.Darin inhalten ist zusätzlich noch das kopieren jeder zweiten zeile von innerhalb des client speichers.

Das Merfache aufrufen (für jede zweite zeile) dauert im mittel 24 ms , also ein drittel mehr!

Ich finde diese Zahlen trotzdem erschreckend hoch !

mein kleines Rechenbeispiel :

RGBA Bild mit 8 bit pro kanal und 720*576 Auflösung macht 1,58 Mbyte pro bild, wenn das über eine PCIE 1x Leitung mit 250MB/s nutzdatenleistung geschickt wird, kommen da 6,32 ms Übertragungszeit...

Klar, dass diese Werte nicht realistisch erreicht werden können, aber dass es doppelt bzw 4 fach so lange dauert find ich ziemlich krass !!

kennt jemand alternativen für das vorgehen ?? ich werde noch ein test mit PB/PBO und synchronen /asynchronen transfer machen, bin aber erst morgen wieder an dem testrechner :)


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

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Hast GetTickCount zum Messen benutzt? Das ist leider zu ungenau um dort sinnvoll etwas aussagen zu können. Wenn ja solltest du es einmal mit QueryPerformanceFrequency und QueryPerformanceCounter ausprobieren. Das ist wesentlich genauer.


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

Registriert: Mo Jan 15, 2007 16:10
Beiträge: 24
Wohnort: bei Düsseldorf
Hi Lossy!

ich benutze eine Abstraktionsmethode, die genau das macht, also Differenz der QueryPerformanceCounter durch QueryPerformanceFrequency teilt. Sollte also daran nicht liegen....


Da ich ja in ein Textur Target meines FBOs render, habe ich die Möglichkeit ausprobiert, diese Textur zu binden und dann auszulesen

Code:
  1.  
  2. glBindTexture(GL_TEXTURE_RECTANGLE_NV, iTexScene[0]);
  3. glGetTexImage(iTexScene[0],0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
  4. for (int i=0;i<iHeight/2;i++)
  5.     memcpy(&pixels2[i*iWidth*4], &pixels[2*i*iWidth*4], 4*iWidth * sizeof(unsigned char));
  6.  


leider bekomme ich nur ein schwarzes bild. Ist das die richtige Vorgehensweise, also kann ich das überhaupt so machen ?

Danke
Chris


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 31, 2007 14:38 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Okay. Wollte wegen dem Messen nur sichergehen, da 16ms sehr sehr typisch für GetTickCount ist. ;)

Der erste Parameter von glGetTexImage ist das Target und nicht die ID. Sonst sehe ich keine Probleme wobei ich keine Ahnung habe was man bei einem FBO beachten oder tun muss.

Ich sehe dort 3 mal iWidth * 4. Ich denke das solltest du alles in Variablen zwischenspeichern um es nicht jedes mal berechnen zu müssen. Da würde ich evtl auch iHeight / 2 zwischenspeichern, da C++ ja auch Variable Schleifenbedingen akzeptiert. Keine Ahnung ob er das selber jedes mal berechnet oder ob er schlau genug ist?

Und evtl würden dir da Pixel Buffer Objects auch noch mal helfen. Jetzt weiß ich auch wieder wo ich das Sample, wovon ich oben von gesprochen habe, her habe. Das steckt in der Spezifikation. Ganz unten unter "Example 3: Asynchronous glReadPixels" ist ein Beispiel in dem mittels 2 PBOs der Bildschirminhalt ausgelesen wird. Und dadurch, dass zu erst nur eine Hälfte gelesen wird muss auch nur halb so lange auf die Daten gewartet werden. Wärend die andere Hälfte intern gesammelt wird kannst du die erste Hälfte schon verarbeiten. Und so solltest du ohne große Verzögerungen dann auf die zweite Hälfte zugreifen können.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 31, 2007 15:24 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Jan 15, 2007 16:10
Beiträge: 24
Wohnort: bei Düsseldorf
upps wieder mal so ein dummer fehler... ich hab also jetzt glGetTexImage(GL_TEXTURE_RECTANGLE_NV,0, GL_BGRA, GL_UNSIGNED_BYTE, pixels); stehen, einmal versucht das fbo zu binden, einmal ohne bind.resultat immer schwarzer bildschirm....
das komische daran ist ja, dass ich die textur dazu benutze auf einem vollbild quad zu rendern mittels shader, und da klappt alles ohne probleme.

Also sollte es doch an dem befehl liegen???

das mit dem zwischenspeichern der variablen und dem pbo werd ich mir morgen näher ansehen, meine kiste hier unterstützt keine pbos :(


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 31, 2007 15:48 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Hmmm. Das mit den PBOs ist ja doof. Ich muss mal zu hause schauen ob die bei mir unterstützt werden. Delphi3D.net war auch nicht sonderlich gesprächig. Zu mindest was ATI angeht. Wobei es davon sowohl eine ARB als auch eine EXT Variante gibt.

FBOs: Also in der Spezifikation habe ich gesehen, dass du auch direkt in Texturen rendern kannst. Das geht mit dem Befehl FramebufferTexture2DEXT. Aber wie gesagt. Kenne mich damit nicht wirklich aus.

PS: Das zwischenspeichern dürfte nicht so wirklich viel bringen aber na ja ein bisschen wenigstens. ;)


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

Registriert: Mo Jan 15, 2007 16:10
Beiträge: 24
Wohnort: bei Düsseldorf
zu den fbos: das ist genau das was ich mache, ich rendere in eine textur und dann lese ich sie aus für den video output und mappe sie zusätzlich auf nen quad für den preview am bildschirm...

ich habe es jetzt geschafft , per glGetTexImage die textur auszulesen (nach stunden fehlersuche, bis ich dann gesehen habe, dass ich im debug modus kompiliert, aber im release die exe ausgeführt habe - ohh mann)


also meine ergebnisse sind:

RGBA Textur - auslesen nach BGRA : 0,014314475s = 14,3 ms
RGB Textur - auslesen nach BGR : 0,052229663s = 52 ms
RGBA Textur - auslesen nach BGR: 0,054466215 = 54ms

das überrascht mich schon ziemlich! Ich hätte wenigstens gedacht, dass wenn die anzahl der Komponenten gleich ist, am wenigsten Zeit braucht. Aber Pustekuchen! das Weglassen einer Komponente dauert fast 4mal so lange ??? das kann doch eigentlich nicht sein !

der etwas ratlose

Chris


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 31, 2007 22:20 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also zu den Pixel Buffer Objects. Die ist ein Bestandteil des OpenGL 2.1 Kerns und auf meiner Radeon 9600 Pro wird sie unterstützt. Tippe bei dir mal auf älterem Treiber. Und laut dem Programm was ich da habe unterstützt das wohl auch die 7500 und die 8500 also denke ich mal eine Frage der Zeit und des neuen Treibers. Da sieht man mal, dass selbst bei einer einer älteren Karte richtig aktuelle Treiber sinnvoll sind.

Zu der Verwirrung mit dem Format. Ich denke du hast auch eine ATI Karte? Die haben bei 24 Bits ein paar Probleme. Es kann sein, dass die Karte die nicht so perfekt unterstützt und der Treiber eingreifen muss. Und jedes mal wenn das passiert, dann wird es etwas langsamer. Wenn man Texturen hochlädt ist eine ATI bei RGB immer langsamer als bei RGBA. Auch noch obwohl sie mehr kopieren muss. Frag mich nicht warum das so ist aber es ist so. Achja NVidia hat dieses Problem im übrigen nicht.


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 1 Gast


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 | 14 Queries | GZIP : On ]