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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    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 confirmé Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    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 confirmé Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    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 confirmé Avatar de matteli
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    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 Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    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.

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 85
    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.

+ 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