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

Aktuelle Zeit: Mi Mai 08, 2024 09:29

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



Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mo Dez 23, 2013 18:04 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Ein Objekt zeichnen geht gut, aber wen ich zwei oder mehrere Objekte einbinden will, komme ich nicht weiter.
Bei Delphi konnte mit glBindVertexArray(uiVAO[2]); sagen, welche Objekte er zeichnen soll, dasselbe beim renden.
Aber java kennt GLES20.glBindVertexArray(???); nicht.

Code:
  1. import java.nio.ByteBuffer;
  2. import java.nio.ByteOrder;
  3. import java.nio.FloatBuffer;
  4.  
  5. import android.opengl.GLES20;
  6.  
  7.  
  8. public class Triangle {
  9.  
  10.     private final String vertexShaderCode =
  11.             "uniform mat4 uMVPMatrix;" +
  12.             "attribute vec4 vPosition;" +
  13.             "attribute vec4 inColor;" +
  14.             "varying vec4 Color;" +
  15.             "void main() {" +
  16.             "  gl_Position = uMVPMatrix * vPosition;" +
  17.             "  Color = inColor;" +
  18.             "}";
  19.  
  20.     private final String fragmentShaderCode =
  21.             "precision mediump float;" +
  22.             //"uniform vec4 vColor;" +
  23.             "varying vec4 Color; " +
  24.             "void main() {" +
  25.             "  gl_FragColor = Color;" +
  26.             "}";
  27.  
  28.     private final FloatBuffer VectorBuffer;
  29.     private final FloatBuffer ColorBuffer;
  30.     private final FloatBuffer DreieckVectorBuffer;
  31.     private final FloatBuffer DreieckColorBuffer;
  32.    
  33.     private final int mProgram;
  34.     private int mPositionHandle;
  35.     private int mColorHandle;
  36.     private int mMVPMatrixHandle;
  37.    
  38.     static float DreieckCoords[] = TriangleVector.DreieckVector;
  39.     static float DreieckColor[] = TriangleVector.DreieckColor;
  40.     static float triangleCoords[] = TriangleVector.triangleVector;
  41.     static float triangleColor[] = TriangleVector.triangleColor;
  42.  
  43.     private final int trianglevertexCount = triangleCoords.length / 3;
  44.     private final int DreieckvertexCount = DreieckCoords.length / 3;
  45.  
  46.     public Triangle() {
  47.         int vertexShader = MyGLRenderer.loadShader(
  48.                 GLES20.GL_VERTEX_SHADER, vertexShaderCode);
  49.         int fragmentShader = MyGLRenderer.loadShader(
  50.                 GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
  51.  
  52.         mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
  53.         GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
  54.         GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
  55.        
  56.         //GLES20.glBindAttribLocation(mProgram, 0, "vPosition");
  57.         //GLES20.glBindAttribLocation(mProgram, 1, "inColor");
  58.        
  59.         GLES20.glLinkProgram(mProgram);                  // create OpenGL program executables        
  60.         GLES20.glUseProgram(mProgram);      
  61.        
  62.         ByteBuffer bb;
  63.         bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
  64.         bb.order(ByteOrder.nativeOrder());
  65.         VectorBuffer = bb.asFloatBuffer();
  66.         VectorBuffer.put(triangleCoords);
  67.         VectorBuffer.position(0);
  68.        
  69.         bb = ByteBuffer.allocateDirect(triangleColor.length * 4);
  70.         bb.order(ByteOrder.nativeOrder());        
  71.         ColorBuffer = bb.asFloatBuffer();
  72.         ColorBuffer.put(triangleColor);
  73.         ColorBuffer.position(0);
  74.        
  75.         bb = ByteBuffer.allocateDirect(DreieckCoords.length * 4);
  76.         bb.order(ByteOrder.nativeOrder());
  77.         DreieckVectorBuffer = bb.asFloatBuffer();
  78.         DreieckVectorBuffer.put(DreieckCoords);
  79.         DreieckVectorBuffer.position(0);
  80.        
  81.         bb = ByteBuffer.allocateDirect(DreieckColor.length * 4);
  82.         bb.order(ByteOrder.nativeOrder());        
  83.         DreieckColorBuffer = bb.asFloatBuffer();
  84.         DreieckColorBuffer.put(DreieckColor);
  85.         DreieckColorBuffer.position(0);        
  86.              
  87.  
  88.         mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
  89.         mColorHandle = GLES20.glGetAttribLocation(mProgram, "inColor");
  90.         mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");    
  91.        
  92.         VectorBuffer.position(0);
  93.         ColorBuffer.position(0);
  94.         GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, VectorBuffer);
  95.         GLES20.glEnableVertexAttribArray(mPositionHandle);
  96.         GLES20.glVertexAttribPointer(mColorHandle, 3, GLES20.GL_FLOAT, false, 0, ColorBuffer);
  97.         GLES20.glEnableVertexAttribArray(mColorHandle);
  98.        
  99.        
  100.         DreieckVectorBuffer.position(0);
  101.         DreieckColorBuffer.position(0);
  102.         GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, DreieckVectorBuffer);
  103.         GLES20.glEnableVertexAttribArray(mPositionHandle);
  104.         GLES20.glVertexAttribPointer(mColorHandle, 3, GLES20.GL_FLOAT, false, 0, DreieckColorBuffer);
  105.         GLES20.glEnableVertexAttribArray(mColorHandle);            
  106.        
  107.         GLES20.glEnable(GLES20.GL_CULL_FACE); // Nur Vorderseite zeichnen
  108.         GLES20.glCullFace(GLES20.GL_BACK);      
  109.     }
  110.  
  111.  
  112.  
  113.     public void draw(float[] mvpMatrix) {      
  114.        
  115.         GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
  116.  
  117.        
  118.         GLES20.glBindVertexArray(1);  // Kennt java nicht
  119.         VectorBuffer.position(0);
  120.         ColorBuffer.position(0);
  121.         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, trianglevertexCount);
  122.         // Was kommt da ?
  123.         DreieckVectorBuffer.position(0);
  124.         DreieckColorBuffer.position(0);
  125.         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, DreieckvertexCount);
  126.     }
  127.  
  128. }

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Dez 23, 2013 19:15 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Ich nehme einfach mal an, OpenGL ES 2.0 entspricht dem, was auf dem Desktop OpenGL 2.0 ist. Da gibt es noch keine Vertex Array Objects - höchstens mit Extension. Dann bleibt dir nichts anderes übrig, als bei jedem Objektwechsel manuell glBindBuffer, glEnableVertexAttribArray und glDisableVertexAttribArray aufzurufen.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Dez 24, 2013 07:20 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Code:
  1. // Objekt A
  2. GLES20.glVertexAttribPointer(shaderPositionHandle, 3, GLES20.GL_FLOAT, false, 0, VertexBufferA);
  3. GLES20.glEnableVertexAttribArray(shaderPositionHandle);
  4. GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, VertexBufferA.capacity() / 3);
  5. // Objekt B
  6. GLES20.glVertexAttribPointer(shaderPositionHandle, 3, GLES20.GL_FLOAT, false, 0, VertexBufferB);
  7. GLES20.glEnableVertexAttribArray(shaderPositionHandle);
  8. GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, VertexBufferB.capacity() / 3);
  9.  


So (ähnlich, natürlich entsprechend abstrahiert) render ich zumindest meine box2D-Sandbox auf Android, und die stellt jede Menge Objekte gleichzeitig dar.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Dez 24, 2013 13:55 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Dies wollte ich verhindern, das ich jedes mal bei draw mit glVertexAttribPointer die Vectoren neu in den shader schreiben muss.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Dez 24, 2013 16:34 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
Man schreibt die ja auch nicht in den Shader. Das "Pointer" am Ende lässt es evtl erahnen, man zeigt halt nur auf die Daten des anderen Objektes.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Dez 24, 2013 17:30 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Ich dachte, mit glVertexAttribPointer kopiert man die Vector-Daten in den Speicher der Grafikkarte.
Oder verstehe ich das was falsch ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Dez 24, 2013 22:07 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
mathias hat geschrieben:
Ich dachte, mit glVertexAttribPointer kopiert man die Vector-Daten in den Speicher der Grafikkarte.
Oder verstehe ich das was falsch ?

Die Daten werden über das VBO auf die Grafikkarte geladen. Mit VertexAttribPointer sagst du nur noch welche Daten aus dem VBO mit welcher Variable im Shader verknüpft werden. (Also zB. die ersten 4 Floats eines Vertices an den Shader Input mit dem Namen "vPosition", oder 3 Byte an "color" usw.)

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Dez 25, 2013 00:34 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Welcher Befehl lädt die Daten in denVBO, wen es nicht glVertexAttribPointer macht ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Dez 25, 2013 02:35 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
Das geht mit folgenden Befehlen (für Buffer, also auch für IBO's dann halt mit GL_ELEMENT_ARRAY_BUFFER):
Code:
  1. glBufferData(GL_ARRAY_BUFFER,size,PointerToData,mode);
  2. glBufferSubData(GL_ARRAY_BUFFER,offset,size,PointerToData);
glBufferData, glBufferSubData

"Normales" OpenGL unterstützt noch folgende Befehle (diese sind glaube ich nicht in OpenGL ES 2 vorhanden), mit denen du den Buffer auch zurücklesen und ändern kannst:
Code:
  1.  Pointer:=glMapBuffer(GL_ARRAY_BUFFER_ARB,GL_READ_WRITE);
  2. //read/write data to pointer
  3. glUnmapBuffer(GL_ARRAY_BUFFER_ARB); 

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 01, 2014 18:31 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Code:
  1. // draw Routine
  2. GLES20.glUniformMatrix4fv(.....
  3. GLES20.glUniform4f(.....
  4.  
  5. GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, DreieckVectorBuffer);
  6. GLES20.glVertexAttribPointer(mNormalHandle, 3, GLES20.GL_FLOAT, false, 0, DreieckNormalBuffer);
  7. GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, DreieckvertexCount);


Was hat diese Lösung für Nachteile gegenüber dieser mit OpenGL 3.x

Code:
  1. var
  2.   uiVBO: array[0..10] of UINT;
  3.   uiVAO: array[0..2] of UINT;  
  4.  
  5. // Render Routine
  6. glGenVertexArrays(3, uiVAO); // Generate two VAOs, one for triangle and one for quad
  7.  
  8. glGenBuffers(8, uiVBO); // And four VBOs
  9.  
  10. glBindVertexArray(uiVAO[0]); 
  11. glBindBuffer(GL_ARRAY_BUFFER, uiVBO[0]);
  12.  
  13. glBufferData(GL_ARRAY_BUFFER, sizeof(fTriangle), @fTriangle, GL_STATIC_DRAW);
  14. glEnableVertexAttribArray(pos_id);
  15. glVertexAttribPointer(pos_id, 3, GL_FLOAT, False, 0, nil);
  16.  
  17.  
  18. // draw Routine 
  19. glBindVertexArray(uiVAO[0]); // Dreieck
  20.  
  21. glUniformMatrix4fv(.........
  22. glUniform4f(.....
  23.  
  24. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);      

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 01, 2014 18:37 
Offline
DGL Member

Registriert: Do Dez 29, 2011 19:40
Beiträge: 421
Wohnort: Deutschland, Bayern
Programmiersprache: C++, C, D, C# VB.Net
So wie du es machst, gar keine.
VAOs gibt es eigentlich dafür, damit die Einstellungen wie die Daten in einen VBO Aufgebaut sind, nicht immer wieder erneut eingestellt werden müssen.
Für das Rendern muss dann nur noch mit einen OpenGL-Aufruf das VAO gebunden werden und es kann los gehen.
Es ist einfach eine Funktion die darauf abzielt, viele unnötige redundante performanceraubende OpenGL-Aufrufe zur Laufzeit beim Rendern einzusparen.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 01, 2014 18:51 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Vielleicht hast du mich falsch verstanden, was ich bei // Render Routine habe, wird nur einmal im Programm aufgerufen. Die // draw Routine bei jedem Timer-Aufruf.

So wie ich es weiter oben verstanden habe braucht VertexAttribPointer fast keine Zeit, da nur ein Pointer auf die Array zeigt.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 01, 2014 19:01 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Jeder OpenGL-Funktionsaufruf braucht Zeit, weshalb man die Anzahl möglichst niedrig halten sollte. Durch den Einsatz von VAOs sparst du dir wie gesagt Aufrufe wie glBindBuffer, glEnableVertexAttribArray und glDisableVertexAttribArray. Dass es in OpenGL2 (ES) bei dir trotzdem ohne diese Funktionen in der Draw-Routine (dazu sagt man eigentlich auch Render-Routine) funktioniert, liegt wahrscheinlich daran, dass du nur ein Objekt zeichnest und daher nie das VBO bzw. die VertexAttrib-Einstellungen ändern musst.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 01, 2014 20:42 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Dass es in OpenGL2 (ES) bei dir trotzdem ohne diese Funktionen in der Draw-Routine (dazu sagt man eigentlich auch Render-Routine) funktioniert, liegt wahrscheinlich daran, dass du nur ein Objekt zeichnest und daher nie das VBO bzw. die VertexAttrib-Einstellungen ändern musst.
Ich habe die Routine zur Initialisierung auf InitScene umbenannt.
Ich habe drei Objekte, mit je einem Vektor und Normalen Vertex welche initialisieren muss und das Programm läuft. Ich hoffe ich habe die Elemente richtig genannt.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 15 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.027s | 18 Queries | GZIP : On ]