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

Aktuelle Zeit: Do Mai 16, 2024 17:20

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



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Di Mai 01, 2007 07:40 
Offline
DGL Member

Registriert: Mo Apr 30, 2007 18:32
Beiträge: 12
Hallo,
ich habe sehr große Bilder zu verwalten (z.B. 6000 Pixel breite Bilder). Dazu habe ich die Bilder als Textur auf ein Quadrat gelegt. Nun möchte ich z.B. das Bild unscharf machen und wende darauf ein Filter an.

Dazu verfahre ich jetzt:
Ich bearbeite das Original Bild und lade die Textur neu auf das Quadrat.

Wunsch:
Der Filter verändert direkt die Werte der Pixel der Textur.

D.h.:
Was ich brauche sind Methoden, wie etwa getPixel(x,y,z) und setPixel(x,y,z,wert).

Kennt jemand solche Methoden oder Möglichkeiten???

Gruß,
Anton


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Mai 01, 2007 10:33 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Du kannst zum Beispiel über glTexSubImage2D und glGetTexSubImage2D beliebige Bereiche aus einer Textur lesen bzw schreiben. Da könntest du auch einen einziges Pixel angeben. Das würde funktionieren. ABER. Davon kann ich nur abraten.

Dadurch würdest du so viele OpenGL Aufrufe erzeugen, dass ich wetten würde, dass es langsamer wäre als wie wenn du die Textur nur einmal ausliest und wieder zurück schreibst. Das kannst du im übrigen auch mit den beiden Methoden machen. Da dabei nur die Daten verändert werden aber keine Textur neu angelegt werden muss, was bei glTexImage2D der Fall ist. Die Textur muss aber trotzdem erst einmal mit glTexImage2D befüllt (initialisiert) worden sein.

Der klassische Fall für einen Weichzeichner sind aber Shader die auf die Textur angewendet werden. Diese wird dann auf eine andere oder sich selbst kopiert. Wenn möglich solltest du so etwas benutzen. Aber das ist nicht so mein Spezialgebiet.

Gamasutra hat einen Artikel veröffentlicht der sehr schön die dahinterliegende Technik beschreibt. Ist aber leider mit DX Shader Code.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Mai 01, 2007 12:54 
Offline
DGL Member

Registriert: Mo Apr 30, 2007 18:32
Beiträge: 12
besten Dank für deine Antwort. Ich hätte da noch eine Frage, und zwar habe ich mehrere Texturen nun so eingebunden:
Code:
  1. Image1Texturen = new GLuint[3];
  2. glGenTextures(3, &Image1Texturen[0]);
  3. for (int i=0; i < 3; i++) {
  4.   glBindTexture(GL_TEXTURE_2D, Image1Texturen[i]);
  5.   glTexImage2D(GL_TEXTURE_2D,0,3,TexturSize,TexturSize,0,GL_RGB,GL_UNSIGNED_BYTE,textureData[i]);
  6.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  7.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  8. }
  9.  
  10. for (int i=0; i < 3; i++) {
  11.   glBindTexture(GL_TEXTURE_2D, Image1Texturen[i]);
  12.   glBegin(GL_QUADS);
  13.   glTexCoord2f(0.0f,0.0f); glVertex3f( i    ,  0, i);
  14.   glTexCoord2f(1.0f,0.0f); glVertex3f( i+1,  0, i);
  15.   glTexCoord2f(1.0f,1.0f); glVertex3f( i+1,  1, i);
  16.   glTexCoord2f(0.0f,1.0f); glVertex3f( i    ,  1, i);
  17.   glEnd();
  18. }
  19.  


damit hätte ich z.B. drei Bilder (die information dazu ist jeweils im tetureData) hintereinander eingebunden, mit jeweils verschiedener Tiefe. Nun möchte ich über glTexSubImage2D/ glGetTexSubImage2D jeweils einen gewissen Bereich, der sich über die drei Bilder (z.B. von linke untere Ecke (0.5, 0) bis rechte obere Ecke (2, 0.5) bearbeiten(z.B. die Pixel in diesem Bereich ROT färben), wie mache ich dies?

P.S. Weichzeichnen war nur ein Beispiel Filter. Über diesen Weg erhoffe ich mir, dass ich den Arbeitsspeicher nicht zu voll mache, was ich beim ständigem ein/auslesen der Bilder hätte.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Mai 01, 2007 13:41 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Mal eine andere Frage. Was hast du damit vor? So etwas wie ein Grafikprogramm?

Na ja. Wenn du mehrere Texturen überspannen möchtest, dann musst du dir mehrere Texturen geben lassen und diese bearbeiten. Je nach Filter kannst du das nacheinander erledigen oder aber du musst einen Weg finden wie du das mit 3 Texturen gleichzeitig machst. Da kannst du entweder den Filter auf Virtuelle Daten loslassen und dann in die echten Bereiche mappen oder aber du kopierst die Daten eben temporär in eine großes Bild und anschließen wieder da raus.

Aber wenn du das häufiger machen musst dann wäre es auch sinnvoller, wenn du die Daten nicht ständig hin und herkopierst. Dann solltest du die Daten im RAM lassen und bei Änderungen auf die Karte kopieren. Je nach Programm sind die 4-16 MB Speicher mehr dann auch nicht so das Problem. Wenn du sie ständig wieder von der Karte ziehst, dann brauchst du den Speicher ja auch. Aber eben nicht dauerhaft.

Du müsstest uns aber bitte etwas genauer erklären wie du dir das vrgestellt hast bzw was du vor hast etc.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Mai 01, 2007 14:10 
Offline
DGL Member

Registriert: Mo Apr 30, 2007 18:32
Beiträge: 12
Lossy eX hat geschrieben:
Mal eine andere Frage. Was hast du damit vor? So etwas wie ein Grafikprogramm?

ja, könnte man sagen. Ich habe einbe Serie vonn Bildern, die zusammengehören (man könnte sich das vorstellen als ob man eine Rundumansicht von einem Zimmer gemacht hätte). Nun packe ich die Bilder als Texturen hintereinander um so das komplette Bild zu sehen.
Jetzt möchte ich z.B. nur ein Gemälde (welches sich über mehrere Bilder erstreckt) einem Filter aussetzen (unscharf machen, Kanten extrahieren ... ). Derzeit hole ich mir über die OpenGL oberfläche nur die Koordinaten des Gemäldes (welche ich per Maus definiere). Mittels dieser Koordinaten stelle ich mir ein neues Bild zusammen und wende darauf den Filter an, anschließend packe ich das Bild wieder als Textur rein.

Das Problem ist. Das ich einmal die Bilderserie einlese, wenn ich die Texture erstelle.
Dann lese ich die Bilder nochmal aus, wenn ich das Gemälde haben will, und dann erstelle ich wieder die Texturen.
Also mehrfache Arbeit.
Einen Schritt kann ich mir nicht ersparren, das erste einlesen der Bilder in die Texturen. Die anderen müssten aber durch einen direkten zugriff die Pixel in dem Texturbereich (dem Gemälde) ersparrt bleiben.

Das zur Aufgabenstellung ;)
Zitat:
Na ja. Wenn du mehrere Texturen überspannen möchtest, dann musst du dir mehrere Texturen geben lassen und diese bearbeiten. Je nach Filter kannst du das nacheinander erledigen oder aber du musst einen Weg finden wie du das mit 3 Texturen gleichzeitig machst. Da kannst du entweder den Filter auf Virtuelle Daten loslassen und dann in die echten Bereiche mappen oder aber du kopierst die Daten eben temporär in eine großes Bild und anschließen wieder da raus.

Ich habe bestimmt, auf wieviele Bilder das Gemälde sich erstreckt, und die genauen Koordinaten bestimmt, die im jeweiligen Bild das Gemälde verwendet. D.h. ich brauchen eine Methode, wie ich auf diesem einem Teilbereich {z.B. (0.5, ) bis (1, 0.5)} die Pixel auslesen und wieder setzen kann.
Könntest du mir das explizit für z.B. die erste Textur sagen wie ich das machen kan?
Zitat:
Aber wenn du das häufiger machen musst dann wäre es auch sinnvoller, wenn du die Daten nicht ständig hin und herkopierst. Dann solltest du die Daten im RAM lassen und bei Änderungen auf die Karte kopieren. Je nach Programm sind die 4-16 MB Speicher mehr dann auch nicht so das Problem. Wenn du sie ständig wieder von der Karte ziehst, dann brauchst du den Speicher ja auch. Aber eben nicht dauerhaft.

Ich hatte zuvor probiert die Daten im RAM zu behalten , jedoch brauchte er beim laden der Bilderserie extrem lange (wenn ich z.B. diese drei Bilder laden sollte). Was sich dadurch lösen lies, dass ich die Bilder einzeln geladen habe, und anschließend sofort als Textur gespeichert hatte habe (unter Image1Texturen) und zum schluß dies an ein Quadrat gebunden habe.

P.S. besten Dan für deine Mühe!!! :-)[/quote]


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Mai 01, 2007 20:54 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Was ich ganz vergessen hatte. Herzlich Willkommen im Forum. :D

Ich muss dir gestehen, dass ich derzeit selber ziemlich extrem an einem Problem kämpfe weswegen ich nur bedingt Aufnahmefähig bin. Also das nur als Vorwarnung, falls ich Begriffsstutzig bin oder völligen Quark rede. ;)

Wobei mir gerade auffällt, dass ich momentan anscheinend echt nicht zurechnungsfähig bin. :roll: Ich habe Quark erzählt. Die Methode glGetTexSubImage2D gibt es gar nicht. Das war wohl eher wunschdenken. Also du kannst dir nur das ganze Bild zurückgeben lassen. Das geht mit der Methode glGetTexImage. Die gibt es dieses mal wirklich. ;)
Falls du die Höhe / Breite deines Bildes nicht kennst (oder die vorher kein POT sind) solltest du sie wie folgt abfragen.
Code:
  1. var
  2.   TempWidth, TempHeight: Integer;
  3. begin
  4.   glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
  5.   glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);

Dann erstellst du dir einen Speicherbereich in dem glGetTexImage die Daten ablegen kann. Dabei solltest du wissen in welchen Format sich die Textur befindet. Das kann man aber auch abfragen (glGetTexLevelParameteriv mit GL_TEXTURE_INTERNAL_FORMAT). Typischerweise ist das Gl_RGBA oder GL_RGB. Wobei das sehr stark vom Loader abhängt. glGetTexImage ist sicher auch bereit das zu konvertieren falls es nicht passen sollte (nur eine Vermutung (Da würde ich aber selber nicht viel drauf geben derzeit)). Aber normal bietet es sich an wenn die Daten nicht konvertiert werden müssen.

Das mit dem RAM habe ich irgendwie nicht verstanden. Sorry. Aber es klingt für so als ob du nicht unerfahren bist und von daher denke ich dass du wissen wirst warum du das so machst wie du das machst.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Mai 02, 2007 07:14 
Offline
DGL Member

Registriert: Mo Apr 30, 2007 18:32
Beiträge: 12
danke für deine Antwort. Sofern ich dies richtig verstanden habe, so würde ich direkt das komplette Bild aus der Textur zuerst auslesen, und dann wieder einbinden müssen?
Das heißt aber wiederum, dass ich nicht direkt auf einzelne Pixel in der Textur zugreifen kann, richtig?

Das auslesen des ganzen Bildes aus der Textur wird mich in dieser hinsicht, glaub ich, nicht weiter bringen. Da könnte ich dann direkt wieder auf das auf der Platte zugreifen.

Vorauf es hinaus lief: Ich kann den Bildspeicher der Grafikkarte nicht direkt als "RAM" speicher verwenden?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Mai 02, 2007 08:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Stimmt. Du kannst nicht mal eben so einzelne Pixel auslesen. Du müsstest dir das ganze Bild geben lassen und der Einfachheit halber solltest du auch das ganze wieder setzen. Weil du sonst teile ausschneiden müsstest und das würde wohl länger dauern als eben alles wieder zu übertragen.

Wobei es noch etwas Anderes gibt. Das aber schon vorweg ist recht neu und es wird wohl deswegen nicht überall unterstützt. In erster Linie wird es von neueren NVidia Karten/Treibern unterstützt. Das ganze sind Pixel Buffer Objects. Mit denen kannst du einen Speicherbereich auf der Grafikkarte reservieren wo du eine Textur hineinkopieren kannst. Diesen Speicherbereich kannst du in den lokalen Speicher (RAM) mappen und direkt darauf zugreifen. Wenn du fertig bist kopierst du den Speicher wieder auf die Textur zurück. Dazu gibt es 2 Extensions die mehr oder weniger gleich sein dürften.
GL_ARB_pixel_buffer_object und
GL_EXT_pixel_buffer_object
Aber ob der Weg über die Extension unbedingt der Beste ist weiß ich nicht. Bis vor kurzem sah die Unterstützung noch ziemlich bescheiden aus. Was sich laut Delphi3D.net mittlerweile aber etwas verbessert hat. Zu mindest lassen sich Ansätze einer Unterstützung erkennen.

Aber mal anders gefragt. Wäre es nicht praktischer, wenn du die Texturen so lädst, dass du sie zu erst ins RAM lädst und anschließend dann nur zur Grafikkarte überträgst? Das musst du ja so oder so machen und alles andere schreit für mich nach umständlicher mehrarbeit. Du darfst sie dann nur nicht wieder aus dem RAM löschen und alles ist fein. Das wäre zu mindest für mich der sinnvollste Weg. Alles andere dauert entweder zu lange oder gestaltet sich als kompliziert bzw nicht so gut unterstützt. Ist zwar sicher nicht die beste Möglichkeit aber was solls? Ich weiß ja auch nicht ob du es derzeit schon so machst, dass du nur die Bilder neu einliest du du brauchst?

Wenn jemand so etwas größeres vor hat, dann muss er halt damit leben, dass der Speicherverbrauch entsprechend größer ist. Ich habe einfache Java und .Net Programme die für so gut wie nichts mal eben locker über 100 MB Speicher beanspruchen.

Ich denke auch mal, dass du JPEGs als Bilder benutzt. Die JPEG Implementation von Delphi ist so ziemlich die Langsamste die es überhaupt gibt. Evtl wäre da ein anderes Format nicht ganz unpraktisch. Oder aber auch eine andere Bibliothek dürfte auch etwas daran verbessern. Ein anderes Format würde zwar mehr Platz auf der Platte brauchen aber dafür wäre es schneller eingelesen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 03, 2007 11:27 
Offline
DGL Member

Registriert: Mo Apr 30, 2007 18:32
Beiträge: 12
Nochmal zurück auf den Befehl:
Code:
  1. glTexSubImage2D

dieser soll ja einen Zeiger auf den Bildspeicher einer Textur geben. Dies würde ja zuerstamal zu meinem Problem passen.
Die Frage wäre jetzt, zu welcher Textur würde er mir den Zeiger zum Bildspeicher geben?
Und anschleißend wie kann ich auswählen zu welcher Textur er mir den Zeiger liefert?

Und dann, wie kann ich eine Pixel, ausgehend von diesem Zeiger, auslesen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 03, 2007 11:45 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Mit glTexSubImage2D kannst du einen Bereich der Textur ersetzen/schreiben. Ich hatte in einem Moment geistiger Umnachtung aber angenommen, dass es eine Methode glGetTexSubImage2D geben würde. Das tut sie aber nicht. Tschuldige vielmals für die Verwirrung aber dieser Weg scheidet aus. Weil er nicht existiert.

Die einzige Methode die dir die Texturdaten zurückgibt ist die glGetTexImage. Diese liefert dir aber die komplette Textur zurück.

Es wird immer die aktuell gebundene Textur zurück benutzt. Und die liefern dir keinen Pointer zurück sondern du reichst einen Pointer an diese Methoden und die Schreiben den Inhalt an die Stelle auf die Pointer zeigt. Du musst dann natürlich dafür sorgen, dass dort genügend Platz vorhanden ist. Aber genaueres findes du auch in dem Wikiartikel zu den Funktionen. Sind verlinkt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 03, 2007 11:54 
Offline
DGL Member

Registriert: Mo Apr 30, 2007 18:32
Beiträge: 12
Lossy eX hat geschrieben:
Mit glTexSubImage2D kannst du einen Bereich der Textur ersetzen/schreiben. Ich hatte in einem Moment geistiger Umnachtung aber angenommen, dass es eine Methode glGetTexSubImage2D geben würde. Das tut sie aber nicht. Tschuldige vielmals für die Verwirrung aber dieser Weg scheidet aus. Weil er nicht existiert.

Die einzige Methode die dir die Texturdaten zurückgibt ist die glGetTexImage. Diese liefert dir aber die komplette Textur zurück.

Es wird immer die aktuell gebundene Textur zurück benutzt. Und die liefern dir keinen Pointer zurück sondern du reichst einen Pointer an diese Methoden und die Schreiben den Inhalt an die Stelle auf die Pointer zeigt. Du musst dann natürlich dafür sorgen, dass dort genügend Platz vorhanden ist. Aber genaueres findes du auch in dem Wikiartikel zu den Funktionen. Sind verlinkt.


Besten Dank für die Aufklärung :)
Ich habe morgen noch ein Treffen mit meinen Kollegen, villeicht haben die noch eine Idee. Melde mich somit später nochmal.

Gruß,
Anton


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.028s | 15 Queries | GZIP : On ]