IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API graphiques Discussion :

Copie d'une image en SDL et OpenGL


Sujet :

API graphiques

  1. #1
    Membre du Club Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    Points : 57
    Points
    57
    Par défaut Copie d'une image en SDL et OpenGL
    Bonjour,

    j'utilise la SDL avec OpenGL pour afficher du 2D.

    A la 1er image :
    - je construis une image de fond dans le buffer (ok)
    - j'aimerais la copier dans un buffer temporaire/surface (?)
    - puis ajouter les sprites (ok)
    - et l'afficher. (ok)

    A la prochaine image :
    - je voudrais coller le contenu du buffer tempo dans le buffer avec un décalage s'il y a eu scrolling (?)
    - et compléter l'image de fond dans ce cas (ok)
    - et ajouter les sprites et l'afficher. (ok)

    J'ai vu comment faire ça en SDL pur dans les tuto mais j'aimerais utiliser les performances d'openGL pour la video.
    J'ai trouvé la commande glCopyPixels mais je ne vois pas diriger le résultat de cette fonction vers un autre buffer.

    Merci de votre aide.

  2. #2
    Membre du Club Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    Points : 57
    Points
    57
    Par défaut
    bon j'ai cherché
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
     
    #include <SDL/SDL.h>
    #include <iostream>
    #include <GL/gl.h>
    #include <GL/glu.h>
     
     
    const unsigned int WIDTH=800;
    const unsigned int HEIGHT=600;
     
    using namespace std;
     
    int main(int argc, char **argv)
    {
     
        SDL_Event event;
        SDL_Surface *screen;
     
        int done = 0, fps, last, now;
        unsigned int checkTime;
        const unsigned int wantedfps = 1;
     
        //Initialisation
        if(SDL_Init(SDL_INIT_VIDEO)!=0) {
            cerr << "Probleme pour initialiser SDL: " << SDL_GetError() << endl;
            return EXIT_FAILURE;
        }
     
     
        //Ouvrir une fenetre
        screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL);
        if(screen==NULL)
            done = 1;
     
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
     
        // recuperation de l'etat du parametre "double buffer"
        int nValue;
        if( SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &nValue) < 0)
        {
            std::cerr << "Echec de recuperation du parametre SDL_GL_DOUBLEBUFFER : " << SDL_GetError() << std::endl;
            return (EXIT_FAILURE);
        }
     
        // assurons nous que le mode "double buffer" est bien actif
        if(nValue != 1)
        {
            std::cerr << "Erreur : SDL_GL_DOUBLEBUFFER inactif" << std::endl;
            return (EXIT_FAILURE);
        }
     
     
        // Mettre le systeme de coordonnees a zero avant de modifier
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
     
        //Mettre la bonne perspective
        glOrtho(0,WIDTH,HEIGHT,0,-1,1);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
     
        //Initialisation du moteur
        //if(moteur.init()==false)
            //done = 1;
     
     
     
        //Pour le taux de rafraichissement
        checkTime = SDL_GetTicks();
     
     
        //Je crée et j'affiche mon carré que je copie d'un autre buffer
        glClear(GL_COLOR_BUFFER_BIT);
        glColor3ub(255, 0, 0);         // unique définition de la couleur bleue
        glBegin(GL_QUADS);                 // début du tracé
            glVertex2i( 0, 50);  // en bas à gauche
            glVertex2i(50, 50);  // en bas à droite
            glVertex2i( 50, 0);  // en haut à droite
            glVertex2i( 0, 0);  // en haut à gauche
        glEnd();
     
        glDrawBuffer(GL_AUX0);
        glCopyPixels(0,0,WIDTH,HEIGHT,GL_COLOR);
     
        SDL_GL_SwapBuffers();
     
     
        while(!done)
        {
     
     
            //Traiter les evenements
            while(SDL_PollEvent(&event))
            {
                switch(event.type)
                {
                    case SDL_QUIT:
                        done=1;
                        break;
                    case SDL_KEYUP:
                        if(event.key.keysym.sym==SDLK_q)
                            done=1;
                        break;
                    default:
                        break;
                }
            }
     
     
            if(SDL_GetTicks() > (checkTime + 1000 / wantedfps) )
            {
                // On met a jour la variable checkTime
                checkTime = SDL_GetTicks();
     
     
     
                // Je copie le contenu de mon buffer auxiliaire et l'affiche
     
                glClear(GL_COLOR_BUFFER_BIT);
                glReadBuffer(GL_AUX0);
                glCopyPixels(0,0,WIDTH,HEIGHT,GL_COLOR);
                SDL_GL_SwapBuffers();
     
     
            }
            else
            {
                // Attendre 5 millisecondes
                SDL_Delay(5);
            }
     
        }
     
        SDL_Quit();
     
        (void) argc;
        (void) argv;
     
        return EXIT_SUCCESS;
    }
    Avec ce code j'ai un carré qui apparait une frame sur 2. Je comprends pas bien pourquoi.

  3. #3
    Membre du Club Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    Points : 57
    Points
    57
    Par défaut
    Salut,

    La commande "glcopypixel" ne marche pas bien.

    J'utilise donc la commande "glReadPixels" et "glDrawPixels" qui marche bien quand je veux copier tout l'écran.

    Par contre pour le scrolling j'ai un problème :

    En effet la commande glRasterPosition permet de positionner le point d'insertion pour copier l'image (elle me permet de décaler l'image vers la droite ou vers le haut) mais pas vers la gauche, ni vers le bas car glRasterPosition n'accepte pas les coordonnées négatives.

    Il y aurait bien quelques astuces me permettant de contourner le problème mais pas de méthode directe.

    Si quelqu'un a une solution.

  4. #4
    Membre du Club Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    Points : 57
    Points
    57
    Par défaut
    Je ne sens pas un enthousiasme débordant sur ce sujet.

    Bon j'ai réussi à faire un bricolage qui marche correctement mais ça m'ennuie de devoir copier quelque chose de la mémoire video en mémoire PC pour le reservir en mémoire video à l'image d'après.

  5. #5
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Salut,
    le plus simple est de créer des textures OGL depuis tes images et de les mapper sur des quads. Je comprends pas trop ton histoire d'ajouter un bout de l'image s'il y a eu scrolling, ni pourquoi tu passes par une surface SDL.
    Vive les roues en pierre

  6. #6
    Membre du Club Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    Points : 57
    Points
    57
    Par défaut
    Mon fond de carte est compressé avec le principe du quadtree nodes.
    J'ai divisé ma carte en bloc de 32 par 32 pixels.
    Un fichier, chargé en mémoire, que je lis bit à bit me permet de "construire" la carte en "construisant" uniquement les blocs visibles à l'écran.
    L'avantage de cette compression est que je dessine des carrés dont je peux modifier la couleur en fonction de paramètres du jeu.

    La "construction" et l'affichage de la partie de la carte à l'écran prend environ 100ms. Si je veux une fréquence d'affichage de 25i/s, je ne peux pas me permettre de "reconstruire" à chaque rendu.

    Je voulais donc mettre en mémoire la carte visible à l'écran pour m'en resservir au prochain rendu.

    S'il n'y a pas de scrolling, je colle la carte en mémoire complètement.
    S'il y a eu scrolling, je colle la carte avec un décalage et je complète la carte en "construisant" les nouveaux blocs nécessaires pour compléter l'écran.

    J'utilise donc la commande "glReadPixels" pour mettre en mémoire RAM l'image et "glDrawPixels" pour la recopier en mémoire vidéo. Et c'est ici que le bas blesse car ces 2 commandes sont assez lentes.

  7. #7
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    A ma connaissance on ne peut pas mixer des SDL surfaces avec Open GL ce sont des routines graphiques différentes.
    SDL sous Windows appelle Direct X qui est évidemment totalement incompatible avec Open GL...
    En plus les pipelines de rendu doivent être différents d'un point de vue technologique

  8. #8
    Membre du Club Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    Points : 57
    Points
    57
    Par défaut
    Autre question alors, est ce que GLUT ne serait pas plus adapté que SDL pour utiliser OpenGL dans mon cas ?

  9. #9
    Expert éminent
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Points : 6 812
    Points
    6 812
    Par défaut
    Pour l'utilisation d'OpenGL, SDL et GLUT sont principalement des gestionnaires de fenêtre. Il créé la fenètre de manière à utiliser OpenGL.

    SDL permet également de créer des fenètre pour une utilisation 2D mais sans interraction possible avec OpenGL.

    GLUT permet, quand à lui, d'ajouter quelques fonctionnalités utile pour une application OpenGL.

    Donc GLUT ou SDL sont à peu près la meme chose pour l'utilisation d'OpenGL .. des createurs de fenètres

    Donc qu'importe lequel tu utilises, tu devra traiter toi même les images que tu veux importer ... GLUT ou SDL, à ma connaissance, ne te seront d'aucune utilité ..
    Mes Tutos DirectX, OpenGL, 3D : http://raptor.developpez.com/

  10. #10
    Membre du Club Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    Points : 57
    Points
    57
    Par défaut
    bon ben c'était tout con, le code dans le deuxième post ne marchait pas à cause d'un oubli (en rouge).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    #include <SDL/SDL.h>
    #include <iostream>
    #include <GL/gl.h>
    #include <GL/glu.h>
     
     
    const unsigned int WIDTH=800;
    const unsigned int HEIGHT=600;
     
    using namespace std;
     
    int main(int argc, char **argv)
    {
     
        SDL_Event event;
        SDL_Surface *screen;
     
        int done = 0, fps, last, now;
        unsigned int checkTime;
        const unsigned int wantedfps = 1;
     
        //Initialisation
        if(SDL_Init(SDL_INIT_VIDEO)!=0) {
            cerr << "Probleme pour initialiser SDL: " << SDL_GetError() << endl;
            return EXIT_FAILURE;
        }
     
        
        //Ouvrir une fenetre
        screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL);
        if(screen==NULL)
            done = 1;
     
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
     
        // recuperation de l'etat du parametre "double buffer"
        int nValue;
        if( SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &nValue) < 0)
        {
            std::cerr << "Echec de recuperation du parametre SDL_GL_DOUBLEBUFFER : " << SDL_GetError() << std::endl;
            return (EXIT_FAILURE);
        }
     
        // assurons nous que le mode "double buffer" est bien actif
        if(nValue != 1)
        {
            std::cerr << "Erreur : SDL_GL_DOUBLEBUFFER inactif" << std::endl;
            return (EXIT_FAILURE);
        }
     
     
        // Mettre le systeme de coordonnees a zero avant de modifier
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
     
        //Mettre la bonne perspective
        glOrtho(0,WIDTH,HEIGHT,0,-1,1);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
     
        //Initialisation du moteur
        //if(moteur.init()==false)
            //done = 1;
     
       
     
        //Pour le taux de rafraichissement
        checkTime = SDL_GetTicks();
     
        
        //Je crée et j'affiche mon carré que je copie d'un autre buffer
        glClear(GL_COLOR_BUFFER_BIT);
        glColor3ub(255, 0, 0);         // unique définition de la couleur bleue
        glBegin(GL_QUADS);                 // début du tracé
            glVertex2i( 0, 50);  // en bas à gauche
            glVertex2i(50, 50);  // en bas à droite
            glVertex2i( 50, 0);  // en haut à droite
            glVertex2i( 0, 0);  // en haut à gauche
        glEnd();
     
        glDrawBuffer(GL_AUX0);
        glCopyPixels(0,0,WIDTH,HEIGHT,GL_COLOR);
        glDrawBuffer(GL_BACK);
     
        SDL_GL_SwapBuffers();
     
     
        while(!done)
        {
     
     
            //Traiter les evenements
            while(SDL_PollEvent(&event))
            {
                switch(event.type)
                {
                    case SDL_QUIT:
                        done=1;
                        break;
                    case SDL_KEYUP:
                        if(event.key.keysym.sym==SDLK_q)
                            done=1;
                        break;
                    default:
                        break;
                }
            }
     
     
            if(SDL_GetTicks() > (checkTime + 1000 / wantedfps) )
            {
                // On met a jour la variable checkTime
                checkTime = SDL_GetTicks();
     
                
     
                // Je copie le contenu de mon buffer auxiliaire et l'affiche
     
                glClear(GL_COLOR_BUFFER_BIT);
                glReadBuffer(GL_AUX0);
                glCopyPixels(0,0,WIDTH,HEIGHT,GL_COLOR);
                SDL_GL_SwapBuffers();
     
     
            }
            else
            {
                // Attendre 5 millisecondes
                SDL_Delay(5);
            }
     
        }
     
        SDL_Quit();
     
        (void) argc;
        (void) argv;
     
        return EXIT_SUCCESS;
    }
    Je ne sais même pas comment j'ai pu passé à côté de ça.

    Ya des jours, on ferait mieux de faire autre chose que programmer, on gagnerait du temps.

    Du coup, je copie mon image dans un buffer auxiliaire que je recopie dans le buffer back quand je me ressert de l'image.
    C'est du coup, beaucoup plus rapide que de passer par la mémoire centrale.

    Seul petit bémol, apparemment les vieilles cartes graphiques ne possèdent pas de buffer auxiliaire. Quelqu'un sait quelque chose là-dessus ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 29/03/2009, 14h38
  2. Réponses: 3
    Dernier message: 13/02/2008, 08h17
  3. Retourner une image grace à SDL
    Par ced236 dans le forum SDL
    Réponses: 4
    Dernier message: 23/10/2007, 19h36
  4. Réponses: 5
    Dernier message: 13/04/2006, 22h54
  5. Empecher la copie d'une image
    Par bouassouille dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 30/11/2004, 08h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo