CGSI3
Messages postés416Date d'inscriptionvendredi 22 février 2008StatutMembreDernière intervention 7 janvier 2018
-
12 juin 2010 à 18:12
CGSI3
Messages postés416Date d'inscriptionvendredi 22 février 2008StatutMembreDernière intervention 7 janvier 2018
-
13 juin 2010 à 19:13
Bonjour,
je dois utiliser rtlmovememory pour un pointeur sur un tableau de byte,
seulement RtlMoveMemory utilise IntPtr (pointeur sur integer) comment
créer et transformer un pointeur sur tableau de byte en pointeur IntPtr ? Mon code:
Public Declare Sub RtlMoveMemory Lib "kernel32" (ByRef Destination As IntPtr, ByRef Source As IntPtr, ByVal length As Integer)
Dim lBufferIn(lNbByte, .Width, .Height) As Byte
RtlMoveMemory(lBufferIn(1, 1, 1),datTmp.Scan0, lNbByte * .Width * .Height) ==> ne marche pas (conversion de vb6 en VB.net)
J'ai trouvé cela mais je n'y comprend rien ...
'System.Runtime.InteropServices.GCHandle(gch = System.Runtime.InteropServices.GCHandle.Alloc(lBufferIn,System.Runtime.InteropServices.GCHandleType.Pinned))
'IntPtr pTableauDeByte = gch. .AddrOfPinnedObject() //Pointeur vers ton tableau de byte.
'puis quand tu as finis, n'oublis pas de librer avec
'gch.Free()
RtlMoveMemory travaille en VB NEt avec des pointeurs aussi bien pour la source que la destination
Dans ton exemple datTmp.Scan0 est une variable de quelle type ?
Le principe est le suivant
1) un tableau défini par une variable : lBufferIn()
2) allocation d'une zone mémoire de la même taille
3) un pointeur sur cette zone mémoire
4) on peut utiliser RtlMoveMemory avec ce pointeur
5) on copie la zone mémoire dans le tableau lBufferIn avec Marshal.Copy
6) on libère la zone mémoire
On ne travaille pas sur les variables elles-mêmes mais sur des copies de celles-ci au niveau contenu dans des zones mémoires définies par des pointeurs.
Ne sachant pas quel est le type de la variable datTmp.Scan0 je ne puis te fournir un code
datTmp.Scan0 étant la source il faut aussi lui fournir un pointeur Intptr en mémoire, transférer le contenu de
datTmp.Scan0 dans cette zone mémoire pour enfin pouvoir utiliser RtlMoveMemory
En connaissant le type de variable de datTmp.Scan0 il y a peut-être une façon plus élégante de faire ce transfert sans passer par RtlMoveMemory
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
CGSI3
Messages postés416Date d'inscriptionvendredi 22 février 2008StatutMembreDernière intervention 7 janvier 20181 12 juin 2010 à 23:07
Merci de ton attention Galain,
Je travail en equipe a fabriquer un moteur 3D avec VB.net & OPENGL
Voici d'ou viens DatTmp
Dim lImage As Bitmap = New Bitmap(NomFichier)
Dim datTmp As Imaging.BitmapData = .LockBits(New Rectangle(0, 0, lImage
.Width, lImage.Height), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format32bppArgb)
Salut CSG13
et Scan0 correspond à quoi ? Car si datTmp est un tableau de bytes Scan0 est quoi comme variable ?
Cela revient-il à transférer le contenu du tableau datTmp dans lBufferIn ?
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
GRENIER Alain
Vous n’avez pas trouvé la réponse que vous recherchez ?
CGSI3
Messages postés416Date d'inscriptionvendredi 22 février 2008StatutMembreDernière intervention 7 janvier 20181 12 juin 2010 à 23:29
ReBonsoir Galain,
Le but est de créer un canal alpha sur un bitmap pour que opengl puisse gérer la transparence des images
On crée 2 buffers qui représentent les pixels de l'image
Dim lBufferIn(lNbByte, .Width, .Height) As Byte
Dim lBufferOut(4, .Width, .Height) As Byte
On met datTmp (BitmapData) dans un tableau2D() de byte
Puis on traite les points pour créer ce canal Alpha selon pTransparentColor
For lX = 1 To .Width
For ly = 1 To .Height
lBufferOut(1, lX, ly) = lBufferIn(1, lX, ly)
lBufferOut(2, lX, ly) = lBufferIn(2, lX, ly)
lBufferOut(3, lX, ly) = lBufferIn(3, lX, ly)
If RGB(lBufferIn(3, lX, ly), lBufferIn(2, lX, ly), lBufferIn(1, lX, ly)) = pTransparentColor Then
lBufferOut(4, lX, ly) = 0
Else
lBufferOut(4, lX, ly) = 255
End If
Next
Next
lBufferOut étant créé, on doit envoyer son pointeur a gl.gltexImage2D
lBufferOut remplacera datTmp.Scan0 dans la fonction suivante
Dans ca cas utilises directement Marshal.copy(source as Intptr,Destination() as byte,StartIndex as integer, Length as integer)
Cela donnerait : Marshal.Copy (datTmp.Scan0,lBufferIn,0,lBufferIn.Length)
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
CGSI3
Messages postés416Date d'inscriptionvendredi 22 février 2008StatutMembreDernière intervention 7 janvier 20181 13 juin 2010 à 00:09
ReBonsoir et ce sera mon dernier mail du week end,
Pour tout expliquer, et être complet, j'adapte cette procedure qui marchait super bien en VB6 à VB.net seulement les pointeurs sont gérés d'une manière différente...
'---------------------------------------------------------------------------------------
' Charge une texture à partir d'un fichier bitmap
'---------------------------------------------------------------------------------------
Public Function TextureAddFromFile(NomFichier As String, Optional pTransparentColor As Long = -1) As Long
Dim lImage As Object
Dim lTexture As Long
Dim lBitmap As bitmap
Dim lNbByte As Long
Dim lFormat As Long
Dim lBufferOut() As Byte
Dim lBufferIn() As Byte
Dim lX As Long, ly As Long
Set lImage = LoadPicture(pFile) ' Charge l'image
Call GetObjectBmp(lImage, Len(lBitmap), lBitmap) ' Lecture des informations de l'image
' Définition des paramètres fonction de la profondeur de couleur
' Ne sont supportés que les images 24bits et 32bits
Select Case lBitmap.bmBitsPixel
Case 24
lNbByte 3: lFormat GL_BGR_EXT
Case 32
lNbByte 4: lFormat GL_BGRA_EXT
Case Else
Set lImage = Nothing
Exit Function
End Select
glGenTextures 1, lTexture ' Génère une texture
glBindTexture GL_TEXTURE_2D, lTexture ' Définit la texture en texture courante
If pTransparentColor <> -1 Then ' Si une couleur de transparence est spécifiée
' Ajoute un canal alpha si nécessaire, et rend transparent les textels de couleur pTransparentColor
ReDim lBufferOut(1 To 4, 1 To lBitmap.bmWidth, 1 To lBitmap.bmHeight) As Byte
ReDim lBufferIn(1 To lNbByte, 1 To lBitmap.bmWidth, 1 To lBitmap.bmHeight) As Byte
RtlMoveMemory lBufferIn(1, 1, 1), ByVal lBitmap.bmBits, lNbByte * lBitmap.bmWidth * lBitmap.bmHeight
For lX = 1 To lBitmap.bmWidth
For ly = 1 To lBitmap.bmHeight
lBufferOut(1, lX, ly) = lBufferIn(1, lX, ly)
lBufferOut(2, lX, ly) = lBufferIn(2, lX, ly)
lBufferOut(3, lX, ly) = lBufferIn(3, lX, ly)
If RGB(lBufferIn(3, lX, ly), lBufferIn(2, lX, ly), lBufferIn(1, lX, ly)) = pTransparentColor Then
lBufferOut(4, lX, ly) = 0
Else
lBufferOut(4, lX, ly) = 255
End If
Next
Next
' Génère la texture à partir de l'image avec transparence
Call glTexImage2D(GL_TEXTURE_2D, 0, 4, lBitmap.bmWidth, lBitmap.bmHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, _
lBufferOut(1, 1, 1))
Else
' Génère la texture à partir de l'image
Call glTexImage2D(GL_TEXTURE_2D, 0, lNbByte, lBitmap.bmWidth, lBitmap.bmHeight, 0, lFormat, GL_UNSIGNED_BYTE, _
ByVal lBitmap.bmBits)
End If
' Libère l'image
Set lImage = Nothing
glBindTexture GL_TEXTURE_2D, 0
' Renvoie le numéro de la texture créée
TextureAddFromFile = lTexture
End Function
CGSI3
Messages postés416Date d'inscriptionvendredi 22 février 2008StatutMembreDernière intervention 7 janvier 20181 13 juin 2010 à 00:47
Est ce que tu as déja utilisé cette fonction ?
Elle est bien présente dans l'explorateur mais c'est incroyable que je n'arrive pas a la déclarer Raaaaaaahhhh
Je te remercie néanmoins beaucoup pour ton aide et je continuerai Lundi ...
Bonne nuit et merci surtout pour ton aide précieuse Philippe
CGSI3
Messages postés416Date d'inscriptionvendredi 22 février 2008StatutMembreDernière intervention 7 janvier 20181 13 juin 2010 à 08:54
Bonjour Galain,
la nuit porte conseil ....
Je viens de déclarer
Imports System.Runtime
en début de module et
InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement(lBufferIn, 0)
dans la fonction et elle se déclare ...
Et seulement de cette manière. Pourquoi? je ne sais pas ....
Elle me met maintenant qu'elle ne peut pas convertir mais je pense réussir avec cela. Je te donnerai une réponse par message lorsque j'aurai fini.
Merci pour ton attention et ton aide.
Si tu t'aventure dans le domaine de la 3D et Opengl, je me ferais un plaisir de t'aider en ce domaine ....
Ton Imports en début de module permet d'importer la classe System.Runtime
Mets plutôt en début de module Imports System.Runtime.InteropServices et ensuite dans ton code tu utilises directement les fonctions Marshal.XXXXXX sans être obligé de répéter InteropServices. devant Marshal
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Dim width As Integer = Bitmap.Width
Dim height As Integer = Bitmap.Height
Dim x, y As Integer
Dim bmpData As BitmapData = Bitmap.LockBits(New Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
Dim newPixel(width * height - 1) As Integer
Marshal.Copy(bmpData.Scan0, newPixel, 0, newPixel.Length)
Dim temp As Integer
For y = 0 To height - 1
For x = 0 To width - 1
temp = newPixel(width * y + x)
newPixel(width * y + x) = temp And &HFF Or (temp And &HFF00) << 8 Or (temp And &HFF0000) >> 8 Or (temp And &HFF000000)
Next
Next
Marshal.Copy(newPixel, 0, bmpData.Scan0, newPixel.Length)
Bitmap.UnlockBits(bmpData)