La Terre est ronde

Programmation avancée de jeux en PureBasic
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

La Terre est ronde

Message par Le Soldat Inconnu »

Salut,

Un petit trip : à partir d'un planisphère (donc d'une image plate), j'ai dessiné la terre en 3d.

Voilà le code, il faut ma lib "Effect"
http://www.lsi-dev.com/index.php?mod=ar ... ires&id=70

Je conseille d'avoir une bonne machine, sinon, il faut éditer le fichier "carte.ini" créer et diminuer le diamètre de la planète.

Le programme ne suffit pas seul, vous trouverez tous les fichiers ici : (le programme compilé et le code avec les fichier images)
http://perso.wanadoo.fr/lesoldatinconnu/bazar.htm

Code : Tout sélectionner

;- Ecran
ExamineDesktops()
Global Ecran_Hauteur, Ecran_Largeur, Ecran_Centre_X, Ecran_Centre_Y, Ecran_Synchronisation
Ecran_Largeur = DesktopWidth(0)
Ecran_Hauteur = DesktopHeight(0)
Ecran_Centre_X = Ecran_Largeur / 2
Ecran_Centre_Y = Ecran_Hauteur / 2
Ecran_Synchronisation = 1

;- Planète
UsePNGImageDecoder()

DataSection
  Carte : IncludeBinary "Carte.png"
EndDataSection
CatchImage(0, ?Carte)
; LoadImage(0, "Carte.png")

Global Image_Hauteur, Image_Largeur
Image_Largeur = ImageWidth() - 1
Image_Hauteur = ImageHeight() - 1
Dim Carte_Bord.l(Image_Hauteur)
Dim Carte_Largeur.l(Image_Hauteur)
Dim Carte(Image_Largeur, Image_Hauteur)
GetImageBits(ImageID(), @Carte())
; On recherche le bord de la carte
; Le noir représente du vide
For y = 0 To Image_Hauteur
  Bord = -1
  Repeat
    Bord + 1
    Couleur = Carte(Bord, y)
  Until Couleur <> 0
  Bord + 2
  Carte_Bord(y) = Bord
  Carte_Largeur(y) = Image_Largeur - 2 * Bord + 1
Next

;- Paramètres dimensionnels de la planète
Global Planete_Rayon.f, Planete_Rotation.f 
Planete_Rayon = 175
Planete_Rotation = 0.002

;- Autres parametres
#Pi = 3.14159265
#Pi_Inv = 1 / #Pi
#ASin_Definition = 2000
Dim ASin_Valeur.f(#ASin_Definition * 2)

Procedure Parametres()
  
  If FileSize("Carte.ini") = -1
    If CreatePreferences("Carte.ini")
      PreferenceComment("LSI Développements - www.lsi-dev.com")
      WritePreferenceLong("Synchronisation", 1)
      WritePreferenceLong("Rayon", 175)
      WritePreferenceLong("Vitesse", 20)
      ClosePreferences()
    EndIf
  EndIf

  OpenPreferences("Carte.ini")
  Ecran_Synchronisation = ReadPreferenceLong("Synchronisation", 1)
  Planete_Rayon = ReadPreferenceLong("Rayon", 175)
  Planete_Rotation = ReadPreferenceLong("Vitesse", 20)
  Planete_Rotation / 10000
  ClosePreferences()
  
EndProcedure

Procedure Calcul_Preliminaire()
  
  For n = -#ASin_Definition To #ASin_Definition
    ASin_Valeur(n + #ASin_Definition) = ASin(n / #ASin_Definition)
  Next
  
EndProcedure

Procedure Planete(x, y, Rayon, Longitude_Depart.f)
  StartDrawing(ScreenOutput())
    
    Rayon2 = Rayon * Rayon
    
    For nn = -Rayon To Rayon
      
      nn2 = nn * nn
      
      ; Rayon de la coupe horizontale de la planète à la distance nn de l'équateur
      Rayon_H.f = Sqr(Rayon2 - nn2)
      
      ; Calcul de la latitude (variant de 0 à 1 équivalent de -90° à +90°)
      Temp = nn * #ASin_Definition / Rayon + #ASin_Definition
      Latitude.f = ASin_Valeur(Temp) * #Pi_Inv
      PosY = Image_Hauteur * (Latitude + 0.5)
      
      For n = -Rayon To Rayon
        
        If Abs(n) < Rayon_H
          
          ; Calcul de la longitude (variant de 0 à 1 équivalent de -90° à +90°)
          If Rayon_H = 0
            Longitude.f = 0
          Else
            Temp = n * #ASin_Definition / Rayon_H + #ASin_Definition
            Longitude.f = ASin_Valeur(Temp) * #Pi_Inv
          EndIf
          
          ; Ajustement de la longitude en fonction du point de départ
          Longitude + Longitude_Depart
          If Longitude > 1
            Longitude - 2
          ElseIf Longitude < -1
            Longitude + 2
          EndIf
          
          PosX = Carte_Bord(PosY) + Carte_Largeur(PosY) * (Longitude * 0.5 + 0.5)
          
          ; Effet de lumiere
          Lumiere_Distance.f = Sqr(n * n + nn2)
          Temp = Lumiere_Distance * #ASin_Definition / Rayon + #ASin_Definition
          Lumiere.f = ASin_Valeur(Temp) * #Pi_Inv * 2
          Lumiere * Lumiere
           
          xx = x + n
          yy = y + nn
          If xx >= 0 And xx < Ecran_Largeur And yy >= 0 And yy < Ecran_Hauteur
            Plot(xx, yy, ColorLuminosity(Carte(PosX, PosY), 1 - Lumiere))
          EndIf
        EndIf
        
      Next
    Next
  StopDrawing()
EndProcedure


; On ouvre l'openscreen
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 7 ou supérieur.", 0)
  End
EndIf

If OpenScreen(Ecran_Largeur, Ecran_Hauteur, 32, "Carte") = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
  End
EndIf

Parametres()
Calcul_Preliminaire()

Repeat
  ClearScreen(0, 0, 0)
  
  ; On lit les évènements clavier et souris
  ExamineMouse()
  ExamineKeyboard()
  
  Longitude.f + Planete_Rotation
  If Longitude >= 2
    Longitude = 0
  EndIf
  Planete(Ecran_Centre_X, Ecran_Centre_Y, Planete_Rayon, Longitude)
  
  If KeyboardReleased(#PB_Key_F1)
    Deboguage = Deboguage ! 1
  EndIf
  If Deboguage
    StartDrawing(ScreenOutput())
      
      BackColor(0, 0, 0)
      FrontColor(255, 255, 255)
      
      ; Calcul du FPS
      Cpt + 1
      If Cpt >= FPS.f
        FPS = Cpt * 1000 / (ElapsedMilliseconds() - Temps)
        Cpt = 0
        Temps = ElapsedMilliseconds()
      EndIf
      
      Locate(5, 5)
      DrawText("FPS = " + StrF(FPS, 1))
      Locate(5, 25)
      DrawText("Longitude = " + StrF(Longitude * 180, 1) + "°")
      Locate(5, 25)
      DrawText("Longitude = " + StrF(Longitude * 180, 1) + "°")
      Locate(5, 45)
      DrawText("Rayon = " + StrF(Planete_Rayon, 0))
      Locate(5, 65)
      DrawText("Vitesse = " + StrF(Planete_Rotation, 4))
      
    StopDrawing()
  EndIf
  
  FlipBuffers(Ecran_Synchronisation)
  
Until KeyboardPushed(#PB_Key_Escape)
Bon amusement
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Simpa ton prog... 8)
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Répondre