[4.60] HuitBit & TerrainMesh

Généralités sur la programmation 3D
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

[4.60] HuitBit & TerrainMesh

Message par G-Rom »

Le code de huitbit a la sauce 3D :

Code : Tout sélectionner

;-@@@@@@@@@@@@@@@
;-Bruit de Perlin & Subdivisions
;Auteur Huitbit
;Grosse contribution G-Rom
;Avril 2011
;PureBasic 4.51 (Windows  -  x86)
;-@@@@@@@@@@@@@@@

;gradient de teintes multicolores quelconques
;{
Enumeration
  #EauxProfondes
  #EauxPeuProfondes
  #Sable
  #Herbe
  #Foret
  #BasseMontagne
  #HauteMontagne
  #Neige
EndEnumeration
;-index des teintes
IndexMaxDesTeintes.l=2550
#IndexRelatifEauxProfondes=0
#IndexRelatifEauxPeuProfondes=0.42
#IndexRelatifSable=0.44
#IndexRelatifHerbe=0.45
#IndexRelatifForet=0.54
#IndexRelatifBasseMontagne=0.65
#IndexRelatifHauteMontagne=0.70
#IndexRelatifNeige=1

Global x.l
Structure Teinte
  Rouge.c
  Vert.c
  Bleu.c
  Index.l
EndStructure

Macro TeinteDeReference(TypeDeTerrain,r,v,b,id);id valeur comprise entre 0 et 1 (0% et 100%)
Teinte(TypeDeTerrain)\Rouge=r
Teinte(TypeDeTerrain)\Vert=v
Teinte(TypeDeTerrain)\Bleu=b
Teinte(TypeDeTerrain)\Index = id*IndexMaxDesTeintes
EndMacro

Macro  Composante(comp)
ValeurComposanteTeinte(x,Teinte(TypeDeTerrain)\Index ,Teinte(TypeDeTerrain)\comp,Teinte(TypeDeTerrain+1)\Index ,Teinte(TypeDeTerrain+1)\comp)
EndMacro

Procedure.f ValeurComposanteTeinte(x.l,xA.f,Ya.f,xB.f,YB.f)
  ProcedureReturn yA + (yB - yA)/(xB - xA) * (x - xA)
EndProcedure

Global Dim Teinte.Teinte(IndexMaxDesTeintes)
Dim couleur.l(2550)
TeinteDeReference(#EauxProfondes,0,0,32,#IndexRelatifEauxProfondes)
TeinteDeReference(#EauxPeuProfondes,0,128,192,#IndexRelatifEauxPeuProfondes)
TeinteDeReference(#Sable,224,224,128,#IndexRelatifSable)
TeinteDeReference(#Herbe,0,192,0,#IndexRelatifHerbe)
TeinteDeReference(#Foret,0,92,0,#IndexRelatifForet)
TeinteDeReference(#BasseMontagne,120,120,68,#IndexRelatifBasseMontagne)
TeinteDeReference(#HauteMontagne,200, 193, 178,#IndexRelatifHauteMontagne)
TeinteDeReference(#Neige,255,255,255,#IndexRelatifNeige)


For x=0 To IndexMaxDesTeintes

  Select x
    Case Teinte(#EauxProfondes)\Index
      TypeDeTerrain=#EauxProfondes
    Case Teinte(#EauxPeuProfondes)\Index
      TypeDeTerrain=#EauxPeuProfondes
    Case Teinte(#Sable)\Index
      TypeDeTerrain=#Sable
    Case Teinte(#Herbe)\Index
      TypeDeTerrain=#Herbe
    Case Teinte(#Foret)\Index
      TypeDeTerrain=#Foret
    Case Teinte(#BasseMontagne)\Index
      TypeDeTerrain=#BasseMontagne
    Case Teinte(#HauteMontagne)\Index
      TypeDeTerrain=#HauteMontagne
  EndSelect

  couleur(x)=RGB(Composante(Rouge),Composante(Vert),Composante(Bleu))
Next x
;}

;-Déclarations
Structure VECTOR3
  x.f :  y.f : z.f
EndStructure
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro SetVector3(V,_x,_y,_z)
V\x=_x
V\y=_y
V\z=_z
EndMacro
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro VectorLength(V)
(V\x*V\x + V\y*V\y + V\z*V\z)
EndMacro
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro Normalize(V)
l.f = VectorLength(V)
If (l <> 0)
  l =  Sqr(l)
  V\x / l
  V\y / l
  V\z / l
EndIf
EndMacro
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro DotProduct(A,B)
A\X * B\X + A\Y * B\Y + A\Z * B\Z
EndMacro
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro CrossProduct(A,B,C)
C\x = (A\y * B\z) - (A\z * B\y)
C\y = (A\z * B\x) - (A\x * B\z)
C\z = (A\x * B\y) - (A\y * B\x)
EndMacro           
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Procedure.d Min(a.d,b.d)
  If a<b
    ProcedureReturn a
  Else
    ProcedureReturn b
  EndIf
EndProcedure
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Procedure.d Max(a.d,b.d)
  If a>b
    ProcedureReturn a
  Else
    ProcedureReturn b
  EndIf
EndProcedure
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------------------------------------
;-SOBEL FILTER DEF
; ----------------------------------------------------------------------------------------------------------------
Global *SobelX.b = AllocateMemory(9)
Global *SobelY.b = AllocateMemory(9)

PokeB(*SobelX  ,-1) : PokeB(*SobelX+1,-2) : PokeB(*SobelX+2,-1)
PokeB(*SobelX+3, 0) : PokeB(*SobelX+4, 0) : PokeB(*SobelX+5, 0)
PokeB(*SobelX+6, 1) : PokeB(*SobelX+7, 2) : PokeB(*SobelX+8, 1)

PokeB(*SobelY  ,-1) : PokeB(*SobelY+1, 0) : PokeB(*SobelY+2, 1)
PokeB(*SobelY+3,-2) : PokeB(*SobelY+4, 0) : PokeB(*SobelY+5, 2)
PokeB(*SobelY+6,-1) : PokeB(*SobelY+7, 0) : PokeB(*SobelY+8, 1)

; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Procedure.i PutImageOnBuffer(ImageID)
  *Memory.i = AllocateMemory(  ImageWidth(ImageID) * ImageHeight(ImageID) * 4 )
  StartDrawing(ImageOutput(ImageID))
  For x = 0 To ImageWidth(ImageID)-1
    For y = 0 To ImageHeight(ImageID)-1
      Color = Point(x,y)
      r=Red(Color)
      g=Green(Color)
      b=Blue(Color)
      gray = (r+b+g) / 3
      Color = RGB(gray,gray,gray)
      PokeI(*Memory + (x*4) +  ImageWidth(ImageID) * (y*4),Color)
    Next
  Next
  StopDrawing()
  ProcedureReturn *Memory
EndProcedure
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro GetPixelBuffer(Memory,w,x,y)
PeekI(Memory + (x*4) + w * (y*4))
EndMacro
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro PutPixelBuffer(Memory,w,x,y,pixel)
PokeI(Memory + (x*4) + w * (y*4),pixel)
EndMacro
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro CharToByte(Char)
Char/255.0
EndMacro
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Macro ByteToChar(Byte)
Byte*255
EndMacro
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Procedure.i GetGrayLevel(*Buffer,w,x,y)
  Color = PeekI(*Buffer + (x*4) + w * (y*4))
  Red     = Color >> 0  & $000000FF
  Green   = Color >> 8  & $000000FF
  Blue    = Color >> 16 & $000000FF
  Gray = (Red+Green+Blue)/3
  ProcedureReturn Gray
EndProcedure
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Procedure.i Conv3x3(*Buffer.i,w.i,h.i,*Sobel.i,Threshold)
  *Gradient.i = AllocateMemory(w*h*4)
  If *Gradient
    For y = 1 To w-2
      For x = 1 To h-2
        Gradient_Value.f = (CharToByte(GetGrayLevel(*Buffer,w,x-1,y-1) * PeekB(*Sobel  ))) +  (CharToByte(GetGrayLevel(*Buffer,w,x  ,y-1) * PeekB(*Sobel+1))) +  (CharToByte(GetGrayLevel(*Buffer,w,x+1,y-1) * PeekB(*Sobel+2))) +  (CharToByte(GetGrayLevel(*Buffer,w,x-1,y  ) * PeekB(*Sobel+3))) +  (CharToByte(GetGrayLevel(*Buffer,w,x  ,y  ) * PeekB(*Sobel+4))) +  (CharToByte(GetGrayLevel(*Buffer,w,x+1,y  ) * PeekB(*Sobel+5))) +  (CharToByte(GetGrayLevel(*Buffer,w,x-1,y+1) * PeekB(*Sobel+6))) +  (CharToByte(GetGrayLevel(*Buffer,w,x  ,y+1) * PeekB(*Sobel+7))) +  (CharToByte(GetGrayLevel(*Buffer,w,x+1,y+1) * PeekB(*Sobel+8)))
        PokeF(*Gradient + (x*4) + w * (y*4),Gradient_Value*Threshold)
      Next
    Next
  EndIf
  ProcedureReturn *Gradient
EndProcedure
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Procedure Map0_to_255(*V.VECTOR3)
  *V\x = max(-256,*V\x)
  *V\y = max(-256,*V\y)
  *V\z = max(-256,*V\z)
  *V\x = min(256,*V\x)
  *V\y = min(256,*V\y)
  *V\z = min(256,*V\z)
  *V\x =*V\x/2 + 127
  *V\y =*V\y/2 + 127
  *V\z =*V\z/2 + 127
EndProcedure
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------
Procedure.i CreateNormalMapFromImageID(ImageID,Threshold=5)
  Protected *Buffer.i,*GradientX.i,*GradientY.i,NewImage.i

  *Buffer     = PutImageOnBuffer(ImageID)
  *GradientX  = Conv3x3(*Buffer,ImageWidth(ImageID),ImageHeight(ImageID),*SobelX,Threshold)
  *GradientY  = Conv3x3(*Buffer,ImageWidth(ImageID),ImageHeight(ImageID),*SobelY,Threshold)


  NewImage = CreateImage(#PB_Any,ImageWidth(ImageID),ImageHeight(ImageID))
  StartDrawing(ImageOutput(NewImage))
  For y = 0 To ImageHeight(NewImage)-1
    For x = 0 To ImageWidth(NewImage)-1
     
      V.VECTOR3
      GrdX.f = PeekF(*GradientX + (x*4) + ImageWidth(ImageID) * (y*4))
      GrdY.f = PeekF(*GradientY + (x*4) + ImageWidth(ImageID) * (y*4))
      SetVector3(V,GrdX,GrdY,0.1)
      Normalize(V)
     
      Color.VECTOR3
      SetVector3(Color,ByteToChar(V\x),ByteToChar(V\y),ByteToChar(V\z))
      Map0_to_255(Color)
      Plot(x,y,RGB(Color\x,Color\y,Color\z))
     
    Next
  Next   
  StopDrawing()


  ProcedureReturn NewImage
EndProcedure
; ----------------------------------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------------------------------

#PasInitial =128
#NbreInitialDePicsHorizontaux =6
#NbreInitialDePicsVerticaux =6
#OctaveMax = 5; de l'octave n°1 à #OctaveMax
#Persistance = 0.55
Octave.b
Persistance.f
FacteurNormalisation.f =(1 - Pow(#Persistance,#OctaveMax)) / (1 - #Persistance)
Composante.w
Pas.l
NbreDePicsHorizontaux.l
NbreDePicsVerticaux.l
NbreMaxDePicsHorizontaux.l = #NbreInitialDePicsHorizontaux * Pow(2 , #OctaveMax - 1)
NbreMaxDePicsVerticaux.l = #NbreInitialDePicsVerticaux * Pow(2 , #OctaveMax - 1)
PasMinimal.l = #PasInitial / Pow(2 , #OctaveMax - 1)
Global LargeurEcran.l = NbreMaxDePicsHorizontaux  * PasMinimal
Global HauteurEcran.l = NbreMaxDePicsVerticaux  * PasMinimal
#NbreDeSubdivisions = 3
RapportSubdv.f = 0.25
IndiceMaxDesPtsDeCtrlHorizontaux.l = (NbreMaxDePicsHorizontaux - 2) * Pow(2,#NbreDeSubdivisions) +1
IndiceMaxDesPtsDeCtrlVerticaux.l = (NbreMaxDePicsVerticaux - 2) * Pow(2,#NbreDeSubdivisions) + 1
IndiceDesPtsDeCtrlHorizontaux.l
IndiceDesPtsDeCtrlVerticaux.l

Structure PtDeCtrl
  x.l
  y.l ; y  =  a  *  x  + b
  z.l
  a.f ; pente
  b.f ; ordonnée à l'origine
EndStructure

Structure Carte
  z.w
EndStructure

Macro affine(a,b,uA,zA,uB,zB)
If (uB-uA)<>0
  a = (zB - zA) / (uB - uA)
  b = zB - a * uB
EndIf
EndMacro

;tableau des points de contrôle
Dim P.PtDeCtrl(LargeurEcran , IndiceMaxDesPtsDeCtrlVerticaux , #OctaveMax)

Dim carte.Carte(LargeurEcran,HauteurEcran,#OctaveMax)

;-Remplissage du tableau  de points de contrôle avec des pics de Perlin
For Octave = 1 To #OctaveMax
  Pas = #PasInitial / Pow(2 , Octave - 1)
  NbreDePicsHorizontaux = #NbreInitialDePicsHorizontaux * Pow(2 , Octave - 1)
  NbreDePicsVerticaux = #NbreInitialDePicsVerticaux * Pow(2 , Octave - 1)
  Persistance =  Pow(#Persistance , Octave - 1)
  For i = 0 To NbreDePicsHorizontaux -1
    For j = 0 To NbreDePicsVerticaux -1
      P(i  , j , Octave)\x = i * Pas
      P(i  , j , Octave)\y = j * Pas
      P(i  , j , Octave)\z = Persistance * Random(255)
     
    Next j
  Next i
Next Octave

  ;-Subdivisions
For Octave = 1 To #OctaveMax
  NbreDePicsHorizontaux = #NbreInitialDePicsHorizontaux * Pow(2 , Octave - 1)
  NbreDePicsVerticaux = #NbreInitialDePicsVerticaux * Pow(2 , Octave - 1)
  IndiceDesPtsDeCtrlHorizontaux = NbreDePicsHorizontaux - 1
  IndiceDesPtsDeCtrlVerticaux = NbreDePicsVerticaux - 1
  Pas = #PasInitial / Pow(2 , Octave - 1)
  ;- Création des lignes de contrôle horizontales pour chaque octave
  ;Utilisation du tableau P(i,j,Octave) pour i allant de i=0 Ã  i=NbreDePicsHorizontauxProvisoire
  ;l'utilisation de i=x=0 à  i=x=LargeurEcran se fera dans la deuxième partie
  ;{

  For j = 0 To IndiceDesPtsDeCtrlVerticaux
   
    For SubdivisionEnCours = 0 To #NbreDeSubdivisions - 1
      IndiceMaxProvisoire = (NbreDePicsHorizontaux - 2) * Pow(2,SubdivisionEnCours) +1
     
      For i = IndiceMaxProvisoire - 1 To 1 Step  - 1
        If i = IndiceMaxProvisoire - 1
          P(2 * i + 1,j,Octave)\x = LargeurEcran
          P(2 * i + 1,j,Octave)\z = P(IndiceMaxProvisoire,j,Octave)\z
          P(2 * i,j,Octave)\x = P(i,j,Octave)\x + RapportSubdv * (P(i + 1,j,Octave)\x - P(i,j,Octave)\x)
          P(2 * i,j,Octave)\z = P(i,j,Octave)\z + RapportSubdv * (P(i + 1,j,Octave)\z - P(i,j,Octave)\z)
         
        Else
          P(2 * i + 1,j,Octave)\x = P(i,j,Octave)\x + (1 - RapportSubdv) * (P(i + 1,j,Octave)\x - P(i,j,Octave)\x)
          P(2 * i + 1,j,Octave)\z = P(i,j,Octave)\z + (1 - RapportSubdv) * (P(i + 1,j,Octave)\z - P(i,j,Octave)\z)
          P(2 * i,j,Octave)\x = P(i,j,Octave)\x + RapportSubdv * (P(i + 1,j,Octave)\x - P(i,j,Octave)\x)
          P(2 * i,j,Octave)\z = P(i,j,Octave)\z + RapportSubdv * (P(i + 1,j,Octave)\z - P(i,j,Octave)\z)
        EndIf
       
      Next i
     
      P(1,j,Octave)\x = P(0,j,Octave)\x + (1 - RapportSubdv) * (P(1,j,Octave)\x - P(0,j,Octave)\x)
      P(1,j,Octave)\z = P(0,j,Octave)\z + (1 - RapportSubdv) * (P(1,j,Octave)\z - P(0,j,Octave)\z)
     
    Next SubdivisionEnCours
   
    ;-calculs des équations affines de chaque segment
    x=0
    For i = 0  To IndiceMaxDesPtsDeCtrlHorizontaux -1
      affine(P(i,j,Octave)\a,P(i,j,Octave)\b,P(i,j,Octave)\x,P(i,j,Octave)\z,P(i + 1,j,Octave)\x,P(i + 1,j,Octave)\z)
     
      ;-remplissage du tableau carte(x,y,Octave)
     
      While x<=P(i+1,j,Octave)\x
        carte(x,j*Pas,Octave)\z=P(i,j,Octave)\a * x  + P(i,j,Octave)\b
        x=x+1
      Wend
    Next i
   
  Next j


  ;}
  ;-subdivisions selon y, les points de contrôles sont issus des lignes de contrôle horizontales
  ;{
  For x=0 To LargeurEcran
    ;Chargement des points de contrôle d'abscisse x
    For j = 0 To IndiceDesPtsDeCtrlVerticaux
      P(x,j,Octave)\z= carte(x,j*Pas ,Octave)\z
      P(x,j,Octave)\y=j*Pas
    Next j
    For SubdivisionEnCours = 0 To #NbreDeSubdivisions - 1
      IndiceMaxProvisoire = (NbreDePicsVerticaux - 2) * Pow(2,SubdivisionEnCours) +1
      For j = IndiceMaxProvisoire - 1 To 1 Step  - 1
        If j = IndiceMaxProvisoire - 1
          P(x,2 * j + 1,Octave)\y = HauteurEcran
          P(x,2 * j + 1,Octave)\z = P(x,IndiceMaxProvisoire,Octave)\z
          P(x,2 * j,Octave)\y = P(x,j,Octave)\y + RapportSubdv * (P(x,j + 1,Octave)\y - P(x,j,Octave)\y)
          P(x,2 * j,Octave)\z = P(x,j,Octave)\z + RapportSubdv * (P(x,j+1,Octave)\z - P(x,j,Octave)\z)
         
        Else
          P(x,2 * j + 1,Octave)\y = P(x,j,Octave)\y + (1 - RapportSubdv) * (P(x,j+ 1,Octave)\y - P(x,j,Octave)\y)
          P(x,2 * j + 1,Octave)\z = P(x,j,Octave)\z + (1 - RapportSubdv) * (P(x,j+ 1,Octave)\z - P(x,j,Octave)\z)
          P(x,2 * j,Octave)\y = P(x,j,Octave)\y + RapportSubdv * (P(x,j + 1,Octave)\y - P(x,j,Octave)\y)
          P(x,2 * j,Octave)\z = P(x,j,Octave)\z + RapportSubdv * (P(x,j+1,Octave)\z - P(x,j,Octave)\z)
         
        EndIf
       
      Next j
     
      P(x,1,Octave)\y = P(x,0,Octave)\y + (1 - RapportSubdv) * (P(x,1,Octave)\y - P(x,0,Octave)\y)
      P(x,1,Octave)\z = P(x,0,Octave)\z + (1 - RapportSubdv) * (P(x,1,Octave)\z - P(x,0,Octave)\z)
     
     
     
    Next SubdivisionEnCours
    ;-calculs des équations affines de chaque segment
   
    y=0
    For j = 0  To IndiceMaxDesPtsDeCtrlVerticaux -1
      affine(P(x,j,Octave)\a,P(x,j,Octave)\b,P(x,j,Octave)\y,P(x,j,Octave)\z,P(x ,j+1,Octave)\y,P(x,j+1,Octave)\z)
      ;-remplissage du tableau carte(x,y,Octave)
     
      While y<=P(x,j+1,Octave)\y
        carte(x,y,Octave)\z=P(x,j,Octave)\a * y  + P(x,j,Octave)\b
        y=y+1
      Wend
    Next j
   
  Next x
  ;}
Next Octave

;-dessin de la carte
DiffuseColor = CreateImage(#PB_Any,LargeurEcran,HauteurEcran)
Global Dim DiffuseColor.i(LargeurEcran,HauteurEcran)
StartDrawing(ImageOutput(DiffuseColor))

If #OctaveMax>1
  For Octave = 2 To #OctaveMax
   
    For x=0 To LargeurEcran
      For y=0 To HauteurEcran
        carte(x,y,1)\z=carte(x,y,1)\z+carte(x,y,Octave)\z
      Next y
    Next x
   
  Next Octave
EndIf

For x=0 To LargeurEcran-1
  For y=0 To HauteurEcran-1
    Composante=carte(x,y,1)\z*10/FacteurNormalisation
    ;-choix des couleurs en fonction de z
    DiffuseColor(x,y )=couleur(composante)
  Next y
Next x
StopDrawing()

HeightMap = CreateImage(#PB_Any,LargeurEcran,HauteurEcran,32)
Global Dim HeightMapColor(LargeurEcran,HauteurEcran)
StartDrawing(ImageOutput(HeightMap))

For x=0 To LargeurEcran-1
  For y=0 To HauteurEcran-1
    Composante=carte(x,y,1)\z/FacteurNormalisation
    If Composante < #IndexRelatifEauxPeuProfondes * 255
      Composante = #IndexRelatifEauxPeuProfondes * 255
    EndIf
    Plot(x,y,RGB(Composante,Composante,Composante))
    HeightMapColor(x,y) = RGB(Composante,Composante,Composante)
  Next y
Next x
StopDrawing()

OldSizeX = LargeurEcran
OldSizeY = HauteurEcran
ResizeImage(HeightMap,512,512)
NormalMap = CreateNormalMapFromImageID(HeightMap,100)
ResizeImage(HeightMap,OldSizeX ,OldSizeY )
ResizeImage(NormalMap,OldSizeX ,OldSizeY )


; Calcul de la lightmap
Global Dim Normal.VECTOR3(LargeurEcran,HauteurEcran)
Global Dim NormalColor(LargeurEcran,HauteurEcran)

StartDrawing(ImageOutput(NormalMap))
For y = 0 To ImageHeight(NormalMap) - 1
  For x = 0 To ImageWidth(NormalMap) - 1
    Color = Point(x,y)
    NormalColor(x,y) = Color
    Normal(x,y)\x=(Red(Color)/255)
    Normal(x,y)\y=(Green(Color)/255)
    Normal(x,y)\z=(Blue(Color)/255)
    normalize(Normal(x,y))
  Next
Next
StopDrawing()


sunColor = $FFFFFF
SunX=60000;30000
SunY=20000;10000
SunZ=60000;30000
lightmap = CreateImage(#PB_Any,ImageWidth(NormalMap), ImageHeight(NormalMap))
Global Dim LightMapColor(LargeurEcran,HauteurEcran)
StartDrawing(ImageOutput(lightmap))

For z = 0 To ImageHeight(NormalMap) - 1
  For x = 0 To ImageWidth(NormalMap) - 1
   
    terrainHeight.f = carte(x,y,1)\z * 100
   
    terrainPixel.VECTOR3
    terrainPixel\x = x
    terrainPixel\y = terrainHeight
    terrainPixel\z = z
   
    SunDir.VECTOR3
    SunDir\x =  (SunX - terrainPixel\x)
    SunDir\y =  (SunY - terrainPixel\y)
    SunDir\z =  (SunZ - terrainPixel\z)
    Normalize(SunDir)
   
   
    tmp.f = DotProduct(SunDir,Normal(x,z))
   
    If tmp<0
      Col.f = -1 * tmp
    Else
      Col.f = tmp
    EndIf
   
   
    Red   = Red(DiffuseColor(x,z))   * Col
    Green = Green(DiffuseColor(x,z)) * Col
    Blue  = Blue(DiffuseColor(x,z))  * Col
   
   
    If Red>255  :Red=255  :EndIf
    If Green>255:Green=255:EndIf
    If Blue>255 :Blue=255 :EndIf
   
    Plot(x,z,RGB(Red,Green,Blue))
    LightMapColor(x,z) = RGB(Red,Green,Blue)
   
  Next
Next

StopDrawing()

; SaveImage(NormalMap,"temp.bmp"); 
SaveImage(lightmap,"temp.bmp")


; Pour le fun , serie de map iso !!!!

IsoColor = CreateImage(#PB_Any,LargeurEcran,HauteurEcran)

StartDrawing(ImageOutput(IsoColor))
For y = 0 To (ImageHeight(IsoColor)/2) - 1
  For x = 0 To (ImageWidth(IsoColor)/2) - 1
   
    Color  = LightMapColor(x*2,y*2)
    Height = carte(x*2,y*2,1)\z / FacteurNormalisation
    
    Composante=carte(x*2,y*2,1)\z/FacteurNormalisation
    If Composante < #IndexRelatifEauxPeuProfondes * 255
      Height = #IndexRelatifEauxPeuProfondes * 255
    EndIf
    
    Height / 4 

    isoX = (x-y) + LargeurEcran/2
    isoY = (((x+y)/2) + HauteurEcran/3) - Height

    If x = (ImageWidth(IsoColor)/2) - 1
      Color = RGB(133, 76, 4)
    EndIf
   
    If y = (ImageHeight(IsoColor)/2) - 1
      Color = RGB(66, 42, 11)
    EndIf

    
    Box(isoX,isoY,1,Height,Color)
  Next
Next
StopDrawing()



IsoNormal = CreateImage(#PB_Any,LargeurEcran,HauteurEcran)

StartDrawing(ImageOutput(IsoNormal))
For y = 0 To (ImageHeight(IsoNormal)/2) - 1
  For x = 0 To (ImageWidth(IsoNormal)/2) - 1
   
    Color  = NormalColor(x*2,y*2)
    Height = carte(x*2,y*2,1)\z / FacteurNormalisation
   
    Composante=carte(x*2,y*2,1)\z/FacteurNormalisation
    If Composante < #IndexRelatifEauxPeuProfondes * 255
      Height = #IndexRelatifEauxPeuProfondes * 255
    EndIf

    Height / 4
    
    isoX = (x-y) + LargeurEcran/2
    isoY = (((x+y)/2) + HauteurEcran/3) - Height

    If x = (ImageWidth(IsoColor)/2) - 1
      Color = RGB(197, 93, 255)
    EndIf
   
    If y = (ImageHeight(IsoColor)/2) - 1
      Color = RGB(181, 188, 243)
    EndIf
       
    Box(isoX,isoY,1,Height,Color)
  Next
Next
StopDrawing()



IsoHeight = CreateImage(#PB_Any,LargeurEcran,HauteurEcran)

StartDrawing(ImageOutput(IsoHeight))
For y = 0 To (ImageHeight(IsoHeight)/2) - 1
  For x = 0 To (ImageWidth(IsoHeight)/2) - 1
   
    Color  = HeightMapColor(x*2,y*2)
    Height = carte(x*2,y*2,1)\z / FacteurNormalisation
   
    Composante=carte(x*2,y*2,1)\z/FacteurNormalisation
    If Composante < #IndexRelatifEauxPeuProfondes * 255
      Height = #IndexRelatifEauxPeuProfondes * 255
    EndIf
    
    Height / 4
    
    isoX = (x-y) + LargeurEcran/2
    isoY = (((x+y)/2) + HauteurEcran/3) - Height

    If x = (ImageWidth(IsoColor)/2) - 1
      Color = $CACACA
    EndIf
   
    If y = (ImageHeight(IsoColor)/2) - 1
      Color = $5A5A5A
    EndIf
       
    Box(isoX,isoY,1,Height,Color)
  Next
Next
StopDrawing()


Procedure MakeTerrain(EdgeSize.i, ScaleFactor.i=100)
  Protected i.l, b.l, a.l, Nb.l
  Protected P1.l, P2.l, P3.l, P4.l
  
  Dim hsmooth.i(LargeurEcran,HauteurEcran)
  
;   For pass = 1 To 4
  
  ;Smooth heightvalue
  For i = 2 To HauteurEcran-2
    For j = 2 To LargeurEcran-2
      
      HeightSmooth.i = 0
      For a = -1 To 1
        For b = -1 To 1
          Col = HeightMapColor(i+a,j+b)
          gray = (Red(Col)+Green(Col)+Blue(Col))/3
          HeightSmooth + gray
        Next 
      Next 
      
      HeightSmooth/9
      hsmooth(i,j) = HeightSmooth
    Next
  Next 
  
  
;   Next 
  
  
  
  
  CreateMesh(0, 1000)
  
  Num = EdgeSize
  
  For b=0 To Num
    For a=0 To Num
      
      hy = (b * HauteurEcran)/num
      hx = (a * LargeurEcran)/num

      Gray = hsmooth(hx,hy)
      
      nn = AddMeshVertex(a - Num/2,Gray*20, b - Num/2) 
      MeshVertexNormal(0,1,0) 
      MeshVertexTextureCoordinate(a/Num, b/Num)
     Next a
  Next b

  i = 0
  Nb=Num+1
  For b=0 To Num-1
    For a=0 To Num-1
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1
      AddMeshFace(P3, P2, P1)
      AddMeshFace(P2, P3, P4)
      i+1
    Next
  Next

  FinishMesh()
  NormalizeMesh(0)
  
  
  LoadTexture(0,"temp.bmp")
  CreateMaterial(0,TextureID(0))
  
  Terrain = CreateEntity(#PB_Any, MeshID(0),MaterialID(0))
  ScaleEntity(Terrain,ScaleFactor,1,ScaleFactor)
  
 
EndProcedure  
  

#PB_Engine_Space_Local=1
#PB_Engine_Space_Parent=2
#PB_Engine_Space_World=4
#PB_Engine_Absolute_Rotation=8
#PB_Engine_Relative_Rotation=16
#PB_Engine_Quaternion_Rotation=32
#PB_Engine_Euler_Rotation=64


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

;- Window
OpenWindow(0, 0, 0, 1024,768, "", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)
OpenWindowedScreen(WindowID(0), 0, 0, 1024,768, 0, 0, 0,#PB_Screen_SmartSynchronization)





Camera = CreateCamera(#PB_Any,0,0,1024,768)
CameraLocate(Camera,5000,5000,5000)
CameraLookAt(Camera,0,0,0)
CameraBackColor(Camera,RGB(64,128,255))
; CameraRenderMode(Camera,#PB_Camera_Wireframe)


Add3DArchive("./",#PB_3DArchive_FileSystem)


Light = CreateLight(#PB_Any,RGB(64,64,64),SunX,SunY,SunZ)

MakeTerrain(200,100)





KeyboardMode(#PB_Keyboard_International)
ReleaseMouse(0)

Repeat
  
  
  event = WindowEvent()
  ExamineMouse()
  ExamineKeyboard()
  ClearScreen(0)
 
  
   ;Camera Free Fly mode
      If KeyboardPushed(#PB_Key_RightShift)
        Boost.f = 10
      Else
        Boost = 1
      EndIf 
      
      If KeyboardPushed(#PB_Key_Up)         :   MoveCamera(Camera,0,0,-2*Boost)   : EndIf 
      If KeyboardPushed(#PB_Key_Down)       :   MoveCamera(Camera,0,0,2*Boost)    : EndIf 
      If KeyboardPushed( #PB_Key_Left)      :   MoveCamera(Camera,-2*Boost,0,0)   : EndIf 
      If KeyboardPushed(#PB_Key_Right)      :   MoveCamera(Camera,2*Boost,0,0)    : EndIf 
      
      
      
      Yaw.f = MouseDeltaX() / 10
      Pitch.f = MouseDeltaY() / 10
      
      RotateCamera(Camera, -Pitch, Yaw, 0, #PB_Engine_Relative_Rotation | #PB_Engine_Euler_Rotation)
  RenderWorld()
  FlipBuffers()
Until event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)

Avatar de l’utilisateur
venom
Messages : 3128
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: [4.60] HuitBit & TerrainMesh

Message par venom »

Problème chez moi avec InitEngine3D() :?

PureBasic 4.60 Beta 2 (Windows - x86)







@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: [4.60] HuitBit & TerrainMesh

Message par Cool Dji »

Salut,

J'ai un Invalid Memory Access (read error at adress 1)
ligne 731
Gray = hsmooth(hx,hy)
et avec
AddMeshFace(P3, P2, P1)
AddMeshFace(P2, P3, P4)

J'ai essayé de cadrer la valeur de Num sans succès...

PureBasic 4.60 Beta 2 (Windows - x86)
Only PureBasic makes it possible
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: [4.60] HuitBit & TerrainMesh

Message par G-Rom »

Le compilo sous windows doit être buggé , sous linux ca marche impec :/
Atomo
Messages : 207
Inscription : lun. 17/sept./2007 12:27

Re: [4.60] HuitBit & TerrainMesh

Message par Atomo »

J'ai le même problème que Cool Dji.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [4.60] HuitBit & TerrainMesh

Message par blendman »

même problème de cool Dji, sous windows xp.
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: [4.60] HuitBit & TerrainMesh

Message par Cool Dji »

Hello,

J'ai testé avec la 4.6 beta 4 (windows x86):
CreateMesch (ligne 721) ne demande plus qu'un seul paramètre (j'ai enlevé la boite englobante) du coup plus rien de devient visible...
Mais ça plante pas :D
Only PureBasic makes it possible
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: [4.60] HuitBit & TerrainMesh

Message par Geo Trouvpatou »

Salut.

Pareil que Cool Dji (Windowsx64).
Mais c'est vrai que la doc windows dit : Resultat = CreateMesh(#Mesh, RayonBoiteEnglobante)
Mais en cliquant sur la fonction dans l'IDE, la barre de status indique CreateMesh(#Mesh)

J'ai donc remplacé CreateMesh(0, 1000) par CreateMesh(0)
Avec cette modif et en virant le debugger ça fonctionne.

Par contre, j'ai mis :

Code : Tout sélectionner

      If KeyboardPushed(#PB_Key_Up)         :   MoveCamera(Camera,0,0,-200*Boost)   : EndIf
      If KeyboardPushed(#PB_Key_Down)       :   MoveCamera(Camera,0,0,200*Boost)    : EndIf
      If KeyboardPushed( #PB_Key_Left)      :   MoveCamera(Camera,-200*Boost,0,0)   : EndIf
      If KeyboardPushed(#PB_Key_Right)      :   MoveCamera(Camera,200*Boost,0,0)    : EndIf
Sinon il fallait 3 jours pour voir la scène entière.

Bravo à toi.
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: [4.60] HuitBit & TerrainMesh

Message par Huitbit »

Hello,

Idem que CoolD ji (PureBasic 4.60 Beta 4 (Windows - x86)).
Dommage.

Pour un programme 2D, j'ai dû retravailler avec les subdivisions(il manque encore un détail à régler avant de poster le bidule), je me suis aperçu d'une petite erreur dans les indices(car j'avais repris mon code tel quel fait 2 ans plus tôt).
Tout est rentré dans l'ordre, ça va mieux :P .
L'objectif est de faire une macro ou une procédure qui prenne en charge des points de contrôle (c'est à dire, subdivisions, coefficients directeurs des segments créés, normales,...etc)
Par exemple, pour ce programme, il y aurait un gros gain de temps si le nombre de subdivisions était lié à l'octave.


Hasta la vista !

PS: je me suis mis à la 3D avec PureBasic pour mon fils :mrgreen:
Cubes en bristol (6cm*6cm*6cm)
Images découpées avec Pb(j'ai découvert GrabImage() :D ).
Utilisation d'un utilitaire(Creative Tool) pour assembler les faces(j'aurais mieux fait de le faire moi-même car l'image affichée ne correspond pas à l'image imprimée, j'ai dû faire les zones de pliages au compas car le logiciel utilise un papier prédécoupé !)
Feuilles découpées et pliées par l'homme (ben ouais, Pb peut pas tout faire :lol: :lol: )
Cubes assemblés et photos prises par le pokémon
Image
Elevé au MSX !
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: [4.60] HuitBit & TerrainMesh

Message par Huitbit »

:D

Code testé avec la version PureBasic 4.60 RC 1 (Windows - x86)

A part la souris qui délire, cette fois-ci, CA MARCHE !

Bravo à l'équipe de PureBasic !

Hasta la vista !
Elevé au MSX !
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: [4.60] HuitBit & TerrainMesh

Message par Geo Trouvpatou »

Huitbit a écrit ::D

Code testé avec la version PureBasic 4.60 RC 1 (Windows - x86)

A part la souris qui délire, cette fois-ci, CA MARCHE !

Bravo à l'équipe de PureBasic !

Hasta la vista !
Ouais enfin j'avais donné la solution juste au dessus de ton post... Mais bon.
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: [4.60] HuitBit & TerrainMesh

Message par Huitbit »

Ouais enfin j'avais donné la solution juste au dessus de ton post... Mais bon.
:mrgreen:

Avec la béta précédente, ta solution donnait, sur mon PC en carton, un bel écran figé tout gris.
Je ne poste pas souvent ces derniers temps :cry:, alors si j'ai pris la peine de le faire... :roll: .

:wink:


Hasta la vista !
Elevé au MSX !
Répondre