[affichage 2D] recherche solution... pb de couleurs.... (ça marche !)

recherche solution... pb de couleurs.... (ça marche !) [affichage 2D] - C++ - Programmation

Marsh Posté le 22-05-2002 à 16:27:40    

après maintes bouletitudes et énormément d'aide de votre part (merci notament à hello world qui m'a énormément aidé et qui a été extrémement patient), le pb est enfin résoulu !
je vous mettrais le code du composant en entier lorsqu'il sera totalement opérationnel ! (il sera plus ou moins sous la forme d'un composant VCL)
ou si vous voulez juste que je le mette en version beta test, ya pas de pb, je peux le mettre tout de suite :), à vous de voir !
 
à bientôt, et encore merci ! :jap:
 
 

Citation :


bin maintenant le sujet, c'est un pb de couleurs...
 
 
voilà mon code :

Code :
  1. if (GetDeviceCaps(hBitmapDC, BITSPIXEL)<16) then begin
  2.       MessageBox(Handle, 'Le nombre de couleur est insuffisant', 'erreur', MB_OK);
  3.    end;
  4.    for i := 0 to Height - 1 do begin
  5.       if (setPixelV(hBitmapDC, Col, i, ColorToRGB(cl3DLight)) = false) then begin
  6.          FormatMessage(
  7.                FORMAT_MESSAGE_ALLOCATE_BUFFER or
  8.                FORMAT_MESSAGE_FROM_SYSTEM or
  9.                FORMAT_MESSAGE_IGNORE_INSERTS,
  10.                Nil,
  11.                GetLastError(),
  12.                0,
  13.                @lpMsgBuf,
  14.                0,
  15.                Nil
  16.          );
  17.          MessageBox( Handle, lpMsgBuf, 'Error', MB_OK or MB_ICONINFORMATION );
  18.          Exit;
  19.       end;
  20.    end;
  21.    BitBlt(Canvas.Handle, Col, 0, 1, Height, hBitmapDC, Col, 0, SRCCOPY);


 
...
ça m'affiche du blanc... si j'utilise setPixel qui renvoie la couleur réellement affichée : cela renvoie une valeur égale à  
ColorToRGB(clWhite)
...
de plus, le nombre de Bpp du HDC est bien supérieur 16 puisque le message n'est jamais affiché !
...
enfin,  
si je fais ça :

Code :
  1. FillRect(hBitmapDC, canvas.ClipRect, GetStockObject(LTGRAY_BRUSH));
  2.    Repaint;


 
c'est bien le light gray qui est affiché....
 
 
 
kel est le problème ??? [:tomawack]  
 
 
 
 
 
 

Citation :


sujet actuel :
 
mon prog fait nimp' :D (code en 2ème page) : tentative de traduction C -> Pascal du programme d'HelloWorld :D
2ème sujet en cours : je suis définitivement un gros boulet... pourriez vous m'aider ?
 
 
 
 
2ème sujet :
 
[quote]est ce ke vous pourriez me donner kelkes explications sur les points suivants :
k'est ce k'un device context ? un hDC ?
kan une fonction win32 me demande un hDC, est-ce que je peux utiliser le handle renvoyé par la méthode Handle d'un objet TPaintBox (par exple) de delphi ?


 
 
 
 
 
 
sujet de départ :
 

Citation :


bon, ça fait plusieurs fois que je poste pour avoir de l'aide la-dessus et je v m'y prendre autrement :
 
j'ai besoin d'une solution simple efficace et PERFORMANTE pour afficher un tableau de pixel (un buffer de couleur en kelkesorte)
 
kelle est selon vous la meilleure solution en terme de :
1. performance;
2. rapidité de dev;
3. "facilité" de dev;
 
performance parceque j'ai besoin de kelke chose de rapide (il me semble que l'acceleration matérielle 2D s'impose... mais là, si vous connaissez des moyens très optimisé d'afficher des trucs, je suis assez ouvert)  
 
voilà, je vous demanderais certainement des détails par la suite parceke Win32, openGL et tout ça, je rame un peu (énormement, en fait... aaa, c bô les langages de haut niveau ;) ) puiske j'ai été plutôt formé au génie logiciel ki est tout sauf du dev...  
 
si vous avez besoin de plus de précision, n'hésitez pas à me les demander... là, je ne sais pas trop koi vous filer comme info...
 
 
 
voilà, en vous remerciant d'avance de l'aide éventuelle que vous pourriez m'apporter... et oui, je suis totalement incompétent :jap: (comme koi les diplômes ne veulent rien dire).


 


 
(j'ai mis à jour le nom du topic pour refléter ce kil contient ;) : à savoir : apprendre la langue microsoft (vous savez, ce pays supra-impérialiste, là, ki est super riche et ecrase tout le monde...))
[/quote]

 

[jfdsdjhfuetppo]--Message édité par Moustaaki le 28-05-2002 à 10:53:17--[/jfdsdjhfuetppo]


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 16:27:40   

Reply

Marsh Posté le 22-05-2002 à 16:35:01    

Hum je sais pas si ça valait vraiment le coup de refaire un topic...
http://forum.hardware.fr/forum2.php3?post=19811&cat=10
Je mets le lien pour éviter les propositions qui ont déjà été faite dans le premier topic.
Ce qu'il faut donc c'est pas juste afficher vite une image de 500x200, mais afficher de manière quasi animée des bandes de 1x200 les unes à côté des autres, pour avoir un graphique qui se construit en temps réel, si j'ai bien compris...


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 22-05-2002 à 16:45:29    

antp a écrit a écrit :

Hum je sais pas si ça valait vraiment le coup de refaire un topic...
http://forum.hardware.fr/forum2.php3?post=19811&cat=10
Je mets le lien pour éviter les propositions qui ont déjà été faite dans le premier topic.
Ce qu'il faut donc c'est pas juste afficher vite une image de 500x200, mais afficher de manière quasi animée des bandes de 1x200 les unes à côté des autres, pour avoir un graphique qui se construit en temps réel, si j'ai bien compris...  




 
 
oui, merci bp antp :) t'as bien compris la chose :) ... et t'as bien fait de mettre le lien vers l'ancien topic...


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 16:52:13    

si tu veux quelque chose de "rapide", moi je ferais le traçage en asm dans un buffer, puis recopie rapide.
surtout pas de traçage au niveau pixel par une primitive quelquonque d'une bibliothèque.
tu peux regarder du coté du directdraw pour faire la recopie rapide...
si accélération matérielle il doit y avoir, ce sera pour la recopie du buffer offscreen vers la fenêtre.
 
vu ton truc, tu peux parfaitement gérér ton buffer en 8bpp avec une palette 256 couleurs, et blitter dans la fenêtre (la fonction cablée du blitter doit en même temps que faire la recopie la reconversion du 256 couleurs vers le format high/true color du framebuffer).
 
enfin de toutes manière gérer le buffer en 256/16bpp/32bpp par toi-même n'est pas un problème.
 
généralement la performance est à l'opposé de la facilité au premier abord, car il faut comprendre exactement ce que les fonctions que tu utilies impliquent au niveau os/hardware.
 
pour moi, le mieux c'est routine de traçage dans en buffer en asm (ou en C bien écrit pour poser l'algo), et puis blittage...
(comme il a été dit).
 
après c soit les fonctions Win32, soit le directdraw (opengl pas rentable).
 
pour ton problème de saccade, c'est surtout passke tu ne régules pas le rafraichissement, fout un timer, ne rafraichit pas en boucle comme un bourrin, peut-être une approche threadé entre le gui avec le traçage de la fenêtre, et les autres routines de ton appli. (si le traçage est trop couteux en temps car cpu trop leg, les autres étapes de ton traitement seront pénalisés et perdront des "infos critiques" ).
si tu passes trop de temps dans certaines étapes, la queue de message ne sera pas "rafraichie" suffisamment correctement (tu cliques sur un bouton ça réagit 3 secs après).

 

[jfdsdjhfuetppo]--Message édité par bjone le 22-05-2002 à 16:54:27--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 22-05-2002 à 17:04:17    

bjone a écrit a écrit :

 
pour moi, le mieux c'est routine de traçage dans en buffer en asm (ou en C bien écrit pour poser l'algo)
 




 
Ouais enfin ici ça sera asm/pascal plutôt que asm/c j'imagine, enfin normalement au niveau vitesse c'est pareil.


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 22-05-2002 à 17:06:53    

antp a écrit a écrit :

 
 
Ouais enfin ici ça sera asm/pascal plutôt que asm/c j'imagine, enfin normalement au niveau vitesse c'est pareil.  




 
on se comprends c le principal ;) :D

Reply

Marsh Posté le 22-05-2002 à 17:10:33    

c'est clair qu'il ne faut surtout pas dessiner les pixels directement sur la surface affichée ! Il est beaucoup plus rapide de déplacer de gros blocs de la mémoire centrale vers la mémoire vidéo que de procéder à de petites écritures directement dans la mémoire vidéo.
 
tu alloues un buffer de 500*200 octets/int/long selon que tu travailles en 8, 16 ou 32 bits, puis tu fais tes opérations de tracé dans ce buffer. une fois que tu as tracé tes 500 colonnes, tu passes par directdraw pour blitter dans la surface visible, tu effaces ton buffer off-screen et tu recommences à tracer.
 
ceci possède 2 avantages : une rapidité accrue, et l'absence de clignotements due au double buffer
 
quant à la saccade, bjone a raison : le rafraichissement n'est pas régulé. le mieux serait de le faire au début de chaque VBL, mais tu devras écrire une routine asm pour déterminer le début d'une nouvelle frame. une fois cet instant trouvé, tu appelles ta fonction qui blittera le buffer off-screen vers la mémoire vidéo
 
je t'accorde que tout ceci n'est pas évident, mais c'est à mon avis le seul moyen d'obtenir qqchose de rapide, fluide et sans clignotements.
 
A+


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 22-05-2002 à 17:16:38    

bjone a écrit a écrit :

 
pour ton problème de saccade, c'est surtout passke tu ne régules pas le rafraichissement, fout un timer, ne rafraichit pas en boucle comme un bourrin, peut-être une approche threadé entre le gui avec le traçage de la fenêtre, et les autres routines de ton appli. (si le traçage est trop couteux en temps car cpu trop leg, les autres étapes de ton traitement seront pénalisés et perdront des "infos critiques" ).
si tu passes trop de temps dans certaines étapes, la queue de message ne sera pas "rafraichie" suffisamment correctement (tu cliques sur un bouton ça réagit 3 secs après).  




 
et bien en fait, le raffraichissement est régulé par la vitesse de récupération des données par le port usb...
 
je peux te faire un shéma si tu veux ;)


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 17:19:35    

eu, autant vous dire tout de suite que ve ke vous dites et pour moi du chinois... mon pb, c'est ke je n'ai absolument aucune formation graphique... pour ce ki est de la prog bas niveau, je suis pas fortiche non plus.. en fait, c'est carrément pas ds mes compétences...  
donc, je relis ce ke vous m'avez dit et je v vous posez des kestions dessus... bougez po ;) :jap:


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 17:25:47    

Harkonnen a écrit a écrit :

c'est clair qu'il ne faut surtout pas dessiner les pixels directement sur la surface affichée ! Il est beaucoup plus rapide de déplacer de gros blocs de la mémoire centrale vers la mémoire vidéo que de procéder à de petites écritures directement dans la mémoire vidéo.




 
 
est-ce que tu veux dire par là kil vaut mieux ke je "précalcul" tout ce ke je dois afficher (soit le spectre en entier) et que j'affiche ensuite ? parceque, c klerr que afficher une fois un bloc de 500*200 est plus rapide que d'afficher 500 fois 1 bloc de 1*200 mais l'utilisateur doit pouvoir voir le spectre s'afficher au fur et à mesure... bon, j'ai certainement mal compris ce ke tu voulais me dire...


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 17:25:47   

Reply

Marsh Posté le 22-05-2002 à 17:28:02    

Je sais pas qui a mal compris qui mais j'ai l'impression que vous parlez pas de la même chose tous les deux :crazy:


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 22-05-2002 à 17:31:06    

Moustaaki a écrit a écrit :

 
 
 
est-ce que tu veux dire par là kil vaut mieux ke je "précalcul" tout ce ke je dois afficher (soit le spectre en entier) et que j'affiche ensuite ? parceque, c klerr que afficher une fois un bloc de 500*200 est plus rapide que d'afficher 500 fois 1 bloc de 1*200 mais l'utilisateur doit pouvoir voir le spectre s'afficher au fur et à mesure... bon, j'ai certainement mal compris ce ke tu voulais me dire...  




il ne s'agit pas d'un précalcul, mais d'un calcul en temps réél. la seule différence, c'est qu'au lieu de dessiner directement sur l'écran, tu dessines sur une zone de la mémoire qui n'est pas visible (buffer off-screen)
l'utilisateur ne s'apercevra de rien, car à chaque VBL le buffer off-screen est affiché à l'écran et effacé ensuite.
c'est le principe du dessin animé : il s'agit d'une suite d'images que tu fais défiler à intervalles réguliers. tu crois que les personnages bougent, mais en fait les images sont réactualisées 24 fois par secondes, donnant l'impression de mouvement. c'est la même chose ici, sauf que tu actualises en fonction du taux de rafraichissement de ton moniteur (VBL ou Vertical Blank)


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 22-05-2002 à 17:35:13    

Harkonnen a écrit a écrit :

 
 
quant à la saccade, bjone a raison : le rafraichissement n'est pas régulé. le mieux serait de le faire au début de chaque VBL, mais tu devras écrire une routine asm pour déterminer le début d'une nouvelle frame. une fois cet instant trouvé, tu appelles ta fonction qui blittera le buffer off-screen vers la mémoire vidéo
 




 
 
heu.. kesk'un VBL ?
 
 

bjone a écrit a écrit :

 
si tu veux quelque chose de "rapide", moi je ferais le traçage en asm dans un buffer, puis recopie rapide.  
surtout pas de traçage au niveau pixel par une primitive quelquonque d'une bibliothèque.  
tu peux regarder du coté du directdraw pour faire la recopie rapide...  
si accélération matérielle il doit y avoir, ce sera pour la recopie du buffer offscreen vers la fenêtre.  




 
est-ce ke j'ai bien compris ?
il faudrait ke je fasse une routine en asm ki me remplit un buffer et ensuite afficher ce buffer à l'écran en utilisant directX...  
eu, l'asm... :( j'avoue que j'ai un peu de mal... j'en ai bien à l'iut ya quelques temps mais à l'époque, j'étais pas très assidu et j'avoue ke j'ai pas trop tout suivi :( ...
directX, c'est pareil, j'ai du mal... notament, j'aimerais bien savoir comment on indique au 'moteur' directX de travailler uniquement sur une zone d'une fenêtre au lieu de travailler en plein écran (la totalité des tutoriels que l'on trouve sur le net sont pour faire des jeux et ils travaillent toujours en plein écran...)...


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 17:36:56    

antp a écrit a écrit :

Je sais pas qui a mal compris qui mais j'ai l'impression que vous parlez pas de la même chose tous les deux :crazy:  




 
 
oui, j'avoue ke je ne comprend pas gd chose à tout ça..


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 17:40:19    

Moustaaki a écrit a écrit :

 
heu.. kesk'un VBL ?  




 
un VBL (Vertical Blank) correspond au moment ou le faisceau d'électrons de ton moniteur est arrivé en bas à droite de l'écran, une image complète est donc affichée. pendant cet instant, le faisceau repart en haut à gauche pour dessiner une nouvelle image
 
pendant le moment ou il "remonte", on a le temps de faire quantité de choses, comme blitter un buffer dans la mémoire vidéo par exemple. de ce fait, l'image sera toujours synchronisée avec le rafraichissement de l'écran et ton animation sera fluide au maximum


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 22-05-2002 à 17:47:06    

Harkonnen a écrit a écrit :

 
il ne s'agit pas d'un précalcul, mais d'un calcul en temps réél. la seule différence, c'est qu'au lieu de dessiner directement sur l'écran, tu dessines sur une zone de la mémoire qui n'est pas visible (buffer off-screen)
l'utilisateur ne s'apercevra de rien, car à chaque VBL le buffer off-screen est affiché à l'écran et effacé ensuite.
c'est le principe du dessin animé : il s'agit d'une suite d'images que tu fais défiler à intervalles réguliers. tu crois que les personnages bougent, mais en fait les images sont réactualisées 24 fois par secondes, donnant l'impression de mouvement. c'est la même chose ici, sauf que tu actualises en fonction du taux de rafraichissement de ton moniteur (VBL ou Vertical Blank)  




 
ok, je crois comprendre ce ke tu veux dire ...
oula, je vois pas du tout comment le programmer par contre.
 
alors, si je comprend bien :
1. il me faut un thread de 'calcul' :
il récupére les données ki sont reçue en continu et les mêt dans le buffer (les couleurs seront déjà ajustées, je suppose...)
 
2. un timer réglé sur le taux de raffraichissement ... moins peut-être : disons, 30-40 images par secondes pourrraient suffire si on considère la persitence rétinienne ?
 
3. un module affichant les données contenues dans le buffer remplit par 1) à chaque fois que le timer 2) le 'stipule'... si c'est 30-40 images par seconde, c'est p'têtre même pas la peine d'utiliser l'accélération matérielle, non ?


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 17:52:01    

Harkonnen a écrit a écrit :

 
 
un VBL (Vertical Blank) correspond au moment ou le faisceau d'électrons de ton moniteur est arrivé en bas à droite de l'écran, une image complète est donc affichée. pendant cet instant, le faisceau repart en haut à gauche pour dessiner une nouvelle image
 
pendant le moment ou il "remonte", on a le temps de faire quantité de choses, comme blitter un buffer dans la mémoire vidéo par exemple. de ce fait, l'image sera toujours synchronisée avec le rafraichissement de l'écran et ton animation sera fluide au maximum  




 
Ok ;) maintenant, ça je l'ai bien compris ;) ...  
existe-t-il des bibliothèques te permettant cette synchro ?
 
et est-ce que afficher 30-40 images par secondes (et donc, non synchro avec le VBL) suffiraient à simuler la fluidité... l'oeil humain ne 'voit' pas plus de 30 img/sec... non ?


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 17:54:11    

Citation :


1. il me faut un thread de 'calcul' :
il récupére les données ki sont reçue en continu et les mêt dans le buffer (les couleurs seront déjà ajustées, je suppose...)


oui, ce thread se chargera de convertir les données reçues en pixels qui alimenteront le buffer.

Citation :


2. un timer réglé sur le taux de raffraichissement ... moins peut-être : disons, 30-40 images par secondes pourrraient suffire si on considère la persitence rétinienne ?


par exemple

Citation :


3. un module affichant les données contenues dans le buffer remplit par 1) à chaque fois que le timer 2) le 'stipule'... si c'est 30-40 images par seconde, c'est p'têtre même pas la peine d'utiliser l'accélération matérielle, non ?  


a priori non, mais si tu peux utiliser DirectDraw, fais le. GDI n'est pas réputé pour sa rapidité. essaie les 2 solutions et compare...


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 22-05-2002 à 18:00:44    

j'avais écrit un roman mais j'ai glissé j'ai tout niqué, je vais donc faire court:
 
vu ton interface sur l'autre topic (0s à gauche, 4s à droite), ton graphe est une FIFO de colonnes.
 
ce qui fait que quand tu "injectes" une nouvelle colonne tu dois retraçer tout la surface.
 
si c'est bien ça, il est rapide de ratraçer la surface en off-screen et blitter tout.
 
tu auras 2 routines:
une pour décaler les anciens traçés de colonnes
une pour traçer la nouvelle colonne.
dans ce cas pas d'affaçement de la surface off-screen....
 
(un peu comme un algo de feu :D)

Reply

Marsh Posté le 22-05-2002 à 18:02:31    

Harkonnen a écrit a écrit :

[quote]
a priori non, mais si tu peux utiliser DirectDraw, fais le. GDI n'est pas réputé pour sa rapidité. essaie les 2 solutions et compare...  




 
ok, donc, là se pose mon pb principal : je ne sais pas utiliser directDraw...
 
l'idéal, ça serait un ens de fonction ki :
1. permettre de désigner une zone de la fenêtre comme "zone de dessin" directDraw (par le biais d'un handle, ça serait le top :) )
2. initialiser directDraw pour cette zone...
3. dessiner sur la surface les pixels contenus dans mon buffer à la bonne place...
 
voilà autant de questions que se pose un gros newbie furieux de parcourir la doc msn depuis 15 jours  :(  . si vous pouviez juste me donner le nom des fonctions à utiliser, ça serait cool... j'pourrais aller voir la doc ensuite et vous posez éventuellement d'autres question ;)


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 18:18:18    

bjone a écrit a écrit :

j'avais écrit un roman mais j'ai glissé j'ai tout niqué, je vais donc faire court:
 
vu ton interface sur l'autre topic (0s à gauche, 4s à droite), ton graphe est une FIFO de colonnes.
 
ce qui fait que quand tu "injectes" une nouvelle colonne tu dois retraçer tout la surface.
 
si c'est bien ça, il est rapide de ratraçer la surface en off-screen et blitter tout.
 
tu auras 2 routines:
une pour décaler les anciens traçés de colonnes
une pour traçer la nouvelle colonne.
dans ce cas pas d'affaçement de la surface off-screen....
 
(un peu comme un algo de feu :D)  




 

Citation :


dans ce cas pas d'affaçement de la surface off-screen....


 
oui, ça m'interesserait bien puisqu'il me faudrait garder tout ce qui a été affiché car  :
 
l'utilisateur peut faire plusieurs passes (à chaque fin de 'passe', la zone est remplie de noire) et s'arreter en milieu de passe -> donc, si je me contente de recopier ce ki est affiché, je me retrouverais avec un spectre incomplet. il me faut donc garder en mémoire ce ki a pu être affiché avant pour pouvoir proposer un sectre complet.  
'fin, tout cela est un autre pb... restons concentrer sur la première chose : afficher tout ça de manière optimisée ;)
 

Citation :


une pour décaler les anciens traçés de colonnes


 
je comprend peut-être mal ce ke tu veux dire par là mais :
il n'ya pas de décalage : on ne fait que rajouter une partie du spectre à droite de ce ki est déjà affiché. kan c'est plein, on vide et on repart au premier pixel. et en fait, c'est pas du FIFO, c'est plutôt du "le premier arrivé reste le plus longtemps" :)  
 
disons ke les chiffres suivants sont les colonnes et le | la fin de la zone d'affichage :
 
1      |           à un temps t
12     |           t+1
123    |           t+2...
1234   |
12345  |
123456 |
1234567|
890... |
 
 
ainsi, ce ki est déjà affiché n'est pas modifié jusqu'à la passe suivante.


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 18:20:44    

bjone a écrit a écrit :

 
tu auras 2 routines:
une pour décaler les anciens traçés de colonnes
une pour traçer la nouvelle colonne.
dans ce cas pas d'affaçement de la surface off-screen....




si, l'effacement sera nécessaire, car si la nouvelle colonne est plus petite que l'ancienne, ce sera l'ancienne qui sera affichée


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 22-05-2002 à 18:41:00    

Harkonnen a écrit a écrit :

 
si, l'effacement sera nécessaire, car si la nouvelle colonne est plus petite que l'ancienne, ce sera l'ancienne qui sera affichée  




 
oui, parceque si je synchronise par rapport à une vitesse d'affichage fixe, ma dernière colonne ne sera quasiment jamais pleine...  
 
petit moment réflexion  :sarcastic: :
 
on considère qu'on doit pouvoir afficher 500 colonnes en 4 sec.
soit 125 colonnes par secondes.
si on prend une fréquence d'affichage de 35 img/sec (discutable... on verra ça plus tard ;) ) :
à chaque image, on doit afficher : 125/35 = 3,57.... colonnes.
 
donc, le nombre de colonne affiché à chaque 'affichage' sera différent... est ce que cela sera visible ?


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 18:48:46    

T'as qu'à choisir une fréquence qui t'affiche un nombre entier de colonnes :p


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 22-05-2002 à 18:52:40    

antp a écrit a écrit :

T'as qu'à choisir une fréquence qui t'affiche un nombre entier de colonnes :p  




 
oui mais je ne l'ai pas encore spécifier mais le logiciel est paramètrable et peut afficher en 4, 8, 20 secondes... je peux certe toujours choisir une frequence qui colle bien pour chaque mode :) ... c'est vrai que c'est une solution...
 
toujours est-il que mon pb principal n'est pas encore résolu : à savoir, l'affichage directDraw...  :jap:


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 19:20:41    

pour récapituler, j'aimerais comme aide sur le point suivant :
 
 
je ne sais pas utiliser directDraw...  
 
l'idéal, ça serait un ens de fonction ki :  
1. permettre de désigner une zone de la fenêtre comme "zone de dessin" directDraw (par le biais d'un handle, ça serait le top :) )  
2. initialiser directDraw pour cette zone...  
3. dessiner sur la surface les pixels contenus dans mon buffer à la bonne place...  
 
 :jap:  
 
bon, c pas tout, mais j'pars du boulot... la suite demain matin donc ou ce soir si j'ai le tps de passer sur le forum ;)


---------------
Boolay for ever...
Reply

Marsh Posté le 22-05-2002 à 19:50:41    

je suis revenu du taf...
 
oki donc c'est pas ce que je voyais....
 
....
 
par contre pour ton "historique" il vaut mieux garder les dernières valeurs dans une table, et ensuite traçer en fonction de la position désirée (comme un oscillo numérique)...

Reply

Marsh Posté le 22-05-2002 à 23:05:02    

pour le traçage il y a CreateDIBSection() qui permet de créer une bitmap offscreen blittable avec BitBlt() (on a en fait un buffer accessible genre RGBAPixel* buffer.)
 
par contre, impossible de trouver les exemples sur la msdn, ils sont apparemment que sur les CDs. donc si tu as les cds de la msdn, cherche l'exemple fire mfc ou atl fire.

Reply

Marsh Posté le 23-05-2002 à 07:11:38    

Pour optmiser un logiciel y'a 2 solutions :
- améliorer l'algorithme utilisé
- améliorer son implémentation
 
Il faut toujours essayer la première avant la seconde. Et c'est aussi la première solution qui donne les meilleurs résultats. Or, vous êtes en train de batailler sur la seconde solution. Et à mon avis il y a bien plus simple à tester avant de se lancer dans du DirectDraw + assembleur !
 

Citation :

tu peux regarder du coté du directdraw pour faire la recopie rapide...


 
le blit de Windows (surement utilisé par Delphi) n'a rien à envier à celui de DirectDraw
 

Citation :

si tu veux quelque chose de "rapide", moi je ferais le traçage en asm dans un buffer, puis recopie rapide


 
les compilateurs modernes savent parfaitement optimiser les boucles. Ecrire un code en assembleur de meilleur qualité requiert de solides compétences en ce langage.
 

Citation :

vu ton truc, tu peux parfaitement gérér ton buffer en 8bpp avec une palette 256 couleurs, et blitter dans la fenêtre (la fonction cablée du blitter doit en même temps que faire la recopie la reconversion du 256 couleurs vers le format high/true color du framebuffer).


 
8ppp ... s'il part de rgb (ce qui semble être le cas) ca va lui compliquer le travail  pour pas grand chose ... traduire du RGB en 8ppp qui sera a nouveau traduit en 16/32 bpp, le tout en se gérant une palette, pour ... ecrire dans le buffer 4 pixels a la fois. Pas mal, sauf que la convertion RGB -> 8ppp a chaque pixel noircit un peu le tableau. En dernier recours ... :)
 
 
Je vous propose plutôt d'étudier 2 secondes l'algo utilisé, et vous allez constater un truc choquant :
 
A chaque cycle, voila ce qui se produit :
- le programme calcul UNE colonne sur les 500 possibles
- le programme affiche 500 colonnes (blit de TOUT le bitmap)
 
conclusion : le programme affiche à chaque cycle 500 fois trop de choses. On peut donc théoriquement afficher 500 fois plus vite ... théoriquement :D
 
Ma solution consiste donc à n'afficher que la nouvelle colonne calculée.
 
Déjà, en utilisant de simples PutPixels on peut avoir de drôles de surprises.
bien que très lente, je ne suis pas sûr que 200 PutPixels soient plus longs que 1 Blit de 200x500 (autrement dit si BitBlt n'est pas 500 fois plus rapides que PutPixels on y gagne).
Le truc consiste donc à trouver un moyen sous Delphi de ne pas raffraîchir l'image à chaque PutPixel (ce qu'il doit faire cet idiot ... soit 500x200 Blit, tu m'étonnes que ca rame !).
En Selphi je sais pas comment on fait ca proprement, mais sous VB y'avait un moyen fastoche et pas très pro (très VB quoi) qui consiste à cacher (visible = false) l'image le temps que l'on dessine dedans.
Ca marchait du tonerre. (en tous cas le gain avait été spectatculaire pour mon programme en VB qui dessinait les courbes).
 
J'ai effectué un test en créant une fenêtre (en C + Win32) 500x200 et en faisant cela :
for(i = 0; i < 500; i++)
{
    for(j = 0; j < 200; j++) PutPixel(hdc, i, j, RGB(255, 0, 0);
}
 
Résultat surprenant : environ 6 "images" à la seconde (Athlon 500, GeForceIIMx, Win2K)
ce qui est ... 24 fois ce que demande Moustaaki (1/4 d'image à la seconde).
 
Mais ce code ca puduku, si on passe une fenetre dessus ca efface tout ...
 
A mon humble avis, l'optimisation principale du programme est là :
 
à chaque nouvelle colonne afficher seulement cette colonne au lieu de réafficher les 499 autres en plus.
 
Or dans ce cas, moi je trouve que PutPixels m'a l'air tout indiquée ... a condition biensûr de travailler sur des bitmaps en mémoire.
 
Je m'explique : DirectDraw, assembleur c'est bien sympa, mais parti comme ca c'est un formidable gaspillage de ressources !  
Tu vas afficher 200x499 points inutile à chaque affichage de colonne ... :crazy:
 
Bueno, la théorie, la pratique now !
 
J'ai doucement modifié le code ci dessus et je suis arrivé au final à ... un programme tout entier ... :lol:
Ce programme test (C + GDI only! :p) la rapidité de divers algo :
 
Le PutPixel : on affiche directement les pixels dans la fenêtre. Ca s'efface ...
Le BlitBourrin : celui que tout le monde veut coder en assembleur + DirectDraw ici ... a savoir j'affiche une colonne et je blit toute l'image.
Le BlitLeger : celui que je préconnise : on blit une seule colonne (Bitblt pemret de spécifier la largeur à blitter => on lui dit de blitter 1 pixel de large)
 
Ensuite j'ai encore rajouté ca histoire d'essayer de comprendre porquoi Delphi est si lent :
SetPixelDelphiBourrin : un putpixel suivit d'un blit complet ...
SetPixelDelphiLeger : un putpixel suivit d'un blit d'une colonne de large ...
 
Le dernier, je vois pas trop qui quoi pourrait l'utiliser ... mais sa sert à voir la différence entre un blit complet et un blit léger.
 
Note : j'ai utilisé tout le temps PutPixel. Soit sur l'écran, soit sur un bitmap (via un Compatible DC). On peut passer directement par un tableau de pixels qu'on manipule, mais avec les DIB et ça c'est l'étape au dessus. :)
Restons simples ... et voyons si ca suffit (suspens ...)
 
Les résultats !
 
Oyez oyez, voici l'adresse ou j'ai compilé tout plein d'exe de tests en diverses résolutions (pas seulement 500x200) : tres large / tres haut afin de voir si un algo est meilleur quand l'image est plus haute que large et inversement. C'est tout dans un zip
source (2.16 Ko): http://www.chez.com/regatbar/moustaaki/source.zip
exe de test (11.6 Ko).: http://www.chez.com/regatbar/moustaaki/exe_de_test.zip
 
Exes garantis sans virus ;)
 
Le delphi, je pense que c'est la version avec les algos bourrins ...
Y'a pas photo, si Delphi utilise bien l'algo SetPixelDelphiBourrin comme je le pense, tu dois être proche de ces chiffres avec ton programme ... pas étonnant que les clients se soient plaints ;)
 
SetPixelDelphiBourrin : 36.5 secondes pour dessiner une image 500x200 :crazy: (comme Delphi ? en tout cas apparement c'est encore plus rapide que VB :gun:)
SetPixelDelphiLeger : surement utilisé nulle part (je vois pas trop comment), mais le temps permet de tirer des conclusions : 3.6 secondes. Autrement dit, faire un blit de 1 colonne au lieu de toute l'image fait est 10 fois plus rapide.
 
les algos plus "pro" :
 
ColonneBlitBourrin : on affiche (dans le bitmap) une colonne et on blit tout le bitmap : le temps est de 210 à 220 millisecondes ...
ColonneBlitLeger : on affiche (dans le bitmap) une colonne et on blit juste la colonne en question : pareil (si peu en moins)
SetPixel : direct à l'écran (on perd tout) : 210 ms.
 
Bref, ca permet largement d'afficher 4 images à la seconde (sur ma bécane), même sur une peu puissante ca devrait afficher 1 image en 4 secondes ...
 
Note : le code source est ici :
c'est du C, mais ca devrait être très facilement incorporé dans ton code Delphi ...
l'algo du blit à une seule colonne :
 

Code :
  1. g_hBMPDC : le bitmap en mémoire
  2. hDc : la fenetre où blitter le bitmap
  3. void ColonneBlitLeger(HDC hDC, int Colonne)
  4. {
  5. int i;
  6. for(i = 0; i < HAUTEUR; i++)
  7. {
  8.  SetPixel(g_hBMPDC, Colonne, i, Couleur);
  9. }
  10. BitBlt(hDC, Col, 0, 1, HAUTEUR, g_hBMPDC, Colonne, 0, SRCCOPY);
  11. }


 
lors là, si ca torche pas !!! :je_me_suicide:
 
Un lien vers des exemples de DIB + Bitmap + ... pleins d'autres super exemples :
qsoft.ragestorm.com\tutors\windows\index.html


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 23-05-2002 à 09:59:02    

HelloWorld a écrit a écrit :

 
Oyez oyez, voici l'adresse ou j'ai compilé tout plein d'exe de tests en diverses résolutions (pas seulement 500x200) : tres large / tres haut afin de voir si un algo est meilleur quand l'image est plus haute que large et inversement. C'est tout dans un zip
source (2.16 Ko): http://www.chez.com/regatbar/moustaaki/source.zip
exe de test (11.6 Ko).: http://www.chez.com/regatbar/moustaaki/exe_de_test.zip
 




 
 
 
coool, merci !!! ... .heu... tu peux mettre les droits d'accès publiques à ces fichiers, stp ? :) (acces forbiden error ;) )


---------------
Boolay for ever...
Reply

Marsh Posté le 23-05-2002 à 10:04:37    

Copie le lien et colle-le dans une nouvelle fenêtre... C'est comme ça chez chez.com :D


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 23-05-2002 à 10:22:49    

HelloWorld a écrit a écrit :

 
le blit de Windows (surement utilisé par Delphi) n'a rien à envier à celui de DirectDraw




 
j'eu fait la comparaison du remplissage du fenêtre de 540*200 avec des méthodes win32 de types : j'affiche le rectangle de pixel contenu dans un buffer à partir de la coordonnées x (à chaque boucle x++)... alors là, je ne sais pas si on fond, il me blit (ke veut dire blit exactement ? raffraichissement de l'affichage ?) toute la fenêtre mais ça allait exactement à la même vitesse kavec delphi... de même en utilisant openPTC... mais là encore, j'essayais d'afficher non pas 40 img/sec mais 125 colonnes/sec en essayant de faire une colonne = une image... soit un "raffraichissement" ki n'est en fait pas visible de 125 img/sec... ce ki est totalement inutile.  
j'ai essayé la même chose avec openGL et c'est bp plus rapide... au lieu de mettre 3,6 secondes, le remplissage ce fait en moins de 1/2 sec.
 

Citation :


les compilateurs modernes savent parfaitement optimiser les boucles. Ecrire un code en assembleur de meilleur qualité requiert de solides compétences en ce langage.


 
je suis d'accord et d'ailleurs je suis complétement incompétent dans ce domaine... je v me retrouver à afficher des trucs sur le bureau en voulant afficher dans la fenêtre, erf.
 
 
 

Citation :


A chaque cycle, voila ce qui se produit :
- le programme calcul UNE colonne sur les 500 possibles
- le programme affiche 500 colonnes (blit de TOUT le bitmap)


 
bin, en fait, j'ai toujours penser n'afficher ke ce ke je rajoutais puiske le reste ne change po... maintenant expliques moi ce k'est le blit... ;)
 

Citation :


Ma solution consiste donc à n'afficher que la nouvelle colonne calculée.


 
vi, la mienne aussi :D  
 

Citation :


Le truc consiste donc à trouver un moyen sous Delphi de ne pas raffraîchir l'image à chaque PutPixel (ce qu'il doit faire cet idiot ... soit 500x200 Blit, tu m'étonnes que ca rame !).


ouai, ya p'têtre une méthode "updating" ou un truc dans ce style comme pour les arborescences graphiques... je regarderais...
 
 

Citation :


J'ai effectué un test en créant une fenêtre (en C + Win32) 500x200 et en faisant cela :
for(i = 0; i < 500; i++)
{
    for(j = 0; j < 200; j++) PutPixel(hdc, i, j, RGB(255, 0, 0);
}
 
Résultat surprenant : environ 6 "images" à la seconde (Athlon 500, GeForceIIMx, Win2K)
ce qui est ... 24 fois ce que demande Moustaaki (1/4 d'image à la seconde).


 
le mieux serait ke ça marche sur un 333 avec une carte graphique de base ;) ...
 

Citation :


Mais ce code ca puduku, si on passe une fenetre dessus ca efface tout ...


 
oui, pas top en effet ;)
 
 

Citation :


à chaque nouvelle colonne afficher seulement cette colonne au lieu de réafficher les 499 autres en plus.


 
oui, je pense ke par rapport à ce ki était fait, il y a une grosse (énorme) optimisation à faire au niveau de la fréquence de raffraichissement. l'ancien programme ce contentait d'attendre l'arrivée des infos et de les afficher tout de suite forçant donc le prog à essayer d'afficher 125 img/sec... inutil, koi.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Citation :


SetPixelDelphiBourrin : 36.5 secondes pour dessiner une image 500x200 :crazy: (comme Delphi ? en tout cas apparement c'est encore plus rapide que VB :gun:)
SetPixelDelphiLeger : surement utilisé nulle part (je vois pas trop comment), mais le temps permet de tirer des conclusions : 3.6 secondes. Autrement dit, faire un blit de 1 colonne au lieu de toute l'image fait est 10 fois plus rapide.


 
non, on était plutôt proche de 4 sec... mais c trop critique puisqu'on devait afficher en 4 sec : le moindre ralentissement du processus entrainait des ralentissement de l'affichage.
 
 

Citation :


ColonneBlitBourrin : on affiche (dans le bitmap) une colonne et on blit tout le bitmap : le temps est de 210 à 220 millisecondes ...


 
ouai, ça c bien !
 

HelloWorld a écrit a écrit :

 
Note : le code source est ici :
c'est du C, mais ca devrait être très facilement incorporé dans ton code Delphi ...
l'algo du blit à une seule colonne :
 

Code :
  1. g_hBMPDC : le bitmap en mémoire
  2. hDc : la fenetre où blitter le bitmap
  3. void ColonneBlitLeger(HDC hDC, int Colonne)
  4. {
  5. int i;
  6. for(i = 0; i < HAUTEUR; i++)
  7. {
  8.  SetPixel(g_hBMPDC, Colonne, i, Couleur);
  9. }
  10. BitBlt(hDC, Col, 0, 1, HAUTEUR, g_hBMPDC, Colonne, 0, SRCCOPY);
  11. }


 
lors là, si ca torche pas !!! :je_me_suicide:
 
Un lien vers des exemples de DIB + Bitmap + ... pleins d'autres super exemples :
qsoft.ragestorm.com\tutors\windows\index.html  




 
 
siouper cool ! merci ! je v tester tout ça ! je vous tiens au courant mais bon, j'en ai pour un moment pour intégrer les timings d'affichage, la récupération des données USB, etc...  
 
et d'ailleurs, pendant ke j'y pense...  
la récupération des données se fait au niveau dll... et si j'affichais directement à partir de ces dll ? genre, je lui passe un handle vers la zone de dessin et il s'occupe de tout :) ...
parceque le chemin :
 
machine -> driver -> dll -> logiciel -> affichage (et tout ce ke ça induit) ...  
 
on peut gagner du tps en supprimant la "couche" logicielle ?


---------------
Boolay for ever...
Reply

Marsh Posté le 23-05-2002 à 10:23:36    

antp a écrit a écrit :

Copie le lien et colle-le dans une nouvelle fenêtre... C'est comme ça chez chez.com :D  




 
a ouai, safety first chez chez.com :) !


---------------
Boolay for ever...
Reply

Marsh Posté le 23-05-2002 à 10:26:54    

putain mais tu t'es grave fais chier !!! avec des petits sélécteurs et tout !!! meeerrrrciiiiiiiiiiii !!!  :love:  :love:  
 
 
 :jap:  :jap:  :jap:  :jap:  :jap:  :jap:


---------------
Boolay for ever...
Reply

Marsh Posté le 23-05-2002 à 10:37:20    

Ouais c'est clair que c'est pas mal ce truc de demo :)
je garde ça précieusement, ça peut servir


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 23-05-2002 à 10:38:00    

Citation :


hDc : la fenetre où blitter le bitmap


 
juste une dernière vérification d'allergique au win32 :
le hDC (handle device context ?), je peux lui donner un handle vers n'importe kelle surface ?? par exemple, l'handle renvoyé par delphi d'un composant zone de desssin ?


---------------
Boolay for ever...
Reply

Marsh Posté le 23-05-2002 à 10:56:32    

voilà une des raisons ki me rendent allérgiques à win32

Code :
  1. g_hBlitLeger = CreateWindow
  2. (
  3.  "BUTTON",
  4.  "Blit leger",
  5.  BS_AUTORADIOBUTTON  | WS_VISIBLE | WS_CHILD,
  6.  RB_WIDTH * 2 + ESPACE,
  7.  TRACE_HEIGHT + ESPACE,
  8.  RB_WIDTH,
  9.  RB_HEIGHT,
  10.  hWnd,
  11.  (HMENU)IDRB_BLITLEGER,
  12.  g_hInstance,
  13.  NULL
  14. );


 
 
pour créer un selecteur, tu appelles la méthode "créerFenetre"... aaaa, comme c intuitif :D ... ils auraient pu l'appeller createGraphicElement ... enfiiiin... je me permettrait pas de juger puisque je ne suis pas des plus compétent mais ça ressemble à de la conception de merde, non ?
 
 
 
 
merci en tout cas à tous ceux ki m'ont aidé dans ce topic avec une spéciale dédicace (cacedédi, ouai ! :D) à :love: HelloWord :love:


---------------
Boolay for ever...
Reply

Marsh Posté le 23-05-2002 à 11:08:35    

Moustaaki a écrit a écrit :

pour créer un selecteur, tu appelles la méthode "créerFenetre"... aaaa, comme c intuitif :D ... ils auraient pu l'appeller createGraphicElement ... enfiiiin... je me permettrait pas de juger puisque je ne suis pas des plus compétent mais ça ressemble à de la conception de merde, non ?


non, car tout élément que tu vois sur ton bureau windows est une fenêtre et est soumis aux mêmes possibilités / contraintes. un bouton d'un dialogue est une fenêtre qui reçoit ses messages click & co, sa méthode de paint par défaut est d'afficher son texte. ce que tu veux afficher c'est une fenêtre standard avec une méthode de paint qui affiche autre chose.

Reply

Marsh Posté le 23-05-2002 à 11:14:44    

youdontcare a écrit a écrit :

non, car tout élément que tu vois sur ton bureau windows est une fenêtre et est soumis aux mêmes possibilités / contraintes. un bouton d'un dialogue est une fenêtre qui reçoit ses messages click & co, sa méthode de paint par défaut est d'afficher son texte. ce que tu veux afficher c'est une fenêtre standard avec une méthode de paint qui affiche autre chose.  




 
ouai, fin ça, c valable parce ke c'est du "procédural"... c'est po de l'objet...
mon bureau windows pourrait être un élément graphique particulier tout comme une fenêtre... chacun ayant une méthode repaint redéfini et spécifique...
enfin, cela est peut-être conçu de cette manière avec les MFC ? :sarcastic:

 

[jfdsdjhfuetppo]--Message édité par Moustaaki le 23-05-2002 à 11:15:10--[/jfdsdjhfuetppo]


---------------
Boolay for ever...
Reply

Marsh Posté le 23-05-2002 à 11:18:42    

Citation :


 Handle to the device context


 
ça, ça peut être n'importe kel handle vers un élément graph'.. heu... vers n'importe kel "window" ?
par exemple, s'il me vient l'idée folle d'afficher des pixels dans mon radio button, c'est possible en passant le handle vers ce radio button ? où s'agit-t-il uniquement du handle vers la fenêtre (au sens visuel du terme, pas au sens API cette fois) parente ?
 
 
 
ou comment pouvoir dire un jour : "bonjour, je suis trilingue, je parle le français, l'anglais et le microsoft... les microsoftiens sont des gens venus d'une autre planéte... leur but est d'écraser le monde... mais je me suis soumis un jour à apprendre leur langage... je n'avais pas le choix... on m'a forcé.

 

[jfdsdjhfuetppo]--Message édité par Moustaaki le 23-05-2002 à 11:35:38--[/jfdsdjhfuetppo]


---------------
Boolay for ever...
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed