[4.60] Remplacer temporairement CreateTerrain

Généralités sur la programmation 3D
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

[4.60] Remplacer temporairement CreateTerrain

Message par kelebrindae »

Sault à tous,

Pour remplacer la commande "CreateTerrain" (en attendant qu'elle soit réparée en v4.61 :wink:) , je me suis rapidement bricolé ce matin une procédure "MyCreateTerrain", que vous trouverez dans l'exemple ci-dessous.
Rien de révolutionnaire, mais ça peut dépanner, et puis ça m'a permis de voir comment fonctionne le nouveau "CreateMesh" (conclusion: il marche bien :mrgreen: ).

Code : Tout sélectionner

; ---------------------------------------------------------------------------------------------------------------
; Author: Kelebrindae
; Date: November,10,2011
; PB version: v4.60
; 
;  Temporary replacement for the "CreateTerrain" command (broken in PB v4.60)
; ---------------------------------------------------------------------------------------------------------------
; NB: Don't exceed 255x255 terrains, because the max vertices number in an Ogre mesh is 652235 !
; ---------------------------------------------------------------------------------------------------------------

EnableExplicit
;************************************************************************************
; Name: myCreateTerrain
; Purpose: Create a terrain mesh
; Parameters:
;   - name of the heightmap
;   - terrain size X
;   - terrain size Y
;   - maximum height (= height of the white points in the heightmap)
;   - numbers of cols in the mesh
;   - numbers of rows in the mesh
; Return-Value: mesh number
;************************************************************************************
Procedure.i MyCreateTerrain(heightmap.s,sizeX.f,sizeZ.f,maxHeight.f,nbCols.i,nbRows.i)
  Protected numImage.i,imSizeX.f,imSizeY.f, height.i
  Protected numMesh.i,i.i,j.i
  Protected v0.i,v1.i,v2.i,v3.i
  Protected cellSizeX.f, cellSizeZ.f,scaleY.f
  
  ; Load the heightmap
  numImage = LoadImage(#PB_Any,heightmap)
  If IsImage(numImage) = #False
    ProcedureReturn 0
  EndIf
  imSizeX = ImageWidth(numImage) - 1
  imSizeY = ImageHeight(numImage) - 1
  
  ; Create the mesh
  numMesh = CreateMesh(#PB_Any)
  cellSizeX = sizeX  / nbCols
  cellSizeZ = sizeZ  / nbRows
  scaleY = maxHeight / 255.0
  
  ; Create the vertices, according to heightmap values
  StartDrawing(ImageOutput(numImage))
  For j = 0 To nbCols
    For i = 0 To nbRows
      height = Red( Point(i * (imSizeX/nbCols) , j * (imSizeY/nbRows) ) )
      
      AddMeshVertex(i*cellSizeX,scaleY * height,j*cellSizeZ)
      MeshVertexColor($FFFFFF)
      MeshVertexTextureCoordinate( i * (1 / nbCols),j * (1 / nbRows) )
    Next i
  Next j
  StopDrawing()
  FreeImage(numImage)
  
  ; Create the faces
  For j=0 To nbRows - 1
    For i = 0 To nbCols - 1
      v0 = i + j*(nbRows + 1)
      v1 = i + j*(nbRows + 1) + 1
      v2 = i + (j+1)*(nbRows + 1)
      v3 = i + (j+1)*(nbRows + 1) + 1
      
      AddMeshFace(v0, v2, v3 ) 
      AddMeshFace(v0, v3, v1 )
    Next i
  Next j
  
  ; Finih and compute the normals
  FinishMesh()
  NormalizeMesh(numMesh)
  
  ProcedureReturn numMesh
EndProcedure
DisableExplicit

;- Initialization
Global FullScreen.b
Resultat = MessageRequester("Create terrain","Full Screen ?",#PB_MessageRequester_YesNo)
If Resultat = 6     
  FullScreen=#True
Else           
  FullScreen=#False
EndIf

If InitEngine3D() = 0
  MessageRequester( "Error" , "Can't initialize 3D, check if engine3D.dll is available" , 0 )
End
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester( "Error" , "Can't find DirectX 7.0 or above" , 0 )
  End
EndIf

If Fullscreen = #True
  OpenScreen(1024,768,32,"Custom Terrain",#PB_Screen_SmartSynchronization)
Else
  OpenWindow(0,0, 0, 800 , 500 ,"Custom Terrain")
  OpenWindowedScreen(WindowID(0),0,0, 800, 500,0,0,0,#PB_Screen_SmartSynchronization)
EndIf

;- Terrain texture
CreateTexture(0,64,64)
StartDrawing(TextureOutput(0))
  Box(0,0,64,64,$FFFFFF)
StopDrawing()

CreateMaterial(2,TextureID(0))
MaterialAmbientColor(2, #PB_Material_AmbientColors)

;- Terrain mesh
UsePNGImageDecoder()
UseJPEGImageDecoder()
heightmap.s = OpenFileRequester("Choisissez une Heightmap","","Images|*.png;*.bmp;*.jpg;*.jpeg",0)
If heightmap = ""
  End
EndIf
numMesh = MyCreateTerrain(heightmap,500,500,50,250,250)

;- Terrain entity
CreateEntity(0,MeshID(numMesh),MaterialID(2))
EntityLocate(0,-50,0,-50)

;- Light
AmbientColor(0)
CreateLight(0,$FFFFFF, 0,500,500)

;- Camera
CreateCamera(0, 0, 0, 100, 100)
CameraBackColor(0,$FF7755)
CameraLocate(0, 400,100,500)
CameraLookAt(0,250,0,250)
#CameraSpeed = 1

;- Main loop
Repeat
  While WindowEvent()
    Delay(1)
  Wend

  If ExamineMouse()
    MouseX = -(MouseDeltaX()/10)*#CameraSpeed
    MouseY = -(MouseDeltaY()/10)*#CameraSpeed
  EndIf
 
  RotateCamera(0, MouseY, MouseX, RollZ, #PB_Relative)
  If ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Up)
      MoveCamera  (0, 0, 0, -#CameraSpeed)
    EndIf
    If KeyboardPushed(#PB_Key_Down)
      MoveCamera  (0, 0, 0, #CameraSpeed)
    EndIf
  EndIf
  
  RenderWorld()    
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1

Vous aurez besoin d'une heightmap, comme celle-ci:
Image

A+
Dernière modification par kelebrindae le jeu. 10/nov./2011 22:36, modifié 1 fois.
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: [4.60] Remplacer temporairement CreateTerrain

Message par comtois »

ça fonctionne bien :)
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.
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Re: [4.60] Remplacer temporairement CreateTerrain

Message par kelebrindae »

Merci!
Mais j'ai vu (un peu tard) que Huitbit et G-Rom m'avaient devancé dans leur post "Terrain Mesh" ici: http://www.purebasic.fr/french/viewtopi ... 13&t=11797
Tant pis...
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: [4.60] Remplacer temporairement CreateTerrain

Message par Huitbit »

Ca marche !

Questions de super novice.
Si on fait :

Code : Tout sélectionner

numMesh = MyCreateTerrain(heightmap,1500,1500,100,250,250) 
On a terrain de bonne qualité, beaucoup plus grand (dans l'exemple "terrain" de la 4.51, je crois que c'était la technique utilisée pour avoir un grand terrain avec une heightmap de 257*257).
C'est une faute de faire ça ou pas ?
Avec le code de G-rom(cité plus haut) est-ce qu'on pourrait faire la même chose ?

Ma partie de ce code sera, un jour, optimisée(choix "intelligent" du nombre de subdivisions) (je suis en train de faire une procédure "subdivision" avec des variables locales pour l'utiliser dans n'importe quelle situation sans se casser la tête)


Hasta la vista !
Elevé au MSX !
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: [4.60] Remplacer temporairement CreateTerrain

Message par venom »

Bonjour,

chez moi il me met ce message d'erreur : Can't initialize 3D, check if engine3D.dll is available c'est du a quoi ?






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Re: [4.60] Remplacer temporairement CreateTerrain

Message par kelebrindae »

@Venom:
Si tu as cette erreur, c'est que le "InitEngine3D" renvoie 0, c'est-à-dire qu'il ne peut s'initialiser ou que la DLL est absente. C'est assez bizarre; Les exemples 3D fournis avec la 4.60 de PB fonctionnent, chez toi? :?

@HuitBit:
"numMesh = MyCreateTerrain(heightmap,1500,1500,100,250,250)"
va créer un terrain de 1500 unités de long sur 1500 de large, de 100 unités de haut maxi (pour les zones blanches de la heightmap), et le mesh sera constitué d'une grille de 250 x 250 carreaux (mesurant 6 unités chacun), soit 62500 en tout. Pas plus de détails, donc, mais un terrain 3 fois plus grand que dans mon exemple.
A priori, on ne peut dépasser 65535 vertices par mesh dans Ogre. On ne peut donc pas monter au-dessus de 255x255 (sauf le fait de faire des submesh permet de contourner la limitation...)
=> ton idée d'optimiser en faisait des subdivisions plus petites pour les zones détaillées et un seul carreau pour les zones "plates" est donc très intéressante. J'espère voir ça bientôt!
Les idées sont le souvenir de choses qui ne se sont pas encore produites.
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: [4.60] Remplacer temporairement CreateTerrain

Message par venom »

C'est bon, j'ai remis a jour directx c'est peut etre du a ça. ?

maintenant ça fonctionne.






@++
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] Remplacer temporairement CreateTerrain

Message par Cool Dji »

Hello,

Vraiment très cool. Très utile aussi pour faire plusieurs petits morceaux de terrains naturels dans un même monde (jardin, bordure, talus...).
Faute de CreateTerrain j'avais commencé à modéliser un sol avec Deled (j'ai vite arrêté !!).

Merci et bravo
Only PureBasic makes it possible
Répondre