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

Aktuelle Zeit: Do Mär 28, 2024 13:06

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



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
BeitragVerfasst: So Sep 18, 2016 18:49 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Hallo,
im Moment experimentiere ich gerade mit einigen Extensions, um den CPU-Overhead zu reduzieren und da bin ich jetzt bei GL_ARB_multi_draw_indirect gelandet. Bei dieser Extension lädt man beliebig viele auszuführende Rendercalls in einen Command-Buffer und frühstückt die anschließend alle mit einem einzigen glMultiDrawElementsIndirect ab. Dabei möchte ich die baseInstance auch auf andere Werte als 0 setzen. Deshalb fordere ich einen GL 4.2-Kontext an, da baseInstance laut OpenGL-Wiki sonst nicht funktioniert. Oder muss man das noch irgendwie explizit anschalten?

Hier der Code, mit dem ich den Command-Buffer erstelle:
Code:
  1. void setupCommandBuffer()
  2. {
  3.   // entweder 1 command mit 3 instances oder 3 commands mit jeweils 1 instance
  4.   constexpr bool allInOneCommand = true;
  5.  
  6.   commands.resize(allInOneCommand? 1: 3);
  7.   for(unsigned int i=0; i<commands.size(); ++i) {
  8.     commands[i].count = 6;
  9.     commands[i].instanceCount = allInOneCommand? 3: 1;
  10.     commands[i].baseIndex = 0;
  11.     commands[i].baseVertex = 0;
  12.     commands[i].baseInstance = i;
  13.   }
  14.  
  15.   glGenBuffers(1, &CboID);
  16.   glBindBuffer(GL_DRAW_INDIRECT_BUFFER, CboID);
  17.   glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(commands[0])*commands.size(), &commands[0], GL_STATIC_DRAW);
  18. }


Anschließend rendere ich mit glMultiDrawElementsIndirect:
Code:
  1. glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0, commands.size(), 0);


Mein Problem ist nun, dass ich im Shader nicht an die baseInstance herankomme. Auf gl_InstanceID hat sie ja keinen Einfluss. Mit der Extension GL_ARB_shader_draw_parameters hätte ich im Vertexshader zwar Zugriff auf die Variable gl_BaseInstanceARB, jedoch möchte ich diese Extension nicht zwingend voraussetzen.
Also habe ich mir überlegt, einen weiteren VBO mit den baseInstances anzulegen und diesen in das VAO einzubinden. Dabei verwende ich glVertexAttribDivisor, um das Vertexattribut einmal pro Instanz (statt pro Vertex) zu aktualisieren:
Code:
  1.   // vbo
  2.   // 1 quad = 4 vertices = 12 floats
  3.   float vertexbuffer[12] = {-0.1,-0.1, 0.0,
  4.                             -0.1, 0.1, 0.0,
  5.                              0.1, 0.1, 0.0,
  6.                              0.1,-0.1, 0.0};
  7.   glGenBuffers(1, &VboID);
  8.   glBindBuffer(GL_ARRAY_BUFFER, VboID);
  9.   glBufferData(GL_ARRAY_BUFFER, sizeof(vertexbuffer), vertexbuffer, GL_STATIC_DRAW);
  10.  
  11.   // vbo2
  12.   int baseInstanceBuffer[3] = {0,1,2};
  13.   glGenBuffers(1, &Vbo2ID);
  14.   glBindBuffer(GL_ARRAY_BUFFER, Vbo2ID);
  15.   glBufferData(GL_ARRAY_BUFFER, sizeof(baseInstanceBuffer), baseInstanceBuffer, GL_STATIC_DRAW);
  16.  
  17.   // vao
  18.   glGenVertexArrays(1, &VaoID);
  19.   glBindVertexArray(VaoID);
  20.   glBindBuffer(GL_ARRAY_BUFFER, VboID);
  21.   glEnableVertexAttribArray(0); // inPos
  22.   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, (void*) 0);
  23.  
  24.   glBindBuffer(GL_ARRAY_BUFFER, Vbo2ID);
  25.   glEnableVertexAttribArray(1); // inVboInstance
  26.   glVertexAttribIPointer(1, 3, GL_INT, 4, (void*) 0);
  27.   glVertexAttribDivisor(1, 1);


Zum Rendern verwende ich folgende Shader:
Code:
  1. #version 420
  2. // vertex shader //
  3. layout(location=0) in vec3 inPos;
  4. layout(location=1) in int inVboInstance;
  5.  
  6. flat out int vf_glInstanceID;
  7.  
  8. void main(void)
  9. {
  10.   vec3 offsets[3];
  11.   offsets[0] = vec3(-0.5, 0.0, 0.0);
  12.   offsets[1] = vec3( 0.0, 0.0, 0.0);
  13.   offsets[2] = vec3( 0.5, 0.0, 0.0);
  14.  
  15.   gl_Position = vec4(inPos + offsets[/*gl_InstanceID +*/inVboInstance], 1.0);
  16.   vf_glInstanceID = gl_InstanceID;
  17. }


Code:
  1. #version 420
  2. // fragment shader //
  3. flat in int vf_glInstanceID;
  4. layout(location=0) out vec4 outColor;
  5.  
  6. void main(void)
  7. {
  8.   vec4 colors[3];
  9.   colors[0] = vec4(1.0, 0.0, 0.0, 1.0);
  10.   colors[1] = vec4(0.0, 1.0, 0.0, 1.0);
  11.   colors[2] = vec4(0.0, 0.0, 1.0, 1.0);
  12.  
  13.   outColor = colors[vf_glInstanceID];
  14. }

Eigentlich müssten als Ergebnis ein rotes, ein grünes und ein blaues Viereck nebeneinander zu sehen sein, unabhängig davon ob ich die Konstante allInOneCommand auf true oder false setze. Offenbar habe ich aber irgendwo einen Fehler drin, so dass inVboInstance im Vertexshader immer 0 ist und daher stets nur ein Viereck sichtbar ist.
Dateianhang:
So soll es aussehen (Bild ist durch Schummelei entstanden).png

Im Anhang ist schließlich noch der gesamte Code (~200 Zeilen). Ich hoffe jemand sieht, was ich falsch mache. Vielen Dank im Voraus!


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
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: Mo Sep 19, 2016 16:10 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Code:
  1.   glBindBuffer(GL_ARRAY_BUFFER, Vbo2ID);
  2.   glEnableVertexAttribArray(1); // inVboInstance
  3.   glVertexAttribIPointer(1, 3, GL_INT, 4, (void*) 0);
  4.   glVertexAttribDivisor(1, 1);

Dein glVertexAttribIPointer sieht für mich falsch aus.
Wenn ich die Doku richtig lese, sollte es folgendes sein.
Code:
  1. glVertexAttribIPointer(1, 1, GL_INT, 4, (void*) 0);

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Sep 19, 2016 17:25 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Oh Mann. Natürlich. Vielen Dank für den Hinweis! Und natürlich sind alle drei Vierecke rot, wenn ich allInOneCommand auf false setze.

_________________
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  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 29 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.051s | 18 Queries | GZIP : On ]