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

Aktuelle Zeit: Mi Jul 16, 2025 10:45

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



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Mehrere Ausgabefenster
BeitragVerfasst: So Aug 03, 2014 17:01 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1282
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Ich habe auf 2 Panels je ein OpenGLControl gesetzt.

Ich habe festgestellt, das es für jedes Fenster ein eigener Shader braucht.
Auch die Zeilen mit glGenVertexArrays, glGenBuffers, glBindVertexArray, etc muss ich doppelt aufrufen.

Komischerweise verwende ich bei beiden Aufrufen in glGenVertexArrays und glGenBuffers die gleichen Variablen, dies müsste doch einen Konflikt geben oder ?

Die Ausgabe ist im Anhang. Beim 2. Bild habe ich den 2. Shader modifiziert.

Code:
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Forms,
  9.   ExtCtrls,
  10.   StdCtrls,
  11.   OpenGLContext,
  12.   dglOpenGL,
  13.   ShaderUnit,
  14.   Classes;
  15.  
  16. type
  17.  
  18.   { TForm1 }
  19.  
  20.   TForm1 = class(TForm)
  21.     OpenGLControl1: TOpenGLControl;
  22.     OpenGLControl2: TOpenGLControl;
  23.     Panel1: TPanel;
  24.     Panel2: TPanel;
  25.     Timer1: TTimer;
  26.     procedure FormCreate(Sender: TObject);
  27.     procedure FormDestroy(Sender: TObject);
  28.     procedure FormResize(Sender: TObject);
  29.     procedure Timer1Timer(Sender: TObject);
  30.   private   { private declarations }
  31.     procedure InitScene;
  32.     procedure RenderScene(OGC: TOpenGLControl);
  33.   public        { public declarations }
  34.     ProgramID: GLuint;
  35.   end;
  36.  
  37. var
  38.   Form1: TForm1;
  39.  
  40. implementation
  41.  
  42. {$R *.lfm}
  43.  
  44. { TForm1 }
  45.  
  46. type
  47.   TVertex3f = array[0..2] of GLfloat;
  48.   TFace = array[0..2] of TVertex3f;
  49.   TMatrix = array[0..3, 0..3] of GLfloat;
  50.  
  51. const
  52.   Triangle: array[0..0] of TFace =
  53.     (((-0.4, 0.1, 0.0), (0.4, 0.1, 0.0), (0.0, 0.7, 0.0)));
  54.   TriangleColor: array[0..0] of TFace =
  55.     (((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)));
  56.  
  57.   Quad: array[0..1] of TFace =
  58.     (((-0.2, -0.6, 0.0), (-0.2, -0.1, 0.0), (0.2, -0.1, 0.0)),
  59.     ((-0.2, -0.6, 0.0), (0.2, -0.1, 0.0), (0.2, -0.6, 0.0)));
  60.   QuadColor: array[0..1] of TFace =
  61.     (((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)),
  62.     ((1.0, 0.0, 0.0), (0.0, 0.0, 1.0), (1.0, 1.0, 0.0)));
  63.  
  64.   EinheitsMatrix: TMatrix = ((1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, 0.0, 0.0, 1.0));
  65.  
  66.  
  67. type
  68.   TVB = record
  69.     VAO,
  70.     VBO0, VBO1: GLuint;
  71.   end;
  72.  
  73. var
  74.   VBTriangle, VBQuad: TVB;
  75.   Vertex_id, Color_id: GLint;
  76.   Matrix_id: GLint;
  77.  
  78.   Matrix: TMatrix;
  79.  
  80. procedure RotateZ(var Matrix: TMatrix; Winkel: GLfloat);
  81. var
  82.   x, y: GLfloat;
  83.   i: integer;
  84. begin
  85.   for i := 0 to 2 do begin
  86.     x := Matrix[i, 0];
  87.     y := Matrix[i, 1];
  88.     Matrix[i, 0] := x * cos(Winkel) - y * sin(Winkel);
  89.     Matrix[i, 1] := x * sin(Winkel) + y * cos(Winkel);
  90.   end;
  91. end;
  92.  
  93. procedure TForm1.InitScene;
  94. begin
  95.  
  96.   glGenVertexArrays(1, @VBTriangle.VAO);
  97.   glGenVertexArrays(1, @VBQuad.VAO);
  98.  
  99.   glGenBuffers(1, @VBTriangle.VBO0);
  100.   glGenBuffers(1, @VBQuad.VBO0);
  101.   glGenBuffers(1, @VBTriangle.VBO1);
  102.   glGenBuffers(1, @VBQuad.VBO1);
  103.  
  104.   glBindVertexArray(VBTriangle.VAO);
  105.  
  106.   glBindBuffer(GL_ARRAY_BUFFER, VBTriangle.VBO0);
  107.   glBufferData(GL_ARRAY_BUFFER, sizeof(Triangle), @Triangle, GL_STATIC_DRAW);
  108.   glEnableVertexAttribArray(Vertex_id);
  109.   glVertexAttribPointer(Vertex_id, 3, GL_FLOAT, False, 0, nil);
  110.  
  111.   glBindBuffer(GL_ARRAY_BUFFER, VBTriangle.VBO1);
  112.   glBufferData(GL_ARRAY_BUFFER, sizeof(TriangleColor), @TriangleColor, GL_STATIC_DRAW);
  113.   glEnableVertexAttribArray(Color_id);
  114.   glVertexAttribPointer(Color_id, 3, GL_FLOAT, False, 0, nil);
  115.  
  116.  
  117.   glBindVertexArray(VBQuad.VAO);
  118.  
  119.   glBindBuffer(GL_ARRAY_BUFFER, VBQuad.VBO0);
  120.   glBufferData(GL_ARRAY_BUFFER, sizeof(Quad), @Quad, GL_STATIC_DRAW);
  121.   glEnableVertexAttribArray(Vertex_id);
  122.   glVertexAttribPointer(Vertex_id, 3, GL_FLOAT, False, 0, nil);
  123.  
  124.   glBindBuffer(GL_ARRAY_BUFFER, VBQuad.VBO1);
  125.   glBufferData(GL_ARRAY_BUFFER, sizeof(QuadColor), @QuadColor, GL_STATIC_DRAW);
  126.   glEnableVertexAttribArray(Color_id);
  127.   glVertexAttribPointer(Color_id, 3, GL_FLOAT, False, 0, nil);
  128.  
  129.   Matrix := EinheitsMatrix;
  130. end;
  131.  
  132. procedure TForm1.RenderScene(OGC:TOpenGLControl);
  133. begin
  134.   OGC.MakeCurrent;
  135.   glClear(GL_COLOR_BUFFER_BIT);
  136.  
  137.   glUniformMatrix4fv(Matrix_id, 1, False, @Matrix);
  138.  
  139.   // Zeichen Dreieck
  140.   glBindVertexArray(VBTriangle.VAO);
  141.   glDrawArrays(GL_TRIANGLES, 0, Length(Triangle) * 3);
  142.  
  143.   // Zeichne Quadrat
  144.   glBindVertexArray(VBQuad.VAO);
  145.   glDrawArrays(GL_TRIANGLES, 0, Length(Quad) * 3);
  146.  
  147.   OGC.SwapBuffers;
  148. end;
  149.  
  150.  
  151. procedure TForm1.FormCreate(Sender: TObject);
  152. begin
  153.   InitOpenGL;
  154.  
  155.   OpenGLControl1.MakeCurrent;
  156.   ReadExtensions;
  157.   ReadImplementationProperties;
  158.  
  159.  
  160.   ProgramID := InitShader('VertexShader.txt', 'FragmentShader.txt');
  161.   glUseProgram(programID);
  162.  
  163.   Vertex_id := glGetAttribLocation(ProgramID, 'inPos');
  164.   Color_id := glGetAttribLocation(ProgramID, 'inColor');
  165.   Matrix_id := glGetUniformLocation(ProgramID, 'Matrix');
  166.  
  167.   glClearColor(0.0, 0.5, 1.0, 1.0);
  168.  
  169.   InitScene;
  170.  
  171.  
  172.  
  173.   OpenGLControl2.MakeCurrent;
  174.  
  175.  
  176.   ProgramID := InitShader('VertexShader.txt', 'FragmentShader2.txt');
  177.   glUseProgram(programID);
  178.  
  179. //  Vertex_id := glGetAttribLocation(ProgramID, 'inPos');
  180. //  Color_id := glGetAttribLocation(ProgramID, 'inColor');
  181. //  Matrix_id := glGetUniformLocation(ProgramID, 'Matrix');
  182.  
  183.   glClearColor(1.0, 0.5, 0.0, 1.0);
  184.   InitScene;
  185. end;
  186.  
  187. procedure TForm1.FormDestroy(Sender: TObject);
  188. begin
  189.   glDeleteBuffers(1, @VBTriangle.VAO);
  190.   glDeleteBuffers(1, @VBQuad.VAO);
  191.  
  192.   glDeleteBuffers(1, @VBTriangle.VBO0);
  193.   glDeleteBuffers(1, @VBQuad.VBO0);
  194.   glDeleteBuffers(1, @VBTriangle.VBO1);
  195.   glDeleteBuffers(1, @VBQuad.VBO1);
  196. end;
  197.  
  198. procedure TForm1.FormResize(Sender: TObject);
  199. begin
  200.   glViewport(0, 0, Panel1.Width, Panel1.Height);
  201. end;
  202.  
  203. procedure TForm1.Timer1Timer(Sender: TObject);
  204. begin
  205.   RenderScene(OpenGLControl1);
  206.   RenderScene(OpenGLControl2);
  207.   RotateZ(Matrix, Pi / 100);
  208. end;
  209.  
  210. end.


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

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Mo Aug 04, 2014 07:47 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Deine Probleme liegen in der Context erzeugung.
Wenn du Resourcen teilen willst, dann musst du auch den Context mit entsprechenden Parameter erzeugen.
http://www.opengl.org/wiki/OpenGL_Context
Ich rate allerdings von ab dies zu machen, da kommst du in deine eigene Private OpenGL Hölle mit unerklärlichen Render Bugs, Performance einbrüchen und FPS Spikes.

glMakeCurrent hat nix mit mehreren OpenGL Context zu tun, das geht nur sicher, dass die single Threaded geschriebene OpenGL API die Befehle an den Thread-Lokalen Context schickt und nicht an wen anderes(was zu Fehlern führen wird).

_________________
"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  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Mo Aug 04, 2014 21:39 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1282
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Ich rate allerdings von ab dies zu machen, da kommst du in deine eigene Private OpenGL Hölle mit unerklärlichen Render Bugs, Performance einbrüchen und FPS Spikes.

Wie wir dann z.B. ein Rückspiegel von einem Auto programmiert ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Di Aug 05, 2014 09:17 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Du kannst 2 getrennte Contexte haben, beide nutzen den gleichen Szene Graphen aber haben eigene OpenGL Objekte für den gleichen Node.
Das sieht am Anfang ungewohnt aus aber eigentlich muss man für sein Scenegraph nur einbauen, dass man mehrere OpenGL Objekt ID's, statt eine zu hinterlegen und diese in Korrelation mit den Context zu bringen.
Ach und du hast dann 2 Kameras, je für eine View.

Wenn man z.B. auf Monitor Wände rendert, dann hat man mehrere PC's, ein Master mit dem Scenegraph und jeder Slave hat dann sein eigenen Render Context und interpretiert den SceneGraph aus der Sicht seines Kamera ausschnitts.
Also es gibt eine Kamera aber mit viewport wird dann jeden Slave ein Teil dieser zugewiesen.

Wenn man ein System hat, welches z.B. 3 Monitore ansprichts dann kann man folgende 2 Wege gehen.

Man benutze ein shared Context und muss darauf achten, dass sämtliche OpenGL Befehle thread safe verarbeitet werden, also mit Mutex auf ein Imaginäres Render Device, damit jede Gameloop, von jeden Fenster, nicht auf den OpenGL Context zugreift, wenn der andere das auch tut. Es gibt ein Mutex, der in der Main erzeugt und an beide Fenster übergeben wird, nun kann jedes Fenster für sich selbst sauber rendern und arbeiten, wenn man den Mutex Locked. Allerdings muss man auch die Resourcen ausserhalb der Fenster Logik handhaben, sonnst werden die Resourcen nicht geshared. Den Mutex braucht man, weil OpenGL kein Multithreaded Support hat.

Wie vorige Variante, allerdings kein shared Context und die benötigten Ressourcen werden innerhalb des Fensters erzeugt und verwaltet. Das hab ich z.B. hier gemacht.
Das benötigt wesentlich mehr VRAM aber ist wesentlich einfacher zu programmieren und zu debuggen.

_________________
"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  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Di Aug 05, 2014 20:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Sep 23, 2002 19:27
Beiträge: 5812
Programmiersprache: C++
mathias hat geschrieben:
Zitat:
Ich rate allerdings von ab dies zu machen, da kommst du in deine eigene Private OpenGL Hölle mit unerklärlichen Render Bugs, Performance einbrüchen und FPS Spikes.

Wie wir dann z.B. ein Rückspiegel von einem Auto programmiert ?


Render-to-Texture, allein schon deshalb weil Rück- und Seitenspiegel im Auto eher selten rechteckig sind und gerne auch mit einer niedrigeren Frequenz aktualisiert werden. Also einfach z.B. ein Framebufferobjekt in dass die rückwärtige Szene dann gerendert wird. Das wird dann als Texture an den Spiegel gebunden und in der finalen Szene gerendert.

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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Di Aug 05, 2014 21:58 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1282
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Wen ich es richtig verstanden habe, werden mehrere OpenGL-Fenster in der Praxis nie verwendet.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Di Aug 05, 2014 22:07 
Offline
DGL Member

Registriert: Do Dez 29, 2011 19:40
Beiträge: 421
Wohnort: Deutschland, Bayern
Programmiersprache: C++, C, D, C# VB.Net
Naja, eigentlich nicht.
Sie werden halt dazu verwendet wozu sie gedacht sind: Mehrere unabhängige Grafikcontrols. Die sind schlicht nicht für Effekte gedacht sondern für mehrere Fenster. Ein CAD Programm mit mehrere Views in eigenen Fenstern zum Beispiel oder so. Der Context-Wechsel ist übrigens angeblich zum Teil sogar so leistungsfressend, das es alleine deshalb schwer möglich ist, flüssige Bilder zu rendern.

Ich würde in der Regel ein Thread für einen Context verwenden und das nie ändern.

Für einen Rückspiegel der spiegelt wäre auch der Stencil Buffer eine Option. Der kleine Vorteil davon ist die Pixel exakte Darstellung ohne richtig zu bemessende verzerrende Texturen. Dafür kann man zwar kaum Verzerrungen realisieren, Rückspiegel sollten das jedoch eigentlich nicht notwendig haben.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Mi Aug 06, 2014 07:31 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
ja ich kenns eigentlich nur von Programmen die sowas wie MDI machen wollen. Aber da koennte man eventuell auch besser mit dem Viewport und Scissor rumspielen. Nehe haben dazu nen schoenes Tutorial.

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Mi Aug 06, 2014 11:25 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Blender und co benutzen ein OpenGL/DX11 Context für je ein Fenster und innerhalb des Fensters wird dann mit Viewport und Scissor gearbeitet, um verschiedene Ansichten zu realisieren.

Für Materials würde ich auf FBO's setzen, weil man die nicht jeden Frame neu zeichnen muss und sich dann eine Menge Arbeit spart.

_________________
"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  
 Betreff des Beitrags: Re: Mehrere Ausgabefenster
BeitragVerfasst: Do Aug 07, 2014 13:27 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Achtung! VBO kann man sharen, VAO aber nicht. Eine mögliche Abhilfe: nur ein Kontext für mehrere OpenGL-Fenster.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 19 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.010s | 15 Queries | GZIP : On ]