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

Aktuelle Zeit: Di Mai 14, 2024 14:59

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



Ein neues Thema erstellen Auf das Thema antworten  [ 26 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
BeitragVerfasst: Mo Nov 28, 2011 19:49 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Hi,

ich habe mir in den letzten paar Tagen eine numerische Lösung des Kepler-Problems programmiert. Gerechnet wird in Delphi d.h. per CPU, die Visualisierung in OpenGL, dafür reichen meine Fähigkeiten noch. Nun will ich allerdings auch mal mehr als 2000 Teilchen simulieren.

Ich hab mir jetzt besagtes Tutorial angeschaut (erstmal das "ältere") und bekomme auch schon meine einzelnen Pünktchen gerendert.
Ich habe auch die vier Shader, eigentlich komplett gleich wie im Tutorial, nur, dass ich noch gl_Color mitschleife.

Allerdings...EGAL was ich in den Physik-Fragmentshader schreibe...Es tut sich nichts!
Kann mir vielleicht jemand ein einfaches Beispiel geben, mit welchem sich etwas tun müsste?
Ich habe mir sowas überlegt:
Code:
  1.  
  2. uniform sampler2D Texture0;
  3. uniform sampler2D Texture1;
  4.  
  5.  
  6. void main(){
  7.     vec4 data0 = texture2D(Texture0,vec2(gl_TexCoord[0]));
  8.     vec4 data1 = texture2D(Texture1,vec2(gl_TexCoord[0]));
  9.  
  10.     // ...Daten modifizieren...
  11.  
  12.         data0.x = data0.x * gl_Color.r * 10;
  13.         data1.x = data0.x;
  14.  
  15.     gl_FragData[0] = data0;
  16.         gl_FragData[1] = data1;
  17. }
  18.  

Halt zum Testen, wobei ich vorher im Programm per glColor3f(random,0,0); ne Random-Zahl in den Shader schleuse. Jetzt dachte ich, dass meine Punte auf der X-Achse "zittern". Allerdings tut sich nichts. Auch ein einfaches x = x +1 ändert nichts.

Hätte jemand ein Beispiel oder wenigstens nen Tipp, was hier falsch läuft?

Vielen Dank,
Flips


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Nov 29, 2011 18:44 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Schreib mal irgendeinen Farbwert raus und schau ob dieser im FBO korrekt ankommt. Bei dieser Art von Technik sind die FBOs immer die Hauptfehlerquelle.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Nov 29, 2011 20:09 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Ich hasse es, solche Antworten geben zu müssen, aber:
Wo einen Farbwert rausschreiben und wie prüfen? Ich denk ich les mir jetzt zuerst mal das Tutorial zu FBO's / VBO's durch ;-)

Habe da mal nach der Initialisierung meiner FBO's diese Error-Funktion aus dem Tutorial reingeklatscht und siehe da, er wirft ne Exception bei "Missing attachement". Hat es vielleicht was damit zu tun? Code ist wie gesagt der aus dem Tutorial.

Sorry nochmal, ich geb zu ich wollte einfach nur, dass die Grafik funktioniert und ich mich um die Physik kümmern kann. Aber da komm ich jetzt wohl nicht um ein wenig Nachsitzen in OpenGL rum.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Nov 29, 2011 21:28 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Hat es vielleicht was damit zu tun? Code ist wie gesagt der aus dem Tutorial.

Ja, daran wird es wohl liegen. FBO's sind etwas widerspenstig ;)

Zitat:
Wo einen Farbwert rausschreiben und wie prüfen? Ich denk ich les mir jetzt zuerst mal das Tutorial zu FBO's / VBO's durch ;-)

Mit glGetTexImage kannst du eine Textur auslesen, ungefähr so:

FBO abschalten (oder anderen FBO binden)
Textur binden
Speicher für "pixels" reservieren
glGetTexImage
pixels irgendwie ausgeben...in ein Log/Datei schreiben, etc...ggf. nur die ersten paar Pixel ausgeben
Speicher freigeben

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Nov 29, 2011 22:59 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Ok die besagte Exception mit den FBO's bekomme ich nur weg, wenn ich die Texturen vor dem BindTexture noch per GenTextures erzeuge. Allerdings flimmert dann mein Bild bzw die gerenderten Pixel. Jedoch muss ich laut dem FBO-Tutorial immer erst per GenTextures die gluInt's, also die Texturnamen in OpenGL, richtig zuweisen lassen. Ich frage mich halt jetzt wieso ich ohne GenTextures überhaupt was angezeigt bekomme, dafür aber die Exception des FBO bekomme, MIT GenTextures keine FBO-Exception aber dafür ein flackerndes Bild.


Zum Physikshader, habe nun folgendes eingebaut:
Code:
  1.  
  2. pass := (pass+1) mod 2;
  3.  
  4. glViewport(0, 0, 256,256);
  5.  
  6. FPhysShader.Use; //Physikshader anwenden, Shadercode steht weiter unten
  7.  
  8. glActiveTexture(GL_TEXTURE0);
  9. glBindTexture(GL_TEXTURE_2D, partikelbuffer[pass * 2]);   //Datentextur 1
  10. glActiveTexture(GL_TEXTURE1);
  11. glBindTexture(GL_TEXTURE_2D, partikelbuffer[ pass * 2 + 1]); //Datentextur 2
  12.  
  13.  
  14. glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, partikel_framebuffer[pass]);
  15.  
  16. glBegin(GL_QUADS);
  17.   glTexCoord2f(0,0); glVertex2f(0,0);
  18.   glTexCoord2f(0,1); glVertex2f(0,1);
  19.   glTexCoord2f(1,1); glVertex2f(1,1);
  20.   glTexCoord2f(1,0); glVertex2f(1,0);
  21. glEnd();
  22.  
  23. glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
  24.  
  25. glActiveTexture(GL_TEXTURE0);
  26. glBindTexture(GL_TEXTURE_2D, partikelbuffer[pass * 2]);
  27. glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, @a);
  28. s := '';
  29. for i := 0 to 1000 do
  30. begin
  31.   s := s + FloatToStr(a[i]) + '   ';
  32. end;
  33.  


Der Physikshader sieht so aus:
Code:
  1.  
  2. //Fragmentshader
  3. uniform sampler2D Texture0;
  4. uniform sampler2D Texture1;
  5.  
  6.  
  7. void main(){
  8.     vec4 data0 = texture2D(Texture0,vec2(gl_TexCoord[0]));
  9.     vec4 data1 = texture2D(Texture1,vec2(gl_TexCoord[0]));  
  10.  
  11.         data0.x = 10;
  12.         data1.x = 10;
  13.  
  14.     gl_FragData[0] = data0;
  15.         gl_FragData[1] = data1;
  16. }
  17.  
  18.  
  19. //Vertexshader
  20. void main(void){
  21.     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
  22.         gl_TexCoord[0] = gl_MultiTexCoord0;
  23. }
  24.  
  25.  


Jetzt müsste man doch eigentlich erwarten, dass jeder X-Wert (bzw jeder R-Wert) in meinem String s am Schluss gleich 10 ist. Also quasi jeder 4. Wert.
Dem ist allerdings nicht so, ich bekomme die zufälligen Werte, dich ich am Anfang bei glTexImage2D mitgegeben habe (ist übrigends interessanterweise egal, ob ich zu Beginn glGenTextures aufgerufen habe, hab das gerade mal getestet...es kommt das selbe raus).

D.h. mein Physikshader klappt nicht so ganz, oder?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Nov 30, 2011 19:11 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
So zwei gute Nachrichten:

Erstens hat sich mein Shader/FBO-Verständnis heute enorm gesteigert.
Zweitens kann ich den Fehler jetzt fest machen.

So wie ich das gelernt habe klemmt sich ein Shader doch zwischen meinen OpenGL-Code und meine Ausgabe auf dem Bildschirm, d.h. er erlaubt mir nachträglich, Sachen zu manipulieren. Logischerweise bekommt doch mein Hauptprogramm davon nix mehr mit.

D.h. der Physikshader ändert zwar meine Texturwerte, aber die Textur selbst bleibt unangetastet.

Wie veranlasse ich denn nun den Shader, die Textur umzuschreiben und nicht nur die Texturdaten, die an die Grafikkarte geschickt werden, zu manipulieren?

Denn zur Zeit ist es ja so:
-> Physikshader manipuliert die Texturdaten, die in den Framebuffer gerendert werden.
-> Rendershader liest selbige per Lookup aus und macht daraus Positionen für meine Partikel.

Ich bräuchte dazwischen noch den Schritt: -> Alte Texturdaten werden durch die neuen (manipulierten) ersetzt.
Kann das mein Shader machen?
Oder müsste ich dafür das, was im Framebuffer steht wieder auf die Textur packen?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Nov 30, 2011 20:08 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
So wie ich das gelernt habe klemmt sich ein Shader doch zwischen meinen OpenGL-Code und meine Ausgabe auf dem Bildschirm, d.h. er erlaubt mir nachträglich, Sachen zu manipulieren. Logischerweise bekommt doch mein Hauptprogramm davon nix mehr mit.

Bild

Mit einem Shader kannst du die rot markierten Teile der Renderpipeline durch kleine Programme ersetzen. Also da wird nichts nachträglich manipuliert. Die komplette Renderpipeline befindet sich auf der Grafikkarte.

Zitat:
Wie veranlasse ich denn nun den Shader, die Textur umzuschreiben und nicht nur die Texturdaten, die an die Grafikkarte geschickt werden, zu manipulieren?

Normalerweise wird in den Framebuffer gerendert. Mit einem Framebuffer-Objekt (FBO) kann man stattdessen in eine oder mehrere Texturen rendern.

Zitat:
Ok die besagte Exception mit den FBO's bekomme ich nur weg, wenn ich die Texturen vor dem BindTexture noch per GenTextures erzeuge.

Texturobjekte MÜSSEN mit glGenTextures erzeugt werden. Der Grund dafür das dein Code auch ohne "funktioniert" ist wahrscheinlich das dein Integer für die Textur nicht initialisiert ist...d.h. da steht irgendein Datenmüll drin. Das gibt mehr oder weniger zufällige Ergebnisse, kann also auch zufällig funktionieren ;)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Nov 30, 2011 20:32 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Zitat:
Normalerweise wird in den Framebuffer gerendert. Mit einem Framebuffer-Objekt (FBO) kann man stattdessen in eine oder mehrere Texturen rendern.


Nehmen wir mal an, ich würde zwei FPO's mit jeweils einer Textur haben.
Dann würde es doch so laufen:

-Shader anwenden
-Binde Textur von FPO 0
-FPO 1 aktivieren
-Rendern (hier wird dann das, was mir der Shader mit den Daten aus der Textur von FPO 0 generiert, reingerendert)

Jetzt habe ich in der Textur vom FPO 1 die neuen Daten und gebe diese aus.


Dummerweise klappt genau das nicht. Ich setze jeden Pixel meiner Textur zu Beginn auf (0,1,1,1). Im Shader sage ich dann er soll mir aus der 0 ne 1 machen. Wenn ich danach aber die Textur vom FPO 1 auslese sind da alle R-Anteile weiterhin 0...


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Nov 30, 2011 21:01 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Es hat die ganze Zeit funktioniert...

Nur hat mir glGetTexImage immer gesagt es würde nicht gehen, als ich dann mal die neu geschriebene Textur gerendert habe war sie weiß, obwohl mir glGetTexImage gesagt hat, dass der R-Wert 0 ist.

Jedenfalls funktioniert es jetzt gut (nachdem ich Artefakte durch einen zusätzlichen Renderbuffer beseitigen konnte). Danke für die Hilfe :-)

[Edit]
Falscher Alarm:

Bin am verzweifeln, Textur war mit zufälligen Farbwerte initialisiert, per Shader auf rot gesetzt.
Das Viereck, das gerendert wird ist rot aber die Funktion glGetTexImage untendrunter gibt mir immer noch die zufälligen Zahlen vom Anfang zurück. Der Shader danach bekommt die dann auch und eben nicht das rot....Sry aber das versteh ich einfach nicht :(

Code:
  1.  
  2. glActiveTexture(GL_TEXTURE0);
  3. glBindTexture(GL_TEXTURE_2D, partikelbuffer[fbo]);
  4.  
  5. glBegin(GL_QUADS);
  6.   glTexCoord2f(0,0); glVertex2f(0,0);
  7.   glTexCoord2f(0,1); glVertex2f(0,1);
  8.   glTexCoord2f(1,1); glVertex2f(1,1);
  9.   glTexCoord2f(1,0); glVertex2f(1,0);
  10. glEnd();
  11.  
  12.  
  13. glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, @a);
  14. s := '';
  15. for i := 0 to 1000 do
  16. begin
  17.   s := s + FloatToStr(a[i]) + '   ';
  18. end;
  19.  



2. Edit

Ich hab jetzt nämlich die neu erstelle Textur mal probeweise rendern lassen (auf die Idee hätte ich mal früher kommen sollen) und sehe, dass immerhin ein Teil der Textur so wird, wie der Shader vorgibt (Zu beginn ist sie rot, der Shader soll alles auf 0 setzen nur B auf 1).
Wenn ich mir jetzt ein Quad mit der veränderten Textur rendern lasse (vorher deaktiviere ich natürlich den Shader), dann ist zumindest die linke obere Ecke blau. Der Rest Rot.
glGetTexImage sagt aber immer noch, dass die Textur nix Blaues hat...


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Dez 01, 2011 20:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Hast du den Viewport richtig (auf die Texturgröße) gesetzt?

glGetTexImage gibt dir ggf. die Farben vertauscht/rückwärts aus. Einfach mal eine Textur auslesen von der du weißt was drin ist.
Beachte das du keine Textur auslesen kann in die gerade via per FBO geschrieben wird. Da kommt einfach Datenmüll. Also immer den FBO deaktivieren (*).




(*) Performance-Fetishisten haben natürlich nur einen einzigen FBO für alles und hängen stattdessen die Texturen im FBO um....da ist schneller. Aber das ist hier nicht wichtig...erstmal überhaupt zum laufen kriegen, dann Performance.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Dez 01, 2011 20:32 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
glViewPort(0,0,256,256) bei einer Textur von 256*256 Pixeln.

Zum Inititalisierungszeitpunkt weise ich den Texturen R,A->0.4 und B,G->0 zu und im Shader setze ich dann R,G->0 und B,A -> 1.0
Heraus kommt das Bild im Anhang.
Ich poste einfach mal den relevanten Code ('tex' und 'fbo' springen immer zwischen 0 und 1; die Textur/Framebuffer mit selbem Index (tex oder fbo) gehören immer zusammen)

Code:
  1.  
  2. glTranslatef(0,0,-1);
  3.  
  4. glPushAttrib(GL_VIEWPORT_BIT);
  5. glViewport(0,0,Size,Size); //Size = 256
  6. FPhysShader.Use;
  7. glActiveTexture(GL_TEXTURE0);
  8. glBindTexture(GL_TEXTURE_2D, partikelbuffer[tex]);    
  9.  
  10. glBindFramebuffer(GL_FRAMEBUFFER, partikel_framebuffer[fbo]);  
  11.  
  12. glDrawBuffers(1, @buffers); //Hab ich aus ner anderen Quelle, buffers beinhaltet GL_COLOR_ATTACHMENT0
  13.  
  14. glBegin(GL_QUADS);
  15.   glTexCoord2f(0,0); glVertex2f(0,0);
  16.   glTexCoord2f(0,1); glVertex2f(0,1);
  17.   glTexCoord2f(1,1); glVertex2f(1,1);
  18.   glTexCoord2f(1,0); glVertex2f(1,0);
  19. glEnd();
  20.  
  21. glBindFramebuffer(GL_FRAMEBUFFER, 0); //Framebuffer ausschalten
  22.  
  23. TShader.KillAllShader;  //Physik-Shader abschalten
  24.  
  25. glPopAttrib;
  26.  
  27. glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT);
  28.  
  29. //Jetzt testweise rendern lassen
  30.  
  31. glBindTexture(GL_TEXTURE_2D, partikelbuffer[fbo]);
  32.  glBegin(GL_QUADS);
  33.   glTexCoord2f(0,0); glVertex2f(-0.5,-0.5);
  34.   glTexCoord2f(0,1); glVertex2f(-0.5,0.5);
  35.   glTexCoord2f(1,1); glVertex2f(0.5,0.5);
  36.   glTexCoord2f(1,0); glVertex2f(0.5,-0.5);
  37. glEnd();
  38.  
  39. glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, @a);
  40. for i := 0 to Pixels-1 do  //Pixels = 256*256
  41. begin
  42. if (a[i] > 0.5) then
  43. ShowMessage(IntToStr(i));  // Wird NIE erreicht, obwohl ja das Quad teilweise blau, also die B Werte = 1 > 0.5 sind...
  44. end;
  45.  


Dateianhänge:
screen.png [22.61 KiB]
Noch nie heruntergeladen
Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Dez 02, 2011 07:46 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, @a);
for i := 0 to Pixels-1 do //Pixels = 256*256
begin
if (a[i] > 0.5) then
ShowMessage(IntToStr(i)); // Wird NIE erreicht, obwohl ja das Quad teilweise blau, also die B Werte = 1 > 0.5 sind...
end;


Deine Textur ist 256x256....mit RGBA...also 4 floats pro Pixel => du schreibst wahrscheinlich Daten einfach so in den Speicher => ein Wunder das es nicht abstürzt?

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Dez 02, 2011 13:24 
Offline
DGL Member

Registriert: Mi Aug 09, 2006 15:47
Beiträge: 44
Wohnort: St. Wendel
Programmiersprache: Delphi, C#, Java, C
Ja das ist mir während mein letzter Post aktuell war auch aufgefallen, führte aber zu keinen Problemen weil das Array groß genug war, ledeglich die Schleife war zu kurz. Tut aber nichts zur Sache, Hauptproblem ist einfach, dass meine Rendertechnik zwar stimmt aber die Perspektive falsch ist und somit nur ein Teil der Textur umgeschrieben wird aber nicht alles. Und ich find einfach keinen Fehler, andere machens genauso (also scheinbar doch anders, aber ich finde den unterschied nicht).

Immerhin weiß ich jetzt, dass mein Problem nicht die Shader sind, sondern das FBO. Ich werde mal einen neuen Thread im passenden Bereich starten und nochmal genau sagen, was ich mache und was rauskommen sollte!


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Dez 03, 2011 00:14 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
In deinem Code zeichnest du 2 mal ein Quad. Einmal für die Berechnung und einmal zum Anzeigen. Ich denke die Koordinaten für das erste sind falsch.
Beide sollten ja eigentlich über den ganzen Viewport gehen. Und da die Projectionmatrix nicht geändert wird, aber die Position anders ist, ist wohl eins falsch. Dem Screenshot nach das erste.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Sa Dez 03, 2011 08:40 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Wenn Projektion und Modelview-Matrix beide die Einheitsmatrix (Identity) sind brauchst du ein Quad das in X und Y Richtung jeweils von -1 bis 1 geht.

_________________
Yeah! :mrgreen:


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 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 | 18 Queries | GZIP : On ]