Précédent   Forum des professionnels en informatique > Applications > Développement 2D, 3D et Jeux > API graphiques > OpenGL
OpenGL Forum d'entraide sur le développement en OpenGL. Avant de poster -> FAQ OpenGL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/12/2011, 20h38   #1
Invité régulier
 
Inscription : juin 2004
Messages : 53
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : juin 2004
Messages : 53
Points : 5
Points : 5
Envoyer un message via MSN à orochimaru
Par défaut [openGL] heightmap: vbo + texturing

Bonjours à tous,

Je suis actuellement en train de me former à openGL et essaye de créer une carte en utilisant un heightmap, mon gestionnaire de fenêtre est SFML2 qui me permet aussi de charger les images (heightmap + textures)

malheureusement, je coince un peu sur l'utilisation des vbo, ou plutot de texturer les terrain qui est stocké dans un vbo.

Voici mon code :
Code :
1
2
3
4
5
6
7
8
struct Vertex
{
    GLfloat x, y, z;        // position
    GLfloat nx, ny, nz;     // normale
    GLfloat s, t;           // texCoord
    GLubyte r, g, b;        // couleur
    GLubyte padding[29];    // alignement sur 32 bits (http://www.opengl.org/wiki/VBO)
};
Code :
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
void Terrain::setVBO()
{
    m_vbo = new Vertex[ m_height * m_width ];
    if( !m_vbo )
    {
        cerr << "Allocation de m_vbo impossible";
        exit(1);
    }
 
    uint index = 0;
    for(uint i=0; i<m_width; i++)
    {
        for(uint j=0; j<m_height; j++)
        {
            m_vbo[index].x = (GLfloat) i * m_pas_x;
            m_vbo[index].y = (GLfloat) m_heightmap.GetPixel(i, j).r * m_pas_y;
            m_vbo[index].z = (GLfloat) j * m_pas_z;
 
            m_vbo[index].r = m_heightmap.GetPixel(i, j).r;
            m_vbo[index].g = m_heightmap.GetPixel(i, j).r;
            m_vbo[index].b = m_heightmap.GetPixel(i, j).r;
 
            m_vbo[index].s = ((GLfloat) i)/m_width; 
            m_vbo[index].t = ((GLfloat) j)/m_height;
 
            index++;
        }
    }
 
    glGenBuffers(1, &m_id_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, m_id_vbo);
    glBufferData(GL_ARRAY_BUFFER, m_width*m_height*sizeof(Vertex), m_vbo, GL_STATIC_DRAW);
 
    /***************************************/
//    m_texture = new sf::Image(); 
//    m_texture->LoadFromFile("textures/Text_main.gif");
//
//    GLuint m_id_tex;
//    glGenTextures(1, &m_id_tex);
//    glBindTexture(GL_TEXTURE_2D, m_id_tex);
//    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
//    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_texture->GetWidth(), m_texture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m_texture->GetPixelsPtr());
 
    /***************************************/
 
    // le tableau est chargé dans la RAM du GPU, on en a plus besoin
    delete[] m_vbo; m_vbo = NULL;
}
j'ai mis en commentaire ce que j'ai tenté de faire et qui ne fonctionne pas

et voici le code d'affichage:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Terrain::draw() const
{
    glBindBuffer(GL_ARRAY_BUFFER, m_id_vbo);
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
    glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(Vertex), BUFFER_OFFSET(32)); // les couleurs sont au 32ieme byte de la structure Vertex
//    glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(24)); // les coordonnées de texture sont au 32ieme byte de la structure Vertex
 
    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_COLOR_ARRAY );
//    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
 
    glDrawElements(m_modeDessin, 6*(m_height-1)*(m_width-1), GL_UNSIGNED_INT, BUFFER_OFFSET(0));
 
//    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
    glDisableClientState( GL_COLOR_ARRAY );
    glDisableClientState( GL_VERTEX_ARRAY );
}
Malgré mes différents tests, je n'arrive pas à texturer ma map :-(
J'en appel donc à votre aide pour m'expliquer comment faire ou me donner un lien. Merci d'avance.

ps: si mon code est buggé ou mauvais, j'aimerais tous les conseils dessus
orochimaru est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2011, 12h52   #2
Responsable 2D/3D/Jeux

 
Avatar de LittleWhite
 
Homme Alexandre Laurent
Étudiant
Inscription : mai 2008
Messages : 6 560
Détails du profil
Informations personnelles :
Nom : Homme Alexandre Laurent
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mai 2008
Messages : 6 560
Points : 14 054
Points : 14 054
Bonjour,

Je me demande quelle est la conséquence du problème (artefacts graphiques ?).
Sinon, je me demande ce qu'il y a dans BUFFER_OFFSET, mais je pense qu'il ne faut pas l'utiliser comme cela, mais plus en passante 32+24.
__________________
Vous souhaitez participer à la section Jeux ? Contactez-moi
La rubrique a aussi un blog !

Ma page sur DVP
Mon Portfolio

Qui connaît l'erreur, connaît la solution.
LittleWhite est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2011, 14h15   #3
Invité régulier
 
Inscription : juin 2004
Messages : 53
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : juin 2004
Messages : 53
Points : 5
Points : 5
Envoyer un message via MSN à orochimaru
Le problème c'est que ça ne fonctionne pas du tout, je ne voit pas comment procéder, autant quand j'utilisai glVertex3f et glTexCoord2f j'ai réussi sans difficulté à texturer ma map (je précise qu'il s'agit d'une seule texture pour tout la carte, je verrais plus tard pour faire du texturing en fonction de la hauteur)
Mais depuis que je l'ai passé en vbo, je bloque.

Dans le bout de code que j'ai fourni plus haut, j'ai chargé l'image via SFML, transformée en texture openGL via glGenTextures, glBindTexture, glTexParameteri et glTexImage2D. J'ai également rentré les coordonnées de chaque vertex de la map dans la texture avec
Code :
1
2
 m_vbo[index].s = ((GLfloat) i)/m_width; 
 m_vbo[index].t = ((GLfloat) j)/m_height;
Puis j'utilise glTexCoordPointer mais en vain.
Déjà je me demande comment indiquer que c'est la texture chargée précédemment qu'il doit utiliser.

pour le BUFFER_OFFSET(), il s'agit d'une macro, la voici :
Code :
#define BUFFER_OFFSET(a) ((char*)NULL + (a))
qui permet de donner l'adresse du a-ième élément dans la structure Vertex.
orochimaru est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2011, 15h37   #4
Responsable 2D/3D/Jeux

 
Avatar de LittleWhite
 
Homme Alexandre Laurent
Étudiant
Inscription : mai 2008
Messages : 6 560
Détails du profil
Informations personnelles :
Nom : Homme Alexandre Laurent
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mai 2008
Messages : 6 560
Points : 14 054
Points : 14 054
Pour spécifier une texture, soit vous passer par un uniforme (technique avec les shaders) soit vous spécifier la texture avec glBindTexture().

Pour le BUFFER_OFFSET(), pour spécifier les coordonnées de texture, il faut bien mettre 24, je mettais trompé la première fois. Sinon, pour le reste, le code me semblait bon. Avez vous vérifier les erreurs avec glGetError() ?
__________________
Vous souhaitez participer à la section Jeux ? Contactez-moi
La rubrique a aussi un blog !

Ma page sur DVP
Mon Portfolio

Qui connaît l'erreur, connaît la solution.
LittleWhite est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/12/2011, 17h14   #5
Invité régulier
 
Inscription : juin 2004
Messages : 53
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : juin 2004
Messages : 53
Points : 5
Points : 5
Envoyer un message via MSN à orochimaru
j'ai ajouté glBindTexture avec l'id de la texture juste avant le glTexCoordPointer mais ca ne fonctionne toujours pas, voici mon nouveau code:

remplissage du VBO :
Code :
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
33
34
35
36
void Terrain::setVBO()
{
    m_vbo = new Vertex[ m_height * m_width ];
    if( !m_vbo )
    {
        std::cerr << "Allocation de m_vbo impossible";
        exit(1);
    }
 
    uint index = 0;
    for(uint i=0; i<m_width; i++)
    {
        for(uint j=0; j<m_height; j++)
        {
            m_vbo[index].x = (GLfloat) i * m_pas_x;
            m_vbo[index].y = (GLfloat) m_heightmap.GetPixel(i, j).r * m_pas_y;
            m_vbo[index].z = (GLfloat) j * m_pas_z;
 
            m_vbo[index].r = m_heightmap.GetPixel(i, j).r;
            m_vbo[index].g = m_heightmap.GetPixel(i, j).r;
            m_vbo[index].b = m_heightmap.GetPixel(i, j).r;
 
            m_vbo[index].s = ((GLfloat) i)/m_width;
            m_vbo[index].t = ((GLfloat) j)/m_height;
 
            index++;
        }
    }
 
    glGenBuffers(1, &m_id_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, m_id_vbo);
    glBufferData(GL_ARRAY_BUFFER, m_width*m_height*sizeof(Vertex), m_vbo, GL_STATIC_DRAW);
 
    // le tableau est chargé dans la RAM du GPU, on en a plus besoin
    delete[] m_vbo; m_vbo = nullptr;
}
Chargement de la texture :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Terrain::chargerTexture()
{
    m_texture = new sf::Image();
    if( !m_texture )
    {
        std::cerr << "Allocation de m_texture impossible";
        exit(1);
    }
    m_texture->LoadFromFile( m_srcTexture );
 
    glGenTextures(1, &m_id_tex);
    glBindTexture(GL_TEXTURE_2D, m_id_tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_texture->GetWidth(), m_texture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m_texture->GetPixelsPtr());
 
    /* Texture en mémoire, on en a plus besoin */
    delete m_texture; m_texture = nullptr;
}
Affichage du terrain :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Terrain::draw() const
{
    glBindBuffer(GL_ARRAY_BUFFER, m_id_vbo);
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
    glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(Vertex), BUFFER_OFFSET(32)); // les couleurs sont au 32ieme byte de la structure Vertex
 
    glBindTexture(GL_TEXTURE_2D, m_id_tex);
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(24)); // les coordonnées de texture sont au 32ieme byte de la structure Vertex
 
    glEnableClientState( GL_VERTEX_ARRAY );
    glEnableClientState( GL_COLOR_ARRAY );
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
 
    glDrawElements(m_modeDessin, 6*(m_height-1)*(m_width-1), GL_UNSIGNED_INT, BUFFER_OFFSET(0));
 
    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
    glDisableClientState( GL_COLOR_ARRAY );
    glDisableClientState( GL_VERTEX_ARRAY );
}
J'ai oublié de préciser que j'utilise un tableau d'index pour afficher le terrain d'ou le 6*(m_height-1)*(m_width-1) pour le nombre d'elements.

Tout fonctionne correctement, sauf le texturing.
orochimaru est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 05h01.


 
 
 
 
Partenaires

Hébergement Web