Page 1 sur 2

Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 9:51
par kelebrindae
Bonjour à tous,

(Je pose la question en sachant qu'il n'y probablement pas de réponse simple, mais j'essaie quand même pour relancer la réflexion :mrgreen: )

Comment pourrait-on récupérer (sous forme d'image ou de sprite) le résultat d'un rendu 3D effectué avec RenderWorld ?

Le soucis, c'est que depuis la 4.40, l'instruction "StartDrawing(ScreenOutput())" échoue dès lors que l'on a fait un "initEngine3D()" au préalable.
=> du coup, on a plus accès au contexte HDC de l'image et on ne peut plus rien faire. :(
Comme en plus, les "grabSprite" et "grabImage" effectué sur l'image avec le "renderWorld" ne marchent pas on plus, on ne peut même plus faire ne serait-ce qu'une malheureuse capture d'écran. Re- :(

Quelqu'un a une idée? Une API DirectX9 qui renverrait le pointeur du buffer écran ou un truc comme ça?

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 10:00
par Fred
GrabSprite() apres le RenderWorld() devrait le faire.

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 10:17
par kelebrindae
J'ai essayé, mais le sprite en sortie est vide (tout noir, quoi).
[EDIT] En fait, la valeur retournée si l'on utilise "#PB_any" comme premier paramètre est même égale à zéro => sprite non initialisé.

M'y serais-je mal pris?

(P.S.: merci pour cette réponse éclair, au passage)

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 13:11
par cederavic

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 13:59
par kelebrindae
@cederavic:
Oui, j'ai pas mal cherché sur les forums français et anglais, et j'étais tombé sur ce code prometteur. Hélas, en PB v4.41, il ne semble pas marcher non plus... (soit ça crash, soit le sprite en sortie est vide).
Merci quand même !

@Fred:
Le petit code suivant illustre de quelle façon j'essaie de faire un "GrabSprite" après le "RenderWorld" :

Code : Tout sélectionner

; "GrabSprite" doesn't work after "RenderWorld" - Sample code
; March 05 2010
; PB v4.41, Windows XP SP2, GPU intel 82915G

;- Initialisation 
If InitEngine3D() = 0 
  MessageRequester( "Error" , "Can't initialize 3D, check if engine3D.dll is available" , 0 ) 
  End
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 
  MessageRequester( "Error" , "Can't find DirectX 7.0 or above" , 0 ) 
  End 
EndIf 

result = MessageRequester("GrabSprite & RenderWorld","Full Screen ?",#PB_MessageRequester_YesNo) 
If result = 6      
  FullScreen=#True
  OpenScreen(800,600,32,"GrabSprite & RenderWorld") 
Else            
  FullScreen=#False 
  OpenWindow(0,0, 0, 800 , 600 ,"GrabSprite & RenderWorld",#PB_Window_ScreenCentered) 
  OpenWindowedScreen(WindowID(0),0,0, 800 , 600,0,0,0) 
EndIf 

;- Mesh
nummesh = CreateMesh(#PB_Any,100)
SetMeshData(nummesh, #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, ?PlanVertices, 4)
SetMeshData(nummesh, #PB_Mesh_Face, ?PlanFaces, 2)

;- Material
Add3DArchive(".",#PB_3DArchive_FileSystem)

CreateImage(0,32,32)
StartDrawing(ImageOutput(0))
  Box(0, 0, ImageWidth(0), ImageHeight(0), $FFFFFF)
  Line(0,0,32,32,$0000FF)
StopDrawing()
SaveImage(0,"temp.bmp")
FreeImage(0)
LoadTexture(0,"temp.bmp")
DeleteFile("temp.bmp")

CreateMaterial(0,TextureID(0))

;- Entity
numEntity = CreateEntity(#PB_Any,MeshID(numMesh),MaterialID(0))
EntityLocate(numEntity,0,0,0)

;- Camera 
CreateCamera(0, 0, 0 , 100 , 100)
CameraBackColor(0,$FF0000)
MoveCamera(0,0,0,-5)
CameraLookAt(0,0,0,0)

;- Main loop
Repeat 
  If fullscreen = #False 
    While WindowEvent() : Wend 
  EndIf
  
  ; Spin entity
  RotateEntity(numEntity,0,0,0.5,#PB_Relative)
  
  ; Render
  RenderWorld()
  
  ; Grab the screen's center in the sprite #0
  GrabSprite(0,400,300,32,32) 

  ; Display sprite
  DisplaySprite(0,10,10) ;  <= This line only displays a black square with DirectX9,
                         ;     and crashes with other sub-systems (sprite is not initialized)
  
  ; Flip buffers
  FlipBuffers()
  
  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape) 

End


;- data Section
DataSection

  PlanVertices:
  Data.f -0.5, -0.5, 0.0
  Data.f 1, 1, 1
  Data.f 0, 1
  Data.f 0.5, -0.5, 0.0
  Data.f 1,1,1
  Data.f 1, 1
  Data.f 0.5, 0.5, 0.0
  Data.f 1,1,1
  Data.f 1, 0
  Data.f -0.5, 0.5, 0.0
  Data.f 1,1,1
  Data.f 0,0
  
  PlanFaces:
  Data.w 2, 1, 0
  Data.w 0, 3, 2

EndDataSection 

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 18:01
par cederavic
J'ai fais le test à midi et ça marchai bien chez moi....

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 18:18
par case
ca ne marche pas chez moi ...

par curiosité peux tu essayer le code sur mon fil

ici

http://www.purebasic.fr/french/viewtopi ... =1&t=10184

est-ce que cela fonctionne ?

j'ai l'impression que tu as le même genre de problème que moi ...

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 18:29
par cederavic
Je suis pas fou pourtant :lol:
Image

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 18:42
par case
le code de kelebrindae ne fonctionne pas chez moi en tout cas, j'ai un fond bleu, un carré gris avec une ligne rouge au milieu qui tourne et un carré noir en haut a gauche de l'écran.

je sais pas d'ou tu sort tes robots et ton gros carre rouge au centre cederavic :p ca n'as pas l'air d'être le même code

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 18:51
par venom
idem que case carré gris qui tourne.







@++

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 19:08
par cederavic
L'exemple mesh de PB et un startdrawing(spriteoutput()) pour verifier que le sprite est "bon" :roll:

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 20:48
par kelebrindae
@case:
Le code sur ton fil semble fonctionner chez moi: j'ai une croix violette et un carré vert qui suit la souris.
Je pense que nous n'avons pas le même problème: le mien est spécifiquement lié à "initEngine3D()" et à "RenderWorld()", qui empêchent le "GrabSprite" de fonctionner. En dehors de ce contexte, je ne rencontre pas de problème avec les sprites.

@venom:
Merci d'avoir testé!

@cederavic:
J'ai pris l'exemple mesh.pb, j'ai ajouté la procédure "GrabSpriteEx" dans le code, j'ai appelé cette procédure et fait un "displaySprite" au même endroit que toi et avec les mêmes paramètres (je me suis basé sur ta capture d'écran), et ça ne marche pas: crash sur "srcDC = StartDrawing(ScreenOutput())": specified output is Null. Et ce, quel que soit le sub-system utilisé. :?
=> es-tu bien en v4.41 ?

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 20:51
par Backup
oui mais l'exemple de kelebrindae ne marche pas !
chez moi un carré noir en haut a gauche (10,10)
au lieu du sprite gris

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 20:57
par cederavic
Oui je suis en 4.41, Dx9...
Si tu met 1 pour le buffer ça donne quoi?

Re: Récupérer une image du rendu 3D (Windows) ?

Publié : ven. 05/mars/2010 20:59
par Backup
pire en sub system7

si tu fait suivre

Code : Tout sélectionner

RenderWorld()
  
  ; Grab the screen's center in the sprite #0
  CallDebugger
  resultat= CreateSprite(1,32,32)
et bien apres un renderworld() impossible de creer un sprite !!
Resultat retourne 0

sans sub systeme ça marche , mais le sprite est noir !


code de test

Code : Tout sélectionner

; "GrabSprite" doesn't work after "RenderWorld" - Sample code
; March 05 2010
; PB v4.41, Windows XP SP2, GPU intel 82915G
#Sprite3D=1
;- Initialisation
If InitEngine3D() = 0
  MessageRequester( "Error" , "Can't initialize 3D, check if engine3D.dll is available" , 0 )
  End
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 Or InitSprite3D() = 0
  MessageRequester( "Error" , "Can't find DirectX 7.0 or above" , 0 )
  End
EndIf

result = MessageRequester("GrabSprite & RenderWorld","Full Screen ?",#PB_MessageRequester_YesNo)
If result = 6     
  FullScreen=#True
  OpenScreen(800,600,32,"GrabSprite & RenderWorld")
Else           
  FullScreen=#False
  OpenWindow(0,0, 0, 800 , 600 ,"GrabSprite & RenderWorld",#PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0),0,0, 800 , 600,0,0,0)
EndIf

;- Mesh
nummesh = CreateMesh(#PB_Any,100)
SetMeshData(nummesh, #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, ?PlanVertices, 4)
SetMeshData(nummesh, #PB_Mesh_Face, ?PlanFaces, 2)

;- Material
Add3DArchive(".",#PB_3DArchive_FileSystem)

CreateImage(0,32,32)
StartDrawing(ImageOutput(0))
  Box(0, 0, ImageWidth(0), ImageHeight(0), $FFFFFF)
  Line(0,0,32,32,$0000FF)
StopDrawing()
SaveImage(0,"temp.bmp")
FreeImage(0)
LoadTexture(0,"temp.bmp")
DeleteFile("temp.bmp")

CreateMaterial(0,TextureID(0))

;- Entity
numEntity = CreateEntity(#PB_Any,MeshID(nummesh),MaterialID(0))
EntityLocate(numEntity,0,0,0)

;- Camera
CreateCamera(0, 0, 0 , 100 , 100)
CameraBackColor(0,$FF0000)
MoveCamera(0,0,0,-5)
CameraLookAt(0,0,0,0)

;- Main loop
Repeat
  If FullScreen = #False
    While WindowEvent() : Wend
  EndIf
  
  ; Spin entity
  RotateEntity(numEntity,0,0,0.5,#PB_Relative)
  
  ; Render
  RenderWorld()
  
  ; Grab the screen's center in the sprite #0
  CallDebugger
  resultat= CreateSprite(1,32,32)
    If  GrabSprite(1,400,300,32,32 )<>0
 
  ; Display sprite
 
      DisplaySprite(1,10,10) ;  <= This line only displays a black square with DirectX9,
    EndIf
 
  
    
  ;     and crashes with other sub-systems (sprite is not initialized)
  
  ; Flip buffers
  FlipBuffers()
  
  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)

End


;- data Section
DataSection
  
  PlanVertices:
  Data.f -0.5, -0.5, 0.0
  Data.f 1, 1, 1
  Data.f 0, 1
  Data.f 0.5, -0.5, 0.0
  Data.f 1,1,1
  Data.f 1, 1
  Data.f 0.5, 0.5, 0.0
  Data.f 1,1,1
  Data.f 1, 0
  Data.f -0.5, 0.5, 0.0
  Data.f 1,1,1
  Data.f 0,0
  
  PlanFaces:
  Data.w 2, 1, 0
  Data.w 0, 3, 2
  
EndDataSection