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

Aktuelle Zeit: Di Mai 14, 2024 08:21

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



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Anfängerfrage Shader
BeitragVerfasst: Mo Jul 19, 2010 22:36 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Hi,
hab eigentlich immer versucht, einen Bogen um Shader zu machen, aber nun will ich sie mir mal doch ansehen... und schon das erste Problem, in einer eigentlich sehr leichten Beispielanwendung:

Code:
      //testShader.use();
      gl.glColor3f(1,1,1);
      gl.glBegin(GL.GL_QUADS);
      gl.glVertex3f(10f, 10f, -50f);
      gl.glColor3f(0,0,1);
      gl.glVertex3f(10f, 0f, -50f);
      gl.glColor3f(1,0,0);
      gl.glVertex3f(0f, 0f, -50f);
      gl.glColor3f(0,1,0);
      gl.glVertex3f(0f, 10f, -50f);
      gl.glEnd();

Zeichnet mir ein Farbiges Rechteck auf den Bildschirm

Wenn ich nun die oberste Zeile reinnehme, bleibt das Bild schwarz. Allerdings kommt auch kein Fehler. Der Inhalt des Shaders wird correct geladen, compiliert und gelinkt. Also nehme ich mal an, der Shader ist falsch. Aber der ist im grunde auch äußerst simpel:
Code:
// vertexshader:
void main() {
   gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
}

//fragmentshader:
void main() {
    gl_FragColor = gl_Color;
}


Kann mir da wer helfen? Danke schonmal


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Mo Jul 19, 2010 22:51 
Offline
DGL Member

Registriert: Do Jan 07, 2010 21:21
Beiträge: 19
Dein Vertexshader muss noch die Farbe setzen:

Code:
void main()
{
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   gl_FrontColor = gl_Color;
}


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Di Jul 20, 2010 19:39 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Okay ich hab das gl_FrontColor = gl_Color; in den vertexshader eingebaut
Allerdings bekomme ich nun eine GL_INVALID_OPERATION

Das Quad wird zwar gezeichnet, aber das wird ja standardmäßig gezeichnet, ob der Shader nun aktiviert ist oder nicht. Die GL_INVALID_OPERATION tritt bei dem aufruf von glUseProgram auf. laut wiki sorgt GL_INVALID_OPERATION dafür, dass die entsprechende operation ignoriert wird. also ist das ganze im Endeffekt so, als haette ich den Shader gar nicht aktiviert und deswegen wird das quad wohl auch gezeichnet. Woran kann dieses GL_INVALID_OPERATION liegen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Di Jul 20, 2010 21:33 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Bau mal absichtlich einen Fehler in den Shader ein um zu testen ob deine Fehlerabfrage beim compilieren sowie beim linken funktioniert.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Di Jul 20, 2010 21:40 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Mh also ne dedizierte Fehlerabfrage beim Compilieren des Shaders hab ich ja im grunde nicht
Ich hab nur die OGL Fehlerabfrage

ich habe mal an den vertexshader ne zeichenkette angehängt: x+y
beide variablen undefiniert, kein semikolon am ende, sollte hoffentlich knallen
Der fehler allerdings bleibt gleich
Wenn ich das useProgram aus der renderroutine rausnehme und den shader nur compilieren und linken lasse, kommt gar kein fehler
also irgendwas stimmt wohl nicht

mal etwas code zum Shader selbst
Code:
public class Shader extends Resource {

   private static GL gl;
   
   private String vertexSource;
   private String fragmentSource;
   
   private int vertexShaderObject;
   private int fragmentShaderObject;
   
   private int shaderProgram;
   
   private int idxModelViewProjection = -1;
   private int idxModelView = -1;
   private int idxNormalMatrix = -1;
   
   
   public Shader(String resourceID, String vertexShaderSource, String fragmentShader) {
      super(resourceID);
      
      gl = Renderer.getInstance().getGL();
   
      vertexSource = vertexShaderSource;
      fragmentSource = fragmentShader;
      
      vertexShaderObject = loadShader(gl.GL_VERTEX_SHADER, vertexSource);
      fragmentShaderObject = loadShader(gl.GL_FRAGMENT_SHADER, fragmentSource);
      
      shaderProgram = attachToProgram(vertexShaderObject, fragmentShaderObject);
   
   }
   
   private static int loadShader(int shaderType, String shaderSource) {
      int result = Renderer.getInstance().getGL().glCreateShader(shaderType);
      
          // Vertex Shader
      BufferedInputStream vert_reader;
        try {
            //vert_reader = new BufferedReader(new FileReader(shaderSource));
           vert_reader = new BufferedInputStream(ResourceManager.getResourceAsStream(shaderSource));
        } catch (FileNotFoundException e) {
            System.out.println(e);
            return -1;
        }
      catch (IOException e)
      {
            System.out.println(e);
            return -1;
      }
        String[] vshader = new String[1];
        vshader[0] = "";
        String line;
        byte[] buffer = new byte[1024];
       
        int bytesRead = 0;
        try
      {
         while ((bytesRead = vert_reader.read(buffer)) != -1) {
            vshader[0] += new String(buffer, 0, bytesRead);
         }
         System.out.println(vshader[0]);
      }
      catch (IOException e)
      {
         
         e.printStackTrace();
         System.out.println("error");
         return -1;
      }
       
        int[] vlen = new int[1];
        vlen[0] = vshader[0].length();
    //    System.out.println(vshader[0]);

        gl.glShaderSource(result, 1, vshader, vlen, 0);
        gl.glCompileShader(result);
       
        String infoLog = getShaderInfoLog(result);
        if (infoLog != null)
           throw new RuntimeException("Shader incorrect");
       
       return result;
   }
   
   public static String getShaderInfoLog(int shaderObject) {
   //   gl.glGetShaderInfoLog(arg0, arg1, arg2, arg3)
      return null;
      
   }

   
   public static int attachToProgram(int vertexShaderObject, int fragmentShaderObject) {
        // Shaderprogram
        int shaderProgram = gl.glCreateProgram();
        gl.glAttachShader(shaderProgram, vertexShaderObject);
        gl.glAttachShader(shaderProgram, fragmentShaderObject);
        gl.glLinkProgram(shaderProgram);
        gl.glValidateProgram(shaderProgram);
        // Freigeben
        gl.glDeleteShader(vertexShaderObject);
        gl.glDeleteShader(fragmentShaderObject);
        return shaderProgram;
   }
   
   public void link() {
      gl.glLinkProgram(shaderProgram);
   }
   
   public void use() {
      gl.glUseProgram(shaderProgram);
   }


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Di Jul 20, 2010 21:47 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Mh also ne dedizierte Fehlerabfrage beim Compilieren des Shaders hab ich ja im grunde nicht
Ich hab nur die OGL Fehlerabfrage

Du musst explizit auf Shaderfehler beim compilieren der beiden Shader sowie beim linken testen. Dabei werden keine normalen OpenGL-Fehler ausgelöst! Der (vermutliche) Grund ist das man Shader häufig dynamisch lädt und nicht die ganze Anwendung abstürzen soll nur weil irgendwo ein Shader nicht geht.

_________________
Yeah! :mrgreen:


Zuletzt geändert von Coolcat am Di Jul 20, 2010 22:24, insgesamt 2-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Di Jul 20, 2010 22:17 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Okay sonne kleine Logging Methode wirkt wirklich wunder:

Vertex shader failed to compile with the following errors:
ERROR: 0:3: 'gl_FragColor' : undeclared identifier
ERROR: 0:3: 'assign' : cannot convert from 'attribute 4-component vector of float' to 'float'
ERROR: 2 compilation errors. No code generated.

Und der Grund war, dass ich einfach nicht aufmerksam gelesen hatte. Ich hab im VertexShader fragColor statt frontColor gesetzt... naja :D
nun gehts :D

danke


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Mi Jul 21, 2010 22:00 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
OKay nächstes Problem:

eine Variable, die ich Probehalber an den Shader übergeben will:
Code:
      gl.glUniform4fv(testShader.getUniformLocation("myColor"), 4, new float[]{0.5f,1f,0.5f,1.0f}, 0);

// erklärung von testShader.getUniformLocation
   public int getUniformLocation(String identifier) {
      return gl.glGetUniformLocation(shaderProgram, identifier);
   }


die Variable teste ich folgendermaßen:
Code:
// vertexshader:
uniform vec4 myColor;
void main() {
   gl_Position  = gl_ModelViewProjectionMatrix * gl_Vertex;

}

//fragmentshader:
uniform vec4 myColor;
void main() {
    gl_FragColor = myColor;
}


Resultat: Das Bild bleibt schwarz, OGL meldet eine GL_INVALID_OPERATION, aber der getShaderLogInfo liefert keinen Fehler.

Das Wiki liefert ja nun einige Infos zu invalid_operation:
GL_INVALID_OPERATION wird generiert, wenn es kein aktives Programmobjekt gibt. -> ging ja vorher, ich würd sagen, daran liegts nich
GL_INVALID_OPERATION wird generiert, wenn die Größe der Uniform-Variable im Shader nicht mit dem entsprechenden Befehl übereinstimmt. -> stimmt meiner Meinung nach
GL_INVALID_OPERATION wird generiert, wenn einer der Integer-Verionen dazu verwendet wird, eine Variable vom Typ float, vec2, vec3, vec4 oder eines Arrays dieses Typs zu verändern. Gleiches gilt für das verändern von int-Variablen, die nicht mit Befehlen vom Typ glUniform*f beschrieben werden können. -> versteh ich nicht
GL_INVALID_OPERATION wird generiert, wenn location ein ungültiger Ort für das aktuelle Programmobjekt ist und location gleichzeitig -1 ist. -> location liefert den Wert 1. Klingt gültig
GL_INVALID_OPERATION wird generiert, wenn count größer als 1 ist und die entsprechende Uniform-Variable kein Array ist. -> zwar größer als eins, aber es geht ja um ein array
GL_INVALID_OPERATION wird generiert, wenn ein sampler mit einem anderen Befehl als glUniform1i und glUniform1iv geladen wird. -> kein Sampler, nicht relevant
GL_INVALID_OPERATION wird generiert wenn glUniform innerhalb eines glBegin-glEnd Blocks aufgerufen wird. -> auch nicht der Fall


Idee?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Do Jul 22, 2010 10:05 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
GL_INVALID_OPERATION wird generiert, wenn es kein aktives Programmobjekt gibt.

Hast du vor dem glUniform4fv den glUseProgram aufgerufen? Im Gegensatz zu glGetUniformLocation bekommt glUniform* nämlich nicht das Programm als Parameter übergeben.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Sa Jul 24, 2010 00:35 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Okay das war natuerlich der Grund ;)

Gleich noch ne Frage zum Shader: http://wiki.delphigl.com/index.php/shader_Terrain_GPU4
In der Beschreibung steht, ein 65 VBO reicht.

So wie mein verständnis ist, brauche ich nicht zwangsläufig ein VBO oder? Ich müsste auch einfach alle Vertices per gl_triangle übergeben können oder? also mit iterierenden x und y koordinaten von 0 bis 64?

Oder muss ich wirklich ein VBO bereitstellen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Anfängerfrage Shader
BeitragVerfasst: Sa Jul 24, 2010 08:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Natürlich würde das gehen, die Frage ist was du dann davon hast. Es geht ja darum so wenig Daten wie möglich an die Grafikkarte schicken zu müssen. Wenn du dann doch die Vertexdaten für jeden Terrainblock neu schicken musst kannst du dir den Aufwand auch sparen.

Über eine Displayliste würde es natürlich gehen. So ein VBO und IBO ist aber auch schnell erstellt:
Code:
const int TERRAIN_LEAFSIZE = 64;
GLuint m_vboLeaf;
GLuint m_iboLeaf;

// create vertex buffer object
{
   glGenBuffers(1, &m_vboLeaf);
   glBindBuffer(GL_ARRAY_BUFFER, m_vboLeaf);
   int verts = TERRAIN_LEAFSIZE+1;
   int data_size = verts*verts*2*sizeof(float);
   glBufferData(GL_ARRAY_BUFFER, data_size, NULL, GL_STATIC_DRAW);
   float* data = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
   int pos = 0;
   for (int y=0; y<verts; ++y) {
      for (int x=0; x<verts; ++x) {
         data[pos++] = x;
         data[pos++] = y;
      }
   }
   glUnmapBuffer(GL_ARRAY_BUFFER);
}


// create index buffer object
{
   glGenBuffers(1, &m_iboLeaf);
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_iboLeaf);
   int verts = TERRAIN_LEAFSIZE+1;
   int data_size = TERRAIN_LEAFSIZE*TERRAIN_LEAFSIZE*2*3*sizeof(GLushort);
   glBufferData(GL_ELEMENT_ARRAY_BUFFER, data_size, NULL, GL_STATIC_DRAW);
   GLushort* data = (GLushort*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
   int pos = 0;
   for (int y=0; y<TERRAIN_LEAFSIZE; ++y) {
      for (int x=0; x<TERRAIN_LEAFSIZE; ++x) {
         data[pos++] = (x+0) + (y+0) * verts;
         data[pos++] = (x+0) + (y+1) * verts;
         data[pos++] = (x+1) + (y+1) * verts;
         data[pos++] = (x+1) + (y+1) * verts;
         data[pos++] = (x+1) + (y+0) * verts;
         data[pos++] = (x+0) + (y+0) * verts;
      }
   }
   glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
}

_________________
Yeah! :mrgreen:


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 » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 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.024s | 17 Queries | GZIP : On ]