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

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

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

Message 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?
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Fred
Site Admin
Messages : 2809
Inscription : mer. 21/janv./2004 11:03

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

Message par Fred »

GrabSprite() apres le RenderWorld() devrait le faire.
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

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

Message 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)
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

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

Message par cederavic »

kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

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

Message 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 
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

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

Message par cederavic »

J'ai fais le test à midi et ça marchai bien chez moi....
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

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

Message 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 ...
ImageImage
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

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

Message par cederavic »

Je suis pas fou pourtant :lol:
Image
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

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

Message 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
ImageImage
Avatar de l’utilisateur
venom
Messages : 3138
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

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

Message par venom »

idem que case carré gris qui tourne.







@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

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

Message par cederavic »

L'exemple mesh de PB et un startdrawing(spriteoutput()) pour verifier que le sprite est "bon" :roll:
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

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

Message 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 ?
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

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

Message 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
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

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

Message par cederavic »

Oui je suis en 4.41, Dx9...
Si tu met 1 pour le buffer ça donne quoi?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

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

Message 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 
Répondre