IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Animation pixel random avec win32 [Débutant(e)]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Inactif  
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 24
    Par défaut Animation pixel random avec win32
    Bonjour,

    J'ai quelques bases en c pour faire des petites applications console mais je débute totalement avec win 32

    Je dois faire un test simple avec la lib win 32:

    Une boucle qui s'exécute toutes les x millisecondes me rafraichit la fenêtre en choisissant au hasard les couleurs des pixels.


    Je suppose que c'est pas très compliqué mais je suis un peu perdu dans tous les tutoriels.



    Voici mon code, pour le moment j'arrive à faire une manipulations de pixels statiques comme ceci (là j'affiche deux pixels blancs tout pourris)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    #include <windows.h>
     
    LPCTSTR ClsName = L"BasicApp";
    LPCTSTR WndName = L"Test de merde";
     
    INT a = 0;
     
     
    LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
    			      WPARAM wParam, LPARAM lParam);
     
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
    {
    	MSG        Msg;
    	HWND       hWnd;
    	WNDCLASSEX WndClsEx;
     
     
    	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
    	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
    	WndClsEx.lpfnWndProc   = WndProcedure;
    	WndClsEx.cbClsExtra    = 0;
    	WndClsEx.cbWndExtra    = 0;
    	WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    	WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    	WndClsEx.lpszMenuName  = NULL;
    	WndClsEx.lpszClassName = ClsName;
    	WndClsEx.hInstance     = hInstance;
    	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
     
     
    	RegisterClassEx(&WndClsEx);
     
    	hWnd = CreateWindow(ClsName,
    			  WndName,
    			  WS_OVERLAPPEDWINDOW,
    			  CW_USEDEFAULT,
    			  CW_USEDEFAULT,
    			  CW_USEDEFAULT,
    			  CW_USEDEFAULT,
    			  NULL,
    			  NULL,
    			  hInstance,
    			  NULL);
     
     
    	if( !hWnd ) 
    		return 0; 
     
     
    	ShowWindow(hWnd, SW_SHOWNORMAL);
    	UpdateWindow(hWnd);
     
     
     
     
     
    	while( GetMessage(&Msg, NULL, 0, 0) )
    	{
     
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
    	}
     
     
     
    	return Msg.wParam;
    }
     
     
     
     
    LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
    			   WPARAM wParam, LPARAM lParam)
    {
     
    	OutputDebugString(L"DEBUT WIN PROCEDURE\n");
     
     
     
    	a=a+1;
     
    	// test d'affichage
     
    	PAINTSTRUCT ps;
    	HDC hdc = BeginPaint(hWnd, &ps);
     
    	SetPixel(hdc, 50+a, 50, RGB(255,255,255));
    	SetPixel(hdc, 100+a, 100, RGB(255,255,255));
     
    	EndPaint(hWnd, &ps);
     
     
     
     
        switch(Msg)
        {
     
        case WM_DESTROY:
     
            PostQuitMessage(WM_QUIT);
            break;
        default:
     
            return DefWindowProc(hWnd, Msg, wParam, lParam);
        }
     
        return 0;
    }

    mais je ne trouve pas comment rafraichir ma fenêtre mettons tous les 16 millisecondes

    et j'aimerais savoir s'il n'y a pas une manière plus rapide de manipuler les pixels, en accédant directement à un tableau d'integer 32.

  2. #2
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Commence déjà par maîtriser cette technique ultra simple :

    - Dans le traitement de WM_CREATE, tu mets SetTimer(hWnd, 1, 16, NULL) pour envoyer le message WM_TIMER à ta fenêtre (hWnd) toutes les 16 millisecondes. 1 est l'Id de ton timer, on aurait pu mettre n'importe quel autre nombre.

    - Dans le traitement de WM_TIMER, tu rafraîchis la fenêtre avec InvalidateRect(hWnd, NULL, FALSE);

    - Dans le traitement de WM_PAINT, dessine ce que tu veux.

    - Dans le traitement de WM_DESTROY, ajoute, avant PostQuitMessage (même si tu peux en fait le mettre n'importe où) : KillTimer(hWnd, 1);

    La précision du Timer n'est cependant pas très précise alors je te conseille de ne pas choisir des intervalles trop faibles (genre 1 milliseconde). Même 16, c'est déjà un peu osé. Mais il y a d'autres méthodes qui répondent mieux à des besoins de précisions. C'est inutile, à mon avis, d'en parler maintenant.

    N'hésite pas à consulter la MSDN Library si tu as une question sur une fonction ou un message quelconque.

    Essaie de mettre tout ça en pratique et poste ton code que tu réussisses après ou pas, on pourra toujours en discuter.

  3. #3
    Inactif  
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 24
    Par défaut
    Merci infiniment pour ton aide,

    ça fonctionne avec setPixel mais c'est très lent


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    #include <windows.h>
    #include "Engine.h"
     
    LPCTSTR ClsName = L"ShitApp";
    LPCTSTR WndName = L"Test de merde";
     
     
     
    LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
    			      WPARAM wParam, LPARAM lParam);
     
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
    {
    	MSG        Msg;
    	HWND       hWnd;
    	WNDCLASSEX WndClsEx;
     
     
    	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
    	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
    	WndClsEx.lpfnWndProc   = WndProcedure;
    	WndClsEx.cbClsExtra    = 0;
    	WndClsEx.cbWndExtra    = 0;
    	WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    	WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    	WndClsEx.lpszMenuName  = NULL;
    	WndClsEx.lpszClassName = ClsName;
    	WndClsEx.hInstance     = hInstance;
    	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
     
     
    	RegisterClassEx(&WndClsEx);
     
     
    	hWnd = CreateWindow(ClsName,
    			  WndName,
    			  WS_OVERLAPPEDWINDOW,
    			  CW_USEDEFAULT,
    			  CW_USEDEFAULT,
    			  640,
    			  480,
    			  NULL,
    			  NULL,
    			  hInstance,
    			  NULL);
     
     
    	if( !hWnd )
    		return 0;
     
     
    	ShowWindow(hWnd, SW_SHOWNORMAL);
    	UpdateWindow(hWnd);
     
    	while( GetMessage(&Msg, NULL, 0, 0) )
    	{
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
    	}
     
    	return Msg.wParam;
    }
     
     
    PAINTSTRUCT ps;
    HDC hdc;
     
    unsigned int *tab;
     
    LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
    			   WPARAM wParam, LPARAM lParam)
    {
     
     
        switch(Msg)
        {
    	case WM_CREATE:
     
    		// INIT
     
    		OutputDebugString(L"CREATE\n");
    		SetTimer(hWnd, 1, 20, NULL);	
     
    		tab = InitEngine(); // get pixel table adress
     
     
    		break;
    	case WM_PAINT:
     
     
    		EngineRoutine(); // update pixel effect
     
     
    		// copy int array in ram	
     
    		hdc = BeginPaint(hWnd, &ps);
     
    		for ( int row = 0 ; row < 480 ; row++ ) {
    			for ( int col = 0 ; col < 640 ; col++ ) {
    				SetPixel(hdc, col , row, tab[ col + 640 * row ] );
    			}
    		}
     
    		EndPaint(hWnd, &ps);
     
     
    		break;
    	case WM_TIMER:
    		InvalidateRect(hWnd, NULL, FALSE);
    		break;
        case WM_DESTROY:
    		KillTimer(hWnd, 1);
            PostQuitMessage(WM_QUIT);
            break;
        default:
            return DefWindowProc(hWnd, Msg, wParam, lParam);
        }
     
        return 0;
    }


    Voilà la partie du code que je dois remplacer par un truc qui va vite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for ( int row = 0 ; row < 480 ; row++ ) {
    	for ( int col = 0 ; col < 640 ; col++ ) {
    		SetPixel(hdc, col , row, tab[ col + 640 * row ] );
    	}
    }
    afin de pouvoir copier rapidement mon tableau d'unsigned int dans l'image qu'affiche ma fenetre

    (et je dois impérativement partir d'un tableau d'unsigned int)

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    SetPixelV() est légèrement plus rapide que SetPixel().
    Si tu as besoin de plus rapide, tu devras jouer avec la mémoire d'un bitmap indépendant (DIB, créé avec CreateDIBSection()).

    Attention: Il ne faut pas utiliser GetStockObject() ou GetSysColorBrush() pour une WNDCLASS: Utilise plutôt un truc du genre (HBRUSH)( COLOR_WINDOWTEXT+1 ) pour du noir et (HBRUSH)( COLOR_WINDOW+1 ) pour du blanc...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Attention: Il ne faut pas utiliser GetStockObject() ou GetSysColorBrush() pour une WNDCLASS
    Ca, ça va m'être utile ...

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Au passage, il y a un léger mensonge dans le texte: Les pseudo-brushes marchent aussi avec Fillrect().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Problème fonction random avec linux
    Par fabetvince dans le forum C
    Réponses: 12
    Dernier message: 25/05/2006, 23h45
  2. Comment faire un random avec un min et un max
    Par crocodingo dans le forum C++
    Réponses: 3
    Dernier message: 06/04/2006, 11h19
  3. Récupération de texte avec win32::ole
    Par bluecurve dans le forum Modules
    Réponses: 2
    Dernier message: 22/02/2006, 16h47
  4. Comment travailler avec Win32
    Par Mathieu.J dans le forum MFC
    Réponses: 4
    Dernier message: 25/01/2006, 09h49
  5. Probleme avec Win32::odbc et mon script
    Par goblin dans le forum Modules
    Réponses: 1
    Dernier message: 29/11/2005, 21h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo