Home Forums Wiki Doc Install Extras Screenshots Source Code Projects Blog Users Groups Register
Glx-Dock / Cairo-Dock List of forums Technical discussions | Discussions techniques les pBuffers
The latest stable release is the *3.4.0* : How to install it here.
Note: We just switched from BZR to Git on Github! (only to host the code and your future pull requests)
Technical discussions | Discussions techniques

Subjects Author Language Messages Last message
[Locked] les pBuffers
fabounet Français 19 fabounet [Read]
25 February 2009 à 12:03

fabounet, Tuesday 27 January 2009 à 16:42


Subscription date : 30 November 2007
Messages : 17118
Nochka je te poste ce que j'ai trouvé sur les pbuffer
pour en créer un : glXCreateGLXPbuffer
un pbuffer a son propre contexte de dessine => GLXMakeCurrent et tout le reste
glitz-0.5.7 a du code sur les pbuffer il me semble.
dans gtkglext il y'a un exemple avec aussi

voila je n'en sais pas plus, je retourne cogiter sur mes DataRenderer

nochka85, Tuesday 27 January 2009 à 18:04


Subscription date : 29 November 2007
Messages : 7408
Merci ! -> Je vais regarder tout çà !

nochka85, Tuesday 27 January 2009 à 20:12


Subscription date : 29 November 2007
Messages : 7408
Bon, Fabounet j'ai vraiment besoin d'aide car je ne trouve rien de "simple" (de mon niveau je veux dire) pour commencer ... et je ne comprends rien

En fait, tout ce que je trouve est pour windows .... et je n'arrive à rien !!!

Bref, pourrais-tu juste m'aider pour le début en me donnant un bout de code ?

En fait, j'ai un rendu de défini et que j'appelle de cette manière : dessineDeskletJauge(zoom, valeur1, valeur2);
Maintenant, comment je fais pour créer mon contexte afin de lancer mon rendu suivi (je suppose) d'un glFlush ... et enfin, comment je fais pour attribuer ce rendu à ma texture ?? <- J'ai bien compris le principe, mais je nage complètement pour l'appliquer !

Bref, pourrais tu "juste" me donner le code me permettant de faire çà (avec les déclarations des variables ET les #include) ? <- En fait , je compte tout mettre dans un "void initRenderToTexture (double zoom, double valeur1, double valeur2)"

... Désolé, mais là, j'ai VRAIMENT besoin d'un coup de main

fabounet, Wednesday 28 January 2009 à 11:19


Subscription date : 30 November 2007
Messages : 17118
le truc c'est que je n'ai aucun code
je débute autant que toi sur les pbuffers, j'ai juste lu la doc que m'a filé gogole.
as-tu regardé dans la demo de gtkglext (pbuffer-simple.c je crois) et dans glitz ?

nochka85, Wednesday 28 January 2009 à 13:00


Subscription date : 29 November 2007
Messages : 7408
as-tu regardé dans la demo de gtkglext (pbuffer-simple.c je crois) et dans glitz ?


Oui, mais j'ai rien compris ! <- A chaque fois c'est la même chose avec les demos : Ils mettent tellement de truc dedans que j'y comprends plus rien !! Il me faudrait un code "minimal" , moi !!

... En fait, le gros problème que j'ai c'est pour ouvrir ce fameux contexte et pour afficher un simple truc dedans !!

Si tu n'as pas de code, ce que je te propose (si tu es d'accord) c'est de le faire ensemble ici

Bref, Imaginons que (pour l'exemple) je souhaite "simplement" dessiner une surface carré rouge de 1x1 pour le mettre dans mon pbuffer et l'affecter à une texture (que nous nommerons "texture") ... le tout dans un void dédié que nous appelerons renderToTexture !

Bref, en gros, voilà ce qu'il faudrait :

void renderToTexture(void);
{
// A FAIRE : Ici je définis mon contexte offscreen

glColor4f(1.0,0.0,0.0,1.0);
glBegin(GL_QUADS);
glVertex2f (-0.5, 0.5);
glVertex2f (-0.5, -0.5);
glVertex2f (0.5, -0.5);
glVertex2f (0.5, 0.5);
glEnd();
glFlush();

// A FAIRE : Ici Je souhaite afficher mon carré pour le mettre dans le pbuffer

// A FAIRE : Pour finir, j'associe mon pbuffer avec ma texture
}


Ensuite, je créerai un simple cube dans une autre fonction sur lequel je plaquerai notre texture !

Bref, voilà le point de départ ! ... bien vide !!!

Donc, dès ce soir, je commence à le remplir et te poste ici ce que j'obtiens ... D'accord ?

EDIT:

Par contre, j'ai trouvé çà : http://www.mesa3d.org/brianp/sig97/offscrn.htm il semblerait que GLX Pixmaps (qui utilise glXMakeCurrent, etc...) n'utilise pas l'accélération graphique !? ... mais cela date de 1997 !!!

Guest, Wednesday 28 January 2009 à 13:42

J'ai trouve ca si ca vous interesse...

http://oss.sgi.com/projects/ogl-sample/registry/ARB/wgl_render_texture.txt

Guest, Wednesday 28 January 2009 à 14:38

et aussi ca
http://www.codesampler.com/oglsrc/oglsrc_7.htm

bon courage

Guest, Wednesday 28 January 2009 à 14:50

Un dernier pour la route

http://ati.amd.com/developer/ATIpbuffer.pdf

fabounet, Wednesday 28 January 2009 à 15:10


Subscription date : 30 November 2007
Messages : 17118
GLX pixmap c'est autre chose je pense, un simple pixmap côté serveur avec un contexte opengl, ça ressemble mais c'est GLX qui définit ça, alors que les pbuffers sont partie intégrante d'openGL

d'après ton lien :
# Call XOpenDisplay to open an X display connection.
# Get a GLXFBConfigSGIX handle by calling glXChooseFBConfigSGIX


sont faits dans le dock déjà.

Create a pbuffer by calling glXCreateGLXPbuffer


=> donc on a notre pbuffer non ?

puis glXMakeCurrent avec en argument le pbuffer pour commencer à dessiner dessus

après c'est le TexSubImage2D sur 'texture', et enfin dessiner le GL_QUADS avec ...

complètement au pif

merci pour les liens au fait, "Invité"

nochka85, Wednesday 28 January 2009 à 18:07


Subscription date : 29 November 2007
Messages : 7408
J'aime bien quand tu dis des trucs comme çà Fab -> mais cela ne m'avance pas du tout sur le "comment on fait" !

Merci aussi Invité .... j'avais déjà vu toutes ces pages ... mais j'arrive pas à l'adapter pour linux -> Je retenterai ce soir

D'ailleurs, concernant le truc d'ATI, on voit bien que c'est pour windows .... car si cela marchait sur linux, les possesseurs d'ATI le sauraient !

fabounet, Wednesday 28 January 2009 à 18:13


Subscription date : 30 November 2007
Messages : 17118
pour avoir le prototype des fonctions, regarde dans /usr/include/GL, ça peut servir
j'espère qu'on aura pas besoin d'attendre qu'Augur revienne pour avoir nos pbuffers

Mav, Wednesday 28 January 2009 à 18:54


Subscription date : 29 November 2007
Messages : 3146
Question bête : les sources du dock d'Augur ne sont pas dispos ?

taiebot65, Wednesday 28 January 2009 à 18:55


Subscription date : 26 October 2008
Messages : 1904
de rien .... j'y comprends rien...

nochka85, Thursday 29 January 2009 à 00:21


Subscription date : 29 November 2007
Messages : 7408
J'ai ENFIN réussi à obtenir quelque chose !!!!

En fait, je me suis servi de ce que j'ai trouvé là : http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/ogladv/tut5

... et il n'est nul par fait mention de pbuffer ... mais plus de frame buffer !

En fait, le principe est encore plus simple que ce que tu disais Fab :

1 - On déclare notre texture
2 - Au départ de la boucle ( ou après avoir rafraichit son écran <- Sinon, c'est "rigolo" ... à essayer ), on lance notre fonction qui créé notre texture
3 - On se place dans la matrice de modelisation et la réinitialise
4 - On lance le rendu que l'on souhaite "mapper" en texture (mais on ne l'affichera jamais .... = pas de glFlush !)
5 - On fait un simple test (TRES IMPORTANT ... car sinon la RAM descend à vue d'oeil !!!! <- J'ai mis un temps fou à comprendre pourquoi !!) :
- Si la texture est vide, on créé notre texture, on la "bind", et on y copie le contenu du buffer
- Si elle a déjà été créée, on se contente de la "binder" et on recopie le buffer

-> Voilà, notre texture est prête -> Il n'y a plus qu'à l'utiliser dans notre programme !

Et voici un bout de code en exemple (je mappe un rendu nommé dessineDeskletHal sur 4 faces d'un cube) qui reprend les étapes citées :

GLuint texture;
            

void renderToTexture (int largeurEcran, int hauteurEcran, double valeur1, double valeur2)
{    
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );

    dessineDeskletHal(1, valeur1, valeur2); // Je lance mon rendu ici
        
    
    if (texture == 0) // Si la texture n'existe pas :
    {
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        // Je copie le contenu du frame buffer dans la texture
        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, largeurEcran, hauteurEcran, 0);
    }
    else // Si la texture existe déjà :
    {
        // Je remplace ma texture
        glBindTexture(GL_TEXTURE_2D, texture);
        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, largeurEcran, hauteurEcran);
    }

}

void dessineCube (double zoom)
{    

    double largeur = 1;
    double hauteur = 1;
    double profondeur = 1;
    
    zoom = zoom * 0.5;
    
    glEnable(GL_DEPTH_TEST);
    glEnable (GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        
    glColor4ub(255,255,255,255);
    
glPushMatrix();
    
    glScalef(largeur * zoom , hauteur * zoom, profondeur * zoom);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
        
    
    glBegin (GL_QUADS);

    // Face gauche:
    glTexCoord2i (1, 1); glVertex3f (-largeur, hauteur, profondeur);
    glTexCoord2i (1, 0); glVertex3f (-largeur, -hauteur, profondeur);
    glTexCoord2i (0, 0); glVertex3f (-largeur, -hauteur, -profondeur);
    glTexCoord2i (0, 1); glVertex3f (-largeur, hauteur, -profondeur);

    // Face droite:
    glTexCoord2i (1, 1); glVertex3f (largeur, hauteur, -profondeur);
    glTexCoord2i (1, 0); glVertex3f (largeur, -hauteur, -profondeur);
    glTexCoord2i (0, 0); glVertex3f (largeur, -hauteur, profondeur);
    glTexCoord2i (0, 1); glVertex3f (largeur, hauteur, profondeur);

    // Face arrière
    glTexCoord2i (1, 1); glVertex3f (-largeur, hauteur, -profondeur);
    glTexCoord2i (1, 0); glVertex3f (-largeur, -hauteur, -profondeur);
    glTexCoord2i (0, 0); glVertex3f (largeur, -hauteur, -profondeur);
    glTexCoord2i (0, 1); glVertex3f (largeur, hauteur, -profondeur);

    // Face avant
    glTexCoord2i (1, 1); glVertex3f (largeur, hauteur, profondeur);
    glTexCoord2i (1, 0); glVertex3f (largeur, -hauteur, profondeur);
    glTexCoord2i (0, 0); glVertex3f (-largeur, -hauteur, profondeur);
    glTexCoord2i (0, 1); glVertex3f (-largeur, hauteur, profondeur);

    glEnd ();
            
    glPopMatrix();
    
    glColor4ub(255,255,255,255);
    glDisable (GL_DEPTH_TEST);
    glDisable (GL_BLEND);
    glDisable(GL_TEXTURE_2D);
        
}

fabounet, Thursday 29 January 2009 à 11:35


Subscription date : 30 November 2007
Messages : 17118
oui mais là tu n'as qu'un seul contexte, et la texture est mise à jour pendant le dessin, alors que dans notre cas il faut qu'elle soit mise à jour lors du changement de valeur.
le rendu du dock se fait à n'importe quel moment (déplacement de souris, etc), tandis que l'update se fait à intervalle régulier (par exemple 1s dans le cas d'une horloge).

nochka85, Thursday 29 January 2009 à 12:36


Subscription date : 29 November 2007
Messages : 7408
oui mais là tu n'as qu'un seul contexte, et la texture est mise à jour pendant le dessin, alors que dans notre cas il faut qu'elle soit mise à jour lors du changement de valeur.


Bah vu que j'ai un mouvement fluide sur mes aiguilles, la texture doit être rechargée à chaque boucle (calée sur mon FPS maxi que j'ai réglé à 20 ). Bref, pour garder mon mouvement fluide, il faut que je recharge 20 fois ma texture par secondes ! ... donc, je pense que c'est assez adapté ! ... et puis cela n'a pas l'air de consommer grand chose niveau CPU <- Je regarderais la conso réelle ce soir

EDIT:

D'ailleurs, je viens de penser à un truc -> Tu dis que dans le cas d'une horloge, il faut mettre la texture à jour toutes les secondes ... mais rien n'empèche d'utiliser une simple boucle qui compte le nombre de frames ... et lorsque le nombre de frames est égal au FPS choisit -> On recharge le texture ! <- En fait, pour la boucle, c'est grosso-modo ce que j'avais utilisé pour le "graphe" du CPU : La "jauge" garde un mouvement fluide pendant que le graphe, lui, ne se met à jour que à intervalle donné

En plus, vu qu'on se sert de la taille du contexte que l'on a, la taille texture générée s'adapte à la taille du desklet (et dans le cas de mon programme utilisant la SDL, elle s'adapte à la taille de ma fenêtre SDL) ... Bref, si on a un "petit" desklet de 100x100 , on ne chargera en mémoire qu'une petite texture de 100x100

Bref, je ne comprend vraiment pas ce qui est génant dans cette méthode ... ni pourquoi on ne pourrait pas l'utilisée pour les desklets du dock

... en tout cas, pour mon "programme de démo", c'est parfait !

EDIT 2 : Bon, je viens de voir pas mal de forums où il est expliqué que le render to texture traditionnel est bel est bien ce que je décris plus haut (glCopyTexImage2D et glCopyTexSubImage2D <- j'ai un peu de mal à comprendre la différence entre les 2 ... je crois que le SubImage sert juste à généré une portion de la texture) ... La seul soucis de cette technique est qu'on est limité à la taille de la fenêtre (ou du contexte) ... et pour palier à ce "soucis", il faut passer au FBO <- Mais sincèrement, je crois que cela n'est pas nécessaire pour nous

fabounet, Thursday 29 January 2009 à 16:43


Subscription date : 30 November 2007
Messages : 17118
si je bouge très vite ma souris dans le dock, je peux très bien le redessiner 100 fois dans la seconde.
si tu as 2 horloges et 3 jauges dedans, il est vraiment dommage de redessiner tout ça pour rien.

si en plus j'ai une animation en cours, ça rajoute encore une trentaine de fps.
ça passe peut-être, mais on sent qu'il y'a un problème de conception.

de plus, tu dessines dans le color buffer, puis tu copies ça dans ta texture ... et si quelqu'un avait déjà dessiné quelque chose dans le color buffer ? ... et si l'icône d'à côté est aussi une jauge qui va se redessiner juste après ?

ton modèle tient car il est très simple, dans le cas du dock ça ne passe pas.
d'où la séparation des contextes

nochka85, Thursday 29 January 2009 à 18:14


Subscription date : 29 November 2007
Messages : 7408
si je bouge très vite ma souris dans le dock, je peux très bien le redessiner 100 fois dans la seconde.
si tu as 2 horloges et 3 jauges dedans, il est vraiment dommage de redessiner tout ça pour rien.


Si le dock se refresh 100x par seconde, c'est que tu n'as pas fixé de FPS maxi !! <- Attention au petite config qui risque d'être "saturée"

... Pour les horloges et les jauges, je crois que tu m'a mal compris -> En fait, le renderToTexture doit être lancé lorsque l'on en a besoin seulement ! Bref, pour une horloge, il suffit de le lancer toutes les secondes ... et idem pour les jauges "saccadés" ! ... Quant aux jauges "fluides", on les lances à chaque frame (ou à l'intervalle que l'on aura défini) ... d'où encore une fois l'importance de limiter (et de connaître) le nombre de FPS

si en plus j'ai une animation en cours, ça rajoute encore une trentaine de fps.
ça passe peut-être, mais on sent qu'il y'a un problème de conception.


... là je ne comprends pas trop non plus -> Normallement tu dois "limiter" ton nombre de FPS et raffraîchir l'ensemble de ta scene d'un coup -> Et tu garde un FPS constant ... non ?

de plus, tu dessines dans le color buffer, puis tu copies ça dans ta texture ... et si quelqu'un avait déjà dessiné quelque chose dans le color buffer ? ... et si l'icône d'à côté est aussi une jauge qui va se redessiner juste après ?


Je ne vois pas trop le problème (encore une fois ) -> Tu affecte une texture par rendu (et donc par applet) + Tu fais une render to texture sur chaque (pas forcément en même temps si certaines n'ont pas besoin d'être rafraichies) PUIS tu calcule ta scene et tu la rafraichie ! ... Bref, pas de soucis ... ou alors je n'ai pas compris

et si l'icône d'à côté est aussi une jauge qui va se redessiner juste après ?


Là, ok !! ... et encore je ne suis pas sûr -> En effet, lorsque tu fais ton render to texture, tu dois "effacer" ta scene avant (et dans le cas du dock, redimensionner l'affichage en carré !!) PUIS tu lances le glCopyTexImage ! ... donc, il n'y a rien à coté (car plus de dock) ... non ?

.... A moins que je ne fasse fausse route ....

Mais c'est sûr que pour que cela marche, il faut (j'insiste encore une fois) absolument limiter le nombre de FPS (mais çà c'est dans tous les cas !!) ... car sinon, çà risque de chauffer un peu

EDIT:

Tiens Fabounet -> Trouvé ici : http://www.developpez.net/forums/d112091/technologies-divers/developpement-2d-3d-jeux/apis-multimedia/opengl/p-buffer-rendu-offscreen/ et écrit par bafman (rédacteur/modérateur <- Il doit s'y connaitre un minimum ) :

houla... les P-Buffer c'est vraiment caca
si tu a moyen, regarde plutot du coté des FBO, les P-Buffer presentant une utilisation inutilement complexe et surtout pas multi plateforme du tout...


Cela fait déjà plusieurs fois que je lis çà (préférer les FBO aux pbuffers !!)... et sur les FBO, j'ai un peu plus de doc ; donc, je crois que je vais investiguer de ce coté là

fabounet, Friday 30 January 2009 à 11:17


Subscription date : 30 November 2007
Messages : 17118
oui le nombre de FPS est limité, mais il peut atteindre son max, qui n'est pas loin de 100. de plus il n'est pas du tout constant, et dépend des actions de l'utilisateur.
mais ce que je voulais dire, c'est que tu peux pas générer la texture comme tu l'as fait pendant la phase d'affichage, les différentes applets vont de marcher dessus.
après est-il possible de dessiner dans le color buffer sans rien flusher, et que ça n'altère pas l'image actuellement à l'écran ?
les pbuffers sont vieux, mais ont tout de même été créés pour ça, donc y'a bien une raison.
les FBO sont peut-être mieux, mais jeunes et donc pas encore bien supportés, on a déjà assez de problème côté driver
si on a moyen de détecter leur présence, je suis ok de les utiliser et de faire un code alternatif si on les a pas.

bref, essaye de dessiner ta texture non pas dans ta boucle de rendu, mais à part (avec un timer différent donc), si ça marche alors tant mieux.
il faudra voir niveau consommation CPU aussi.

Edit : cool je viens de regarder ton lien et y'a du code clair, je le poste là pour pas avoir à le chercher.

    XVisualInfo*            visInfo;
    GLXFBConfig*            fbConf;

    int                    tmpDW;

    int    visAttribs [] = {GLX_RENDER_TYPE, GLX_RGBA_BIT,
                 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
                    GLX_DEPTH_SIZE,     16,
                    0
     };

    int                        pbufAttribs [] = {
         GLX_PBUFFER_WIDTH,     width,
                                GLX_PBUFFER_HEIGHT, height,
                                GLX_LARGEST_PBUFFER, true,
                                0
};

    if (!(m_display = XOpenDisplay (NULL)))
    {
        g_log->write ("[Error] XOpenDisplay", MW_ERROR);
        return;
    }

    if (!glXQueryExtension (m_display, &tmpDW, &tmpDW))
    {
        g_log->write ("[Error] glXQueryExtension", MW_ERROR);
        return;
    }

    if (!(fbConf = glXChooseFBConfig (m_display, DefaultScreen(m_display), visAttribs, &tmpDW)))
    {
        g_log->write ("[Error] glXChooseFBConfig", MW_ERROR);
        return;
    }

    if (!(m_pbuffer = glXCreatePbuffer (m_display, fbConf[0], pbufAttribs)))
    {
        g_log->write ("[Error] glXCreatePbuffer", MW_ERROR);
        return;
    }

    if (!(visInfo = glXGetVisualFromFBConfig (m_display, fbConf[0])))
    {
        g_log->write ("[Error] glXGetVisualFromFBConfig", MW_ERROR);
        return;
    }

    if (!(m_context = glXCreateContext (m_display, visInfo, winContext, true)))
    {
        g_log->write ("[Error] glXCreateContext", MW_ERROR);
        return;
    }

XFree (visInfo);
XFree (fbConf);

    m_width = width;
    m_height = height;



c'est ce que je pensais, donc c'est assez simple au final, les 3/4 sont déjà dans le dock

fabounet, Wednesday 25 February 2009 à 12:03


Subscription date : 30 November 2007
Messages : 17118
ce sujet est donc clos mais je rajoute ici 2 liens qui devraient aider à corriger le problème de la mauvaise transparence.
http://bugzilla.openedhand.com/show_bug.cgi?id=1406
http://stackoverflow.com/questions/146140/opengl-how-to-do-rgba-rgba-blitting-without-changing-destination-alpha

Technical discussions | Discussions techniques

Subjects Author Language Messages Last message
[Locked] les pBuffers
fabounet Français 19 fabounet [Read]
25 February 2009 à 12:03


Glx-Dock / Cairo-Dock List of forums Technical discussions | Discussions techniques les pBuffers Top

Online users :

Powered by ElementSpeak © 2007 Adrien Pilleboue, 2009-2013 Matthieu Baerts.
Dock based on CSS Dock Menu (Ndesign) with jQuery. Icons by zgegball
Cairo-Dock is a free software under GNU-GPL3 licence. First stable version created by Fabounet.
Many thanks to TuxFamily for the web Hosting and Mav for the domain name.