Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1685 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [OpenGL] récupérer les pixels (glReadPixels trop lent)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[OpenGL] récupérer les pixels (glReadPixels trop lent)

n°1403822
PacoDL
Posté le 10-07-2006 à 14:04:50  profilanswer
 

Bonjour,
 
Ayant de besoin de récupérer l'image générée par OpenGL dans un programme 2D devant tourner à 45 FPS, j'utilise glReadPixels qui me donne le bon résultat mais qui s'avère beaucoup trop lent (je tombe à 17 FPS). En effet, ma technique est de:
 
1 - récupérer les pixels dans un tableau avec glReadPixels
2 - lire le tableau pour le transformer en surface 2D
3 - afficher ma surface 2D
 
Ce qu'il faudrait c'est arriver à pouvoir lire directement le tableau de pixels d'OpenGL sans avoir à le recopier avec glReadPixels(). Quelqu'un sait comment faire ?
 
Je précise que le tout tourne sur PDA (d'ou le framerate bas) avec OpenGL ES (comporte moins de fonctions redondantes qu'OpenGL desktop), mais ne vous focaliser pas du tout dessus, le principe est absolument le même...

mood
Publicité
Posté le 10-07-2006 à 14:04:50  profilanswer
 

n°1404323
el muchach​o
Comfortably Numb
Posté le 11-07-2006 à 07:44:45  profilanswer
 

Je ne suis pas sûr qu'il y ait mieux à faire. OpenGL, et surtout les puces graphiques, ne sont pas faits pour relire des données pixel rapidement. Le bus a une très grande bande passante en écriture de données (vers la CG), mais pas dans l'autre sens.
Quoi que tu fasses, tu ne pourras pas récupérer la vidéo avec le framerate optimal.


Message édité par el muchacho le 11-07-2006 à 07:48:13

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
n°1404351
tropicano
Posté le 11-07-2006 à 09:09:02  profilanswer
 

Est ce que tu as regardé du côté de: glCopyTexImage2D ?.
Il y a des exemples de son utilisation sur sulaco:
Render Faces et Render to Texture

n°1404517
PacoDL
Posté le 11-07-2006 à 12:32:53  profilanswer
 

J'ai regardé tes exemples, il me semble que le résultat doit malheureusement être le même que le coûteux glReadPixel.
 
Sinon, j'ai trouvé la fonction glGetPointerv qui normalement me renvoie pointeur du tableau désiré, en l'occurence GL_COLOR_ARRAY_POINTER. Mais sur internet, impossible de trouver un exemple concret et le manuel n'est pas vraiment explicit d'autant plus que j'ai vérifié la valeur du pointeur qui s'avère être 0 (idem pour les pointeurs des vertex et normal array)... Quelqu'un sait s'en servir...
 
>Réponse à El muchacho
Dans le pire des cas (ultime), j'ai les sources de l'implémentation donc il me semble qu'il me sera possible de modifier le comportement de l'API a ma sauce...


Message édité par PacoDL le 11-07-2006 à 12:38:53
n°1404582
IrmatDen
Posté le 11-07-2006 à 13:50:01  profilanswer
 

L'idée du Render to texture, est que tu rends toute ta scène dans une texture, que tu affiches à l'écran en texturant une primitive qui couvre tout l'écran.
Ce devrait être plus rapide que le glReadPixels, puisque tu peux bosser sur ta texture avant l'affichage, enfin... normalement.

n°1404723
PacoDL
Posté le 11-07-2006 à 15:50:52  profilanswer
 

D'accord j'ai remplacé mon
 
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
 
par:
 
GLuint RenderedTex;
glBindTexture(GL_TEXTURE_2D, RenderedTex);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, height, 0);
 
Comment accéder au contenu d'une texture?

n°1405055
IrmatDen
Posté le 11-07-2006 à 23:25:37  profilanswer
 

Il me semble que tu n'as plus qu'à toucher au buffer que tu as fourni à la création de la texture. Une fois modifié comme tu le sens, tu appelles glTexSubImage2D pour mettre à jour ta texture.
 
Mais bon, il vaut mieux avoir une doc plus détaillée, ça repose sur des extensions que j'espère que ton matos supporte, je suis loin d'être bon là-dedans :/
Sinon, c'est comme el muchacho a dit; j'ai lu à plusieurs endroits que le format de texture pouvait te faire gagner un peu de perf. A voir aussi donc.

n°1406691
PacoDL
Posté le 13-07-2006 à 21:27:32  profilanswer
 

Marche po


Message édité par PacoDL le 13-07-2006 à 23:43:10
n°1406748
PacoDL
Posté le 13-07-2006 à 23:40:12  profilanswer
 

Désolé, j'ai du mal avec le post de messages...


Message édité par PacoDL le 13-07-2006 à 23:43:46
n°1406749
PacoDL
Posté le 13-07-2006 à 23:42:31  profilanswer
 

Nop, je peus rien faire avec ses extensions, elles ne sont pas supportés par mon implémentation.
 
Voilà ce que j'ai fais:
 
unsigned char pixels = new unsigned char [glWindowWidth*glWindowHeight*4];
GLuint RenderedTex;
glGenTextures(1, &RenderedTex);
glBindTexture(GL_TEXTURE_2D, RenderedTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glWindowWidth, glWindowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 
void drawScene(int width, int height)
{
// Scene ...
 
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, RenderedTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
}
 
le render to texture marche (je l'applique à un cube à la fin)
 
Question
le pBuffer passé en paramètre à la création de la texture est-il recopié ou sert-il de référence?
Parce que lorsque je le consulte, pas de trace des pixels de rendu...


Message édité par PacoDL le 14-07-2006 à 00:02:52
mood
Publicité
Posté le 13-07-2006 à 23:42:31  profilanswer
 

n°1406774
IrmatDen
Posté le 14-07-2006 à 01:06:22  profilanswer
 

le buffer est recopié, tu peux même le supprimer après avoir initialisé la texture. Par contre, est-ce que tes hauteurs et largeur sont une puissance de 2?
 
Tiens, je viens de chopper un exemple, ça a l'air simple comme ça :D

n°1406784
PacoDL
Posté le 14-07-2006 à 02:59:44  profilanswer
 

Oui, c'est 128*128, j'arrive à rendre sur la texture donc à ce niveau plus de problème...
 
En revanche, ce que je ne comprend pas c'est que si je met NULL en dernier paramètre de glTexImage2D à la place de pixels, ma texture sera remplie de noir. Comme si pixels était nécessaire pour recevoir le rendu, par contre, il n'est en rien modifié, c'est ce qui m'embête...
 
Sinon, comment puis-je :
>"...toucher au buffer que tu as fourni à la création de la texture..."
???
 
Je précise aussi que je n'utilise pas glCopyTexImage2D (ne fonctionnne pas pour moi) mais glTexImage2D...


Message édité par PacoDL le 14-07-2006 à 03:08:39
n°1406786
nraynaud
lol
Posté le 14-07-2006 à 03:25:42  profilanswer
 

on peut savoir ce que tu fais sur ton image entre le moment où tu la lis et celui où tu la réécris ?

n°1406860
PacoDL
Posté le 14-07-2006 à 12:16:11  profilanswer
 

je suppose que tu parles de mon tableau de pixels, je ne le réécris pas puisque je souhaite y recevoir le rendu d'opengl pour le lire ensuite et le recopier dans une surface de mon choix...

n°1406863
nraynaud
lol
Posté le 14-07-2006 à 12:21:33  profilanswer
 

quel est l'intérêt ? fonctionnellement tu fais quoi ? quel est le but de ton application ?  
 
autant te le dire tout de suite : ta question sent la mauvaise idée, comme disent les consultants étasuniens y'a un "smell"

n°1407029
PacoDL
Posté le 14-07-2006 à 18:44:59  profilanswer
 

Je l'ai pourtant expliqué dans le 1er post, mais je vais la refaire...
 
L'intérêt est de faire ce qu'on appelle du offscreen rendering, c'est à dire faire fonctionner une appli opengl sans pour autant la relier à une fenêtre et tout son tintouin...
 
L'idée est de récupérer le résultat une image (celle qui normalement aurait dû être affichée à l'écran) afin de l'exploiter à sa convenance, dans mon cas la réafficher dans une appli gérée par une librairie 2D, ce qui donne une application géré par une librairie hybride 2D + 3D. Ca marche impeccable avec glReadPixels excepté au niveau des performances sur le PDA (sur le PC, c impec), je souhaitais savoir comment trouver un moyen de contourner ce problème...
 
Pour terminer, je n'ai pas inventé la technique, elle existe belle et bien, je me demande même si ce n'est pas comme ça que fonctionne SDL et OpenGL, enfin bon...
 
Sinon, je suis en train de regarder si il ne vaut pas mieux effectuer un rendu dans un pixmap, chose qui semble finalement plus aisée, à moins que quelqu'un n'ait trouvé la solution?

n°1407143
PacoDL
Posté le 15-07-2006 à 05:17:19  profilanswer
 

Bon ben, ce n'était pas de tout repos mais la solution à mon problème est bien le pixmap rendering. En gros:
1 - On crée une pixmap qui servira à recevoir le rendu
2 - On l'associe au rendu
3 - Lors de la création de la Pixmap, on lui a associé un pointeur vers son Image buffer, facilement lisible par la suite...
 
Résultat: je retrouve mes 45FPS à comparer aux 17FPS via la méthode glReadPixels qui finalement, ne sert à rien qu'à dégradé les performances sans apporter du mieux par rapport à du PixMap rendering.
 
Bien sûr tout ça dépend de votre implémentation... je n'aurais surement pas eu à faire tant de pied et de main sur une implémentation PC (moi c OpenGL ES).
 
Merci encore à tous.

n°1407173
el muchach​o
Comfortably Numb
Posté le 15-07-2006 à 11:29:33  profilanswer
 

De rien. Tu apportes là une info intéressante.


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [OpenGL] récupérer les pixels (glReadPixels trop lent)

 

Sujets relatifs
Recupérer une URL a partir d'une autre qui y pointe par redirection?Récupérer valeur de la variable qui incremente
[Javascript/PHP] Récuperer le contenu d'un array et le passer par GETScript trop lent
[Select + onchange] Recupérer la valeur de l'index précédentrecuperer l'id de la page en JS
récuperer le nom d une page[Opengl] Les normals : un seul point !
recuperer un xml dans un blobRécupérer les valeurs d'un champ au nom variable
Plus de sujets relatifs à : [OpenGL] récupérer les pixels (glReadPixels trop lent)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR