Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

ArthurII

Treue Seele

  • »ArthurII« ist der Autor dieses Themas

Beiträge: 132

Wohnort: Aachen

Beruf: Student

  • Private Nachricht senden

1

02.03.2010, 16:54

[OpenGL] Schatten mit Stencil Buffer

Hey ho
In den Vergangenen Monaten hab ich ein kleines Jump'n'Run Spiel mit OpenGL entstehen lassen. Der aktuelle Entwicklungspunkt sieht die Implementierung von Schatten vor.

Bei der Realisierung habe ich mich unter anderem an diesem Tutorial orientiert joachimrohde.com.

Leider will mein Spiel das so nicht :(

Ich initialisiere so:


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void initGL()
{
    glEnable(GL_TEXTURE_2D); // Texture Mapping aktivieren


    //glEnable(GL_COLOR_MATERIAL);

    glShadeModel(GL_SMOOTH); //antialising


    //glEnable(GL_LINE_SMOOTH); //Antialasing aktivieren


    glClearColor(0, 0, 0, 0.5f); 
    glClearDepth(1.0f);
    glClearStencil(0);

    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LEQUAL); 

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    

    glEnable(GL_LIGHTING);
    
    glEnable(GL_CULL_FACE);                             // Enable Culling

    glCullFace(GL_BACK);                                // Set Culling Face To Back Face

    
    glClearColor(0.1f, 1.0f, 0.5f, 1.0f);

    
}



im verlauf der draw-methode zeichne ich zuerst alle objekte über zuvor berechnete displaylisten.

Danach kommen folgende Einstellungen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
glClear(GL_STENCIL_BUFFER_BIT);
        glBindTexture(GL_TEXTURE_2D, NULL); //Textur abwählen


        glDisable(GL_LIGHTING);
        
        glColorMask(0,0,0,0);

        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_ALWAYS, 1, 0xffffffff);

        glDepthMask(GL_FALSE);
        glDepthFunc(GL_LEQUAL);


danach rufe ich für alle Schattenwerfen cast_shadow auf:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Sprite::cast_shadow(Vektor lp)
{

    glTranslatef(pos.x, pos.y, pos.z);

    //erster durchgang

    glFrontFace(GL_CCW);
    glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);

    render_shadow_volume(lp-pos);


    //zweiter durchgang


    glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); 
    glFrontFace(GL_CW);
    render_shadow_volume(lp-pos);

    glFrontFace(GL_CCW);

    glTranslatef(-pos.x, -pos.y, -pos.z);
    
}


wobei render_shadow_volume die Schatten Volumina zeichnet (eine kopie sprengt hier zum einen den rahmen, zum anderen habe ich erfolgreich geprüft, dass das Volumen korrekt berechnet wird).

danach noch das "Schatten-Polygon"

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
glLoadIdentity();

        glColorMask(1,1,1,1);
        glStencilFunc(GL_NEVER, 0, 0xffffffff);
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

        glPushMatrix();
        glEnable(GL_BLEND);
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        glColor4f(0.0f, 0,0,0.5f);

        glBegin( GL_TRIANGLE_STRIP );
            glVertex3f(-0.1f, 0.1f,-0.40f);
            glVertex3f(-0.1f,-0.1f,-0.40f);
            glVertex3f( 0.1f, 0.1f,-0.40f);
            glVertex3f( 0.1f,-0.1f,-0.40f);
        glEnd();

        glDisable(GL_BLEND);

        glDepthFunc(GL_LEQUAL);
        glDepthMask(GL_TRUE);
        glEnable(GL_LIGHTING);
        glDisable(GL_STENCIL_TEST);
        glShadeModel(GL_SMOOTH);



irgendwo habe ich da falsche Einstellungen. ich kann allerdings beim besten Willen nicht finden wo. Wenn ich die anwendung starte sieht das ganze etwa so aus:

(Link)



Mir ist klar, dass ich das Viereck über den ganzen Monitor zeichnen sollte, nur dann erkennt man keinen unterschied, und denkt nur die ganze Szene wäre sehr dunkel.

Ich wäre jedem, der sich die Sache mal anguckt und unter Umständen mit seinem eigenen Code vergleicht sehr verbunden.

Vielen Dank

Arthur
Ich bin nicht verrückt - nur verhaltensoriginell!
Project-Seite: Aura

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

2

02.03.2010, 18:09

Also alle bis auf den letzten Block sehen auf den ersten Blick soweit korrekt aus. Der letzte ist allerdings Käse.

GL_KEEP,GL_KEEP,GL_KEEP ist soweit korrekt, er soll ja schließlich keine Änderungen mehr durchführen, aber GL_NEVER kann nicht stimmen.

Mein eigener Quelltext dafür ist leider verschollen, aber du musst dort das Zeichnen auf den Bereich limitieren, bei dem ... durch den Z-Buffer... nur die Front-Planes gezeichnet wurden, bei NeHe sieht's so aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
    glColor4f( 0.0f, 0.0f, 0.0f, 0.4f );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );
    glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
    glPushMatrix();
    glLoadIdentity();
    glBegin( GL_TRIANGLE_STRIP );
        glVertex3f(-0.1f, 0.1f,-0.10f);
        glVertex3f(-0.1f,-0.1f,-0.10f);
        glVertex3f( 0.1f, 0.1f,-0.10f);
        glVertex3f( 0.1f,-0.1f,-0.10f);
    glEnd();


Also dein Never auf jeden Fall schonmal durch das NotEqual ersetzen, sollte es dann eventuell schon tun.

Mich wundert, dass er bei GL_NEVER überhaupt noch was zeichnet oder hast du da beim Screenshot GL_STENCIL_TEST schon wieder disabled?

LG
Alyx

ArthurII

Treue Seele

  • »ArthurII« ist der Autor dieses Themas

Beiträge: 132

Wohnort: Aachen

Beruf: Student

  • Private Nachricht senden

3

02.03.2010, 23:21

der Screenshot ist von dem Code.

allerdings ändert sich auch mit GL_NOTEQUAL nichts. schaut immer noch genau so aus wie vorher

(GL_NEVER hatte ich zu Testzwecken eingesetzt um zu gucken ob das mit dem Stenicl-Test überhaupt klappt)
Ich bin nicht verrückt - nur verhaltensoriginell!
Project-Seite: Aura

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

4

03.03.2010, 00:10

Was mich nach wie vor wundert ist dass er trotz NEVER das graue Rechteck gezeichnet hat.

Vergleich dein Projekt einfach noch mal hiermit:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=27

Was aus deinem Code nicht ersichtlich ist:
Dumme Frage, aber um sicher zu gehen: Du hast schon 8-Bit-Stencil reserviert oder?

Ansonsten nochmal die Checkliste:
- Welt normal zeichnen
- Stencil-Buffer mit 0 clearen
- Depth-Write aus
- Color-Mask aus
- Stencil-Test auf Always, Increase +1
- Front-Planes zeichnen
- Stencil-Test auf Always, Decrease +1
- Back-Planes zeichnen
- Stencil-Write ausschalten
- Stencil-Test auf != 0
- Shadow-Rect über den ganzen Bildschirm zeichnen

Wenn der Quelltext von deinem Test kompakt und problemlos direkt compilierbar ist, kannst du ihn mir mal an alyx ät theneposproject.de schicken, dann schau ichs mir morgen Abend mal an und habs wahrscheinlich in 2 Minuten, aber so ist's immer ein bischen Rätsel raten :-).

LG
Alyx

ArthurII

Treue Seele

  • »ArthurII« ist der Autor dieses Themas

Beiträge: 132

Wohnort: Aachen

Beruf: Student

  • Private Nachricht senden

5

03.03.2010, 00:40

Zitat

Was aus deinem Code nicht ersichtlich ist:
Dumme Frage, aber um sicher zu gehen: Du hast schon 8-Bit-Stencil reserviert oder?


Muss ich das?? bzw. wie geht das??
Und was bedeutet das??
In keinem der Tutorials oder Texte zum Thema Stencil-Buffer stand was davon...
Ich bin nicht verrückt - nur verhaltensoriginell!
Project-Seite: Aura

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

6

03.03.2010, 22:06

Je nachdem wie und womit du es initialisierst.

Wenn du GLUT nimmst, müssen folgende Flags gesetzt sein....

Zitat

For example, for a double-buffered, RGBA-mode window with a depth and stencil buffer, use GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL


Bei mir siehts so aus (direkte OpenGL Intialisierung via wglChoosePixelFormat):

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
    int iAttributes[] = { 
        WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,                                             // 0
        WGL_SUPPORT_OPENGL_ARB,GL_TRUE,                                             // 1
        WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,                             // 2
        WGL_COLOR_BITS_ARB,24,                                                      // 3
        WGL_ALPHA_BITS_ARB,0,                                                       // 4
        WGL_DEPTH_BITS_ARB,24,                                                      // 5
        WGL_STENCIL_BITS_ARB,8,                                                     // 6
        WGL_DOUBLE_BUFFER_ARB,GL_TRUE,                                              // 7
        WGL_SAMPLE_BUFFERS_ARB,mfFeatures.miMultiSampling ? GL_TRUE : GL_FALSE,     // 8
        WGL_SAMPLES_ARB, mfFeatures.miMultiSampling,                                // 9
        0,0};                                                                       // 10


LG
Alyx

ArthurII

Treue Seele

  • »ArthurII« ist der Autor dieses Themas

Beiträge: 132

Wohnort: Aachen

Beruf: Student

  • Private Nachricht senden

7

03.03.2010, 22:45

da war der haken. wie gesagt, stand nirgendwo was von...

war schon fast am verzweifeln an der Geschichte...
Ich bin nicht verrückt - nur verhaltensoriginell!
Project-Seite: Aura

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

8

03.03.2010, 22:51

Gut, dann bin ich beruhigt. Das erklärt auch wieso er bei GL_NEVER trotzdem gezeichnet hat... er wird wohl sämtliche Stencil-Funktionen völlig ignoriert haben, da es nicht verfügbar war, damit auch das NEVER :-).

LG
Alyx

ArthurII

Treue Seele

  • »ArthurII« ist der Autor dieses Themas

Beiträge: 132

Wohnort: Aachen

Beruf: Student

  • Private Nachricht senden

9

04.03.2010, 22:17

So, ich hab das jetzt in einer vernünftigen Weise realisiert.

Der Haken ist nur: nah an den Kanten meiner Objekte flimmert manchmal der Schatten quasi weg und wieder zurück (ich stehe mit meiner Kamera in dem Moment auf keinen Fall im Volumen drin ist).

hab mal einen kleinen Screenshot gemacht:


(Link)


Ich hoffe man kann erkennen was ich meine.
Ich bin nicht verrückt - nur verhaltensoriginell!
Project-Seite: Aura

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

10

04.03.2010, 22:52

Was verstehst du unter "flimmert weg"?

Werbeanzeige