DGL https://delphigl.com/forum/ |
|
Anfängerfrage Shader https://delphigl.com/forum/viewtopic.php?f=20&t=9341 |
Seite 1 von 1 |
Autor: | Shaddow [ Mo Jul 19, 2010 22:36 ] |
Betreff des Beitrags: | Anfängerfrage Shader |
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 |
Autor: | k-bal [ Mo Jul 19, 2010 22:51 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
Dein Vertexshader muss noch die Farbe setzen: Code: void main()
{ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_FrontColor = gl_Color; } |
Autor: | Shaddow [ Di Jul 20, 2010 19:39 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
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? |
Autor: | Coolcat [ Di Jul 20, 2010 21:33 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
Bau mal absichtlich einen Fehler in den Shader ein um zu testen ob deine Fehlerabfrage beim compilieren sowie beim linken funktioniert. |
Autor: | Shaddow [ Di Jul 20, 2010 21:40 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
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); } |
Autor: | Coolcat [ Di Jul 20, 2010 21:47 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
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. |
Autor: | Shaddow [ Di Jul 20, 2010 22:17 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
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 ![]() nun gehts ![]() danke |
Autor: | Shaddow [ Mi Jul 21, 2010 22:00 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
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? |
Autor: | Coolcat [ Do Jul 22, 2010 10:05 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
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. |
Autor: | Shaddow [ Sa Jul 24, 2010 00:35 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
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? |
Autor: | Coolcat [ Sa Jul 24, 2010 08:15 ] |
Betreff des Beitrags: | Re: Anfängerfrage Shader |
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); } |
Seite 1 von 1 | Alle Zeiten sind UTC + 1 Stunde |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |