Question

J'ai joué avec OpenGL pour une semaine complète ou équivalent. Après 2D J'essaie maintenant 3D. Je veux reproduire la scène 3D, vous pouvez voir dans la troisième vidéo http://johnnylee.net/projects/ wii / .
J'ai eu du mal à faire le travail de tout correctement avec des textures et la profondeur.

J'ai eu récemment deux problèmes qui ont quelque peu visuellement le même impact:

  • Une avec des textures qui ne se mélangent pas bien en 3D en utilisant les techniques que j'ai trouvé 2D.
  • Un des objets qui apparaissent en haut au-dessus du bas. Comme le problème exposé ici: buffer de profondeur dans OpenGL

Je l'ai résolu les deux problèmes, mais je voudrais savoir si je reçois les choses , en particulier pour le deuxième point .

Pour la première , je pense que je l'ai eu. Je une image d'une cible ronde, avec alpha pour tout l'extérieur du disque. Il est bien chargé à l'intérieur OpenGL. Certains (en raison de mon problème z-ordre) d'autres cibles derrière elle a souffert d'être caché par les régions transparentes du quad naturellement place, je l'habitude de peindre.

La raison était que chaque partie de la texture est supposée être opaque complète à l'égard de la mémoire tampon de profondeur. L'utilisation d'un glEnable(GL_ALPHA_TEST) avec un test glAlphaFunc(GL_GREATER, 0.5f) fait la couche alpha de l'acte de texture comme indicateur d'opacité par pixel (booléen), et rend ainsi le mélange tout à fait inutile (parce que mon image a la transparence booléenne).

Question supplémentaire: Soit dit en passant, est-il un moyen de spécifier une autre source pour le test alpha que la couche alpha utilisée pour le mélange

?

Deuxième , j'ai trouvé une solution à mon problème. Avant d'effacer la mémoire tampon de couleur et de la profondeur que j'ai mis la profondeur par défaut à 0 et glClearDepth(0.0f) et j'ai faire usage de la fonction de la profondeur « plus » glDepthFunc(GL_GREATER).

Ce qui semble étrange pour moi est que la profondeur est de 1,0 et la fonction de la profondeur est « moins » GL_LESS par défaut. J'inverser essentiellement que pour que mes objets ne sont pas affichés inversée ...

Je l'ai vu nulle part hack un tel, mais d'autre part j'ai vu des objets nulle part se laisser entraîner systématiquement dans le mauvais ordre, quelle que soit l'ordre que je les dessine

OK, voici le morceau de code (dépouillé, pas trop je l'espère) qui est maintenant travailler comme je veux:

    int main(int argc, char** argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
        glutInitWindowSize(600, 600); // Size of the OpenGL window
        glutCreateWindow("OpenGL - 3D Test"); // Creates OpenGL Window
        glutDisplayFunc(display);
        glutReshapeFunc(reshape);

        PngImage* pi = new PngImage(); // custom class that reads well PNG with transparency
        pi->read_from_file("target.png");
        GLuint texs[1];
        glGenTextures(1, texs);
        target_texture = texs[0];
        glBindTexture(GL_TEXTURE_2D, target_texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, pi->getGLInternalFormat(), pi->getWidth(), pi->getHeight(), 0, pi->getGLFormat(), GL_UNSIGNED_BYTE, pi->getTexels());

        glutMainLoop(); // never returns!
        return 0;
    }

    void reshape(int w, int h) {
        glViewport(0, 0, (GLsizei) w, (GLsizei) h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(-1, 1, -1, 1);
        gluPerspective(45.0, w/(GLdouble)h, 0.5, 10.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }

    void display(void) {
        // The stared *** lines in this function make the (ugly?) fix for my second problem
        glClearColor(0, 0, 0, 1.00);
        glClearDepth(0);          // ***
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glShadeModel(GL_SMOOTH);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_DEPTH_FUNC);  // ***
        glDepthFunc(GL_GREATER);  // ***

        draw_scene();

        glutSwapBuffers();
        glutPostRedisplay();
    }

    void draw_scene() {
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(1.5, 0, -3, 0, 0, 1, 0, 1, 0);

        glColor4f(1.0, 1.0, 1.0, 1.0);
        glEnable(GL_TEXTURE_2D);
        // The following 2 lines fix the first problem
        glEnable(GL_ALPHA_TEST);       // makes highly transparent parts
        glAlphaFunc(GL_GREATER, 0.2f); // as not existent/not drawn
        glBindTexture(GL_TEXTURE_2D, target_texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        // Drawing a textured target
        float x = 0, y = 0, z = 0, size = 0.2;
        glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(x-size, y-size, z);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(x+size, y-size, z);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(x+size, y+size, z);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(x-size, y+size, z);
        glEnd();
        // Drawing an textured target behind the other (but drawn after)
        float x = 0, y = 0, z = 2, size = 0.2;
        glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(x-size, y-size, z);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(x+size, y-size, z);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(x+size, y+size, z);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(x-size, y+size, z);
        glEnd();
    }
Était-ce utile?

La solution

Normalement, la valeur nette profondeur est 1 (efficacement l'infini) et la fonction passe en profondeur est moins parce que vous souhaitez simuler le monde réel où vous voyez des choses qui sont en face des choses derrière eux. En décochant la mémoire tampon de profondeur à 1, vous dites en substance que tous les objets plus proches que la profondeur maximale doivent être tirées. La modification de ces paramètres est généralement pas quelque chose que vous voulez faire à moins que vous comprenez vraiment ce que vous faites.

Avec les paramètres de la caméra que vous passer à gluLookAt et les positions de vos objets, z = 2 quad sera plus loin de la caméra que z = 0 objet. Qu'est-ce que vous essayez d'accomplir de telle sorte que cela ne semble pas correcte?

L'approche standard pour réaliser la fusion alpha-ordre correct est de rendre tous les objets opaques, puis rendre tous les objets transparents arrière vers l'avant. La fonction de la profondeur régulière / par défaut serait toujours utilisé.

Notez également que vous pouvez obtenir un comportement bizarre de la façon dont vous configurez votre matrice en perspective. Normalement, vous appelleriez gluOrtho OU gluPerspective. Mais pas les deux. Cela multipliera les deux matrices en perspective différentes ensemble, ce qui est sans doute pas ce que vous voulez.

Autres conseils

  

Question supplémentaire: Soit dit en passant, est   il un moyen de spécifier un autre   source pour le test alpha de la   couche alpha utilisée pour le mélange?

Oui, si vous utilisez un shader vous pouvez vous calculer la valeur alpha du fragment de sortie.

En ce qui concerne le deuxième problème. Il est très probablement quelque chose de mal avec votre matrice modelViewProjection

J'ai eu le même problème (et pourrait « fix » avec votre hack) Wich a été provoquée par moi en utilisant une matrice qui était en quelque sorte étrangement mal. Je l'ai résolu instaurera ma génération de matrice.

Formules mis en oeuvre dans la norme de carte fonction glOrtho zNear à -1 et zFar à 1, qui sont par défaut mis en correspondance avec les coordonnées de la fenêtre comme [0,1] (modifiable via glDepthRange pour pipeline fixe, pas sûr que cette fonction est toujours supportée) . test de profondeur fonctionne en ces termes en effet. La façon de contourner cela est simplement supposer que zNear est le plus éloigné du plan de projection, ou générer matrice vous-même, qui aurait besoin de toute façon, si vous voulez vous débarrasser de pipeline existant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top