Question

Je construis un premier jeu de tir subjectif en utilisant OpenGL, et je suis en train d'obtenir un modèle de pistolet à flotter devant la caméra. J'ai arraché un modèle de Fallout 3 en utilisant un décompilateur de ressources (converti en .OBJ et chargé dans).

Cependant, voici ce qu'elle ressemble à l'écran:

Capture d

La moitié des triangles de l'arme à feu sont tronquées à ce qui semble être le tronc de cône.

Je l'ai mis devant mon appareil photo comme ceci:

glPushMatrix();
    glLoadIdentity();

    glTranslatef(m_GunPos.x, m_GunPos.y, m_GunPos.z);
    glRotatef(m_GunRot.x, 1, 0, 0);
    glRotatef(m_GunRot.y, 0, 1, 0);
    glRotatef(m_GunRot.z, 0, 0, 1);
    glScalef(m_GunScale.x, m_GunScale.y, m_GunScale.z);

    m_Gun->Render(NULL);
glPopMatrix();

Je sauve la matrice de GL_MODELVIEW d'origine, charger la matrice d'identité, traduire mon fusil légèrement à droite de mon appareil photo et de le rendre. Ceci est ma routine pour rendre un SceneNode:

glPushMatrix();
    if (m_Model) { m_Model->Render(&final); }

    if (m_Children.size() > 0)
    {
        for (std::vector<SceneNode*>::iterator i = m_Children.begin(); i != m_Children.end(); ++i)
        {
            (*i)->Render(&final);
        }
    }
glPopMatrix();

Il rend son propre modèle et tout enfant des années SceneNode. Enfin, le rendu de maillage réelle ressemble à ceci:

if (m_Material)
{
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_Material->m_TexDiffuse);
}

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

glVertexPointer(3, GL_FLOAT, sizeof(Vec3), &m_Vertex[0]);
glNormalPointer(GL_FLOAT, sizeof(Vec3), &m_Normal[0]);
glTexCoordPointer(2, GL_FLOAT, 0, &m_UV[0]);

glDrawArrays(GL_TRIANGLES, 0, m_Vertex.size());

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

Est-il possible de désactiver l'écrêtage pour juste le pistolet? Comment les autres jeux le font?

Merci d'avance.

Était-ce utile?

La solution

Du point de vue (sans jeu de mots) d'OpenGL, la frustrum est juste une autre matrice. Vous devriez être en mesure de pousser la matrice de projection, appelez gluPerspective (ou glFrustrum, si vous êtes aventureux) pour définir znear à une valeur très faible, tirer le pistolet, pop alors la matrice de projection et d'en tirer le reste de la scène (méfiez-vous, cependant, que la pile de la matrice de projection est souvent assez faible profondeur -. il peut être aussi peu que deux niveaux)

Une mise en garde: Je ne l'ai jamais vraiment réfléchi à la façon dont cela pourrait influer sur z combats. Il pourrait ne pas faire une vraie bonne -. Il pourrait travailler comme si vous aviez la valeur znear plus petit tout en tirant toute la scène

Autres conseils

Le problème est causé par le plan proche écrêtage.

Réduire la valeur znear que vous avez utilisé pour calculer votre matrice de projection. Seulement faire aussi bas que nécessaire si. Plus il est bas, plus les problèmes de lutte contre z vous obtiendrez.

Avez-vous essayé de pousser votre arme plus loin dans la scène (à savoir: loin de la caméra)? Lorsque vous le faites, sont le polygone encore clipser? Si non, alors, comme le suggère votre modèle est coupé par le lieu de coupure près de (défini dans votre matrice de projection). Si vous avez encore des artefacts, le problème pourrait être quelque chose d'autre de rendre les états, le chargement du modèle, etc, etc.

Avez-vous vu le modèle entier dans une visionneuse? Peut-être que la façon dont le modèle ressemble et le nombre de poly a été optimisé car vous avez besoin de voir ces polys dans le jeu

Pourquoi ne pas pousser juste le pistolet plus loin dans la scène et l'échelle vers le haut pour qu'il ne coupe pas contre le plan proche?

Vous devez spécifier un autre plan de clipping proche-lointain lorsque vous rendre des objets proches, comme une prise d'armes par un personnage. Cela causerait les valeurs de profondeur fenêtre espace des fragments étaient invalides par rapport à vos autres éléments de la scène, alors vous avez aussi de modifier la plage de profondeur cible en appelant glDepthRange. Cela vous donnera augmenter la précision dans l'appareil photo à proximité d'objets.

Comme vous l'avez mentionné, que la modification des plans quasi loin de votre scène générale frustum n'est pas une solution, ni déplacer le pistolet vers l'avant / arrière, car ils introduisent des problèmes z combat.

« Superposition » avec la matrice de projection différente peut être dangereux si vous ne faites pas attention car les valeurs de profondeur entre les différentes couches ne sont pas dans le même « espace ». Ce que je vous appelle une couche est ici un groupe d'objets rendus avec une matrice de projection donnée. Il y a généralement 2 solutions à ceci:

  1. Rendu vos différentes couches (avec tous les objets sur ceux-ci) à partir de la plus éloignée de compensation et le tampon de profondeur entre chaque rendus.
  2. Répartir le tampon de profondeur entre vos couches en utilisant glDepthRange.

Notez que l'utilisation une de ces techniques vous permettra de corriger si les problèmes potentiels avec des objets de différentes couches combattant ensemble mais il quelques inconvénients:

  1. Il empêche les objets d'intersection entre eux (couches près de toujours apparaître au-dessus des autres couches - ils ne se croisent jamais). Parfois, il est quelque chose que vous souhaitez obtenir de toute façon avec ips où le pistolet est toujours au-dessus de tout
  2. Votre tampon de profondeur sera inutilisable pour des trucs comme PostFX (profondeur de champ, etc.) ou le rendu différé.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top