Question

Im travaille sur ma tâche OpenGL, et la prochaine étape est des modèles de chargement et de produire des ombres en utilisant l'algorithme de volumes d'ombre. Je le fais en 3 étapes -

  1. setConnectivity - conclusion voisins de chaque triangle et stocker leurs indices dans neigh paramètre de chaque triangle,

  2. markVisible(float* lp) - si lp représente vecteur de lumière de position, triangles repères comme visible = true ou visible = false en fonction de la production dot de son vecteur normal et la lumière la position,

  3. markSilhoutte(float *lp) -. Marquage arêtes de silhouette et la construction du volume lui-même, l'extension silhouette à l'infini (100 unités suffisent) dans la direction opposée à la lumière

J'ai vérifié toutes les étapes, et peut certainement dire que son tout ok avec deux premiers, donc le problème est en troisième fonction, que j'inclus dans ma question. J'utilise l'algorithme mis en place dans ce tutoriel: http://www.3dcodingtutorial.com/Shadows/ shadow-Volumes.html

En bref, le bord est inclus dans silhouette si elle appartient au triangle visible et non visible triangle en même temps. Voici une paire de captures d'écran pour vous montrer ce qui est erroné: http://prntscr.com/17dmg , http://prntscr.com/17dmq

Comme vous pouvez le voir, sphère verte représente la position de la lumière, et ces polygones vert-bleu laid sont les visages de « volume d'ombre ». Vous pouvez également voir que im appliquer cette fonction au modèle de cube, et l'un des côtés de volume est manquante (ce ne est pas fermé, mais je devrais être). Quelqu'un peut-il suggérer ce qui est erroné avec mon code et comment puis-je résoudre ce problème? Ici va le code i promis d'inclure (noms de variables sont explicites, je suppose, mais si vous ne pensez que je puisse ajouter une description pour chacun d'eux):

void Model::markSilhouette(float* lp){
        glBegin(GL_QUADS);
        for ( int i = 0; i < m_numMeshes; i++ )
        {
            for ( int t = 0; t < m_pMeshes[i].m_numTriangles; t++ )
            {
                int triangleIndex = m_pMeshes[i].m_pTriangleIndices[t];
                Triangle* pTri = &m_pTriangles[triangleIndex];
                if (pTri->visible){

                    for(int j=0;j<3;j++){
                        int triangleIndex = m_pMeshes[i].m_pTriangleIndices[pTri->neigh[j]-1];
                        Triangle* pTrk = &m_pTriangles[triangleIndex];
                        if(!pTrk->visible){
                            int p1j=pTri->m_vertexIndices[j];
                            int p2j=pTri->m_vertexIndices[(j+1)%3];
                            float* v1=m_pVertices[p1j].m_location;
                            float* v2=m_pVertices[p2j].m_location;

                            float x1=m_pVertices[p1j].m_location[0];
                            float y1=m_pVertices[p1j].m_location[1];
                            float z1=m_pVertices[p1j].m_location[2];

                            float x2=m_pVertices[p2j].m_location[0];
                            float y2=m_pVertices[p2j].m_location[1];
                            float z2=m_pVertices[p2j].m_location[2];

                            t=100;

                            float xl1=(x1-lp[0])*t;
                            float yl1=(y1-lp[1])*t;
                            float zl1=(z1-lp[2])*t;

                            float xl2=(x2-lp[0])*t;
                            float yl2=(y2-lp[1])*t;
                            float zl2=(z2-lp[2])*t;
                            glColor3f(0,0,1);

                            glVertex3f(x1 + xl1,
                                y1 + yl1,
                                z1 + zl1);
                            glVertex3f(x1,
                                y1,
                                z1);
                            glColor3f(0,1,0);

                            glVertex3f(x2 + xl2,
                                y2 + yl2,
                                z2 + zl2);
                            glVertex3f(x2,
                                y2,
                                z2);
                        }
                    }

                }

            }
        }
        glEnd();
    }
Était-ce utile?

La solution

Je l'ai trouvé. On dirait que si vous ne voyez pas une erreur d'algorithme évident pour quelques jours, vous avez fait une f * cking erreur stupide.

Ma variable d'index de triangle est appelé t. Devine quoi? Mon extension longueur du vecteur est aussi appelé t, et ils sont dans la même portée, et je mis t = 100 après la première triangle visible: D Maintenant volumes ressembler à ceci: en dehors http://prntscr.com/17l3n à l'intérieur http://prntscr.com/17l40 Et il semble bon pour toutes les positions claires (acceptables par des volumes d'ombre aglorithm, bien sûr). Ainsi, le code de travail pour dessiner un volume d'ombre est la suivante:

void Model::markSilouette(float* lp){
    glDisable(GL_LIGHTING);
    glPointSize(4.0);
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT_AND_BACK,GL_FILL);
    glBegin(GL_QUADS);
    for ( int i = 0; i < m_numMeshes; i++ )
    {
        for ( int t = 0; t < m_pMeshes[i].m_numTriangles; t++ )
        {
            int triangleIndex = m_pMeshes[i].m_pTriangleIndices[t];
            Triangle* pTri = &m_pTriangles[triangleIndex];

            if (pTri->visible){
                for(int j=0;j<3;j++){
                    Triangle* pTrk;
                    if(pTri->neigh[j]){
                        int triangleIndex = m_pMeshes[i].m_pTriangleIndices[pTri->neigh[j]-1];
                        pTrk = &m_pTriangles[triangleIndex];
                    }

                        if((!pTri->neigh[j]) || !pTrk->visible){

                            int p1j=pTri->m_vertexIndices[j];
                            int p2j=pTri->m_vertexIndices[(j+1)%3];
                            float* v1=m_pVertices[p1j].m_location;
                            float* v2=m_pVertices[p2j].m_location;

                            float x1=m_pVertices[p1j].m_location[0];
                            float y1=m_pVertices[p1j].m_location[1];
                            float z1=m_pVertices[p1j].m_location[2];

                            float x2=m_pVertices[p2j].m_location[0];
                            float y2=m_pVertices[p2j].m_location[1];
                            float z2=m_pVertices[p2j].m_location[2];

                            float f=100; // THE PROBLEM WAS HERE

                            float xl1=(x1-lp[0])*f;
                            float yl1=(y1-lp[1])*f;
                            float zl1=(z1-lp[2])*f;

                            float xl2=(x2-lp[0])*f;
                            float yl2=(y2-lp[1])*f;
                            float zl2=(z2-lp[2])*f;
                            glColor3f(0,0,0);
                            glVertex3f(x1 + xl1,
                                y1 + yl1,
                                z1 + zl1);
                            glVertex3f(x1,
                                y1,
                                z1);
                            glVertex3f(x2,
                                y2,
                                z2);
                            glVertex3f(x2 + xl2,
                                y2 + yl2,
                                z2 + zl2);
                        }
                    }
                }

        }
    }
    glEnd();
}

Autres conseils

Je pense que tout est ok, vous juste du rendu volume sans test de profondeur =)

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