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

Aktuelle Zeit: Fr Jul 18, 2025 00:26

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



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Stencil
BeitragVerfasst: Do Feb 11, 2010 05:17 
Offline
DGL Member
Benutzeravatar

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

ich möchte aus beliebigen Formen Kreise ausschneiden, um Rohre hindurchzuführen. In den Rohren soll eine gerendertes Element nicht als Wand erscheinen.
Also habe ich mir gedacht, dass ich das Tutorial http://wiki.delphigl.com/index.php/Tuto ... cilSpiegel nehme, das ja einen bestimmten Bereich zum Zeichnen nimmt und alles andere ausblendet und es umarbeite. Nämlich so, dass dort, wo jetzt gespiegelt wird, dann nichts mehr gezeichnet wird.
Aber: ich krieg es nicht hin.

Code:
  1.  
  2. procedure MakeVal (var P: TGLVector);
  3. // nur für die testphase, um  aus den angezeigten rechtecken
  4. // teile rauszuschneiden. Soll nachher durch runde löcher ersetzt werden.
  5. begin
  6.   if P.X = 0 then begin
  7.     if P.Y > 0 then begin
  8.       P.Y := P.Y - 5;
  9.     end else begin
  10.       P.Y := P.Y + 5;
  11.     end;
  12.     if P.Z > 0 then begin
  13.       P.Z := P.Z - 5;
  14.     end else begin
  15.       P.Z := P.Z + 5;
  16.     end;
  17.   end else if P.Y = 0 then begin
  18.     if P.X > 0 then begin
  19.       P.X := P.X - 5;
  20.     end else begin
  21.       P.X := P.X + 5;
  22.     end;
  23.     if P.Z > 0 then begin
  24.       P.Z := P.Z - 5;
  25.     end else begin
  26.       P.Z := P.Z + 5;
  27.     end;
  28.   end else if P.Z = 0 then begin
  29.     if P.X > 0 then begin
  30.       P.X := P.X - 5;
  31.     end else begin
  32.       P.X := P.X + 5;
  33.     end;
  34.     if P.Y > 0 then begin
  35.       P.Y := P.Y - 5;
  36.     end else begin
  37.       P.Y := P.Y + 5;
  38.     end;
  39.   end;
  40. end;
  41.  
  42.   .
  43.   .
  44.   .
  45.  
  46.   glColorMask(False, False, False, False);
  47.   glEnable(GL_STENCIL_TEST);
  48.   glStencilFunc(GL_ALWAYS, 0, 0);
  49.   glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
  50.   glDisable(GL_DEPTH_TEST);
  51.   glDisable(GL_TEXTURE_2D);
  52.  
  53.   P1 := Ecke1;
  54.   P2 := Ecke2;
  55.   P3 := Ecke3;
  56.   P4 := Ecke4;
  57.  
  58.   // da, wo das quad erscheint, soll nachher nicht gezeichnet werden.
  59.   // die abmessungen der quadrate werden so verkleinert, dass sie innerhalb
  60.   // der auszustanzenden quadrate liegen.
  61.   MakeVal (P1);
  62.   MakeVal (P2);
  63.   MakeVal (P3);
  64.   MakeVal (P4);
  65.   glBegin(GL_QUADS);  // Start Drawing Quad
  66.     glVertex3dv(@P1); // links unten
  67.     glVertex3dv(@P2); // rechts unten
  68.     glVertex3dv(@P3); // rechts oben
  69.     glVertex3dv(@P4); // links oben
  70.   glEnd();            // Done Drawing Quad
  71.   glEnable(GL_TEXTURE_2D);
  72.   glEnable(GL_DEPTH_TEST);
  73.   glColorMask(True, True, True, True);
  74.   glStencilFunc(GL_EQUAL, 1, 1);
  75.   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  76.   // jetzt kommen die sichtbaren quadrate. diese sind grösser als die
  77.   // vorher gezeichneten, sollten also nur als rahmen sichtbar sein.
  78.   glBegin(GL_QUADS);// Start Drawing Quad
  79.     glTexCoord2d(0,0);                       glVertex3dv(@Ecke1); // links unten
  80.     glTexCoord2d(TextureTileX,0);            glVertex3dv(@Ecke2); // rechts unten
  81.     glTexCoord2d(TextureTileX,TextureTileY); glVertex3dv(@Ecke3); // rechts oben
  82.     glTexCoord2d(0,TextureTileY);            glVertex3dv(@Ecke4); // links oben
  83.   glEnd();          // Done Drawing Quad
  84.   gldisable(GL_STENCIL_TEST);
  85.   .
  86.   .
  87.   .
  88.  


Die Einstellungen für StencilFunc und StencilOp sind im Beispiel wie im Tutorial.
Ich habe aber einige Einstellungen ausprobiert und nichts fruchtet.

Sollte mir jemand schnell helfen können, wäre ich sehr dankbar.

Andree


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: Do Feb 11, 2010 13:14 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Zitat:
ich möchte aus beliebigen Formen Kreise ausschneiden, um Rohre hindurchzuführen. In den Rohren soll eine gerendertes Element nicht als Wand erscheinen.


So richtig verstanden habe ich dein Problem nicht. Willst du direkt die Geometrie verändern, so wie in einem CAD Programm, oder willst, du einfach , dass an einer Stelle des Bildschirms, vorrübergehend nichts gezeichnet wird, und man so durch neu hinzugekommene Objekte durchschauen kann.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: Do Feb 11, 2010 13:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ich verstehe ebenfalls nicht was du genau erreichen möchtest. Vielleicht kannst du mal ein Screenshot machen was aktuell dabei raus kommt und das dann mit GIMP/Photoshop/etc. so verändern wie du es haben willst um uns mal eine Vorstellung zu geben. Übrigens ist mir die Funktionsweise von MakeVal auch ein Rätsel.

Allgemeine Hinweise:
  • Der Stencil-Buffer arbeitet nur im Screenspace, also nur 2D, nicht 3D. In deinem Code schaltest du den Z-Buffer ab, das kann zu Problemen führen, wenn ein Objekt mit Loch im Hintergrund von einem Vordergrundobjekt verdeckt wird.
  • Wenn du wirklich die Geometrie verändern, also echte Löcher produzieren möchtest musst du auf CSG Methoden zurückgreifen. Dafür gibt es fertige Bibliotheken, beispielsweise CGAL.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: Do Feb 11, 2010 14:37 
Offline
DGL Member
Benutzeravatar

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

erst einmal vielen Dank für die Antworten.

Vielleicht geht es auch ohne Screenshot:

Ich mache ein Quad. In dem Quad soll ein Loch sein (rund oder eckig, ist egal).
Durch dieses Loch will ich ein Rohr oder einen hohlen Balken führen so dass es aussieht, als würde dieses/r nahtlos hindurchgeführt.
Das Loch muss sein, damit man durch das Rohr/den hohlen Balken hindurchsehen kann.

Danke,

Andree


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: Do Feb 11, 2010 14:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ok, ich denke ich habs verstanden. Was genau funktioniert den im Augenblick nicht?

Womit löscht du im Augenblick den Stencilbuffer? Den der Defaultwert von glClearStencil ist 0, was der gleiche Wert ist den du auch an die Stellen schreibst wo du die Löcher haben willst. Ich vermute du musst einfach statt glStencilFunc(GL_ALWAYS, 0, 0) das folgende benutzen:
Code:
  1. glStencilFunc(GL_ALWAYS, 1, 0);


Wie schon erwähnt, das abschalten des Z-Buffers kann zu Problemen führen das du Löcher an stellen hast an denen eigentlich keine sein sollten.

Edit: Genau genommen musst du erst die normale Szene (ohne Rohre) nur in den Z-Buffer rendern, dann den Stencil-Buffer füllen und dann die Szene (ohne Rohre) nochmal rendern. Am Ende renderst du dann die Rohre. Ich bin mir aber nicht sicher ob das ganze auch dann noch funktioniert, wenn du durch ein Rohr blickst und dahinter wieder normale Geometrie sehen kannst. Den diese normale Geometrie wird ja wegen des Stencilbuffers nicht gerendert.

Edit2: Die beste Möglichkeit auch derartige Spezialfälle problemlos behandeln zu können ist wahrscheinlich das ganze wirklich in der Geometrie nachzubilden. Das gilt insbesondere dann, wenn es sich um statische Geometrie handelt. Das würde das rendern auch wesentlich einfacher machen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: Do Feb 11, 2010 15:27 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Schade, aber das ist es nicht. Diese Überlegungen hatte ich auch schon angestellt.
Der von Dir vorgeschlagene Versuch bringt das Ergebnis aus der Datei "So ist es.jpg".
Das sind drei in jeder Ebene um den Nullpunkt konstruierte Quadrate.

Das gewünschte Ergebnis ist in der Datei "So soll es sein.jpg" enthalten. Der Einfachheit
halber habe ich hie nur ein Quadrat dargestellt.

Meine gewünschte Vorgehensweise ist:

In den Stencilpuffer die Werte schreiben, die nachher nicht geschrieben werden sollen.
Dann mit einer richtigen Kombination von StencilFunc und StencilOp die Werte um diesen
Puffer herum schreiben.

Danke,

Andree


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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: Do Feb 11, 2010 16:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ok, nachdem ich die Geometrie gesehen habe verstehe ich auch diese MakeVal Prozedur. Das hätte man auch in einer Zeile mit einer Skalierung lösen können. ;)

Was das Problem betrifft, versuch mal das hier:
Code:
  1. glStencilFunc(GL_ALWAYS, 1, 1); // 1 schreiben überall wo Löcher sein sollen.
  2. ...
  3. glStencilFunc(GL_NOTEQUAL, 1, 1); // nur da rendern wo keine 1 ist.
  4.  


Wie schon zuvor versucht zu erklären kannst du mir deiner Methode maximal das Folgende erreichen. Und das auch nur, wenn du wie oben erwähnt zuerst einen extra Durchlauf machst um den Z-Buffer zu füllen. In den Stencil-Bereichen kannst du keine Geometrie sehen die hinter dem Loch liegt, da diese ebenfalls nicht gerendert wird.
Dateianhang:
stencil2.jpg


Ich vermute du erwartest eher sowas hier, also mit den roten Bereichen. Das liegt daran das der Stencilbuffer eine 2D-Operation ist. Die einzige Möglichkeit um dieses Problem mit deiner Stencil-Methode in den Griff zu kriegen wäre jedes Polygon einzeln zu rendern, oder zumindest fällt mir nichts besseres ein. Aber Polygone einzeln zu rendern ist natürlich Overkill, insbesondere da du drei Passes pro Polygon benötigst.
Wenn dieses Problem also wirklich ein Problem in deinem Anwendungsfall ist, solltest du darüber nachdenken die Löcher direkt in der Geometrie zu machen.
Dateianhang:
stencil3.jpg


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

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: Fr Feb 12, 2010 17:43 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 20, 2005 13:18
Beiträge: 1054
Wohnort: Dresden
Programmiersprache: C, C++, Pascal, OPL
Man könnte auch die Textur anpassen, dass die da nen "Alpha==0 Quadrat" hat... Müsste dann nur in der richtigen Reihenfolge zeichen und/oder AlphaTest anmachen.

_________________
Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut.
Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’.
Und du schaust mich an und fragst ob ich das kann.
Und ich denk, ich werd' mich ändern irgendwann.

_________________Farin Urlaub - Bewegungslos


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: Fr Feb 12, 2010 18:08 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ja, der Alpha-Test ist in der Tat eine gute Idee. :)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Stencil
BeitragVerfasst: So Feb 14, 2010 05:29 
Offline
DGL Member
Benutzeravatar

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

ich bin bekehrt. Der Stenciltest ist wohl nicht der optimale Weg zur Erreichung meines Ziels. Da ich ja ein "richtiges" Loch von beliebiger Form in beliebigen OpenGL-Konstrukten haben möchte, muss ich mir diese Dinger wohl selber bauen.

Danke,

Andree


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 7 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.008s | 14 Queries | GZIP : On ]