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

Assembleur Discussion :

Affichage rapide d'un point dans une fenêtre - CreateDIBSection ?


Sujet :

Assembleur

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Points : 20
    Points
    20
    Par défaut Affichage rapide d'un point dans une fenêtre - CreateDIBSection ?
    Bonjour,
    Je programme en assembleur (NASM) pour une machine windows x64.
    Je crée une fenêtre par la winapi de 1250x800 (1 Mpx). Je remplis cette fenêtre de points de différentes couleurs. La couleur de chaque point est calculée à partir de sa position et d'un gros paquet de données déjà calculées et stockées dans une plage mémoire réservée dans la section .bss.
    A ce jour, je dessine les points avec la fonction SetPixel de la winapi. Le problème est que c'est lent, très lent : pour redessiner l'ensemble de la fenêtre, ça prend un peu plus de 2 secondes, alors que pour mon application, il faudrait que ça prenne environ 100 ms.
    La lenteur vient presque exclusivement de la fonction SetPixel : sans l'appel à cette fonction, le 1 M de boucles dure environ 10 ms.
    Ma question est donc : comment puis-je dessiner un point plus rapidement qu'avec SetPixel ? (via la winapi, mais peut-être autrement ?)
    Merci d'avance de votre réponses, même si ce ne sont que des directions de recherches.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Points : 20
    Points
    20
    Par défaut
    J'ai peut-être une solution à mon problème : l'utilisation d'une section DIB.
    J'ai essayé de mettre ça en oeuvre, mais j'ai toujours un retour de 0 (donc section non créée).
    Est-ce que quelqu'un a déjà utilisé CreateDIBSection en assembleur et pourrait me dire ce qui ne va pas ?
    (la création du hdc est ok et me donne bien un handle valide)

    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
     
                ; structure bitMapInfo
                    ; bmiHeader (40) :
                    mov [bitMapInfos + 0 ], dword 40            ; biSize            DWORD / 4    40+12
                    mov [bitMapInfos + 4 ], dword 1250                ; biWidth           LONG / 4
                    mov [bitMapInfos + 8 ], dword -800                 ; biHeight          LONG / 4
                    mov [bitMapInfos + 12 ], word 1                   ; biPlanes          WORD / 2
                    mov [bitMapInfos + 14 ], word 24                  ; biBitCount        WORD / 2
                    mov [bitMapInfos + 16 ], dword BI_RGB             ; biCompression     DWORD / 4
                    mov [bitMapInfos + 20 ], dword 0                  ; biSizeImage       DWORD / 4   ou 1250x800x3 ou 4
                    mov [bitMapInfos + 24 ], dword 0                  ; biXPelsPerMeter   LONG / 4
                    mov [bitMapInfos + 28 ], dword 0                  ; biYPelsPerMeter   LONG / 4
                    mov [bitMapInfos + 32 ], dword 0                  ; biClrUsed         DWORD / 4
                    mov [bitMapInfos + 36 ], dword 0                  ; biClrImportant    DWORD / 4
                    ; RGBQUAD          bmiColors[1];
                    mov [bitMapInfos + 40 ], dword 0xFFFFFF00
     
               ; création de la section DIB
                    mov rcx, qword [DrawingCtxHandle]           ; [in]  HDC              hdc
                    lea rdx, [bitMapInfos]                  ; [in]  const BITMAPINFO *pbmi
                    mov r8d, DIB_RGB_COLORS                      ; [in]  UINT             usage
                    lea r9, [pBitData]                      ; [out] VOID             **ppvBits
                    push 0                                      ; [in]  DWORD            offset
                    push 0                                      ; [in]  HANDLE           hSection
                    sub rsp, 32
                    call CreateDIBSection
                    add rsp, 32
                    add rsp, 16

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 14
    Points : 20
    Points
    20
    Par défaut
    Bon ...
    Juste avant de partir une semaine en vacances, j'ai trouvé mon problème, et ma solution
    Les ressources et aides sont tellement rares pour l'assembleur que je vais la poster
    C'est un extrait de mon code fonctionnel (mais j'ai peut-être oublié quelques éléments)
    Attention, il faut bien sûr créer la classe de fenêtre, la fenêtre, et sa procédure avant le cas WM_PAINT
    A noter : la difficulté que j'ai eue à résoudre mon problème vient d'un fonctionnement anormal de CreateDIBSection :
    Le premier appel à CreateDIBSection de WM_PAINT renvoie une adresse et un handle à 0, mais sans déclencher d'erreur
    Par contre, tous les appels suivants fonctionnement normalement
    Nota : je n'ai pas encore mesuré le temps d'exécution, mais je pense être en dessous des 10 ms

    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
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
       ; pour window proc
            extern GetDC
            extern TextOutA
            extern ReleaseDC
            extern DefWindowProcA
            extern DestroyWindow
            extern PostQuitMessage
        ; pour paint
            extern BeginPaint
            extern SelectObject
            extern DeleteObject
            extern EndPaint
     
            extern BitBlt
            extern CreateCompatibleDC
            extern CreateCompatibleBitmap
     
            extern CreateDIBSection
            extern GdiFlush
     
    ; quelques constantes utiles ...
     
            PS_SOLID: equ 0x00
     
            ROP: equ 0x00C000CA
                SRCCOPY: equ -1 ; a utiliser en theorie
                MERGECOPY: equ 0x00C000CA ; fonctionne
                BLACKNESS: equ 0x00000000
            SRCERASE: equ 0x00440328
     
            DIB_RGB_COLORS: equ 0x00000000
            BI_RGB: equ 0x00000000
     
    ; variables (à trier)
            Instance: resq 1
            OurWindowclass: resb 80 ; 4/4/8/4/4/8/8/8/8/8/8/8
            Windowhandle: resq 1
            WindowMessage: resq 48 ; ?
            PaintStruct: resb 72 ; 8/4/4+4+4+4/4/4/8+8+8+8/4?
            DrawingCtxHandle: resq 1
            DrawingCtxHandle2: resq 1
            BitmapHandle2: resq 1
            OldBitmapHandle2: resq 1
            bitMapInfos: resb 56 ; 4/4/4/2/2/4/4/4/4/4/4 + 4x4 : a corriger quand ca marchera
            pBitDataAdress: resq 1
            pBitDataHandle: resq 1
     
    ; structure bitMapInfo
    		; bmiHeader (40) :
    		mov [bitMapInfos + 0 ], dword 40       ; biSize            DWORD / 4
    		mov [bitMapInfos + 4 ], dword 1250     ; biWidth           LONG / 4
    		mov [bitMapInfos + 8 ], dword -800     ; biHeight          LONG / 4
    		mov [bitMapInfos + 12 ], word 1        ; biPlanes          WORD / 2
    		mov [bitMapInfos + 14 ], word 24       ; biBitCount        WORD / 2
    		mov [bitMapInfos + 16 ], dword BI_RGB  ; biCompression     DWORD / 4
    		mov [bitMapInfos + 20 ], dword 0       ; biSizeImage       DWORD / 4
    		mov [bitMapInfos + 24 ], dword 0       ; biXPelsPerMeter   LONG / 4
    		mov [bitMapInfos + 28 ], dword 0       ; biYPelsPerMeter   LONG / 4
    		mov [bitMapInfos + 32 ], dword 0       ; biClrUsed         DWORD / 4
    		mov [bitMapInfos + 36 ], dword 0       ; biClrImportant    DWORD / 4
     
    ; dans WindowProc : -------------------------------------------------------
    	cas_WM_PAINT:
    	; initialisation du tracage => hdc
    		mov rcx, qword [rbp+16]                         ; hWnd
    		lea rdx, [PaintStruct]                          ; lpPaint
    		sub rsp, 32
    		call BeginPaint
    		add rsp, 32
    		mov [DrawingCtxHandle], rax                     ; hdc
    	; creation d'un contexte de tracage similaire 2 => hdc2
    		mov rcx, qword [DrawingCtxHandle]
    		sub rsp, 32
    		call CreateCompatibleDC
    		add rsp, 32
    		mov [DrawingCtxHandle2], rax
    	; creation d'une section DIB => pBitDataHandle
    		mov rcx, qword [DrawingCtxHandle2]  ; [in]  HDC              hdc
    		lea rdx, [bitMapInfos]              ; [in]  const BITMAPINFO *pbmi
    		mov r8, DIB_RGB_COLORS              ; [in]  UINT             usage
    		lea r9, [pBitDataAdress]            ; [out] VOID             **ppvBits
    		push 0                              ; [in]  DWORD            offset
    		push 0                              ; [in]  HANDLE           hSection
    		sub rsp, 32
    		call CreateDIBSection
    		add rsp, 32
    		add rsp, 16
    		mov [pBitDataHandle], rax
    	; verification DIBSection bien creee
    		mov rax, [pBitDataAdress]
    		cmp rax, 0
    		je no_dibs
    	; adaptation de la section DIB au hdc2
    		mov rcx, qword [DrawingCtxHandle2]
    		mov rdx, qword [pBitDataHandle]
    		sub rsp, 32
    		call SelectObject
    		add rsp, 32
    		mov [OldBitmapHandle2], rax
    	; purge actions GDI
    		sub rsp, 32
    		call GdiFlush
    		add rsp, 32
    	; tracage sur DIBSection
    		mov rdx, [pBitDataAdress]
    		mov rcx, 1250*800
    		boucle_points:
    			mov [rdx], byte 0x7F
    			mov [rdx+1], byte 0x7F
    			mov [rdx+2], byte 0x7F
    			; suivant
    			add rdx, 3
    			dec rcx
    			cmp rcx, 0
    			jne boucle_points
    	; copie d'un morceau de section DIB vers hDC
    			mov rcx, qword [DrawingCtxHandle]       ; Destination device context
    			mov edx, 0                              ; Destination X
    			mov r8d, 0                              ; Destination Y
    			mov r9d, LARGEUR_FENETRE                ; Width
    			sub rsp, 8
    			push ROP                  ; Operation (SRCCOPY, BLACKNESS, SRCERASE)
    			push 0                                  ; Source Y
    			push 0                                  ; Source X
    			mov rax, qword [DrawingCtxHandle2]
    			push rax                                ; Source device context
    			push HAUTEUR_FENETRE                    ; Height
    			sub rsp, 32
    			call BitBlt                             ; Blit a rectangle
    			add rsp, 32
    			add rsp, 48
    	; recuperation de l'ancien objet bitmap 2
    		mov rcx, qword [DrawingCtxHandle2]
    		mov rdx, qword [OldBitmapHandle2]
    		sub rsp, 32
    		call SelectObject
    		add rsp, 32
    	; destruction de l'objet bitmap 2
    		mov rcx, qword [pBitDataHandle]
    		sub rsp, 32
    		call DeleteObject
    		add rsp, 32
    	no_dibs:
    	fin_tracage:
    	; cloture du tracage
    		mov rcx, qword [rbp+16]                     ; hWnd
    		lea rdx, PaintStruct                        ; lpPaint
    		sub rsp, 32
    		call EndPaint
    		add rsp, 32
    	; suite
    		xor rax, rax
    		jmp traitement_standard

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Affichage du nombre de points dans une zone
    Par atlanthot dans le forum IGN API Géoportail
    Réponses: 10
    Dernier message: 06/11/2012, 17h33
  2. le pixel noir le plus proche d'un point dans une image
    Par tlemcenvisit dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 28/03/2006, 09h44
  3. [VB.NET] image d'un bouton dans un panel dans une fentre MDI
    Par smedini dans le forum Windows Forms
    Réponses: 6
    Dernier message: 02/02/2006, 19h15
  4. Réponses: 1
    Dernier message: 07/01/2006, 22h10
  5. [MySQL] Affichage de valeurs par selection dans une table
    Par Flushovsky dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 16/12/2005, 18h04

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