Question

J'ai un pointeur vers un tampon COLORREF, quelque chose comme: COLORREF* buf = new COLORREF[x*y];

Un sous-programme remplit ce tampon avec d'information de couleur. Chaque COLORREF représente un pixel.

.

Maintenant, je veux dessiner ce tampon à un contexte de périphérique Mes travaux d'approche en cours, mais il est assez lent (== ~ 200ms par dessin, en fonction de la taille de l'image):

for (size_t i = 0; i < pixelpos; ++i) 
{
    // Get X and Y coordinates from 1-dimensional buffer.
    size_t y = i / wnd_size.cx;
    size_t x = i % wnd_size.cx;
    ::SetPixelV(hDC, x, y, buf[i]);
}

Est-il possible de le faire plus vite; à la fois, pas un pixel après l'autre? Je ne suis pas vraiment familier avec le GDI. J'ai entendu parler al beaucoup d'API comme CreateDIBitmap (), BitBlt (), HBITMAP, CImage et tout ce genre de choses, mais ne sais pas comment l'appliquer. Il semble tout assez compliqué ...
MFC est également la bienvenue.

Toutes les idées?

Merci d'avance.

(Rappel:. La sous-routine I mentionné ci-dessus est un noyau OpenCL - le GPU calcule une image et d'un coffre-fort Mandelbrot dans le tampon de COLORREF)

EDIT: Merci à tous pour vos suggestions. Les réponses (et liens) m'a donné un aperçu de la programmation graphique de Windows. La performance est maintenant acceptable (semi-temps réel à défilement horizontal dans le Mandelbrot fonctionne :)
J'ai fini avec la solution suivante (MFC):

...
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);

CBitmap mandelbrotBmp;
mandelbrotBmp.CreateBitmap(clientRect.Width(), clientRect.Height(), 1, 32, buf);

CBitmap* oldBmp = dcMemory.SelectObject(&mandelbrotBmp);
pDC->BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &dcMemory, 0, 0, SRCCOPY);

dcMemory.SelectObject(oldBmp);
mandelbrotBmp.DeleteObject();

Donc, fondamentalement CBitmap :: CreateBitmap () m'a sauvé d'utiliser l'API première (que je ne comprends toujours pas complètement). L'exemple dans la documentation CDC :: CreateCompatibleDC a également été utile.
Mon Mandelbrot est maintenant bleu - en utilisant SetPixelV (), il était rouge. Mais je suppose que cela a quelque chose à voir avec CBitmap :: CreateBitmap () l'interprétation de mon tampon, pas vraiment important.

Je pourrais essayer la suggestion OpenGL, car il aurait été le choix beaucoup plus logique et je voulais essayer OpenCL sous Linux de toute façon.

Était-ce utile?

La solution

Dans les circonstances, je serais probablement utiliser une section de DIB (que vous créez avec CreateDIBSection ). Une section DIB est un bitmap qui vous permet d'accéder au contenu directement comme un tableau, mais toujours l'utiliser avec toutes les fonctions habituelles de GDI.

Je pense que vous donnera la meilleure performance de quoi que ce soit basé sur GDI. Si vous avez besoin de mieux, alors @Kornel est fondamentalement correcte - vous aurez besoin de passer à quelque chose qui a un soutien plus direct pour l'accélération matérielle (DirectX ou OpenGL - bien que l'OMI, OpenGL est beaucoup mieux choix pour le travail que DirectX).

Étant donné que vous faites actuellement le calcul OpenCL et le dépôt de la sortie dans un tampon de couleur, OpenGL serait le vraiment choix évident. En particulier, vous pouvez déposer OpenCL la sortie dans une texture OpenGL, vous avez OpenGL dessiner un quad en utilisant cette texture. Sinon, puisque vous êtes juste mettre la sortie à l'écran de toute façon, vous pouvez simplement faire le calcul dans un fragment shader OpenGL (ou, bien sûr, un pixel shader DirectX), de sorte que vous ne mettriez pas la sortie en mémoire hors écran juste pour que vous pouvez copier le résultat sur l'écran. Si ma mémoire est bonne, le livre orange a un shader Mandelbrot comme l'un de ses exemples.

Autres conseils

Oui, bien sûr, qui est lent. Vous faites un aller-retour par le pilote de périphérique du noyau et vidéo pour chaque pixel. Vous faites vite en tirant à la mémoire d'abord, puis mettre à jour l'écran d'un seul coup. Cela prend, par exemple, CreateDIBitmap, CreateCompatibleDC () et BitBlt ().

Ce n'est pas un bon moment et le lieu pour un tutoriel complet sur la programmation graphique. Il est bien couvert par un texte d'introduction sur GDI et / ou la programmation API Windows. Tout ce que vous aurez besoin de savoir que vous pouvez trouver dans la programmation séminal de Petzold de Windows.

Puisque vous avez déjà un tableau de pixels, vous pouvez utiliser directement BitBlt pour le transférer à courant continu de la fenêtre. Voir ce lien pour un exemple partiel: http://msdn.microsoft.com/en-us/library/aa928058. aspx

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top