DGL
https://delphigl.com/forum/

Shader-Probleme unter Delphi 2009
https://delphigl.com/forum/viewtopic.php?f=20&t=8594
Seite 1 von 2

Autor:  KSM [ Fr Aug 07, 2009 12:11 ]
Betreff des Beitrags:  Shader-Probleme unter Delphi 2009

Hi :)!

Ich würde sehr gerne anfangen, mit glSlang zu arbeiten.

Doch ich habe noch nicht so richtig verstanden, wie ich die Shader in meinem Programm anwende. Das Laden der Shader funktioniert, nur ich würde gerne einmal den Beispielshader aus dem glSlang-Tutorial 1 nachbauen. Wie mache ich das beim Rendern?

Bisher mache ich das so:

Beim Rendern:

Code:
  1.  
  2.  
  3. glEnable(GL_TEXTURE_2D);
  4.  
  5.   glUseProgramObjectARB( ProgramObject );
  6.  
  7.   glUniform1iARB( GetUniLoc( ProgramObject, 'Texture0' ), TextureID[ 0 ] );
  8.   glUniform1iARB( GetUniLoc( ProgramObject, 'Texture1' ), TextureID[ 1 ] );
  9.   glUniform1iARB( GetUniLoc( ProgramObject, 'Texture2' ), TextureID[ 2 ] );
  10.   glUniform1iARB( GetUniLoc( ProgramObject, 'Texture3' ), TextureID[ 3 ] );
  11.   glUniform4fARB( GetUniLoc( ProgramObject, 'GlobalColor' , 1.0, 1.0, 1.0, 1.0 );
  12.  
  13.   glBegin(GL_QUADS);
  14.     glTexCoord2f( 0,0 );
  15.     glVertex3f(-0.5,-0.5, -1);
  16.  
  17.     glTexCoord2f( 0,1 );
  18.     glVertex3f( 0.5, -0.5, -1);
  19.  
  20.  
  21.     glTexCoord2f( 1,1 );
  22.     glVertex3f( 0.5, 0.5, -1);
  23.  
  24.  
  25.     glTexCoord2f( 1,0 );
  26.     glVertex3f( -0.5, 0.5, -1);
  27.   glEnd();
  28.  
  29.   glUseProgramObjectARB( 0 );
  30.  
  31.  


Funktion GetUniLoc:

Code:
  1.  
  2.  
  3. function GetUniLoc( ProgrammObjekt: Integer; VarName: String ): Integer;
  4. begin
  5.   Result := glGetUniformLocationARB( ProgrammObjekt, PGLCharARB( VarName ) );
  6. end;
  7.  
  8.  


Könnt ihr mir sagen, was ich falsch mache?
Schöne Grüße, KSM

Autor:  Flash [ Fr Aug 07, 2009 12:43 ]
Betreff des Beitrags: 

Konnte im Wiki ebenfalls kein Code-Archiv zum Tutorial finden. (Nur für GLSL2)

Falls jemand ein passendes Stück Code hat, bitte posten, damit das ins Wiki kann.

Autor:  Coolcat [ Fr Aug 07, 2009 13:14 ]
Betreff des Beitrags: 

Ich denke mal es wird daran liegen das du die Texturen nicht richtig setzt...so müsste es gehen, habe aber nicht probiert:

Code:
  1. glEnable(GL_TEXTURE_2D);
  2. glActiveTexture(GL_TEXTURE0);
  3. glBindTexture(GL_TEXTURE_2D, TextureID[0]);
  4. glActiveTexture(GL_TEXTURE1);
  5. glBindTexture(GL_TEXTURE_2D, TextureID[1]);
  6. glActiveTexture(GL_TEXTURE2);
  7. glBindTexture(GL_TEXTURE_2D, TextureID[2]);
  8. glActiveTexture(GL_TEXTURE3);
  9. glBindTexture(GL_TEXTURE_2D, TextureID[3]);
  10.  
  11. glUseProgramObjectARB( ProgramObject );
  12. glUniform1iARB( GetUniLoc( ProgramObject, 'Texture0' ), 0);
  13. glUniform1iARB( GetUniLoc( ProgramObject, 'Texture1' ), 1);
  14. glUniform1iARB( GetUniLoc( ProgramObject, 'Texture2' ), 2);
  15. glUniform1iARB( GetUniLoc( ProgramObject, 'Texture3' ), 3);
  16. glUniform4fARB( GetUniLoc( ProgramObject, 'GlobalColor' , 1.0, 1.0, 1.0, 1.0 );
  17.  
  18. glBegin(GL_QUADS);
  19. glTexCoord2f( 0,0 );
  20. glVertex3f(-0.5,-0.5, -1);
  21. glTexCoord2f( 0,1 );
  22. glVertex3f( 0.5, -0.5, -1);
  23. glTexCoord2f( 1,1 );
  24. glVertex3f( 0.5, 0.5, -1);
  25. glTexCoord2f( 1,0 );
  26. glVertex3f( -0.5, 0.5, -1);
  27. glEnd();
  28.  
  29. glUseProgramObjectARB( 0 );


Nachtrag:
Sofern die Uniforms (auch nur einzelne) wie in diesem Fall konstant sind, braucht man die nur ein einziges mal setzen. Das geht auch wenn man zwischen durch andere Shader verwendet.

Autor:  KSM [ Fr Aug 07, 2009 13:23 ]
Betreff des Beitrags: 

Hmm, ich habe den Quelltext geändert, er zeigt allerdings nur die Hintergrund-Textur an (TextureID[0]), also die, die nur rot, grün und blau ist.

Autor:  Coolcat [ Fr Aug 07, 2009 14:17 ]
Betreff des Beitrags: 

Sind den die Texturen korrekt geladen, also stimmen die Werte in TextureID[1] bis TextureID[3] ?

Autor:  KSM [ Fr Aug 07, 2009 17:07 ]
Betreff des Beitrags: 

Ja, ohne Shader hat es ja damit immer funktioniert...

Autor:  Coolcat [ Fr Aug 07, 2009 17:35 ]
Betreff des Beitrags: 

Zitat:
Das Laden der Shader funktioniert

Bist du dir da sicher? Hast du auf Compiler- und Link-Fehler geprüft? Für mich sieht das so aus, als ob du ganz normal mit der FFP arbeitest...

Autor:  KSM [ Fr Aug 07, 2009 17:42 ]
Betreff des Beitrags: 

Das Laden funktiiniert auf jeden Fall. ShowMessage liefert leere Dialoge. Hier nochmal der Quelltext:

Code:
  1.  
  2.  
  3. // =============================================================================
  4. //  TfrmMain.SetupShaders
  5. // =============================================================================
  6. //  Hier werden die Shader initialisert.
  7. // =============================================================================
  8. procedure TfrmMain.SetupShaders;
  9. var
  10.   VShader, FShader: AnsiString;
  11.   VShaderl, FShaderl: Integer;
  12.  
  13.   procedure LoadShaderS( Shader: String; var ShaderText: AnsiString; var ShaderLength: Integer );
  14.   var
  15.     Str: TStringList;
  16.     Rc: TResourceStream;
  17.   begin
  18.     Rc := TResourceStream.Create( HInstance, Shader, PChar( Copy( Shader, 1, 2 ) ) );
  19.     try
  20.       Str := TStringList.Create;
  21.       try
  22.         Str.LoadFromStream( Rc );
  23.         ShaderText := AnsiString( Str.Text );
  24.         ShaderLength := Length( Str.Text );
  25.       finally
  26.         Str.Free;
  27.       end;
  28.     finally
  29.       Rc.Free;
  30.     end;
  31.   end;
  32. begin
  33.  
  34.   // Shader erstellen
  35.   ProgramObject := glCreateProgramObjectARB;
  36.   VertexShaderObject := glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
  37.   FragmentShaderObject := glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
  38.  
  39.   // Shadertext laden
  40.   LoadShaderS( 'VSHADER', VShader, VShaderL );
  41.   LoadShaderS( 'FSHADER', FShader, FShaderL );
  42.  
  43.   glShaderSourceARB(VertexShaderObject, 1, @VShader, @VShaderL);
  44.   glShaderSourceARB(FragmentShaderObject, 1, @FShader, @FShaderL);
  45.   // Shadertext kompilieren
  46.   glCompileShaderARB(VertexShaderObject);
  47.   ShowMessage(glSlang_GetInfoLog(VertexShaderObject));
  48.  
  49.   glCompileShaderARB(FragmentShaderObject);
  50.   ShowMessage(glSlang_GetInfoLog(FragmentShaderObject));
  51.  
  52.   // Fehler abrufen
  53.   glAttachObjectARB(ProgramObject, VertexShaderObject);
  54.   glAttachObjectARB(ProgramObject, FragmentShaderObject);
  55.   // Shaderobjekte wieder frei geben
  56.   glDeleteObjectARB(VertexShaderObject);
  57.   glDeleteObjectARB(FragmentShaderObject);
  58.   // Shader linken
  59.   glLinkProgramARB(ProgramObject);
  60.  
  61. end;
  62.  
  63.  


Und die Shader:

Vertexs.:
Code:
  1.  
  2.  
  3. uniform vec4 GlobalColor;
  4.  
  5. void main(void)
  6. {
  7.  gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
  8.  gl_FrontColor   = gl_Color * GlobalColor;
  9.  gl_TexCoord[0]  = gl_MultiTexCoord0;
  10. }
  11.  
  12.  


Fragments.:

Code:
  1.  
  2.  
  3. uniform sampler2D Texture0;
  4. uniform sampler2D Texture1;
  5. uniform sampler2D Texture2;
  6. uniform sampler2D Texture3;
  7.  
  8. void main(void)
  9. {
  10.  vec2 TexCoord = vec2( gl_TexCoord[0] );
  11.  vec4 RGB      = texture2D( Texture0, TexCoord );
  12.  
  13.  gl_FragColor  = texture2D(Texture1, TexCoord) * RGB.r +
  14.                  texture2D(Texture2, TexCoord) * RGB.g +
  15.                  texture2D(Texture3, TexCoord) * RGB.b;
  16. }
  17.  
  18.  

Autor:  Coolcat [ Fr Aug 07, 2009 18:01 ]
Betreff des Beitrags: 

Code:
  1. // Shaderobjekte wieder frei geben
  2. glDeleteObjectARB(VertexShaderObject);
  3. glDeleteObjectARB(FragmentShaderObject);
  4. // Shader linken
  5. glLinkProgramARB(ProgramObject);

Hm, ich weiß nicht ob es eine gute Idee ist die Shader-Objekte freizugeben bevor du das Programm linkst. Allerdings würde ich mal annehmen das dann da eine Fehlermeldung beim Linken kommen würde (und es steht auch so im Tutorial). Ansonsten sieht das eigentlich gut aus.

Autor:  KSM [ Sa Aug 08, 2009 00:18 ]
Betreff des Beitrags: 

Was mich ja so wundert ist, dass er die Haupttextur anzeigt ... :?:

Autor:  humflo [ Sa Aug 08, 2009 02:35 ]
Betreff des Beitrags: 

Muss man nicht für jede Textureinheit das Target aktivieren? Textureinheit haben ja alle ihren eigenen State.
Code:
  1.  
  2. glActiveTexture(GL_TEXTURE0);
  3. glEnable(GL_TEXTURE_2D);
  4. glBindTexture(GL_TEXTURE_2D, TextureID[0]);
  5. glActiveTexture(GL_TEXTURE1);
  6. glEnable(GL_TEXTURE_2D);
  7. glBindTexture(GL_TEXTURE_2D, TextureID[1]);
  8. glActiveTexture(GL_TEXTURE2);
  9. glEnable(GL_TEXTURE_2D);
  10. glBindTexture(GL_TEXTURE_2D, TextureID[2]);
  11. glActiveTexture(GL_TEXTURE3);
  12. glEnable(GL_TEXTURE_2D);
  13. glBindTexture(GL_TEXTURE_2D, TextureID[3]);
  14.  


Zitat:
Hm, ich weiß nicht ob es eine gute Idee ist die Shader-Objekte freizugeben bevor du das Programm linkst. Allerdings würde ich mal annehmen das dann da eine Fehlermeldung beim Linken kommen würde (und es steht auch so im Tutorial). Ansonsten sieht das eigentlich gut aus.

Mache ich auch immer so. Müsste also funktionieren.

humflo

Autor:  KSM [ Sa Aug 08, 2009 11:12 ]
Betreff des Beitrags: 

Daran hab ich auch schon gedacht, hat aber leider auch nicht geholfen :(

Autor:  KSM [ Sa Aug 08, 2009 11:31 ]
Betreff des Beitrags: 

Ich habe mal versucht, statt "GL_TEXTURE0" "GL_TEXTURE0_ARB" zu verwenden, leider auch ohne Erfolg ... Brauche ich denn vielleicht glTexEnv?
Oder muss ich statt glTexCoord2f glMultiTexCoord2f bzw. glMultiTexCoord2f verwenden? Wobei ich letzteres auch versucht habe ...

EDIT:

Könnte mir vielleicht jemand einen Quelltext von einem einfachen Shader schicken?

Autor:  Coolcat [ Sa Aug 08, 2009 11:50 ]
Betreff des Beitrags: 

Setze mal bitte ein
[glsl]gl_FragColor.a = 1.0;[/glsl]
ans Ende des Fragmentshaders. Dein Alpha-Wert ist sonst undefiniert und könnte bei aktiviertem Blending zu komischen Ergebnissen führen.

Wenn das nicht funktioniert, versuch mal bitte diesen Fragmentshader:
[glsl]uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;

void main(void)
{
vec2 TexCoord = vec2( gl_TexCoord[0] );
gl_FragColor = vec4(TexCoord.x, TexCoord.y, 0.0, 1.0);
} [/glsl]

Sollte unabhängig von den Texturen einen Farbverlauf geben: eine Ecke Rot, eine Ecke Grün, eine Ecke Schwarz und eine Ecke Gelb.


Edit:

Zitat:
Brauche ich denn vielleicht glTexEnv?

Sofern du sonst nirgendwo in deinem Programm etwas verstellt hast solltest du das nicht brauchen.

Zitat:
Oder muss ich statt glTexCoord2f glMultiTexCoord2f bzw. glMultiTexCoord2f verwenden?

glTexCoord2f müsste reichen.

Zitat:
Könnte mir vielleicht jemand einen Quelltext von einem einfachen Shader schicken?

Ich habe leider nichts derartiges zur Hand, und sowieso kein Delphi ;)

Autor:  KSM [ Sa Aug 08, 2009 17:48 ]
Betreff des Beitrags: 

Ah! Zwar funktioniert leider der alte Shader nicht, aber bei deinem bekomme ich zumindest ein anderes Bild (siehe Screenshot):

Dateianhänge:
Dateikommentar: Neues Bild
Neues Bild.jpg [119.58 KiB]
6-mal heruntergeladen

Seite 1 von 2 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/