image to scene 3d

Généralités sur la programmation 3D
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

image to scene 3d

Message par Zorro »

Je sais pas si cela a deja été fait ,

voici un petit code, qui permet de charger une image (de preference pas trop grande :genre 800x600 )
pour en faire un scene Ogre en relief...

exemple cette image :
Image

va donner :

Image

Image


le code n'est absolument pas optimisé , je suis parti d'un code existant dans les exemples 3D
du coup , l'utilisation des touches flechées pour se promener dans la scene
et la souris pour changer l'orientation de la vue ...

prennez de preference des images bien contrasté pour mieux apercevoir le relief de la scene
Esc pour quitter

a savoir :

plus la couleur est foncé, plus c'est en relief , je fait une moyenne des composants RVB
ça donne une valeur en niveau de gris, c'est cette valeur qui determine le relief
ligne 66

Code : Tout sélectionner

coul_hauteur=255-(red(coul)+green(coul)+blue(coul))/3
pour avoir les couleurs foncé en creux (donc l'inverse de l'exemple ci dessous)
il faut retirer le "255-" au debut de la ligne

la hauteur des cubes se regle ligne 70

Code : Tout sélectionner

ScaleEntity(compteur, 1,  coul_hauteur/30,1)
le "/30" determine la hauteur , si on retire le "/30" ça va etre TRES en relief :)
si on met "/80" ça diminue le relief ....

ligne 51 je reduit volontairement la taille de l'image par 10

Code : Tout sélectionner

ResizeImage( #image,ImageWidth(#image)/10,ImageHeight(#image)/10)
une image 800x600 generera un scene de 80x60 cubes , ce qui fait deja beaucoup

c'est pour ça qu'il ne faut pas charger d'images trop grande , sinon la scene va augmenter
et votre systeme risque de ramer ....
si toutefois ça rame chez vous , divisez par,20 , 30 ou 40 pour generer moins de cubes ....

a l'inverse , si vous chargez une image trop petite , alors retirez la reduction "/10"




Le code :

Code : Tout sélectionner


;
; ------------------------------------------------------------
;
;   PureBasic -image to scene3d
;
;  By Zorro
;
; ------------------------------------------------------------
;
UsePNGImageDecoder()
UseJPEGImageDecoder()

#PB_Material_SpecularColor = 1
#PB_Material_AmbientColor  = 2
IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
Define.f KeyX, KeyY, MouseX, MouseY
#CameraSpeed  = 1
#RobotMesh    = 0
#RobotTexture = 0
#Robot        = 0
#image=0
Global compteur=0
If InitEngine3D()
		Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
		Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
		InitSprite()
		InitKeyboard()
		InitMouse()
		If Screen3DRequester()
				
				
				LoadTexture(#RobotTexture, "soil_wall.jpg")
				CreateMaterial(0, TextureID(#RobotTexture))
				
				imagePath.s= OpenFileRequester("ouvre image", "d:\", "*mp|*.jpg|*.png", 1 )
				If LoadImage(#image,imagePath.s)
						ResizeImage( #image,ImageWidth(#image)/10,ImageHeight(#image)/10)
				Else
						MessageRequester("erreur","l'image ne se charge pas ! ")
						End
				Endif
				CreateCube(0, 1) ; creer un mesh defaut
				id_entity=CreateEntity(#pb_any, MeshID(0), MaterialID(0))
				SetEntityMaterial(#Robot, MaterialID(0))
				StartDrawing(ImageOutput(#image))
						compteur=0
						For y=1 to ImageHeight(#image)-1
								For x=1 to ImageWidth(#image)-1
										coul= Point(x,y)
										coul_hauteur=255-(red(coul)+green(coul)+blue(coul))/3
										compteur=compteur+1
										CopyEntity(id_entity, compteur)										
										ScaleEntity(compteur, 1,  coul_hauteur/30,1)
										MoveEntity(compteur, X, 1, y )
										texture=CreateMaterial(#Pb_any, TextureID(#RobotTexture))
										SetEntityMaterial(id_entity, MaterialID(texture))
										SetMaterialColor(texture,#PB_Material_AmbientColor, coul)
								Next x
						Next y						
				StopDrawing()
				
				DisableMaterialLighting(0, 1)
				SetMaterialColor(0, #PB_Material_AmbientColor, RGB(100, 100, 100))
				SetMaterialColor(0, #PB_Material_SpecularColor, RGB(255, 255, 255))
				
				CreateLight(0, RGB(0,0,255), 100.0, 0, 0)
				SetLightColor(0, #PB_Light_SpecularColor, RGB(255, 0, 0))
				CreateCamera(0, 0, 0, 100, 100)
				MoveCamera(0,  50, 40, 150)
				CameraBackColor(0, RGB(255, 255, 255))
				Repeat
						Screen3DEvents()
						If ExamineMouse()
								MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
								MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
						EndIf
						If ExamineKeyboard()
								If KeyboardPushed(#PB_Key_Left)
										KeyX = -#CameraSpeed
								ElseIf KeyboardPushed(#PB_Key_Right)
										KeyX = #CameraSpeed
								Else
										KeyX = 0
								EndIf
								If KeyboardPushed(#PB_Key_Up)
										KeyY = -#CameraSpeed
								ElseIf KeyboardPushed(#PB_Key_Down)
										KeyY = #CameraSpeed
								Else
										KeyY = 0
								EndIf
						EndIf
						RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
						MoveCamera  (0, KeyX, 0, KeyY)
						RenderWorld()
						Screen3DStats()
						FlipBuffers()
				Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
		EndIf
Else
		MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf
End
Dernière modification par Zorro le ven. 02/mars/2018 11:07, modifié 1 fois.
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: image to scene 3d

Message par falsam »

Zorro a écrit :Je sais pas si cela a deja été fait
A ma connaissance non. Ta méthode consistant à générer un mesh par point est trop consommatrice de ressources system et le lag n'est pas loin.

Une autre méthode consisterait à créer un seul mesh. C'est ce qu'à fait ApplePie sur le forum anglophone.
http://www.purebasic.fr/english/viewtop ... 19#p468019
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: image to scene 3d

Message par Zorro »

j'y ai bien pensé , mais ma maitrise des meshs et de leur triangulations , est quasi nul ! :)

[reedit]
ça proviens aussi d'un manque dans les fonctions de Purebasic
par exemple une fonction d'instanciation d'objet serait bienvenue

-instance d'objet est une copie faisant en fait reference a un seul objet , une copie virtuel en quelque sorte , le meme objet "virtuellement copié"
du coup c'est plus 80x60 cubes qu'on aurait, mais juste 1 seul , dont les copies "fantome" seraient utilisé , comme dans les softs 3D genre Blender/C4d ....


ps: en meme temps ralentir une machine "Musclée" , a ce point, avec seulement 4800 cubes ....hum ... :mrgreen:
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
SPH
Messages : 4722
Inscription : mer. 09/nov./2005 9:53

Re: image to scene 3d

Message par SPH »

Impressionnant ce truc 8O
http://HexaScrabble.com/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: image to scene 3d

Message par Zorro »

l'idee est tres simple

chaque pixel de l'image est représenté par un cube , ce cube est coloré avec la couleur du pixel de l'image correspondant

ensuite, on decide de la taille en y (hauteur) du cube en utilisant la valeur de 0 a 255 de la moyenne de la couleur du pixel donc => hauteur= (rouge+vert+bleu)/3
ça renvoi le niveau de gris , mais en fait une valeur entre 0 et 255 ...
cette valeur je la divise par 30 car sinon , il y a une trop grande difference entre un cube de 1 de haut et un autre de 255 ... ç'est la faute a la fonction Purebasic
qui gere le resize d'un cube (ScaleEntity() )

voila c'est tout :)
donc a chaque pixel , on creer un cube, on le colore avec la couleur du pixel
et on le resize en fonction de cette couleur .. ça creer ainsi une map pour pouvoir jouer dessus :)

on peut choisir n'importe qu'elle image , meme une image dessinant des reliefs en niveau de gris , on retrouvera le resultat en 3D :)

ps: je faisait deja ça en DarkBasic :) et celui-ci etait bien plus reactif que Ogre avec Purebasic :roll:
de plus DarkBasic avait une fonction Matrix qui permettait de faire un plan avec des points de relief :)
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: image to scene 3d

Message par Zorro »

une petite variante du code ci dessus
cette fois, je met tout les cubes a la meme hauteur
mais je ne selectionne que ceux qui sont plus grand que 10 ou inferieur a -10

ce qui a pour effet d'isoler le personnage d'une image, si celui-ci est entouré de blanc !
comme Crillin au debut de ce post

voici le resultat :

ps : j'ai ajouté la possibilité de prendre de l'altitude avec les touches Page up et page down ;)


ligne 67 commenté = pas de relief dans le personnage
Image

et voici le nouveau code :

Code : Tout sélectionner


;
; ------------------------------------------------------------
;
;   PureBasic -image to scene3d (2)
;
;  By Zorro
;
; ------------------------------------------------------------
;
UsePNGImageDecoder()
UseJPEGImageDecoder()

#PB_Material_SpecularColor = 1
#PB_Material_AmbientColor  = 2
IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
Define.f KeyX, KeyY, MouseX, MouseY
#CameraSpeed  = 1


enumeration
		#image 
		#Texture 
		#mesh
		#entity
		#material
EndEnumeration

Global compteur=0
If InitEngine3D()
		Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
		Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
		InitSprite()
		InitKeyboard()
		InitMouse()
		If Screen3DRequester()
				
				
				;  LoadTexture(#Texture, "soil_wall.jpg")
				CreateTexture(#texture,256,256)
				StartDrawing(TextureOutput(#Texture))
						box(0,0,256,256,rgb(255,255,255))
				StopDrawing()
				CreateMaterial(#material, TextureID(#Texture))
				
				imagePath.s= OpenFileRequester("ouvre image", "d:\", "*mp|*.jpg|*.png", 1 )
				If LoadImage(#image,imagePath.s)
						ResizeImage( #image,ImageWidth(#image)/10,ImageHeight(#image)/10)
				Else
						MessageRequester("erreur","l'image ne se charge pas ! ")
						End
				Endif
				CreateCube(#mesh, 1) ; creer un mesh defaut
				
				id_entity=CreateEntity(#pb_any, MeshID(#mesh), MaterialID(#material))
				SetEntityMaterial(id_entity, MaterialID(#material))
				ScaleEntity(id_entity, 1,  4,1) 
				StartDrawing(ImageOutput(#image))
						compteur=0
						For y=1 to ImageHeight(#image)-1
								For x=1 to ImageWidth(#image)-1
										coul= Point(x,y)
										coul_hauteur=255-(red(coul)+green(coul)+blue(coul))/3
										compteur=compteur+1
										If coul_hauteur>10 or coul_hauteur< -10
										CopyEntity(id_entity, compteur)                              
								;;;		ScaleEntity(compteur, 1,  coul_hauteur/100,1) ;<<<<<<<<<<<<< a activer pour avoir le relief dans l'image
										MoveEntity(compteur, X, 1, y )
										material=CreateMaterial(#Pb_any, TextureID(#Texture))
										SetEntityMaterial(id_entity, MaterialID(material))
										SetMaterialColor(material,#PB_Material_AmbientColor, coul)
										Endif
								Next x
						Next y                  
				StopDrawing()
				
				DisableMaterialLighting(#material, 1)
				SetMaterialColor(#material, #PB_Material_AmbientColor, RGB(100, 100, 100))
				SetMaterialColor(#material, #PB_Material_SpecularColor, RGB(255, 255, 255))
				
				CreateLight(0, RGB(0,0,255), 100.0, 0, 0)
				SetLightColor(0, #PB_Light_SpecularColor, RGB(255, 0, 0))
				CreateCamera(0, 0, 0, 100, 100)
				MoveCamera(0,  50, 40, 150)
				CameraBackColor(0, RGB(255, 255, 255))
				Repeat
						Screen3DEvents()
						If ExamineMouse()
								MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
								MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
						EndIf
						If ExamineKeyboard()
								If KeyboardPushed(#PB_Key_Left)
										KeyX = -#CameraSpeed
								ElseIf KeyboardPushed(#PB_Key_Right)
										KeyX = #CameraSpeed
								Else
										KeyX = 0
								EndIf
								If KeyboardPushed(#PB_Key_Up)
										KeyY = -#CameraSpeed
								ElseIf KeyboardPushed(#PB_Key_Down)
										KeyY = #CameraSpeed
								Else
										KeyY = 0
								EndIf
								If KeyboardPushed(#PB_Key_PageDown)
										KeyZ = -#CameraSpeed
								ElseIf KeyboardPushed(#PB_Key_PageUp)
										KeyZ = #CameraSpeed
								Else
										KeyZ = 0
								EndIf
						EndIf
						RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
						MoveCamera  (0, KeyX,KeyZ, KeyY)
						RenderWorld()
						Screen3DStats()
						FlipBuffers()
				Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
		EndIf
Else
		MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf
End


autre exemple : ligne 67 décommenté , = relief dans le personnage
Image
Dernière modification par Zorro le ven. 02/mars/2018 18:28, modifié 5 fois.
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
kernadec
Messages : 1594
Inscription : ven. 25/avr./2008 11:14

Re: image to scene 3d

Message par kernadec »

merci Zorro pour cette idée
Cordialement
Répondre