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

Aktuelle Zeit: Mi Apr 24, 2024 05:01

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



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Wie rendert man richtig Objekte?
BeitragVerfasst: Fr Jun 27, 2014 13:34 
Offline
DGL Member

Registriert: Di Aug 09, 2011 07:33
Beiträge: 163
Programmiersprache: C/C++
Hey,

Ich beschäftige mich gerade mit OpenGL 3.X und höher und habe nun Probleme Objekte richtig zu rendern.
Die gängie Methode sollte es ja sein ein/mehrere VBO(s) zu erstellen und anschließend erstellt man ein VAO mit den Daten.

Das Problem beginnt, wenn das Objekt 2 oder mehr Texturen hat, da ich ja nur zu begin einmal eine Texture binden kann.
Nur wie macht man es richtig? Ich habe wo gelesen, dass man für jede Textur die das Objekt hat ein extra VBO erstellt nur ist das wirklich schnell?
Und wie setze ich dann richtig das VAO zusammen bzw. den passenden Shader?

:cry:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Wie rendert man richtig Objekte?
BeitragVerfasst: Fr Jun 27, 2014 17:53 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1278
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Du kannst für jedes Object eine eigene Textur binden. Ich habe ein etwas älterer Quelltext gefunden welcher 2 Object mit unterschiedlicher Textur demonstriert. Vieleicht hilft dir dieser weiter.

Code:
  1. var
  2.   uiVBO: array[0..10] of UINT;
  3.   uiVAO: array[0..2] of UINT;
  4.  
  5.   WorldMatrix_id, CameraMatrix_id, texture_id, pos_id, col_id, Normale_id: GLint;
  6.  
  7.   textureID1, textureID2: GLuint;
  8.  
  9. var
  10.   tx, ty, tx2, ty2: integer;
  11.   TexturData1, TexturData2: array of GLuint;
  12.  
  13. procedure TForm1.InitScene;
  14. var
  15.   x, y: integer;
  16.   p: Pointer;
  17. begin
  18.   tx := Image1.Picture.Width;
  19.   ty := Image1.Picture.Height;
  20.   SetLength(TexturData1, tx * ty);
  21.   for x := 0 to tx - 1 do begin
  22.     for y := 0 to ty - 1 do begin
  23.       TexturData1[y * tx + x] := Image2.Picture.Bitmap.Canvas.Pixels[x, y];
  24.     end;
  25.   end;
  26.  
  27.   tx2 := Image2.Picture.Width;
  28.   ty2 := Image2.Picture.Height;
  29.   SetLength(TexturData2, tx2 * ty2);
  30.   for x := 0 to tx2 - 1 do begin
  31.     for y := 0 to ty2 - 1 do begin
  32.       TexturData2[y * tx2 + x] := Image1.Picture.Bitmap.Canvas.Pixels[x, y];
  33.     end;
  34.   end;
  35.  
  36.   ProgramID := InitShader('VertexShader.txt', 'FragmentShader.txt');
  37.   glUseProgram(programID);
  38.  
  39.   VertexModif.Normale(fCube, FCubeNormale);
  40.   VertexModif.Normale(Triangle, fTriangleNormale);
  41.  
  42.   glClearColor(0.0, 0.5, 1.0, 1.0); //Hintergrundfarbe: Hier ein leichtes Blau
  43.  
  44.   // Enable depth test
  45.   glEnable(GL_DEPTH_TEST);
  46.   // Accept fragment if it closer to the camera than the former one
  47.   glDepthFunc(GL_LESS);
  48.  
  49.   pos_id := glGetAttribLocation(ProgramID, 'inPos');
  50.   col_id := glGetAttribLocation(ProgramID, 'inColor');
  51.   Normale_id := glGetAttribLocation(ProgramID, 'inNormal');
  52.   texture_id := glGetAttribLocation(ProgramID, 'vertexUV');
  53.  
  54.  
  55.   WorldMatrix_id := glGetUniformLocation(ProgramID, PGLCharARB('WorldMatrix'));
  56.   CameraMatrix_id := glGetUniformLocation(ProgramID, PGLCharARB('CameraMatrix'));
  57.  
  58.   glGenVertexArrays(2, uiVAO);
  59.  
  60.   glGenBuffers(6, uiVBO);
  61.  
  62.   glBindVertexArray(uiVAO[0]); // Dreieck
  63.  
  64.   glBindBuffer(GL_ARRAY_BUFFER, uiVBO[0]);
  65.   glBufferData(GL_ARRAY_BUFFER, sizeof(Triangle), @Triangle, GL_STATIC_DRAW);
  66.   glEnableVertexAttribArray(pos_id);
  67.   glVertexAttribPointer(pos_id, 3, GL_FLOAT, False, 0, nil);
  68.  
  69.   glBindBuffer(GL_ARRAY_BUFFER, uiVBO[1]);
  70.   glBufferData(GL_ARRAY_BUFFER, sizeof(fTriangleNormale), @fTriangleNormale, GL_STATIC_DRAW);
  71.   glEnableVertexAttribArray(Normale_id);
  72.   glVertexAttribPointer(Normale_id, 3, GL_FLOAT, False, 0, nil);
  73.  
  74.   glBindBuffer(GL_ARRAY_BUFFER, uiVBO[2]);
  75.   glBufferData(GL_ARRAY_BUFFER, sizeof(TriangleTextureVertex), @TriangleTextureVertex, GL_STATIC_DRAW);
  76.   glEnableVertexAttribArray(texture_id);
  77.   glVertexAttribPointer(texture_id, 2, GL_FLOAT, False, 0, nil);
  78.  
  79.   glGenTextures(1, @textureID1);
  80.   glBindTexture(GL_TEXTURE_2D, textureID1);
  81.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx, ty, 0, GL_RGBA, GL_UNSIGNED_BYTE, Pointer(TexturData1));
  82.   //  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  83.   //  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  84.   glGenerateMipmap(GL_TEXTURE_2D);
  85.  
  86.   glBindVertexArray(uiVAO[1]);    // Würfel
  87.  
  88.   glBindBuffer(GL_ARRAY_BUFFER, uiVBO[3]);
  89.   glBufferData(GL_ARRAY_BUFFER, sizeof(fCube), @fCube, GL_STATIC_DRAW);
  90.   glEnableVertexAttribArray(pos_id);
  91.   glVertexAttribPointer(pos_id, 3, GL_FLOAT, False, 0, nil);
  92.  
  93.   glBindBuffer(GL_ARRAY_BUFFER, uiVBO[4]);
  94.   glBufferData(GL_ARRAY_BUFFER, sizeof(fCubeNormale), @fCubeNormale, GL_STATIC_DRAW);
  95.   glEnableVertexAttribArray(Normale_id);
  96.   glVertexAttribPointer(Normale_id, 3, GL_FLOAT, False, 0, nil);
  97.  
  98.   glBindBuffer(GL_ARRAY_BUFFER, uiVBO[5]);
  99.   glBufferData(GL_ARRAY_BUFFER, sizeof(CubeTextureVec), @CubeTextureVec, GL_STATIC_DRAW);
  100.   glEnableVertexAttribArray(texture_id);
  101.   glVertexAttribPointer(texture_id, 2, GL_FLOAT, False, 0, nil);
  102.  
  103.   glGenTextures(1, @textureID2);
  104.   glBindTexture(GL_TEXTURE_2D, textureID2);
  105.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx2, ty2, 0, GL_RGBA, GL_UNSIGNED_BYTE, Pointer(TexturData2));
  106.   //  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  107.   //  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  108.   glGenerateMipmap(GL_TEXTURE_2D);
  109.  
  110. end;
  111.  
  112. procedure TForm1.RenderScene;
  113. var
  114.   CMatrix: TMatrix;
  115.  
  116. begin
  117.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);  // We just clear color
  118.  
  119.   glEnable(GL_CULL_FACE);
  120.   glCullface(GL_BACK);
  121.  
  122.  
  123.   glBindVertexArray(uiVAO[0]); // Dreieck
  124.   glBindTexture(GL_TEXTURE_2D, textureID1);
  125.  
  126.   Matrix := WurfelMatrix;
  127.  
  128.  
  129.   glUniformMatrix4fv(WorldMatrix_id, 1, False, @Matrix);
  130.   CMatrix := MatrixModif.MultiplyMatrices(CameraMatrix, Matrix);
  131.   glUniformMatrix4fv(CameraMatrix_id, 1, False, @CMatrix);
  132.   glDrawArrays(GL_TRIANGLES, 0, Length(Triangle) * 3);
  133.  
  134.  
  135.   glBindVertexArray(uiVAO[1]); // Würfel
  136.   glBindTexture(GL_TEXTURE_2D, textureID2);
  137.  
  138.   Matrix := WurfelMatrix;
  139.  
  140.   MatrixModif.Translate(Matrix, -0.5, -0.2, 0);
  141.   glUniformMatrix4fv(WorldMatrix_id, 1, False, @Matrix);
  142.   CMatrix := MatrixModif.MultiplyMatrices(CameraMatrix, Matrix);
  143.   glUniformMatrix4fv(CameraMatrix_id, 1, False, @CMatrix);
  144.   glDrawArrays(GL_TRIANGLES, 0, Length(fCube) * 3);
  145.  
  146.  
  147.   SwapBuffers(DC);
  148. end;    

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Wie rendert man richtig Objekte?
BeitragVerfasst: Fr Jun 27, 2014 22:51 
Offline
DGL Member

Registriert: Do Dez 29, 2011 19:40
Beiträge: 421
Wohnort: Deutschland, Bayern
Programmiersprache: C++, C, D, C# VB.Net
Grundsätzlich kannst du zur Zeit tatsächlich immernur mit einigen wenigen Texturen rendern.
Es gibt ein paar sehr neue Extensions die das aufheben können, aber ich glaube nicht, dass dich diese jetzt weiterhelfe. (Bindless Texture)
Gängig gibt es im Prinzip zwei Lösungsansätze die je nach Fall zur Anwendung kommen:
  1. Die verschiedenen Texturen verbinden. Zum Beispiel in einem Texturatlas oder noch besser einem Texture Array.
  2. Oder aber ein Objekt nicht in einem Schwung rendern sondern die verschieden texturierten Teile jeweils einzelln rendern. Prinzipiell ein weniger performanter Ansatz, weil mehr Draw Calls leicht eine signifikante Engstelle werden kann. Texturwechsel sind wie alle Statewechsel auch nicht gerade das Schnellste.
  3. Es besteht auch noch die theoretische Möglichkeit mit mehreren Samplern also Multitexturing mit mehreren Textureunits und die Textur im Shader auswählen. Allerdings ist die Anzahl der Texturen dann wieder stark beschränkt, weil nur eine bestimmte Anzahl Texture Units zur Verfügung steht. Die Performance ist auf jeden Fall ersterem unterlegen, im Vergleich zu 2. traue ich mir keine sichere Aussage zu. Schon gar nicht für de allgemeinen Fall.


Normalerweise würde ich in Richtung 1. gehen. Das Verbinden von Texturen kann von Hand machen oder automatisieren. Einige 3D Programme sollen das können. Der Renderer und Shader sind außerdem super simpel umzusetzen, weil ja weiterhin nur eine logische Textur existiert.


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: 0 Mitglieder und 38 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.192s | 17 Queries | GZIP : On ]