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

Aktuelle Zeit: Fr Jul 18, 2025 08:18

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



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 15:59 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Hallo,

ich habe das Tutorial bezüglich der FrameBufferObjekte durchgearbeitet und eine dazu passende Komponente entwickelt. Leider bekomme ich beim Anlegen des Objekts in der Funktion CheckFBO immer den Fehler >> GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT <<, so dass die Komponente nicht korrekt angelegt wird. Meiner Meinung nach habe ich alles so umgesetzt wie vorgegeben. Ich habe auch die Existenz der Erweiterung abgeprüft, bekomme den Fehler aber trotzdem.

Kann mir jemand weiterhelfen?

Danke,

Andree

___________________
Hier die Abprüfung der Extension:
___________________
Code:
  1.  
  2. var
  3.   FBO: TFrameBufferObject;
  4. .
  5. .
  6. .
  7.   if CheckGLExtension ('GL_EXT_framebuffer_object') then begin
  8.     FBO := TFrameBufferObject.Create(512, 512);
  9.   end else begin
  10.     FBO := nil;
  11.     raise Exception.Create('Spiegelanzeige ist nicht möglich, da die'+#10+#13+
  12.                                    'Grafikkarte dies nicht unterstützt.');
  13.   end;
  14. .
  15. .
  16. .
  17.  
  18.  
  19. function TFMain.CheckGLExtension (cExt: string): boolean;
  20. var
  21.   cGLExt: string;
  22. begin
  23.   result := false;
  24.   cGLExt := glGetString (GL_EXTENSIONS);
  25.   if UpperPos (cExt, cGLExt) > 0 then begin
  26.     result := true;
  27.   end;
  28. end;
  29.  

___________________
Hier die Komponente:
___________________
Code:
  1.  
  2. unit FrameBufferObjectClass;
  3.  
  4. interface
  5.  
  6. uses
  7.   dglopenGL,
  8.   Windows,
  9.   Classes;
  10.  
  11. type
  12.   TFrameBufferObject = class(TComponent)
  13.     public
  14.       Log        : TstringList;
  15.       procedure Bind;
  16.       procedure PrepareRender;
  17.       procedure FinishRender;
  18.       constructor Create (pWidth, pHeight: GLUInt); reintroduce;
  19.       destructor Destroy; override;
  20.     private
  21.       fbo        : GLUInt;
  22.       depthbuffer: GLUInt;
  23.       Width,
  24.       Height     : GLUInt;
  25.       FBO_tex    : GLUInt;
  26.       procedure CheckFBO;
  27.     procedure WriteLog(s: string);
  28.   end;
  29.  
  30. implementation
  31.  
  32. uses
  33.   SysUtils;
  34.  
  35. destructor TFrameBufferObject.Destroy;
  36. begin
  37.   Log.Free;
  38.   glDeleteTextures(1, @FBO_tex);
  39.   glDeleteFramebuffersEXT(1, @fbo);
  40.   glDeleteRenderbuffersEXT(1, @depthbuffer);
  41.   inherited;
  42. end;
  43.  
  44. constructor TFrameBufferObject.Create (pWidth, pHeight: GLUInt);
  45. begin
  46.   Width  := pWidth;
  47.   Height := pHeight;
  48.  
  49.   Log    := TStringlist.Create;
  50.  
  51.   // Zuerst einmal muss das Framebufferobjekt generiert werden. Dies läuft
  52.   // ähnlich wie das Erstellen einer Textur ab.
  53.   WriteLog ('glGenFramebuffersEXT(1, @fbo)');
  54.   glGenFramebuffersEXT(1, @fbo);
  55.   // Wie bei allem anderen auch müssen wir das Framebufferobjekt jetzt binden,
  56.   // damit alles, was folgt sich auf dieses Objekt bezieht
  57.   WriteLog ('glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo)');
  58.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  59.  
  60.   // Ein einfaches Framebufferobjekt ist noch ziemlich nutzlos. Deswegen
  61.   // fügen wir zuerst einmal einen der neu eingeführten Renderbuffer als
  62.   // Depthbuffer hinzu. Renderbuffer sind im Prinzip Objekte, die benutzt
  63.   // werden wenn ein Buffer kein zugehöriges Texturformat besitzt. Dazu zählen
  64.   // u.a. der Stencilbuffer, der Accumulationbuffer und der Depthbuffer. Das
  65.   // Binden an den Accumulationbuffer wurde allerdings auf eine spätere
  66.   // Extension verschoben. Wie auch beim Framebufferobjekt müssen wir einen
  67.   // Renderbuffer zuerst generieren und dann binden:
  68.   WriteLog ('glGenRenderbuffersEXT(1, @depthbuffer)');
  69.   glGenRenderbuffersEXT(1, @depthbuffer);
  70.   WriteLog ('glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer)');
  71.   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);
  72.  
  73.   // Derzeit hat der Renderbuffer allerdings noch keinen Speicher zugeteilt
  74.   // bekommen. Deswegen sagen wir OpenGL, wie wir den Renderbuffer benutzen
  75.   // wollen und welche Größe er haben soll:
  76.   WriteLog ('glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, '+IntToStr(pWidth)+', '+IntToStr(pHeight)+')');
  77.   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, pWidth, pHeight);
  78.  
  79.   // Mit glRenderbufferStorageEXT hat OpenGL den Speicher für den Renderbuffer,
  80.   // den wir als Depthbuffer nutzen, reserviert. Jetzt können wir unseren
  81.   // Depthbuffer zum FBO hinzufügen:
  82.   WriteLog ('glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,'+
  83.                                          'GL_DEPTH_ATTACHMENT_EXT,'+
  84.                                          'GL_RENDERBUFFER_EXT, depthbuffer)');
  85.   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
  86.                                GL_DEPTH_ATTACHMENT_EXT,
  87.                                GL_RENDERBUFFER_EXT, depthbuffer);
  88.   // Die letzte Anweisung sollte ziemlich einfach zu verstehen sein. Der zweite
  89.   // Parameter sagt einfach, als was der Renderbuffer genutzt werden soll
  90.  
  91.   // Um Farbinformationen in unser Framebufferobjekt schreiben zu können,
  92.   // fügen wir eine Textur hinzu. Bevor wir sie hinzufügen können müssen wir
  93.   // sie natürlich noch erstellen:
  94.   WriteLog ('glGenTextures(1, @FBO_tex)');
  95.   glGenTextures(1, @FBO_tex);
  96.   WriteLog ('glBindTexture(GL_TEXTURE_2D, FBO_tex)');
  97.   glBindTexture(GL_TEXTURE_2D, FBO_tex);
  98.   WriteLog ('glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST)');
  99.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  100.   WriteLog ('glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST)');
  101.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  102.   WriteLog ('glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, '+IntToStr(pWidth)+', '+IntToStr(pHeight)+', 0, GL_RGB8, GL_UNSIGNED_BYTE, nil)');
  103.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, pWidth, pHeight, 0, GL_RGB8, GL_UNSIGNED_BYTE, nil);
  104.   // Es dürfte eigentlich nichts völlig Unverständliches da stehen. Wir
  105.   // erstellen die Textur, binden sie, stellen die Filtermodi ein und erzeugen
  106.   // im Speicher den entsprechenden Platz. Anzumerken ist aber, dass die Textur
  107.   // die gleiche Größe wie der Renderbuffer haben muss. Alle Größen müssen
  108.   // einheitlich sein. Man kann also nicht einen Renderbuffer von 512*512 und
  109.   // eine Textur von 256*256 erstellen und sie zusammen in einem FBO nutzen.
  110.   // Hinzugefügt wird sie nach dem gleichen Schema wie der Depthbuffer:
  111.   WriteLog ('glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, FBO_tex, 0)');
  112.   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, FBO_tex, 0);
  113.   // Wie gesagt, nicht viel neues hier. Der zweite Parameter,
  114.   // GL_COLOR_ATTACHMENT0_EXT sagt OpenGL wo die Textur hinzugefügt werden
  115.   // soll (man kann mehrere hinzufügen, doch dazu später mehr). Der letzte
  116.   // Parameter beschreibt das Mipmaping-Level.
  117.  
  118.   WriteLog ('checking error');
  119.   CheckFBO;
  120. end;
  121.  
  122. procedure TFrameBufferObject.CheckFBO;
  123. var
  124.   error: GlEnum;
  125. begin
  126.   error := glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  127.   WriteLog ('error: '+IntToStr(error));
  128.   case error of
  129.     GL_FRAMEBUFFER_COMPLETE_EXT:
  130.       Exit;
  131.     GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
  132.       raise Exception.Create('FBO: Incomplete attachment');
  133.     GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
  134.       raise Exception.Create('FBO: Missing attachment');
  135.     GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
  136.       raise Exception.Create('FBO: Incomplete dimensions');
  137.     GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
  138.       raise Exception.Create('FBO: Incomplete formats');
  139.     GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
  140.       raise Exception.Create('FBO: Incomplete draw buffer');
  141.     GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
  142.       raise Exception.Create('FBO: Incomplete read buffer');
  143.     GL_FRAMEBUFFER_UNSUPPORTED_EXT:
  144.       raise Exception.Create('FBO: Framebufferobjects unsupported');
  145.   end;
  146. end;
  147.  
  148. procedure TFrameBufferObject.WriteLog (s: string);
  149. begin
  150.   Log.Add(s);
  151. end;
  152.  
  153. procedure TFrameBufferObject.PrepareRender;
  154. // bind vor dem rendern auf die textur aufrufen und dann einfach rendern.
  155. // den viewport dann nicht mehr verändern.
  156. begin
  157.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  158.   glPushAttrib(GL_VIEWPORT_BIT);
  159.   glViewPort(0, 0, Width, Height);
  160. end;
  161.  
  162. procedure TFrameBufferObject.FinishRender;
  163. // release nach dem rendern auf die textur aufrufen um den viewport
  164. // zurückzusetzen.
  165. begin
  166.   glPopAttrib;
  167.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  168. end;
  169.  
  170. procedure TFrameBufferObject.Bind;
  171. // vor dem Benutzen der Textur aufrufen
  172. begin
  173.   glBindTexture(GL_TEXTURE_2D, FBO_tex);
  174.   glGenerateMipmapEXT(GL_TEXTURE_2D);
  175.   //Textur danach ganz normal benutzen
  176. end;
  177.  
  178. end.
  179.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 16:34 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich habe mit FBOs noch nicht so viel gemacht, erinnere mich aber, dass man Texturen, die als Puffer fungieren, nicht gebunden haben sollte... Mal ein glBind(GL_TEXTURE_2D, 0); vorm CheckFBO versucht?

greetings
(*schuss ins blaue*)

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 16:41 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Hallo,

glBindTexture(GL_TEXTURE_2D, 0) hat es leider nicht gebracht, das habe ich sofort ausprobiert.

Trotzdem danke,

Andree


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 16:45 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Ich denke nicht, dass es Probleme mit der Erweiterung gibt. Also wenn deine Grafikkarte FBOs nicht könnte, dann würde bereits der Befehl glGenFramebuffersEXT eine Zugriffsverletzung werfen. Weil die Funktionen erst dann existieren wenn deine Karte sie auch kann.

Also spontan kann ich nur eines finde woran sich eine empfindliche OpenGL Implementation stören könnte. Und zwar nimm mal als Format (Siebte Parameter/Zweite GL_RGB8 ) bei glTexImage2D GL_RGB und nicht GL_RGB8. Weiß nicht ob deine OpenGL Implementation da irgendwie empfindlicher ist. Ist vielleicht sogar auch ein bisschen an den Haaren herbeigezogen.

Falls das nichts ändernt kannst du mal folgendes versuchen.
- RGBA8 als Texturformat. Grafikkarten mögen 32 Bit Alignment.
- Überall mit glGetError auf Fehler prüfen. Wenn du irgendwo eine falschen Konstante rein reichst, dann sorgt das natürlich dafür, dass das FBO nicht funktioniert. Allerdings sieht man nicht ob ein Befehl eventuell einen Fehler geworfen hat. Also so etwas wie glBegin(GL_RGB) wird von OpenGL verworfen, weil er es nicht auswerten kann. Dein Programm wird aber trotzdem ganz normal weiter laufen. Allerdings wird in OpenGL ein Fehler gesetzt. Den kann man mit glGetError abfragen. Das solltest du dann idealerweise mit in dein Log Schreiben. Also nach jedem Befehl. Oder kombinieren. Also dein Writelog nach dem OpenGL Befehl aufrufen und das Ergebniss von glGetError direkt übergeben und gleich zusammen wegschreiben.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 17:11 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Hallo Lossy Ex,

war nicht an den Haaren herbeigezogen. Da ich in unterschiedlichen Tutorials und Beispielen für diesen Parameter auch unterschiedliche Einstellungen gefunden hatte, habe ich anscheinend einiges durcheinandergebracht. Der Fehler ist jetzt weg, dafür ist mein Bildschirm schwarz. Wo ich vorher umherfliegende Kacheln sah, ist jetzt nur noch eine schwarze Fläche. Welche Einstellung muss ich den sichern und wiederherstellen? Ich habe glPush- und Popmatrix und glPush- und PopAttrib mit GL_ALL_ATTRIB_BITS probiert. Bringt null und nix.

Ich sehe nichts.

Danke,

Andree

-------------------
Hier der neue Code:
-------------------

Code:
  1.  
  2. unit FrameBufferObjectClass;
  3.  
  4. interface
  5.  
  6. uses
  7.   dglopenGL,
  8.   Windows,
  9.   Classes;
  10.  
  11. type
  12.   TFrameBufferObject = class(TComponent)
  13.     public
  14.       Log        : TstringList;
  15.       procedure Bind;
  16.       procedure PrepareRender;
  17.       procedure FinishRender;
  18.       constructor Create (pWidth, pHeight: GLUInt); reintroduce;
  19.       destructor Destroy; override;
  20.     private
  21.       fbo        : GLUInt;
  22.       depthbuffer: GLUInt;
  23.       Width,
  24.       Height     : GLUInt;
  25.       FBO_tex    : GLUInt;
  26.       procedure CheckFBO;
  27.     procedure WriteLog(s: string);
  28.   end;
  29.  
  30. implementation
  31.  
  32. uses
  33.   SysUtils,
  34.   Forms;
  35.  
  36. destructor TFrameBufferObject.Destroy;
  37. begin
  38.   Log.Free;
  39.   glDeleteTextures(1, @FBO_tex);
  40.   glDeleteFramebuffersEXT(1, @fbo);
  41.   glDeleteRenderbuffersEXT(1, @depthbuffer);
  42.   inherited;
  43. end;
  44.  
  45. constructor TFrameBufferObject.Create (pWidth, pHeight: GLUInt);
  46. begin
  47.   Width  := pWidth;
  48.   Height := pHeight;
  49.  
  50.   Log    := TStringlist.Create;
  51.  
  52.   // Zuerst einmal muss das Framebufferobjekt generiert werden. Dies läuft
  53.   // ähnlich wie das Erstellen einer Textur ab.
  54.   WriteLog ('glGenFramebuffersEXT(1, @fbo)');
  55.   glGenFramebuffersEXT(1, @fbo);
  56.   WriteLog ('error: '+IntToStr(glGetError));
  57.   // Wie bei allem anderen auch müssen wir das Framebufferobjekt jetzt binden,
  58.   // damit alles, was folgt sich auf dieses Objekt bezieht
  59.   WriteLog ('glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo)');
  60.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  61.   WriteLog ('error: '+IntToStr(glGetError));
  62.  
  63.   // Ein einfaches Framebufferobjekt ist noch ziemlich nutzlos. Deswegen
  64.   // fügen wir zuerst einmal einen der neu eingeführten Renderbuffer als
  65.   // Depthbuffer hinzu. Renderbuffer sind im Prinzip Objekte, die benutzt
  66.   // werden wenn ein Buffer kein zugehöriges Texturformat besitzt. Dazu zählen
  67.   // u.a. der Stencilbuffer, der Accumulationbuffer und der Depthbuffer. Das
  68.   // Binden an den Accumulationbuffer wurde allerdings auf eine spätere
  69.   // Extension verschoben. Wie auch beim Framebufferobjekt müssen wir einen
  70.   // Renderbuffer zuerst generieren und dann binden:
  71.   WriteLog ('glGenRenderbuffersEXT(1, @depthbuffer)');
  72.   glGenRenderbuffersEXT(1, @depthbuffer);
  73.   WriteLog ('error: '+IntToStr(glGetError));
  74.  
  75.   WriteLog ('glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer)');
  76.   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);
  77.   WriteLog ('error: '+IntToStr(glGetError));
  78.  
  79.   // Derzeit hat der Renderbuffer allerdings noch keinen Speicher zugeteilt
  80.   // bekommen. Deswegen sagen wir OpenGL, wie wir den Renderbuffer benutzen
  81.   // wollen und welche Größe er haben soll:
  82.   WriteLog ('glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, '+IntToStr(pWidth)+', '+IntToStr(pHeight)+')');
  83.   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, pWidth, pHeight);
  84.   WriteLog ('error: '+IntToStr(glGetError));
  85.  
  86.   // Mit glRenderbufferStorageEXT hat OpenGL den Speicher für den Renderbuffer,
  87.   // den wir als Depthbuffer nutzen, reserviert. Jetzt können wir unseren
  88.   // Depthbuffer zum FBO hinzufügen:
  89.   WriteLog ('glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,'+
  90.                                          'GL_DEPTH_ATTACHMENT_EXT,'+
  91.                                          'GL_RENDERBUFFER_EXT, depthbuffer)');
  92.   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
  93.                                GL_DEPTH_ATTACHMENT_EXT,
  94.                                GL_RENDERBUFFER_EXT, depthbuffer);
  95.   WriteLog ('error: '+IntToStr(glGetError));
  96.   // Die letzte Anweisung sollte ziemlich einfach zu verstehen sein. Der zweite
  97.   // Parameter sagt einfach, als was der Renderbuffer genutzt werden soll
  98.  
  99.   // Um Farbinformationen in unser Framebufferobjekt schreiben zu können,
  100.   // fügen wir eine Textur hinzu. Bevor wir sie hinzufügen können müssen wir
  101.   // sie natürlich noch erstellen:
  102.   WriteLog ('glGenTextures(1, @FBO_tex)');
  103.   glGenTextures(1, @FBO_tex);
  104.   WriteLog ('error: '+IntToStr(glGetError));
  105.  
  106.   WriteLog ('glBindTexture(GL_TEXTURE_2D, FBO_tex)');
  107.   glBindTexture(GL_TEXTURE_2D, FBO_tex);
  108.   WriteLog ('error: '+IntToStr(glGetError));
  109.  
  110.   WriteLog ('glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST)');
  111.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  112.   WriteLog ('error: '+IntToStr(glGetError));
  113.  
  114.   WriteLog ('glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST)');
  115.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  116.   WriteLog ('error: '+IntToStr(glGetError));
  117.  
  118.   WriteLog ('glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, '+IntToStr(pWidth)+', '+IntToStr(pHeight)+', 0, GL_RGB8, GL_UNSIGNED_BYTE, nil)');
  119.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, pWidth, pHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, nil);
  120.   WriteLog ('error: '+IntToStr(glGetError));
  121.  
  122.   // Es dürfte eigentlich nichts völlig Unverständliches da stehen. Wir
  123.   // erstellen die Textur, binden sie, stellen die Filtermodi ein und erzeugen
  124.   // im Speicher den entsprechenden Platz. Anzumerken ist aber, dass die Textur
  125.   // die gleiche Größe wie der Renderbuffer haben muss. Alle Größen müssen
  126.   // einheitlich sein. Man kann also nicht einen Renderbuffer von 512*512 und
  127.   // eine Textur von 256*256 erstellen und sie zusammen in einem FBO nutzen.
  128.   // Hinzugefügt wird sie nach dem gleichen Schema wie der Depthbuffer:
  129.   WriteLog ('glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, FBO_tex, 0)');
  130.   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, FBO_tex, 0);
  131.   WriteLog ('error: '+IntToStr(glGetError));
  132.  
  133.   // Wie gesagt, nicht viel neues hier. Der zweite Parameter,
  134.   // GL_COLOR_ATTACHMENT0_EXT sagt OpenGL wo die Textur hinzugefügt werden
  135.   // soll (man kann mehrere hinzufügen, doch dazu später mehr). Der letzte
  136.   // Parameter beschreibt das Mipmaping-Level.
  137.  
  138.   WriteLog ('checking error');
  139.   CheckFBO;
  140. end;
  141.  
  142. procedure TFrameBufferObject.CheckFBO;
  143. var
  144.   error: GlEnum;
  145.   i: integer;
  146. begin
  147.   error := glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  148.   WriteLog ('error: '+IntToStr(error));
  149.   if error <> GL_FRAMEBUFFER_COMPLETE_EXT then begin
  150.     for i := 0 to Log.Count-1 do begin
  151.       Application.MessageBox(pchar('error '+IntToStr (i+1)+': '+Log.Strings[i]),
  152.                              'Error', MB_OK);
  153.     end;
  154.   end;
  155.   case error of
  156.     GL_FRAMEBUFFER_COMPLETE_EXT:
  157.       Exit;
  158.     GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
  159.       raise Exception.Create('FBO: Incomplete attachment');
  160.     GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
  161.       raise Exception.Create('FBO: Missing attachment');
  162.     GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
  163.       raise Exception.Create('FBO: Incomplete dimensions');
  164.     GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
  165.       raise Exception.Create('FBO: Incomplete formats');
  166.     GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
  167.       raise Exception.Create('FBO: Incomplete draw buffer');
  168.     GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
  169.       raise Exception.Create('FBO: Incomplete read buffer');
  170.     GL_FRAMEBUFFER_UNSUPPORTED_EXT:
  171.       raise Exception.Create('FBO: Framebufferobjects unsupported');
  172.   end;
  173. end;
  174.  
  175. procedure TFrameBufferObject.WriteLog (s: string);
  176. begin
  177.   Log.Add(s);
  178. end;
  179.  
  180. procedure TFrameBufferObject.PrepareRender;
  181. // bind vor dem rendern auf die textur aufrufen und dann einfach rendern.
  182. // den viewport dann nicht mehr verändern.
  183. begin
  184.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  185.   glPushAttrib(GL_VIEWPORT_BIT);
  186.   glViewPort(0, 0, Width, Height);
  187. end;
  188.  
  189. procedure TFrameBufferObject.FinishRender;
  190. // release nach dem rendern auf die textur aufrufen um den viewport
  191. // zurückzusetzen.
  192. begin
  193.   glPopAttrib;
  194.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  195. end;
  196.  
  197. procedure TFrameBufferObject.Bind;
  198. // vor dem Benutzen der Textur aufrufen
  199. begin
  200.   glBindTexture(GL_TEXTURE_2D, FBO_tex);
  201.   glGenerateMipmapEXT(GL_TEXTURE_2D);
  202.   //Textur danach ganz normal benutzen
  203. end;
  204.  
  205. end.
  206.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 17:36 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Dazu wäre interessant zu wissen, wie du überhaupt zeichnest und was du mit deinem FBO anstellst. Wenn du da reingezeichnet hast, musst du das noch irgendwo wieder aufbringen, als Textur. Ist ja meistens der Sinn der Übung.

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 17:53 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Hallo Lord,

bisher zeichne ich die Textur des FBOs überhaupt nicht. Dafür habe ich aber die Methoden FBO.PrepareRender und FBO.FinishRender vorgesehen. Die dann geschriebene Textur kann man mit der Methode FBO.Bind aktivieren. Mein Bildschirm bleibt schwarz, wenn ich das Objekt anlege, also die Methode FBO.Create (512, 512) aufrufe. Alle meine bisherigen Zeichenanweisungen, die funktionieren wenn ich das Objekt nicht anlege, sind dann wirkungslos.

Andree


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 17:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ah, das könnte damit zusammenhängen, dass du beim Erzeugen das VBO zwar bindest (»glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);«), aber später nicht wieder entbindest, mit:
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

das sollte helfen, nach CheckFBO wäre das angebracht.

Denn solange das FBO gebunden ist, wird dort auch reingerendert. Zumindest meines Wissens nach.

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 18:09 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Denn solange das FBO gebunden ist, wird dort auch reingerendert. Zumindest meines Wissens nach.

Korrekt. Die zugehörige Textur ist auch erst verfügbar, wenn ein anderes FBO gebunden wird (z.B. das Default-FBO mit der ID 0)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: FrameBufferObject
BeitragVerfasst: Di Nov 24, 2009 18:54 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Danke,

das war es. Jetzt werde ich meine Klasse austesten und wenn die jemanden interessiert, kann er sich die dann hier abholen. Bisher sieht alles prima aus. Sollten sich noch etwaige Änderungen ergeben, werde ich die hier veröffentlichen.

Andree

Code:
  1.  
  2. unit FrameBufferObjectClass;
  3.  
  4. interface
  5.  
  6. uses
  7.   dglopenGL,
  8.   Windows,
  9.   Classes;
  10.  
  11. type
  12.   TFrameBufferObject = class(TComponent)
  13.     public
  14.       Log        : TstringList;
  15.       Rendering  : boolean;
  16.       procedure Bind;
  17.       procedure PrepareRender;
  18.       procedure FinishRender;
  19.       constructor Create (pWidth, pHeight: GLUInt); reintroduce;
  20.       destructor Destroy; override;
  21.     private
  22.       fbo        : GLUInt;
  23.       depthbuffer: GLUInt;
  24.       Width,
  25.       Height     : GLUInt;
  26.       FBO_tex    : GLUInt;
  27.       procedure CheckFBO;
  28.     procedure WriteLog(s: string);
  29.   end;
  30.  
  31. implementation
  32.  
  33. uses
  34.   SysUtils,
  35.   Forms;
  36.  
  37. destructor TFrameBufferObject.Destroy;
  38. begin
  39.   Log.Free;
  40.   glDeleteTextures(1, @FBO_tex);
  41.   glDeleteFramebuffersEXT(1, @fbo);
  42.   glDeleteRenderbuffersEXT(1, @depthbuffer);
  43.   inherited;
  44. end;
  45.  
  46. constructor TFrameBufferObject.Create (pWidth, pHeight: GLUInt);
  47. begin
  48.   Width     := pWidth;
  49.   Height    := pHeight;
  50.  
  51.   Rendering := false;
  52.  
  53.   Log       := TStringlist.Create;
  54.  
  55.   // Zuerst einmal muss das Framebufferobjekt generiert werden. Dies läuft
  56.   // ähnlich wie das Erstellen einer Textur ab.
  57.   WriteLog ('glGenFramebuffersEXT(1, @fbo)');
  58.   glGenFramebuffersEXT(1, @fbo);
  59.   WriteLog ('error: '+IntToStr(glGetError));
  60.   // Wie bei allem anderen auch müssen wir das Framebufferobjekt jetzt binden,
  61.   // damit alles, was folgt sich auf dieses Objekt bezieht
  62.   WriteLog ('glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo)');
  63.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  64.   WriteLog ('error: '+IntToStr(glGetError));
  65.  
  66.   // Ein einfaches Framebufferobjekt ist noch ziemlich nutzlos. Deswegen
  67.   // fügen wir zuerst einmal einen der neu eingeführten Renderbuffer als
  68.   // Depthbuffer hinzu. Renderbuffer sind im Prinzip Objekte, die benutzt
  69.   // werden wenn ein Buffer kein zugehöriges Texturformat besitzt. Dazu zählen
  70.   // u.a. der Stencilbuffer, der Accumulationbuffer und der Depthbuffer. Das
  71.   // Binden an den Accumulationbuffer wurde allerdings auf eine spätere
  72.   // Extension verschoben. Wie auch beim Framebufferobjekt müssen wir einen
  73.   // Renderbuffer zuerst generieren und dann binden:
  74.   WriteLog ('glGenRenderbuffersEXT(1, @depthbuffer)');
  75.   glGenRenderbuffersEXT(1, @depthbuffer);
  76.   WriteLog ('error: '+IntToStr(glGetError));
  77.  
  78.   WriteLog ('glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer)');
  79.   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);
  80.   WriteLog ('error: '+IntToStr(glGetError));
  81.  
  82.   // Derzeit hat der Renderbuffer allerdings noch keinen Speicher zugeteilt
  83.   // bekommen. Deswegen sagen wir OpenGL, wie wir den Renderbuffer benutzen
  84.   // wollen und welche Größe er haben soll:
  85.   WriteLog ('glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, '+IntToStr(pWidth)+', '+IntToStr(pHeight)+')');
  86.   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, pWidth, pHeight);
  87.   WriteLog ('error: '+IntToStr(glGetError));
  88.  
  89.   // Mit glRenderbufferStorageEXT hat OpenGL den Speicher für den Renderbuffer,
  90.   // den wir als Depthbuffer nutzen, reserviert. Jetzt können wir unseren
  91.   // Depthbuffer zum FBO hinzufügen:
  92.   WriteLog ('glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,'+
  93.                                          'GL_DEPTH_ATTACHMENT_EXT,'+
  94.                                          'GL_RENDERBUFFER_EXT, depthbuffer)');
  95.   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
  96.                                GL_DEPTH_ATTACHMENT_EXT,
  97.                                GL_RENDERBUFFER_EXT, depthbuffer);
  98.   WriteLog ('error: '+IntToStr(glGetError));
  99.   // Die letzte Anweisung sollte ziemlich einfach zu verstehen sein. Der zweite
  100.   // Parameter sagt einfach, als was der Renderbuffer genutzt werden soll
  101.  
  102.   // Um Farbinformationen in unser Framebufferobjekt schreiben zu können,
  103.   // fügen wir eine Textur hinzu. Bevor wir sie hinzufügen können müssen wir
  104.   // sie natürlich noch erstellen:
  105.   WriteLog ('glGenTextures(1, @FBO_tex)');
  106.   glGenTextures(1, @FBO_tex);
  107.   WriteLog ('error: '+IntToStr(glGetError));
  108.  
  109.   WriteLog ('glBindTexture(GL_TEXTURE_2D, FBO_tex)');
  110.   glBindTexture(GL_TEXTURE_2D, FBO_tex);
  111.   WriteLog ('error: '+IntToStr(glGetError));
  112.  
  113.   WriteLog ('glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST)');
  114.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  115.   WriteLog ('error: '+IntToStr(glGetError));
  116.  
  117.   WriteLog ('glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST)');
  118.   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  119.   WriteLog ('error: '+IntToStr(glGetError));
  120.  
  121.   WriteLog ('glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, '+IntToStr(pWidth)+', '+IntToStr(pHeight)+', 0, GL_RGB8, GL_UNSIGNED_BYTE, nil)');
  122.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, pWidth, pHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, nil);
  123.   WriteLog ('error: '+IntToStr(glGetError));
  124.  
  125.   // Es dürfte eigentlich nichts völlig Unverständliches da stehen. Wir
  126.   // erstellen die Textur, binden sie, stellen die Filtermodi ein und erzeugen
  127.   // im Speicher den entsprechenden Platz. Anzumerken ist aber, dass die Textur
  128.   // die gleiche Größe wie der Renderbuffer haben muss. Alle Größen müssen
  129.   // einheitlich sein. Man kann also nicht einen Renderbuffer von 512*512 und
  130.   // eine Textur von 256*256 erstellen und sie zusammen in einem FBO nutzen.
  131.   // Hinzugefügt wird sie nach dem gleichen Schema wie der Depthbuffer:
  132.   WriteLog ('glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, FBO_tex, 0)');
  133.   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, FBO_tex, 0);
  134.   WriteLog ('error: '+IntToStr(glGetError));
  135.  
  136.   // Wie gesagt, nicht viel neues hier. Der zweite Parameter,
  137.   // GL_COLOR_ATTACHMENT0_EXT sagt OpenGL wo die Textur hinzugefügt werden
  138.   // soll (man kann mehrere hinzufügen, doch dazu später mehr). Der letzte
  139.   // Parameter beschreibt das Mipmaping-Level.
  140.  
  141.   WriteLog ('checking error');
  142.   CheckFBO;
  143.  
  144.   // FBO "entbinden", damit wieder normal gezeichnet werden kann.
  145.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  146. end;
  147.  
  148. procedure TFrameBufferObject.CheckFBO;
  149. var
  150.   error: GlEnum;
  151.   i: integer;
  152. begin
  153.   error := glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  154.   WriteLog ('error: '+IntToStr(error));
  155.   if error <> GL_FRAMEBUFFER_COMPLETE_EXT then begin
  156.     for i := 0 to Log.Count-1 do begin
  157.       Application.MessageBox(pchar('error '+IntToStr (i+1)+': '+Log.Strings[i]),
  158.                              'Error', MB_OK);
  159.     end;
  160.   end;
  161.   case error of
  162.     GL_FRAMEBUFFER_COMPLETE_EXT:
  163.       Exit;
  164.     GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
  165.       raise Exception.Create('FBO: Incomplete attachment');
  166.     GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
  167.       raise Exception.Create('FBO: Missing attachment');
  168.     GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
  169.       raise Exception.Create('FBO: Incomplete dimensions');
  170.     GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
  171.       raise Exception.Create('FBO: Incomplete formats');
  172.     GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
  173.       raise Exception.Create('FBO: Incomplete draw buffer');
  174.     GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
  175.       raise Exception.Create('FBO: Incomplete read buffer');
  176.     GL_FRAMEBUFFER_UNSUPPORTED_EXT:
  177.       raise Exception.Create('FBO: Framebufferobjects unsupported');
  178.   end;
  179. end;
  180.  
  181. procedure TFrameBufferObject.WriteLog (s: string);
  182. begin
  183.   Log.Add(s);
  184. end;
  185.  
  186. procedure TFrameBufferObject.PrepareRender;
  187. // bind vor dem rendern auf die textur aufrufen und dann einfach rendern.
  188. // den viewport dann nicht mehr verändern.
  189. begin
  190.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
  191.   glPushAttrib(GL_VIEWPORT_BIT);
  192.   glViewPort(0, 0, Width, Height);
  193.   Rendering := true;
  194. end;
  195.  
  196. procedure TFrameBufferObject.FinishRender;
  197. // release nach dem rendern auf die textur aufrufen um den viewport
  198. // zurückzusetzen.
  199. begin
  200.   glPopAttrib;
  201.   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  202.   Rendering := false;
  203. end;
  204.  
  205. procedure TFrameBufferObject.Bind;
  206. // vor dem Benutzen der Textur aufrufen
  207. begin
  208.   glBindTexture(GL_TEXTURE_2D, FBO_tex);
  209.   glGenerateMipmapEXT(GL_TEXTURE_2D);
  210.   //Textur danach ganz normal benutzen
  211. end;
  212.  
  213. end.
  214.  


Zuletzt geändert von Lord Horazont am Di Nov 24, 2009 19:29, insgesamt 1-mal geändert.
Code-Tag auf Pascal umgestellt


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Ready: FrameBufferObject
BeitragVerfasst: Mi Nov 25, 2009 04:30 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Hallo,

ich bin soweit fertig. Da ich leider hier keine ZIP-Datei anhängen kann, habe ich die fertige Software (EXE) als Archiv auf meine Homepage gestellt. Wer mich kontaktiert, bekommt auch den Sourcecode. Direkter Link zum Download: http://www.heyroths.de/main.html?src=%2F#2,3
Diese Anwendung ist nur als Test für die neue Klasse und weitere meiner Versuche gedacht. Trotzdem viel Spaß,

Andree


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 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.013s | 17 Queries | GZIP : On ]