Histoire d'un Cube (Notions de base à la 3D)

Généralités sur la programmation 3D
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Histoire d'un Cube : Le cube suit un chemin.

Message par falsam »

Comment obliger une entité à suivre un chemin ? C'est ce que nous allons voir avec l'objet CreateSpline().

Ce chemin que nous allons mettre en oeuvre est matérialisé par un certain nombre de points de passage que nous allons créer avec AddSplinePoint().

On utilisera ComputeSpline() afin de connaitre la position (x,y,z) du point de déplacement sur ce chemin.

Il suffira de placer une entité sur les coordonnées de ce point.

Dans cet exemple de code, le cube devra suivre un chemin triangulaire.

Code : Tout sélectionner

; Naissance d'un cube : Le cube suit un chemin

EnableExplicit

Enumeration
  #Mainform
EndEnumeration

Define.l Event

Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered
Global Camera, Texture.i, Material.i, Mesh.i, Entity.i, N.f, StepX.f

;Path Finding
Global SPLine, Time.f, x.f, y.f, z.f, StepValue.f, TimeSinceLastFrame.f

InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

OpenWindow(#Mainform,0,0,1024,768, "Suivre un chemin", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Mainform),0,0,1024,768,0, 0, 0)

KeyboardMode(#PB_Keyboard_International)
  
;
;Lumiere et ombre
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), -1.8, 10, 5)
WorldShadows(#PB_Shadow_Additive)

;
;Une camera 
Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera, RGB(145, 182, 201))
MoveCamera(Camera, 0, 5 , 10, #PB_Absolute)
CameraLookAt(Camera, 0, 0, 0)

;
;Texture & Material
Texture = CreateTexture(#PB_Any,256,256)
StartDrawing(TextureOutput(Texture))
Box(0,0,256,256,RGB(0, 0, 0))
Box(1,1,252,252,RGB(255, 216, 0))
StopDrawing()
Material = CreateMaterial(#PB_Any, TextureID(Texture))

;
;Creation du sol
Mesh = CreatePlane(#PB_Any, 50, 50, 1, 1, 6, 6)
Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material))
CreateEntityBody(Entity, #PB_Entity_StaticBody, 0,0,1)

;
;Création du cube
Mesh = CreateCube(#PB_Any, 1) 
Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material), 0, 1, 0)  

;
;Création de l'objet chemin
spline = CreateSpline(#PB_Any)

; On indique des points de passages de du chemin (Ici on trace un triangle)
AddSplinePoint(spline,  0, 1,  0)   ;Premier point
AddSplinePoint(spline,  5, 1, -15)  ;Second point
AddSplinePoint(spline, -5, 1, -15)  ;Troisiéme point

;L'entité passera par ces points et reviendra au premier point
AddSplinePoint(spline,  0, 1,  0) ;Premier point

;Sa vitesse est déterminée par la valeur du pas (Valeur décimale)
StepValue = 2.00

;Nous voila dans la boucle evenementielle
Repeat
  Repeat
    Event  = WindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
  Until Event = 0
  
  ExamineKeyboard()
  
  If KeyboardPushed (#PB_Key_Escape)
    Break
  EndIf      
  
  ;Calcule la position du point de déplacement (offset) spécifié. 
  ComputeSpline(spline, time)
    
  ;Une fois que le point a été calculé, sa position est disponible 
  x = SplineX(spline)
  y = SplineY(spline)
  z = SplineZ(spline)
  
  ;L'entité regarde en direction de ces trois points 
  EntityLookAt(Entity, x, y, z, 1, 0, 0)     
  
  ;Et on le positionne sur ces coordonnées 
  MoveEntity(Entity, x, y, z, #PB_Absolute)
  
  ;Ou en est ton dans notre déplacement ? 
  time + StepValue * TimeSinceLastFrame / 30
  
  ;La valeur de décalage varie de 0.0 à 1.0 
  If time > 1 ;fin de la spline
    Time = 0 ;début de la spline
  EndIf  
  
  ;Quel est le temps écoulé depuis la dernière image en millisecondes. 
  TimeSinceLastFrame = RenderWorld() / 1000
  
  ; Affiche le rendu de la scène
  ClearScreen(RGB(0, 0, 0))
  FlipBuffers()  
  
ForEver
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
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Histoire d'un Cube : Le cube suit un chemin

Message par falsam »

Ce code est un peu différent du précédent. Le cube va suivre un chemin comportant des points de passage obligés matérialisés par des balises sphériques blanches. Le cube devra aussi passer une passerelle constituée de deux plans inclinés à 45°.

La position x,y et z du cube s'affichera en bas de l'écran ainsi que le nombre de tours effectué.

Pour ne plus voir les balises, vous pouvez commenter les instructions CreateMarker.

Code : Tout sélectionner

; Naissance d'un cube : Le cube suit un chemin (Affichage des coordonnées et du nombre de tours)

EnableExplicit

Enumeration
  #Mainform
EndEnumeration

Define.l Event

Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered
Global Camera, Texture.i, Material.i, Mesh.i, Entity.i, N.f, StepX.f

Global SPLine, Time.f, x.f, y.f, z.f, StepValue.f, TimeSinceLastFrame.f, Waypoint .i

Global Panel.i

Procedure CreateMarker (x.f, y.f, z.f)
  CreateEntity(#PB_Any, MeshID(CreateSphere(#PB_Any, 0.1)), #PB_Material_None, x, y, z)  
EndProcedure

InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

OpenWindow(#Mainform,0,0,1024,768, "Suivre un chemin", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Mainform),0,0,1024,768,0, 0, 0)

KeyboardMode(#PB_Keyboard_International)
  
;
;Lumiere et ombre
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), -1.8, 10, 5)
WorldShadows(#PB_Shadow_Modulative, 0, RGB(175, 175, 175))

;
;Une camera 
Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera, RGB(145, 182, 201))
MoveCamera(Camera, 0, 8 , 15, #PB_Absolute)
CameraLookAt(Camera, 0, 0, 0)

;
;Texture & Material
Texture = CreateTexture(#PB_Any,256,256)
StartDrawing(TextureOutput(Texture))
Box(0,0,256,256,RGB(0, 0, 0))
Box(1,1,252,252,RGB(255, 216, 0))
StopDrawing()
Material = CreateMaterial(#PB_Any, TextureID(Texture))
MaterialFilteringMode(Material, #PB_Material_Anisotropic, 6) ;Meilleurs rendu du materiel
;
;Creation du sol
Mesh = CreatePlane(#PB_Any, 50, 50, 1, 1, 6, 6)
Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material))
CreateEntityBody(Entity, #PB_Entity_StaticBody)

;
;Mise en place d'un obstacle à franchir ayant ce profil /¯¯\


;Premier profil /
Entity = CreateEntity(#PB_Any, MeshID(CreateCube(#PB_Any, 3)), MaterialID(Material), -2.5,1,0)
ScaleEntity(Entity, 1, 0.05, 1, #PB_Absolute) 
RotateEntity(Entity, 0, 0, 45)

;Deuxiéme profil ¯¯
Entity = CreateEntity(#PB_Any, MeshID(CreateCube(#PB_Any, 3)), MaterialID(Material), 0,2,0)
ScaleEntity(Entity, 1, 0.05, 1, #PB_Absolute) 

;Troisiéme profil \
Entity = CreateEntity(#PB_Any, MeshID(CreateCube(#PB_Any, 3)), MaterialID(Material), 2.5,1,0)
ScaleEntity(Entity, 1, 0.05, 1, #PB_Absolute) 
RotateEntity(Entity, 0, 0, -45)

;
;Création du cube qui va suivre un chemin passant par cet obstacle
Entity = CreateEntity(#PB_Any, MeshID(CreateCube(#PB_Any, 1)), MaterialID(Material))  



;
;Création de l'objet chemin
spline = CreateSpline(#PB_Any)

; On indique des points de passages du chemin 
; Les différentes coordonnées auraient pu être placé dans une liste ou un tableau

CreateMarker(-8, 0.6, -15) ;Balise coin haut gauche
AddSplinePoint(spline,  -8, 0.6, -15) 
CreateEntity(#PB_Any, MeshID(CreateCylinder(#PB_Any, 2, 1)), #PB_Material_None, -5, 0.5, -13)

CreateMarker(-8, 0.6, 0) ;Balise coin bas gauche
AddSplinePoint(spline, -8, 0.6, 0)
CreateEntity(#PB_Any, MeshID(CreateCylinder(#PB_Any, 2, 1)), #PB_Material_None, -5, 0.5, -3)

CreateMarker(-4, 0.7, 0) ;Balise entrée du premier plan à 45° ./
AddSplinePoint(spline, -4, 0.7, 0)

CreateMarker(-1.5, 2.7, 0) ;Balise bord gauche du plan horizontal °¯¯
AddSplinePoint(spline, -1.5, 2.7, 0)

CreateMarker(1.5, 2.7, 0) ;Balise bord droit du plan horizontal ¯¯°
AddSplinePoint(spline, 1.5, 2.7, 0)

CreateMarker(4, 0.7, 0) ;Balise sortie du deuxiéme plan à 45° \.
AddSplinePoint(spline,4, 0.7, 0)

CreateMarker(8, 0.7, 0) ;Balise coin bas droit
AddSplinePoint(spline, 8, 0.7, 0)
CreateEntity(#PB_Any, MeshID(CreateCylinder(#PB_Any, 2, 1)), #PB_Material_None, 5, 0.5, -3)

CreateMarker(8, 0.6, -15) ;Balise coin haut droit
AddSplinePoint(spline,  8, 0.6, -15) 
CreateEntity(#PB_Any, MeshID(CreateCylinder(#PB_Any, 2, 1)), #PB_Material_None, 5, 0.5, -13)


;L'entité passera par ces points et reviendra au premier point
AddSplinePoint(spline,  -8, 0.6, -15)  ;Premier point

;Sa vitesse est déterminée par la valeur du pas (Valeur décimale)
StepValue = 3.00

;Nous voila dans la boucle evenementielle
Repeat
  Repeat
    Event  = WindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
  Until Event = 0
  
  ExamineKeyboard()
  
  If KeyboardPushed (#PB_Key_Escape)
    Break
  EndIf      
  
  ;Calcule la position du point de déplacement (offset) spécifié. 
  ComputeSpline(spline, time)
    
  ;Une fois que le point a été calculé, sa position est disponible 
  x = SplineX(spline)
  y = SplineY(spline)
  z = SplineZ(spline)
  
  ;L'entité regarde en direction de ces trois points 
  EntityLookAt(Entity, x, y, z)
  
  ;Et on le positionne sur ces coordonnées 
  MoveEntity(Entity, x, y, z, #PB_Absolute)
  
  ;Ou en est ton dans notre déplacement ? 
  time + StepValue * TimeSinceLastFrame / 35
  
  ;Fin de la spline : On ajoute 1 au compteur de passage
  If time > 1
    Waypoint +1
    Time = 0 ;début de la spline
  EndIf  
  
  ;Quel est le temps écoulé depuis la dernière image en millisecondes. 
  TimeSinceLastFrame = RenderWorld() / 1000
  
  ; Affiche le rendu de la scène
  ClearScreen(RGB(0, 0, 0))
  RenderWorld(80)
  
  ; Affichage sur un sprite de la valeur de la composante alpha (transparence) de la couleur.
  Panel = CreateSprite(#PB_Any,1024,20)
  StartDrawing(SpriteOutput(Panel))
  Box(0, 0, 1024, 20, RGB(70, 130, 180))
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(5,2,"Position x:"+ StrF(x, 2) + " y: " + StrF(y, 2) + " z:" + StrF(z, 2))
  DrawText(300, 2, "Nombre de passage " + Str(Waypoint))
  DrawText(900, 2, " - Esc pour quitter")
  StopDrawing()  
  DisplaySprite(Panel, 0, 746)
  
  FlipBuffers()  
  
ForEver
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
venom
Messages : 3071
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par venom »

Excellents.
Bravo pour tous ces exemples. 8) Il continue sont petit bout de chemin ce cube :P





@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
SPH
Messages : 4722
Inscription : mer. 09/nov./2005 9:53

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par SPH »

Oui, bravo.

Mais j'ai une petite inquietude sur la 3D de PB : se limite t'elle a un cube ?

Quand je regarde tes (excellents) exemples, je me demande toujours comment je pourrais utiliser ca pour faire mon cube qui tourne dans la face d'un cube qui tourne lui meme dans la face d'un cube. Mais je ne trouve pas comment faire...
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
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par falsam »

SPH a écrit :Mais j'ai une petite inquietude sur la 3D de PB : se limite t'elle a un cube ?
Heureusement que non :)
SPH a écrit :je me demande toujours comment je pourrais utiliser ca pour faire mon cube qui tourne dans la face d'un cube qui tourne lui meme dans la face d'un cube. Mais je ne trouve pas comment faire...
Mince tu n'as pas vu ou mal compris mes exemples ..... a moins que mes explications ne soient pas compréhensibles :|

Un cube qui tourne dans la face d'un cube ? Juste sur une seule face ? :roll: Et le cube qui contient ce cube sur une de ses faces tourne sur lui même ? C'est bien ça hein ? :mrgreen: Tu ne me caches rien d'autre ? :)

Alors voila un code qui vient du chapitre sur les nodes : Un cube tournant sur lui même. Sur quatre de ses faces, un cube est fixé et tourne aussi sur lui même.

Code : Tout sélectionner

;Histoire d'un cube : Les nodes

Define.f X,Z

InitEngine3D()
InitKeyboard()
InitSprite()

window = OpenWindow(#PB_Any,0,0,1024,768,"Les nodes")
OpenWindowedScreen(WindowID(window),0,0,1024,768)

; Mesh
Cube_Mesh = CreateCube(#PB_Any, 1) 
Ground_Mesh = CreatePlane(#PB_Any, 20, 20, 3, 6, 6, 6)

; Materiel
Texture1 = CreateTexture(#PB_Any,512,512)
StartDrawing(TextureOutput(Texture1))
Box(0,0,512,512,RGB(0, 0, 0))
Box(1,1,510,510,RGB(255, 216, 0))
StopDrawing()
Material1 = CreateMaterial(#PB_Any,TextureID(texture1))

; Création du sol 
Ground_Entity = CreateEntity(#PB_Any, MeshID(Ground_Mesh), MaterialID(Material1), 0, 0, 0)
CreateEntityBody(Ground_Entity, #PB_Entity_StaticBody, 2, 0, 1)

;
; Lumiere et ombre
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), -1.8, 10, 5)
WorldShadows(#PB_Shadow_Additive)

;
; Création d'un node sur lequel seront attaché les entités.
; Le cube 0 sera au meme emplacement que le node.
Node = CreateNode(#PB_Any, 0, 0, 0) 

Cube0 = CreateEntity(#PB_Any, MeshID(Cube_Mesh), MaterialID(Material1), 0, 2, 0)
ScaleEntity(Cube0, 4, 4, 4)
AttachNodeObject(Node, EntityID(Cube0))

Cube1 = CreateEntity(#PB_Any, MeshID(Cube_Mesh), MaterialID(Material1), 2, 2, 0)
AttachNodeObject(Node, EntityID(Cube1))

Cube2 = CreateEntity(#PB_Any, MeshID(Cube_Mesh), MaterialID(Material1), -2, 2, 0)
AttachNodeObject(Node, EntityID(Cube2))

Cube3 = CreateEntity(#PB_Any, MeshID(Cube_Mesh), MaterialID(Material1), 0, 2, 2)
AttachNodeObject(Node, EntityID(Cube3))

Cube4 = CreateEntity(#PB_Any, MeshID(Cube_Mesh), MaterialID(Material1), 0, 2, -2)
AttachNodeObject(Node, EntityID(Cube4))


;
; Une camera 
Camera = CreateCamera(#PB_Any,0,0,100,100)

While #True
  
  Event = WindowEvent()
    
  If ExamineKeyboard()    
    If Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
      Break
    EndIf      
    
    If KeyboardPushed(#PB_Key_Left)
      X-0.1
    ElseIf KeyboardPushed(#PB_Key_Right)
      X+0.1
    EndIf
    
    If KeyboardPushed(#PB_Key_Up)
      Z-0.1
    ElseIf KeyboardPushed(#PB_Key_Down)
      Z+0.1
    EndIf
      
  EndIf
  
  ; Rotation du node et non plus de l'entité
  RotateNode(Node, 0, 1, 0, #PB_Relative)  
    
  ; Rotation de chacun des cubes
  ; Les deux premiers cubes étaient placés sur l'axe X
  ; Les deux suivant sur l'axe Z
  RotateEntity(cube1, -0.5, 0, 0, #PB_Relative)
  RotateEntity(cube2, 0.5, 0, 0, #PB_Relative)
  
  RotateEntity(cube3, 0, 0, -0.5, #PB_Relative)
  RotateEntity(cube4, 0, 0, 0.5, #PB_Relative)
  
  MoveCamera(Camera, 4, 4 , 15, #PB_Absolute)
  CameraLookAt(camera,0,0,0)
  
  MoveNode(Node, x, 0, z, #PB_Absolute)
    
  ; Affiche le rendu de la scène
  ClearScreen(RGB(0, 0, 0))
  RenderWorld()
  FlipBuffers()
Wend
A toi de modifier ce code pour qu'il ne reste qu'un seul cube tournant sur une des face du gros cube tournant sur lui même :)
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
SPH
Messages : 4722
Inscription : mer. 09/nov./2005 9:53

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par SPH »

Ce n'est pas comme cela que je l'imaginais. Moi je pense a un gros cube avec une couleur par face (et tournant sur ses 3 axes) et qui aurait sur chaque face un cube coloré tournant sur ses 3 axes. Et dans ces cubes il y aurait aussi d'autres cubes tournoyant
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
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par falsam »

SPH a écrit :Ce n'est pas comme cela que je l'imaginais. Moi je pense a un gros cube avec une couleur par face (et tournant sur ses 3 axes) et qui aurait sur chaque face un cube coloré tournant sur ses 3 axes. Et dans ces cubes il y aurait aussi d'autres cubes tournoyant
Je savais que tu ne disais pas tout :mrgreen:

Voila un sujet interessant. Ce thread étant plutôt dédié à un débroussaillage de la 3D avec Pure basic, pourrais tu ouvrir un nouveau sujet. je ne manquerais pas de t'aider. Merci SPH :)
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
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Histoire d'un Cube (Notions de base à la 3D) : Affichage du

Message par falsam »

■ Vous pouvez afficher le nombre d'images par seconde en utilisant la fonction Engine3DFrameRate() associé au flag #PB_Engine3D_Current

Exemple : Result = Engine3DFrameRate(#PB_Engine3D_Current)

■ Depuis la version 5.30 de Pure Basic, cette fonction est devenu obsolète, elle est remplacée par la fonction Engine3DStatus() associé au paramétre #PB_Engine3D_CurrentFPS

Exemple Result = Engine3DStatus(#PB_Engine3D_CurrentFPS)

■ On peut aussi connaitre le FPS Minimum, maximum et la moyenne avec respectivement les paramètres #PB_Engine3D_MinimumFPS, #PB_Engine3D_MaximumFPS et #PB_Engine3D_AverageFPS

Code : Tout sélectionner

;Naissance d'un cube : Afficher le FPS (Courant, minimum et maximum)

; Coordonnées x,y,z du Cube Avatar
Define.f X, Y, Z

InitEngine3D()
InitKeyboard()
InitSprite()

window = OpenWindow(#PB_Any,0,0,1024,768,"Histoire d'un cube : Afficher FPS")
OpenWindowedScreen(WindowID(window),0,0,1024,768)

;
;Camera 
Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera, RGB(131, 204, 249))
MoveCamera(Camera, 2, 1 , 15, #PB_Absolute)
CameraLookAt(Camera, 0, 0, 0)

;
;Lumiere et ombre
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), -1.8, 10, 5)
WorldShadows(#PB_Shadow_Additive)

; 
;Texture qui servira pour le sol et les cubes
Texture = CreateTexture(#PB_Any,512,512)
StartDrawing(TextureOutput(Texture))
Box(0,0,512,512,RGB(0, 0, 0))
Box(1,1,510,510,RGB(255, 216, 0))
StopDrawing()

;
;Materiel qui servira pour le sol et les cubes
Material = CreateMaterial(#PB_Any,TextureID(texture))

;
; Création du sol 
Mesh = CreatePlane(#PB_Any, 20, 20, 3, 6, 6, 6)
Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material), 0, -2, 0)
CreateEntityBody(Entity, #PB_Entity_StaticBody, 2, 0, 1)

;
;Chute des cubes
Mesh = CreateCube(#PB_Any, 1) 

For N=1 To 1000
  Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material), Random(5), Random(1000, 10), Random(5))
  CreateEntityBody(Entity, #PB_Entity_BoxBody, 0.5,0.1,1)
Next


While #True
  Event = WindowEvent()
  
  EntityMove=#False
  
  If ExamineKeyboard()  
  
    ; Touche Escape pour fermer l'application
    If Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
      Break
    EndIf      
  EndIf 
  
  ; Affiche le rendu de la scène
  ClearScreen(RGB(0, 0, 0))
  RenderWorld()
  
  ;-Affichage du FPS + FPS Minimum + FPS maximum
  PanelScore = CreateSprite(#PB_Any,1024,20)
  StartDrawing(SpriteOutput(PanelScore))
  Box(0,0,1024,20, RGBA(178, 34, 34, 255))
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(5,2,"FPS: "+ Str(Engine3DStatus(#PB_Engine3D_CurrentFPS)) +
               "  Min: " + Str(Engine3DStatus(#PB_Engine3D_MinimumFPS)) + 
               "  Max: " + Str(Engine3DStatus(#PB_Engine3D_MaximumFPS)))
  StopDrawing()  
  DisplaySprite(PanelScore, 0, 0)

    FlipBuffers()
Wend
:idea: Retour au sommaire
Dernière modification par falsam le dim. 01/juin/2014 10:43, modifié 2 fois.
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%
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Histoire d'un Cube (Notions de base à la 3D) : Affichage

Message par comtois »

falsam a écrit :Depuis la version 5.30 de Pure Basic il est possible d'afficher le nombre d'images par seconde sur un écran grâce à la fonction Engine3DStatus() associé au paramétre #PB_Engine3D_CurrentFPS

On peut aussi connaitre le FPS Minimum, maximum et la moyenne avec respectivement les paramètres #PB_Engine3D_MinimumFPS, #PB_Engine3D_MaximumFPS et #PB_Engine3D_AverageFPS
ça existait déjà dans les versions précédentes :)
http://www.purebasic.com/documentation/ ... erate.html

la nouveauté c'est qu'on peut obtenir le nombre de batches avec #PB_Engine3D_NbRenderedBatches
Batching

You may be using too many individual objects/submeshes. Graphics cards (GPU) like to have rendering queued into a relatively small number of large batches to operate at peak efficiency. If you use lots of small movable objects, especially if they are composed of multiple submeshes (each of which is its own render operation), the GPU underperforms because too much time is being spent in the overhead of setting up the individual rendering operations. This enqueueing process is done in the driver, which is constrained by the speed of the CPU, not the GPU. This presentation(external link) explains that 25000 batches per second will saturate (completely, on its own) a 1Ghz CPU. That means to maintain 60 FPS on a 1Ghz CPU you cannot issue more than about 416 batches per frame, where a batch is one instance of a submesh (for example). Of course, other factors may limit your performance earlier. You can improve batching by grouping static objects together in a StaticGeometry object, or by reducing the number of submeshes you use per mesh (do you really need that many different materials per mesh?).
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par falsam »

Pour être honnête, je n'avais pas vu cette fonction Engine3DFrameRate() (Hou le nul que je suis :oops:)

l'information reste quand même bonne puisque Engine3DFrameRate() est devenu obsolète avec la version 5.30. Je modifie mon message. Merci Comtois :)
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
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par falsam »

Mise à jour du sommaire de ce topic : Créer une SEULE entité avec un ensemble de meshs.
:arrow: A voir sur ce lien http://www.purebasic.fr/french/viewtopi ... 13&t=14996
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
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par microdevweb »

Très très bon tuto. Je pensait déjà me mettre à la 3D (j'étudie blender dans ce hypothèse) mais ton tuto ma vraiment mis l'eau à la bouche.

Un grand merci Falsam
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par falsam »

Bonjour microdevweb. La 3D avec Pure Basic est simple et il n'y a aucune raison de ne pas se faire plaisir en essayant.
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
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Le Culling

Message par falsam »

Il y a longtemps je me suis demandé comment rendre un cube semi transparent et j'ai posté ce code
:arrow: http://www.purebasic.fr/french/viewtopi ... 52#p157052

■ La problématique était que je ne voyais pas les faces intérieur du cube en question.

En cherchant j'ai découvert un mot : Culling (Pas Curling ou C... )

■ Petite définition (Je ne sais pas si c'est la bonne définition mais ça y ressemble)
Le Culling en imagerie 3D consiste à éliminer prématurément des parties de la scène qui ne seront pas visibles à l'écran, soit parce qu'elle sont cachées par d'autres objets ou tout simplement parce que ces objets ne sont pas dans le champ de vision.


Pure Basic permet de ne pas appliquer cette notion de Culling sur le material.
:idea: MaterialCullingMode(#Material, #PB_Material_NoCulling)

Hummm ça devient intéressant.

Après pas mal de recherche sur les différents forums Anglais et Allemand inclus, j'ai compris qu'il fallait préparer le matériel avant d'appliquer cette fonctionnalité.

■ Le code qui suit va afficher un cube en rotation avec à l'intérieur une sphere. On appliquera un peu de Physics

Code : Tout sélectionner

Enumeration Window
  #Mainform
EndEnumeration

Enumeration Entities
  #Cube
  #Sphere
EndEnumeration

Enumeration Material
  #Damier
EndEnumeration

Global Event

InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

;Pour cette démonstration, je me servirais des textures du dossier exemples
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)

OpenWindow(#Mainform, 0, 0, 800, 600, "Le culling", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Mainform),0,0,800,600)

;Lumiere et ombre
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), 0, 0, 100)
WorldShadows(#PB_Shadow_Additive)

;Camera 
Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera, RGB(145, 182, 201))

MoveCamera(Camera, 2, 5, 15)  
CameraLookAt(Camera, 0,0,0)   

;Création du materiel
CreateMaterial(#Damier, TextureID(LoadTexture(#PB_Any, "MRAMOR6X6.jpg"))) 

;On va utiliser le canal alpha de la texture (Celle qui gére la transparence)
MaterialBlendingMode(#Damier, #PB_Material_AlphaBlend)

;On va modifier la couleur de la matière avec une opacité moyenne de 100 
SetMaterialColor(#Damier, #PB_Material_DiffuseColor, RGBA(255, 255, 255, 100))

;Et enfin on va rendre visible les faces cachées
MaterialCullingMode(#Damier, #PB_Material_NoCulling)

;Création d'un cube
CreateEntity(#Cube, MeshID(CreateCube(#PB_Any, 8)), MaterialID(#Damier))
CreateEntityBody(#Cube, #PB_Entity_StaticBody, 1, 1, 1)

;Une balle à l'intérieur du cube 
CreateEntity(#Sphere, MeshID(CreateSphere(#PB_Any, 1)), #PB_Material_None)
CreateEntityBody(#Sphere, #PB_Entity_SphereBody, 1, 1, 0.1)

Repeat
  Repeat
    Event  = WindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
  Until Event = 0
  
  If ExamineKeyboard()
    
    If KeyboardPushed (#PB_Key_Escape)
      Break
    EndIf
  EndIf
  
  RotateEntity(#Cube, 0.5, 0.5, 0.5, #PB_Relative) 
  
  ; Affiche le rendu de la scéne
  RenderWorld(80)
  FlipBuffers()  
ForEver
Je rappelle que je suis néophyte en 3D et qu'il ne faut pas hésiter à me corriger.
Dernière modification par falsam le mer. 17/déc./2014 23:00, modifié 1 fois.
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%
klystron
Messages : 149
Inscription : mar. 02/déc./2014 12:16

Re: Histoire d'un Cube (Notions de base à la 3D)

Message par klystron »

jolies tout ça ... :D

les fichiers compilés ne fonctionnent pas ,pourquoi ?
bonne soirée.

une question , dans le code ou les cubes tombent , à la fin les cubes qui restent sont ils toujours au meme endroit une fois tombés ?.
Répondre