Technical discussions | Discussions techniques
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 ? |
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
|
|
Technical discussions | Discussions techniques
|