Basic Terrain Generator

Everything related to 3D programming
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Basic Terrain Generator

Post by Samuel »

Do you need to have a 13 inch HP laptop? It looks like most of the 13 inch ones only have integrated intel graphics, but some of the bigger ones have AMD graphic cards.

For example this 15.6 inch HP laptop comes with a AMD Radeon HD 8330 graphic card.
http://www.amazon.com/HP-15-d020nr-15-6 ... 180&sr=8-1
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Basic Terrain Generator

Post by Samuel »

I updated my original post. I've added UV scaling within the procedure which means you no longer have to use material scale to get texture repetition. I also created an alpha blending example.
Here's a picture for those interested in what alpha blending can do to the terrain.
Image

Let me know if you see any problems or if you have any questions.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Basic Terrain Generator

Post by applePi »

thanks Samuel for the update, Terrain with alphaBlend example are very nice. i have tried it with physics and a ball it is okay even it is initiated after 3 seconds with physics enabled and instantaneous without physics and that speed depends on the hardware and OS used. but i haven't enabled physics yet for the huge mesh 4202500 index posted by Comtois http://purebasic.fr/english/viewtopic.p ... 72#p402072 since i'm now on windows xp which have a poor memory management.
some users are using the terrain from a mesh since it is straightforward and simple.
best regards
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Basic Terrain Generator

Post by Samuel »

Thanks for the reply, applePi. The next addition I'm adding is terrain level of detail and I'm hoping that will help speed up the physics side.
User avatar
zxretrosoft
Enthusiast
Enthusiast
Posts: 171
Joined: Wed May 15, 2013 8:26 am
Location: Czech Republic, Prague
Contact:

Re: Basic Terrain Generator

Post by zxretrosoft »

Absolutely perfect Samuel! Thank you!
Great job! :)

That's just a step to make it so that, for example: Lowlands were green and mountains were brown / white. Am I right? :idea:
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Basic Terrain Generator

Post by applePi »

Hi Samuel
i haven't studied yet how you have woven your mesh, but i have played with making holes with it. i have used TilesX = 100, TilesZ = 100

Code: Select all

center = 50 ; center of the hole
        a.f=20:b.f=20 ; if a=b then it is a circle else it is a horizontal or vertical ellipse
        value.f = Pow(CTRX-center,2)/(a*a) + Pow(CTRZ-center,2)/(b*b)
        If value < 1 ; if inside the ellipse then ...
          hole = -15
          Else
          hole = 0
        EndIf
        
      
        Vertices(VCTR, 0) = TileLocX
        Vertices(VCTR, 1) = TileLocY + hole
        Vertices(VCTR, 2) = TileLocZ
this will make a circular hole with radius a at the terrain center. if a<>b then it is an elliptical hole . if variable Hole is positive then we get a mountain not a hole.
as it is noticed the hole have a stretched material and this is unrealistic, on the other hand we can't texture the hole exactly like the terrain, but it should be different slightly i'm still following this topic and not sure about it.
again thanks for this handy terrain generator and at least it is a fun to do experiments with it.

the code is by Samuel, i have added a hole to the terrain, and it should be run inside the terrain generator in page 1

Code: Select all

Enumeration
  #Window
  #Font
  #HelpSprite
  #Texture
  #Material
  #Light
  #Camera
  #Terrain
  #HeightMap
  #RedMaterial
EndEnumeration

Declare TG_UpdateSprite()
Declare TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)

If InitEngine3D() = 0
  MessageRequester("ERROR", "Failed to initialize the 3D engine.", #PB_MessageRequester_Ok)
  End
EndIf

If InitSprite() = 0
  MessageRequester("ERROR", "Failed to initialize the sprite environment.", #PB_MessageRequester_Ok)
  End
EndIf

If InitKeyboard() = 0
  MessageRequester("ERROR", "Failed to initialize the keyboard environment.", #PB_MessageRequester_Ok)
  End
EndIf
  
If InitMouse() = 0
  MessageRequester("ERROR", "Failed to initialize the mouse environment.", #PB_MessageRequester_Ok)
  End
EndIf

UsePNGImageDecoder()
UseJPEGImageDecoder()

ExamineDesktops()
WindowW = DesktopWidth(0)
WindowH = DesktopHeight(0)

Define.f MouseX, MouseY, KeyX, KeyY

Global.i RenderMode, Help=0

LoadFont(#Font, "Courier New", 11, #PB_Font_Bold)

If OpenWindow(#Window, 0, 0, WindowW, WindowH, "Terrain Generator", #PB_Window_ScreenCentered)
  ;AntialiasingMode(#PB_AntialiasingMode_x6)
  If OpenWindowedScreen(WindowID(#Window), 0, 0, WindowW, WindowH, 0, 0, 0)
    
    Add3DArchive("Programs\", #PB_3DArchive_FileSystem)
    Add3DArchive("Scripts\", #PB_3DArchive_FileSystem)
    Add3DArchive("Textures\", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    CreateSprite(#HelpSprite, 300, 145)
    
    ;# Get the script that contains the alpha splatting information.
    GetScriptMaterial(#Material, "AlphaSplatting")
        
    ;# Greyscale image that will be used for generating the terrain.
    LoadImage(#HeightMap, "Textures\HeightMap02.png")
    
    ;## A FEW NOTES ##
    ;# Stay below 510 tiles total or you will exceed the vertex limit.
    ;# TerrainHeight can have a positive or negative value.

    MeshHandle = TG_GenerateTerrain(100, 100, 10, 50, 50, 1, 1, #HeightMap)
    TestHandle = IsMesh(MeshHandle)
    If TestHandle <> 0
      CreateEntity(#Terrain, MeshID(MeshHandle), MaterialID(#Material))
    EndIf
    
    CreateLight  (#Light, RGB(0,0,0), 0, 500, 1000)
    SetLightColor(#Light, #PB_Light_DiffuseColor, RGB(255,255,255))
    
    AmbientColor(RGB(50,50,50))
    
    CreateCamera   (#Camera, 0, 0, 100, 100)
    MoveCamera     (#Camera, -25, 38, 40, #PB_Absolute)
    CameraLookAt   (#Camera, 0, 00, 0)
    CameraBackColor(#Camera, RGB(80,80,80))
    
    ;# WARNING!! If you use stencil shadow types (#PB_Shadow_Modulative or #PB_Shadow_Additive)
    ;and you have over 360 tiles in your terrain the program may crash as you've exceeded the 16 bit index.
    
    ;In this case I personally wouldn't use stencil shadows. As they're not meant to be
    ;used in complex scenes.
    ;If you really want to use stencil shadows. I highly suggest you keep the terrain simple.
    
    ;WorldShadows(#PB_Shadow_Modulative, 100, RGB(150, 150, 150))
    EntityPhysicBody(#Terrain, #PB_Entity_StaticBody, 1, 1, 1)
    GetScriptMaterial(#RedMaterial, "Color/Red")
    CreateSphere(200, 0.6)
    CreateEntity(200, MeshID(200), MaterialID(#RedMaterial) , 0, 25,0)
    EntityPhysicBody(200, #PB_Entity_SphereBody , 1, 0.5, 0.5)

    Repeat
      
      Event = WindowEvent()   
      
      If ExamineMouse()
        
        MouseX = -MouseDeltaX() / 10
        MouseY = -MouseDeltaY() / 10
        
      EndIf
      
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_A)
          KeyX = -0.9
        ElseIf KeyboardPushed(#PB_Key_D)
          KeyX = 0.9
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_W)
          KeyY = -0.9
        ElseIf KeyboardPushed(#PB_Key_S)
          KeyY = 0.9
        Else
          KeyY = 0
        EndIf
        
        If KeyboardReleased(#PB_Key_R)
          If RenderMode = 0
            CameraRenderMode(#Camera, #PB_Camera_Wireframe)
            RenderMode = 1
          Else
            CameraRenderMode(#Camera, #PB_Camera_Textured)
            RenderMode = 0
          EndIf
        EndIf
        
        If KeyboardReleased(#PB_Key_H)
          If Help = 0
            Help = 1
          Else
            Help = 0
          EndIf
        EndIf
        
      EndIf
      
      DisableEntityBody(200, 0)
      ApplyEntityImpulse(200, 0, 0.01, 0 )

      
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera  (#Camera, KeyX, 0, KeyY)
      
      RenderWorld()
      If Help = 0
        TG_UpdateSprite()
        DisplaySprite(#HelpSprite, 0, 0)
      EndIf
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape)
    
  EndIf
EndIf  

End

Procedure TG_UpdateSprite()
  
  Define.i FPS, Triangles, Batches
  
  FPS       = Engine3DStatus(#PB_Engine3D_CurrentFPS)
  Triangles = Engine3DStatus(#PB_Engine3D_NbRenderedTriangles)
  Batches   = Engine3DStatus(#PB_Engine3D_NbRenderedBatches)
  
  StartDrawing(SpriteOutput(#HelpSprite))
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, 0, SpriteWidth(#HelpSprite), SpriteHeight(#HelpSprite), RGB(20,20,20))
    DrawingFont(FontID(#Font))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(5, 5, "FPS       : " + Str(FPS), RGB(255,0,0))
    DrawText(5, 25, "Triangles : " + Str(Triangles), RGB(0,255,0))
    DrawText(5, 45, "Batches   : " + Str(Batches), RGB(0,128,255))
    DrawText(5, 65, "Press W,A,S,D to Move Camera.", RGB(255,255,255))
    DrawText(5, 85, "Move Mouse to Rotate Camera.", RGB(255,255,255))
    If RenderMode = 0
      DrawText(5, 105, "Press R : Wireframe Off", RGB(255,128,0))
    Else
      DrawText(5, 105, "Press R : Wireframe On", RGB(255,128,0))
    EndIf
    If Help = 0
      DrawText(5, 125, "Press H : Help On", RGB(255,255,0))
    Else
      DrawText(5, 125, "Press H : Help Off", RGB(255,255,0))
    EndIf
  StopDrawing()
  
EndProcedure

Procedure TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)
  
  ;# First check and see if all parameters have valid values.
  ;# TerrainHeight can have any value positive or negative. So, we will not be testing for it.
  
  If TilesX <= 0
    MessageRequester("ERROR", "TilesX must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TilesZ <= 0
    MessageRequester("ERROR", "TilesZ must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TerrainSizeX <= 0
    MessageRequester("ERROR", "TerrainSizeX must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TerrainSizeZ <= 0
    MessageRequester("ERROR", "TerrainSizeZ must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TextureRepeatU <= 0
    MessageRequester("ERROR", "TextureRepeatU must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TextureRepeatV <= 0
    MessageRequester("ERROR", "TextureRepeatV must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If IsImage(HeightMapHandle) = 0
    MessageRequester("ERROR", "Failed to find HeightMap.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  ;# Test to make sure terrain will not exceed the 16 bit index limitations (65,536 vertices).
  ;# There are ways around this limitation, but that's for another day.
  Define.i TotalVertices
  
  TotalVertices = (TilesX + 1) * (TilesZ + 1)

  If TotalVertices > 65536
    MessageRequester("ERROR", "Terrain has too many tiles. Vertex limit has been exceeded.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  ;# Generating Vertex Data
  Dim Vertices.d(TotalVertices, 2)
  
  Define.d TileSizeX, TileSizeZ
  
  TileSizeX = TerrainSizeX / TilesX
  TileSizeZ = TerrainSizeZ / TilesZ
  
  Define.d TileLocX, TileLocY, TileLocZ
  
  TileLocX = (TerrainSizeX * 0.5) * -1
  TileLocZ = (TerrainSizeZ * 0.5) * -1
  
  StartDrawing(ImageOutput(HeightMapHandle))
  
    Define.i ImgWidth, ImgHeight
  
    ImgWidth  = ImageWidth (HeightMapHandle) - 1
    ImgHeight = ImageHeight(HeightMapHandle) - 1
    
    Define.d ImgXRatio, ImgZRatio
    
    ImgXRatio = ImgWidth  / TerrainSizeX
    ImgZRatio = ImgHeight / TerrainSizeZ
    
    Define.d HeightRatio
    
    HeightRatio = TerrainHeight / 255
    
    Define.i PixelX, PixelY
    Define.i VCTR, CTRX, CTRZ
    Define.i Color, ColorValue
    
    For CTRZ = 0 To TilesZ
    
      For CTRX = 0 To TilesX
              
        PixelX = ((TerrainSizeX * 0.5) + TileLocX) * ImgXRatio
        PixelY = ((TerrainSizeZ * 0.5) + TileLocZ) * ImgZRatio
        
        Color = Point(PixelX, PixelY)
        
        ColorValue = Red(Color)
        
        TileLocY = ColorValue * HeightRatio
        center = 50 ; center of the hole
        a.f=20:b.f=20 ; if a=b then it is a circle else it is a horizontal or vertical ellipse
        value.f = Pow(CTRX-center,2)/(a*a) + Pow(CTRZ-center,2)/(b*b)
        If value < 1 ; if inside the ellipse then ...
          hole = -15
          Else
          hole = 0
        EndIf
        
      
        Vertices(VCTR, 0) = TileLocX
        Vertices(VCTR, 1) = TileLocY + hole
        Vertices(VCTR, 2) = TileLocZ
        
        TileLocX = TileLocX + TileSizeX
        
        VCTR + 1
        
      Next
    
      TileLocX = (TerrainSizeX * 0.5) * -1
      TileLocZ = TileLocZ + TileSizeZ
    
    Next
  StopDrawing()
  
  ;# Generating Face Data
  Define.i TotalFaces
  
  TotalFaces = (TilesX * TilesZ) * 2
  
  Dim Faces(TotalFaces, 2)
  
  Define.i FCTR, FaceCTR
  
  For CTRZ = 0 To TilesZ - 1
    For CTRX = 0 To TilesX - 1
    
      Faces(FCTR, 0) = FaceCTR
      Faces(FCTR, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR, 2) = FaceCTR + 1
      
      Faces(FCTR + 1, 0) = FaceCTR + 1
      Faces(FCTR + 1, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR + 1, 2) = FaceCTR + 2 + TilesX
      
      FCTR + 2
      FaceCTR + 1
    
    Next
    FaceCTR + 1
  Next
  
  ;# Now we can create our terrain
  Define.i UCounter
  Define.d U, V, Uoffset, Voffset

  Uoffset = TextureRepeatU * (1 / TilesX)
  Voffset = TextureRepeatV * (1 / TilesZ)
  
  Handle = CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Static)

    For CTR = 0 To TotalVertices -1
      
      MeshVertexPosition(Vertices(CTR, 0), Vertices(CTR, 1)-hole, Vertices(CTR, 2))
      MeshVertexNormal(0, 0, 0)
      MeshVertexTextureCoordinate(U, V)
      
      U = U + Uoffset
      UCounter + 1
      
      If UCounter > TilesX
        UCounter = 0
        U = 0
        V = V + Voffset
      EndIf
      
    Next

    For CTR = 0 To TotalFaces
      MeshFace(Faces(CTR, 0), Faces(CTR, 1), Faces(CTR, 2))
    Next
      
  FinishMesh(#True)
  
  ;# We normalize the mesh because I haven't spent the time to manually calculate the vertex normals.
  ;I might add this process later on, but for now I'll keep it this way.
  
  NormalizeMesh(Handle)
  BuildMeshTangents(Handle)
  
  FreeArray(Vertices())
  FreeArray(Faces())
  
  ProcedureReturn Handle

EndProcedure


User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Basic Terrain Generator

Post by Samuel »

@zxretrosoft
Yes, that's pretty much what I'm after. If everything goes well with the LOD system the next step will be to start creating an editor for the generator. This would allow us to paint textures onto our terrain and also allow us to change the terrain shape on the fly.
Instead of the current way where all the editing needs to be done in a separate painting software.


@applePi
Nice example and I'm glad you've found a use for this generator.
As for your problem it's the UV coordinates that are causing the stretching effect. I'd guess they need to reflect the depth of the hole somehow, but at the same time not mess up the rest of the terrain. Which is a bit over my head, but maybe you can come up with a solution.
If I can be of any help let me know.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Basic Terrain Generator

Post by Samuel »

I need some help from some you physic gurus out there. I created a physic example for the terrain, but it doesn't seem to be working correctly.

I have 1000 spheres above the terrain that all fall at once and it looks like about half of them are falling strait through the terrain.
I've tried as few as ten spheres and setting them at different heights, but each time it seems to have a similar effect. I also tried simplifying the terrain detail, but that also didn't seem to improve anything.

Here's the code. It's looking for some of the images in my original download. So, you'll need to save it within the same directory as the other examples.

Thanks to everyone who takes a look at it.

Code: Select all

Enumeration
  #Window
  #Font
  #HelpSprite
  #Texture
  #Material
  #Light
  #Camera
  #Terrain
  #HeightMap
EndEnumeration

Declare TG_UpdateSprite()
Declare TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)

If InitEngine3D(#PB_Engine3D_DebugLog) = 0
  MessageRequester("ERROR", "Failed to initialize the 3D engine.", #PB_MessageRequester_Ok)
  End
EndIf

If InitSprite() = 0
  MessageRequester("ERROR", "Failed to initialize the sprite environment.", #PB_MessageRequester_Ok)
  End
EndIf

If InitKeyboard() = 0
  MessageRequester("ERROR", "Failed to initialize the keyboard environment.", #PB_MessageRequester_Ok)
  End
EndIf
  
If InitMouse() = 0
  MessageRequester("ERROR", "Failed to initialize the mouse environment.", #PB_MessageRequester_Ok)
  End
EndIf

UsePNGImageDecoder()
UseJPEGImageDecoder()

WindowW = 1280
WindowH = 720

Define.f MouseX, MouseY, KeyX, KeyY

Global.i RenderMode, Help

LoadFont(#Font, "Courier New", 11, #PB_Font_Bold)

If OpenWindow(#Window, 0, 0, WindowW, WindowH, "Terrain Generator", #PB_Window_ScreenCentered)
  ;AntialiasingMode(#PB_AntialiasingMode_x6)
  If OpenWindowedScreen(WindowID(#Window), 0, 0, WindowW, WindowH, 0, 0, 0)
    
    Add3DArchive("Programs\", #PB_3DArchive_FileSystem)
    Add3DArchive("Scripts\", #PB_3DArchive_FileSystem)
    Add3DArchive("Textures\", #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    EnableWorldPhysics(#True)
    
    CreateSprite(#HelpSprite, 300, 145)
    
    ;# Texture that will cover the terrain.
    LoadTexture(#Texture, "grass.jpg")
    CreateMaterial(#Material, TextureID(#Texture))
    
    ;# Greyscale image that will be used for generating the terrain.
    LoadImage(#HeightMap, "Textures\HeightMap00.png")
    

    ;## A FEW NOTES ##
    ;# Stay below 510 tiles total or you will exceed the vertex limit.
    ;# TerrainHeight can have a positive or negative value.
    
    MeshHandle = TG_GenerateTerrain(255, 255, 5, 50, 50, 100, 100, #HeightMap)
    TestHandle = IsMesh(MeshHandle)
    If TestHandle <> 0
      CreateEntity(#Terrain, MeshID(MeshHandle), MaterialID(#Material))
      EntityPhysicBody(#Terrain, #PB_Entity_StaticBody)
    EndIf
    
    CreateLight  (#Light, RGB(0,0,0), 0, 500, 1000)
    SetLightColor(#Light, #PB_Light_DiffuseColor, RGB(255,255,255))

    AmbientColor(RGB(50,50,50))
    
    CreateCamera   (#Camera, 0, 0, 100, 100)
    MoveCamera     (#Camera, -20, 20, 20, #PB_Absolute)
    CameraLookAt   (#Camera, 0, 00, 0)
    CameraBackColor(#Camera, RGB(80,80,80))
    CameraRenderMode(#Camera, #PB_Camera_Wireframe)
    RenderMode = 1
    
    SphereMesh = CreateSphere(#PB_Any, 0.1)
    
    For CTR = 1 To 1000
    
      SphereEntity = CreateEntity(#PB_Any, MeshID(SphereMesh), #PB_Material_None, Random(50,0)-25,Random(20,10),Random(50,0)-25)
      EntityPhysicBody(SphereEntity, #PB_Entity_SphereBody, 1.0, 0.3, 0.5)
      
    Next
    
    ;# WARNING!! If you use stencil shadow types (#PB_Shadow_Modulative or #PB_Shadow_Additive)
    ;and you have over 360 tiles in your terrain the program may crash as you've exceeded the 16 bit index.
    
    ;In this case I personally wouldn't use stencil shadows. As they're not meant to be
    ;used in complex scenes.
    ;If you really want to use stencil shadows. I highly suggest you keep the terrain simple.
    
    ;WorldShadows(#PB_Shadow_Modulative, 100, RGB(150, 150, 150))

    Repeat
      
      Event = WindowEvent()   
      
      If ExamineMouse()
        
        MouseX = -MouseDeltaX() / 10
        MouseY = -MouseDeltaY() / 10
        
      EndIf
      
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_A)
          KeyX = -0.2
        ElseIf KeyboardPushed(#PB_Key_D)
          KeyX = 0.2
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_W)
          KeyY = -0.2
        ElseIf KeyboardPushed(#PB_Key_S)
          KeyY = 0.2
        Else
          KeyY = 0
        EndIf
        
        If KeyboardReleased(#PB_Key_R)
          If RenderMode = 0
            CameraRenderMode(#Camera, #PB_Camera_Wireframe)
            RenderMode = 1
          Else
            CameraRenderMode(#Camera, #PB_Camera_Textured)
            RenderMode = 0
          EndIf
        EndIf
        
        If KeyboardReleased(#PB_Key_H)
          If Help = 0
            Help = 1
          Else
            Help = 0
          EndIf
        EndIf
        
      EndIf
      
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera  (#Camera, KeyX, 0, KeyY)
      
      RenderWorld()
      If Help = 0
        TG_UpdateSprite()
        DisplaySprite(#HelpSprite, 0, 0)
      EndIf
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape)
    
  EndIf
EndIf  

End

Procedure TG_UpdateSprite()
  
  Define.i FPS, Triangles, Batches
  
  FPS       = Engine3DStatus(#PB_Engine3D_CurrentFPS)
  Triangles = Engine3DStatus(#PB_Engine3D_NbRenderedTriangles)
  Batches   = Engine3DStatus(#PB_Engine3D_NbRenderedBatches)
  
  StartDrawing(SpriteOutput(#HelpSprite))
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, 0, SpriteWidth(#HelpSprite), SpriteHeight(#HelpSprite), RGB(20,20,20))
    DrawingFont(FontID(#Font))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(5, 5, "FPS       : " + Str(FPS), RGB(255,0,0))
    DrawText(5, 25, "Triangles : " + Str(Triangles), RGB(0,255,0))
    DrawText(5, 45, "Batches   : " + Str(Batches), RGB(0,128,255))
    DrawText(5, 65, "Press W,A,S,D to Move Camera.", RGB(255,255,255))
    DrawText(5, 85, "Move Mouse to Rotate Camera.", RGB(255,255,255))
    If RenderMode = 0
      DrawText(5, 105, "Press R : Wireframe Off", RGB(255,128,0))
    Else
      DrawText(5, 105, "Press R : Wireframe On", RGB(255,128,0))
    EndIf
    If Help = 0
      DrawText(5, 125, "Press H : Help On", RGB(255,255,0))
    Else
      DrawText(5, 125, "Press H : Help Off", RGB(255,255,0))
    EndIf
  StopDrawing()
  
EndProcedure

Procedure TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)
  
  ;# First check and see if all parameters have valid values.
  ;# TerrainHeight can have any value positive or negative. So, we will not be testing for it.
  
  If TilesX <= 0
    MessageRequester("ERROR", "TilesX must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TilesZ <= 0
    MessageRequester("ERROR", "TilesZ must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TerrainSizeX <= 0
    MessageRequester("ERROR", "TerrainSizeX must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TerrainSizeZ <= 0
    MessageRequester("ERROR", "TerrainSizeZ must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TextureRepeatU <= 0
    MessageRequester("ERROR", "TextureRepeatU must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TextureRepeatV <= 0
    MessageRequester("ERROR", "TextureRepeatV must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If IsImage(HeightMapHandle) = 0
    MessageRequester("ERROR", "Failed to find HeightMap.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  ;# Test to make sure terrain will not exceed the 16 bit index limitations (65,536 vertices).
  ;# There are ways around this limitation, but that's for another day.
  Define.i TotalVertices
  
  TotalVertices = (TilesX + 1) * (TilesZ + 1)

  If TotalVertices > 65536
    MessageRequester("ERROR", "Terrain has too many tiles. Vertex limit has been exceeded.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  ;# Generating Vertex Data
  Dim Vertices.d(TotalVertices, 2)
  
  Define.d TileSizeX, TileSizeZ
  
  TileSizeX = TerrainSizeX / TilesX
  TileSizeZ = TerrainSizeZ / TilesZ
  
  Define.d TileLocX, TileLocY, TileLocZ
  
  TileLocX = (TerrainSizeX * 0.5) * -1
  TileLocZ = (TerrainSizeZ * 0.5) * -1
  
  StartDrawing(ImageOutput(HeightMapHandle))
  
    Define.i ImgWidth, ImgHeight
  
    ImgWidth  = ImageWidth (HeightMapHandle) - 1
    ImgHeight = ImageHeight(HeightMapHandle) - 1
    
    Define.d ImgXRatio, ImgZRatio
    
    ImgXRatio = ImgWidth  / TerrainSizeX
    ImgZRatio = ImgHeight / TerrainSizeZ
    
    Define.d HeightRatio
    
    HeightRatio = TerrainHeight / 255
    
    Define.i PixelX, PixelY
    Define.i VCTR, CTRX, CTRZ
    Define.i Color, ColorValue
    
    For CTRZ = 0 To TilesZ
    
      For CTRX = 0 To TilesX
              
        PixelX = ((TerrainSizeX * 0.5) + TileLocX) * ImgXRatio
        PixelY = ((TerrainSizeZ * 0.5) + TileLocZ) * ImgZRatio
        
        Color = Point(PixelX, PixelY)
        
        ColorValue = Red(Color)
        
        TileLocY = ColorValue * HeightRatio
        
        Vertices(VCTR, 0) = TileLocX
        Vertices(VCTR, 1) = TileLocY
        Vertices(VCTR, 2) = TileLocZ
        TileLocX = TileLocX + TileSizeX
        
        VCTR + 1
        
      Next
    
      TileLocX = (TerrainSizeX * 0.5) * -1
      TileLocZ = TileLocZ + TileSizeZ
    
    Next
  StopDrawing()
  
  ;# Generating Face Data
  Define.i TotalFaces
  
  TotalFaces = (TilesX * TilesZ) * 2
  
  Dim Faces(TotalFaces, 2)
  
  Define.i FCTR, FaceCTR
  
  For CTRZ = 0 To TilesZ - 1
    For CTRX = 0 To TilesX - 1
    
      Faces(FCTR, 0) = FaceCTR
      Faces(FCTR, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR, 2) = FaceCTR + 1
      
      Faces(FCTR + 1, 0) = FaceCTR + 1
      Faces(FCTR + 1, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR + 1, 2) = FaceCTR + 2 + TilesX
      
      FCTR + 2
      FaceCTR + 1
    
    Next
    FaceCTR + 1
  Next
  
  ;# Now we can create our terrain
  Define.i UCounter
  Define.d U, V, Uoffset, Voffset

  Uoffset = TextureRepeatU * (1 / TilesX)
  Voffset = TextureRepeatV * (1 / TilesZ)
  
  Handle = CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Static)

    For CTR = 0 To TotalVertices -1
      
      MeshVertexPosition(Vertices(CTR, 0), Vertices(CTR, 1), Vertices(CTR, 2))
      MeshVertexNormal(0, 0, 0)
      MeshVertexTextureCoordinate(U, V)
      
      U = U + Uoffset
      UCounter + 1
      
      If UCounter > TilesX
        UCounter = 0
        U = 0
        V = V + Voffset
      EndIf
      
    Next

    For CTR = 0 To TotalFaces
      MeshFace(Faces(CTR, 0), Faces(CTR, 1), Faces(CTR, 2))
    Next
      
  FinishMesh(#True)
  
  ;# We normalize the mesh because I haven't spent the time to manually calculate the vertex normals.
  ;I might add this process later on, but for now I'll keep it this way.
  
  NormalizeMesh(Handle)
  
  FreeArray(Vertices())
  FreeArray(Faces())
  
  ProcedureReturn Handle

EndProcedure
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Basic Terrain Generator

Post by applePi »

Hi Samuel
the very small spheres with #PB_Entity_SphereBody are usually penetrate the other meshes and this is also noticed with other engines . sphere radius 0.4 and up does not penetrate your terrain. and to prevent visual illusion happened from the spheres dropped from the edges use big terrain, also we can use a slightly concave terrain but the question is: does 0.1 radius sphere penetrate a more compact mesh ie more faces ?
also if we used #PB_Entity_ConvexHullBody there is less spheres escape but then less Mobility .
for your convenience here is your same example but bigger terrain and a scaled cube under it with physics, press ' B ' to initiate making 500 spheres, (1000 will make the program very slow on my hardware especially the bigger spheres and with material NoCulling.
the spheres here are 0.4 radius. a few spheres are penetrating the scaled cube but not your terrain.
for the users: save this at the same folder of the terrain generator by Samuel here: http://purebasic.fr/english/viewtopic.php?f=36&t=59954

Code: Select all

Enumeration
  #Window
  #Font
  #HelpSprite
  #Texture
  #Material
  #Light
  #Camera
  #Terrain
  #HeightMap
EndEnumeration

Declare TG_UpdateSprite()
Declare TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)

If InitEngine3D(#PB_Engine3D_DebugLog) = 0
  MessageRequester("ERROR", "Failed to initialize the 3D engine.", #PB_MessageRequester_Ok)
  End
EndIf

If InitSprite() = 0
  MessageRequester("ERROR", "Failed to initialize the sprite environment.", #PB_MessageRequester_Ok)
  End
EndIf

If InitKeyboard() = 0
  MessageRequester("ERROR", "Failed to initialize the keyboard environment.", #PB_MessageRequester_Ok)
  End
EndIf
  
If InitMouse() = 0
  MessageRequester("ERROR", "Failed to initialize the mouse environment.", #PB_MessageRequester_Ok)
  End
EndIf

UsePNGImageDecoder()
UseJPEGImageDecoder()

WindowW = 1280
WindowH = 720

Define.f MouseX, MouseY, KeyX, KeyY

Global.i RenderMode, Help

LoadFont(#Font, "Courier New", 11, #PB_Font_Bold)

If OpenWindow(#Window, 0, 0, WindowW, WindowH, "Terrain Generator, ...... press 'B' to drop the spheres", #PB_Window_ScreenCentered)
  ;AntialiasingMode(#PB_AntialiasingMode_x6)
  If OpenWindowedScreen(WindowID(#Window), 0, 0, WindowW, WindowH, 0, 0, 0)
    
    Add3DArchive("Programs\", #PB_3DArchive_FileSystem)
    Add3DArchive("Scripts\", #PB_3DArchive_FileSystem)
    Add3DArchive("Textures\", #PB_3DArchive_FileSystem)
    ;Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    EnableWorldPhysics(#True)
    
    CreateSprite(#HelpSprite, 300, 145)
    
    ;# Texture that will cover the terrain.
    LoadTexture(#Texture, "grass.jpg")
    CreateMaterial(#Material, TextureID(#Texture))
    
    ;# Greyscale image that will be used for generating the terrain.
    LoadImage(#HeightMap, "Textures\HeightMap00.png")
    

    ;## A FEW NOTES ##
    ;# Stay below 510 tiles total or you will exceed the vertex limit.
    ;# TerrainHeight can have a positive or negative value.
    
    MeshHandle = TG_GenerateTerrain(255, 255, 5, 200, 200, 100, 100, #HeightMap)
    TestHandle = IsMesh(MeshHandle)
    If TestHandle <> 0
      CreateEntity(#Terrain, MeshID(MeshHandle), MaterialID(#Material))
      MaterialCullingMode(#Material, #PB_Material_NoCulling)
      ;RotateEntity(#Terrain, 0,0,180)
      EntityPhysicBody(#Terrain, #PB_Entity_StaticBody)
    EndIf
    
    CreateLight  (#Light, RGB(0,0,0), 0, 500, 1000)
    SetLightColor(#Light, #PB_Light_DiffuseColor, RGB(255,255,255))

    AmbientColor(RGB(50,50,50))
    
    CreateCamera   (#Camera, 0, 0, 100, 100)
    MoveCamera     (#Camera, -20, 100, 270, #PB_Absolute)
    CameraLookAt   (#Camera, 0, 00, 0)
    CameraBackColor(#Camera, RGB(80,80,80))
    CameraRenderMode(#Camera, #PB_Camera_Wireframe)
    RenderMode = 1
    
    SphereMesh = CreateSphere(#PB_Any, 0.4)
    ;CreateCylinder(5, 250, 50,  8,0,0)
    ;CreateEntity(5, MeshID(5),MaterialID(#Material) , 0,-50, 0)
    ;EntityPhysicBody(5, #PB_Entity_StaticBody) 
    CreateCube(5, 1)
    CreateEntity(5, MeshID(5),MaterialID(#Material) , 0,-50, 0)
    ScaleEntity(5, 400,30,400)
    EntityPhysicBody(5, #PB_Entity_StaticBody) 
    ;For CTR = 1 To 10
    
     ; SphereEntity = CreateEntity(#PB_Any, MeshID(SphereMesh), #PB_Material_None, Random(50,0)-25,Random(20,10),Random(50,0)-25)
      ;EntityPhysicBody(SphereEntity, #PB_Entity_SphereBody, 1.0, 0.3, 0.5)
      
    ;Next
    
    ;# WARNING!! If you use stencil shadow types (#PB_Shadow_Modulative or #PB_Shadow_Additive)
    ;and you have over 360 tiles in your terrain the program may crash as you've exceeded the 16 bit index.
    
    ;In this case I personally wouldn't use stencil shadows. As they're not meant to be
    ;used in complex scenes.
    ;If you really want to use stencil shadows. I highly suggest you keep the terrain simple.
    
    ;WorldShadows(#PB_Shadow_Modulative, 100, RGB(150, 150, 150))

    Repeat
      
      Event = WindowEvent()   
      
      If ExamineMouse()
        
        MouseX = -MouseDeltaX() / 10
        MouseY = -MouseDeltaY() / 10
        
      EndIf
      
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_A)
          KeyX = -1.5
        ElseIf KeyboardPushed(#PB_Key_D)
          KeyX = 1.5
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_W)
          KeyY = -1.5
        ElseIf KeyboardPushed(#PB_Key_S)
          KeyY = 1.5
        Else
          KeyY = 0
        EndIf
        
        If KeyboardReleased(#PB_Key_R)
          If RenderMode = 0
            CameraRenderMode(#Camera, #PB_Camera_Wireframe)
            RenderMode = 1
          Else
            CameraRenderMode(#Camera, #PB_Camera_Textured)
            RenderMode = 0
          EndIf
        EndIf
        
        If KeyboardReleased(#PB_Key_H)
          If Help = 0
            Help = 1
          Else
            Help = 0
          EndIf
        EndIf
        
      EndIf
      
      If KeyboardReleased(#PB_Key_B)
      For CTR = 1 To 500
    
      SphereEntity = CreateEntity(#PB_Any, MeshID(SphereMesh), #PB_Material_None, Random(50,0)-25,Random(20,10),Random(50,0)-25)
      EntityPhysicBody(SphereEntity, #PB_Entity_SphereBody , 1.0, 0.3, 0.5)
      ;DisableEntityBody(SphereEntity,0)
    Next
    EndIf
      
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera  (#Camera, KeyX, 0, KeyY)
      
      RenderWorld()
      If Help = 0
        TG_UpdateSprite()
        DisplaySprite(#HelpSprite, 0, 0)
      EndIf
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape)
    
  EndIf
EndIf  

End

Procedure TG_UpdateSprite()
  
  Define.i FPS, Triangles, Batches
  
  FPS       = Engine3DStatus(#PB_Engine3D_CurrentFPS)
  Triangles = Engine3DStatus(#PB_Engine3D_NbRenderedTriangles)
  Batches   = Engine3DStatus(#PB_Engine3D_NbRenderedBatches)
  
  StartDrawing(SpriteOutput(#HelpSprite))
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, 0, SpriteWidth(#HelpSprite), SpriteHeight(#HelpSprite), RGB(20,20,20))
    DrawingFont(FontID(#Font))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(5, 5, "FPS       : " + Str(FPS), RGB(255,0,0))
    DrawText(5, 25, "Triangles : " + Str(Triangles), RGB(0,255,0))
    DrawText(5, 45, "Batches   : " + Str(Batches), RGB(0,128,255))
    DrawText(5, 65, "Press W,A,S,D to Move Camera.", RGB(255,255,255))
    DrawText(5, 85, "Move Mouse to Rotate Camera.", RGB(255,255,255))
    If RenderMode = 0
      DrawText(5, 105, "Press R : Wireframe Off", RGB(255,128,0))
    Else
      DrawText(5, 105, "Press R : Wireframe On", RGB(255,128,0))
    EndIf
    If Help = 0
      DrawText(5, 125, "Press H : Help On", RGB(255,255,0))
    Else
      DrawText(5, 125, "Press H : Help Off", RGB(255,255,0))
    EndIf
  StopDrawing()
  
EndProcedure

Procedure TG_GenerateTerrain(TilesX, TilesZ, TerrainHeight, TerrainSizeX, TerrainSizeZ, TextureRepeatU, TextureRepeatV, HeightMapHandle)
  
  ;# First check and see if all parameters have valid values.
  ;# TerrainHeight can have any value positive or negative. So, we will not be testing for it.
  
  If TilesX <= 0
    MessageRequester("ERROR", "TilesX must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TilesZ <= 0
    MessageRequester("ERROR", "TilesZ must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TerrainSizeX <= 0
    MessageRequester("ERROR", "TerrainSizeX must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TerrainSizeZ <= 0
    MessageRequester("ERROR", "TerrainSizeZ must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TextureRepeatU <= 0
    MessageRequester("ERROR", "TextureRepeatU must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If TextureRepeatV <= 0
    MessageRequester("ERROR", "TextureRepeatV must be greater than 0.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  If IsImage(HeightMapHandle) = 0
    MessageRequester("ERROR", "Failed to find HeightMap.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  ;# Test to make sure terrain will not exceed the 16 bit index limitations (65,536 vertices).
  ;# There are ways around this limitation, but that's for another day.
  Define.i TotalVertices
  
  TotalVertices = (TilesX + 1) * (TilesZ + 1)

  If TotalVertices > 65536
    MessageRequester("ERROR", "Terrain has too many tiles. Vertex limit has been exceeded.", #PB_MessageRequester_Ok)
    ProcedureReturn #False
  EndIf
  
  ;# Generating Vertex Data
  Dim Vertices.d(TotalVertices, 2)
  
  Define.d TileSizeX, TileSizeZ
  
  TileSizeX = TerrainSizeX / TilesX
  TileSizeZ = TerrainSizeZ / TilesZ
  
  Define.d TileLocX, TileLocY, TileLocZ
  
  TileLocX = (TerrainSizeX * 0.5) * -1
  TileLocZ = (TerrainSizeZ * 0.5) * -1
  
  StartDrawing(ImageOutput(HeightMapHandle))
  
    Define.i ImgWidth, ImgHeight
  
    ImgWidth  = ImageWidth (HeightMapHandle) - 1
    ImgHeight = ImageHeight(HeightMapHandle) - 1
    
    Define.d ImgXRatio, ImgZRatio
    
    ImgXRatio = ImgWidth  / TerrainSizeX
    ImgZRatio = ImgHeight / TerrainSizeZ
    
    Define.d HeightRatio
    
    HeightRatio = TerrainHeight / 255
    
    Define.i PixelX, PixelY
    Define.i VCTR, CTRX, CTRZ
    Define.i Color, ColorValue
    
    For CTRZ = 0 To TilesZ
    
      For CTRX = 0 To TilesX
              
        PixelX = ((TerrainSizeX * 0.5) + TileLocX) * ImgXRatio
        PixelY = ((TerrainSizeZ * 0.5) + TileLocZ) * ImgZRatio
        
        Color = Point(PixelX, PixelY)
        
        ColorValue = Red(Color)
        
        TileLocY = ColorValue * HeightRatio
        
        Vertices(VCTR, 0) = TileLocX
        Vertices(VCTR, 1) = TileLocY
        Vertices(VCTR, 2) = TileLocZ
        TileLocX = TileLocX + TileSizeX
        
        VCTR + 1
        
      Next
    
      TileLocX = (TerrainSizeX * 0.5) * -1
      TileLocZ = TileLocZ + TileSizeZ
    
    Next
  StopDrawing()
  
  ;# Generating Face Data
  Define.i TotalFaces
  
  TotalFaces = (TilesX * TilesZ) * 2
  
  Dim Faces(TotalFaces, 2)
  
  Define.i FCTR, FaceCTR
  
  For CTRZ = 0 To TilesZ - 1
    For CTRX = 0 To TilesX - 1
    
      Faces(FCTR, 0) = FaceCTR
      Faces(FCTR, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR, 2) = FaceCTR + 1
      
      Faces(FCTR + 1, 0) = FaceCTR + 1
      Faces(FCTR + 1, 1) = FaceCTR + 1 + TilesX
      Faces(FCTR + 1, 2) = FaceCTR + 2 + TilesX
      
      FCTR + 2
      FaceCTR + 1
    
    Next
    FaceCTR + 1
  Next
  
  ;# Now we can create our terrain
  Define.i UCounter
  Define.d U, V, Uoffset, Voffset

  Uoffset = TextureRepeatU * (1 / TilesX)
  Voffset = TextureRepeatV * (1 / TilesZ)
  
  Handle = CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Static)

    For CTR = 0 To TotalVertices -1
      
      MeshVertexPosition(Vertices(CTR, 0), Vertices(CTR, 1), Vertices(CTR, 2))
      MeshVertexNormal(0, 0, 0)
      MeshVertexTextureCoordinate(U, V)
      
      U = U + Uoffset
      UCounter + 1
      
      If UCounter > TilesX
        UCounter = 0
        U = 0
        V = V + Voffset
      EndIf
      
    Next

    For CTR = 0 To TotalFaces
      MeshFace(Faces(CTR, 0), Faces(CTR, 1), Faces(CTR, 2))
    Next
      
  FinishMesh(#True)
  
  ;# We normalize the mesh because I haven't spent the time to manually calculate the vertex normals.
  ;I might add this process later on, but for now I'll keep it this way.
  
  NormalizeMesh(Handle)
  
  FreeArray(Vertices())
  FreeArray(Faces())
  
  ProcedureReturn Handle

EndProcedure
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Basic Terrain Generator

Post by Samuel »

Hello applePi,
Thank you for the example. When I read that you had noticed this issue with other engines. I decided to do a little more research and this is what I found.
kromenak wrote: This is actually a well-known issue in all of game development that has to do with the way that physics are simulated in games. It is sometimes called the "Bullet Through Paper" problem.

This problem occurs because physics in games is not actually continuous. The game is taking a series of snapshots of your scene (sometimes called "physics steps") and using those snapshots to see if things are colliding. If, in a snapshot, two objects are colliding or overlapping, the physics system can take the correct action and stop the objects from going through one another.

However, a common problem for fast-moving or thin objects is that on one step, the moving object will be falling towards a surface, but then after the object's next position is calculated from its velocity, it has completely moved past the floor or other object. The physics system never sees a snapshot with the two objects touching, so it never thinks they collided.
This sounds a lot like the problem from my original example.
User avatar
zxretrosoft
Enthusiast
Enthusiast
Posts: 171
Joined: Wed May 15, 2013 8:26 am
Location: Czech Republic, Prague
Contact:

Re: Basic Terrain Generator

Post by zxretrosoft »

Samuel wrote:Do you need to have a 13 inch HP laptop? It looks like most of the 13 inch ones only have integrated intel graphics, but some of the bigger ones have AMD graphic cards.

For example this 15.6 inch HP laptop comes with a AMD Radeon HD 8330 graphic card.
http://www.amazon.com/HP-15-d020nr-15-6 ... 180&sr=8-1
Hello Samuel, thanks for everything!
It is difficult. I can not find any notebook with Nvidia or AMD graphics chip.

It's strange. I tried the more expensive notebook, and it did not work. Shaders are not there.
http://www.czc.cz/hp-probook-430-g2-cer ... 73/produkt

Now I want to try, perhaps the last chance, the only laptop with nVidia Geforce card on the market. Very expensive (about 600 USD).
http://www.alza.cz/hp-pavilion-15-r006n ... 939657.htm

But it is strange that it does not work on Intel platform...(?)
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Basic Terrain Generator

Post by Samuel »

The one from your second link looks like it should run everything without a problem.
zxretrosoft wrote: But it is strange that it does not work on Intel platform...(?)
Intel's cpus aren't built for graphics. The main reason they have integrated graphics is just to cover the basic graphic needs of computers (videos and stuff like that). They aren't meant for newer games or anything that's graphic intensive.

Heck, I have a Nividia GeForce FX 5500 that can run most of my basic shaders and it's over ten years old. To me that alone proves that it's better to have a dedicated graphic card over a cpu with integrated graphics.
User avatar
zxretrosoft
Enthusiast
Enthusiast
Posts: 171
Joined: Wed May 15, 2013 8:26 am
Location: Czech Republic, Prague
Contact:

Re: Basic Terrain Generator

Post by zxretrosoft »

Thanks for the answer!

Now I get it:-) Finally:-))

The main problem why I do not understand is that here (in CZ) are not commonly notebooks with dedicated graphics card (nVidia or AMD), but all of them are Intel (integrated).
Why, I do not know. Exceptionally, I found those pieces with AMD or nVidia, although they are expensive. Well, I'll buy some one and let you know;-)

I look forward to the Terrain Generator:-)

Thanks a lot!
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Basic Terrain Generator

Post by applePi »

i have noticed an amazing effect with the Samuel terrain generator file: "Terrain Generator AlphaBlend.pb". if we add material grass.jpg with ScrollMaterial. add these lines:

Code: Select all

AddMaterialLayer(#Material, LoadTexture(32, "grass.jpg"))
ScrollMaterial(#Material, -0.1, 0, #PB_Material_Animated,1)
after line:

Code: Select all

GetScriptMaterial(#Material, "AlphaSplatting")
and enjoy what is like flowing water, it is flowing in the frost spots over the terrain.
note that:
ScrollMaterial(#Material, -0.1, 0, #PB_Material_Animated,1)
if we change -0.1 to +0.1 then the water will reverse its flow direction
download the Terrain generator from page 1, and edit file "Terrain Generator AlphaBlend.pb" as above to see the water effect
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Basic Terrain Generator

Post by Samuel »

zxretrosoft wrote: Thanks a lot!
No problem and I hope you find what your looking for.

applePi wrote: enjoy what is like flowing water, it is flowing in the frost spots over the terrain.
Very nice. 8)
If I was a little more ambitious I might go even further with your flowing water idea and add things like fresnel, reflections, and normal maps for tumbling waters.
Post Reply