Quad Mesh, with cartesian and parametric equations

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Quad Mesh, with cartesian and parametric equations

Post by applePi »

i see quad mesh much more beautiful than triangular mesh: in opengl we use #GL_QUADS such as:
glDrawElements_(#GL_QUADS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
but i can't see how quads is possible in Ogre engine.
first example using cartesian equations, we use structured 2D array to fill the values of height y. press 'W' to toggle between wire/solid frame
Image
note you need to change the plot range in line 180 to suit other functions
i have used the OpenGLGadget special keys. tested in winxp/32 and ubuntu/x64

Code: Select all

Structure Point3D
  x.f
  y.f
  z.f
  tu.f
  tv.f
  r.f
  g.f
  b.f
EndStructure

UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()

Declare FillArray()

Define event, quit

#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"
Dim *Buffer(7)

For i=1 To 7
  Select i
      Case 1
        LoadImage(i, #ImagePath+"Wood.jpg")
        Case 2
          LoadImage(i, #ImagePath+"terrain_texture.jpg")
          Case 3
            LoadImage(i, #ImagePath+"ValetCoeur.jpg")
            Case 4
              LoadImage(i, #ImagePath+"MRAMOR6X6.jpg")
              Case 5
                LoadImage(i, #ImagePath+"Geebee2.bmp")
                Case 6
                  LoadImage(i, #ImagePath+"clouds.jpg")
                  Case 7
                  LoadImage(i, #ImagePath+"Wood.jpg")
   EndSelect 
   *Buffer(i) = EncodeImage(i) ; default is: #PB_ImagePlugin_BMP : encode the image in BMP 
Next

Dim TexID(7)

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press '+' to go to next texture, ..... Up/Down: zoom in/out... 'W': wire frame... 'A'/'Z': change Camera view")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

;- Generate textures
For i = 1 To 7
glGenTextures_(1, @TexID(i))
glBindTexture_(#GL_TEXTURE_2D, TexID(i))
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth(i), ImageHeight(i), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *Buffer(i)+57)
Next

For i=1 To 7
  FreeMemory(*Buffer(i))
Next

glEnable_(#GL_TEXTURE_2D)   ; Enable texture mapping 
glBindTexture_(#GL_TEXTURE_2D, TexID(2)) ; use texture number 1

glLoadIdentity_();
gluPerspective_(45.0, DesktopWidth(0)/DesktopHeight(0), 1.0, 60.0)
glTranslatef_(0, 0, -5)
glEnable_(#GL_DEPTH_TEST)

Global NbX = 100
Global NbZ = 100

Global Dim Point3D.Point3D(NbX,NbZ)
Global Dim MeshDataInd.PB_MeshFace(0)
Global indexsize ;= ArraySize(MeshDataInd()) + 1
;Debug indexsize

FillArray()
  ;Debug indx  
 ;=================================================================================
rot.f = 1
glPointSize_( 3 )  ; tick points in case we use points
;glTranslatef_(0.0, 0.0, -30)
SetActiveGadget(0) ; make the openGLgadget active

glPushMatrix_(); to store the current state
glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, WindowWidth(0)/WindowHeight(0), 1.0, 200.0)
glMatrixMode_(#GL_MODELVIEW)
;glTranslatef_(0, 0, -5)
glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))

gluLookAt_( 0, 20, 30, ; the camera looking from position 0,0.3,0.5  to 0,0,0 from above
            0,  0, 0,
            0,  1,  0 ) 

glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
glPopMatrix_()
glPushMatrix_()
;t=1:
Repeat

  Event = WindowEvent()

  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glClearColor_(0.9, 0.9, 0.9, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
    
  glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
  glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glRotatef_(rot/10, 0, 1, 0);
 
  glVertexPointer_(3, #GL_FLOAT,SizeOf(Point3D),@Point3D(0,0)\x)
  glColorPointer_(3, #GL_FLOAT, SizeOf(Point3D), @Point3D(0,0)\r)
  glTexCoordPointer_(2, #GL_FLOAT, SizeOf(Point3D), @Point3D(0,0)\tu)
  
  ;glDrawElements_(#GL_LINES,indx,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  ;glDrawElements_(#GL_POINTS,indx,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  ;glDrawElements_(#GL_TRIANGLES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  glDrawElements_(#GL_QUADS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  
  glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glDisableClientState_(#GL_COLOR_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY);
  
  If Event = #PB_Event_Gadget And EventGadget() = 0 
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
            If key = #PB_Shortcut_Add
               t+1: If t=8:t=1:EndIf ; go in round trip between textures 1 to 7
               glBindTexture_(#GL_TEXTURE_2D, 0)
               glBindTexture_(#GL_TEXTURE_2D, TexID(t))
               ElseIf key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
            
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL)
                fill ! 1
              EndIf
              ElseIf Key = #PB_Shortcut_Up
                glScalef_(1.05,1.05,1.05)
              ElseIf Key = #PB_Shortcut_Down
                glScalef_(0.95,0.95,0.95)
              ElseIf Key = #PB_Shortcut_A
                glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_()           ;
                gluLookAt_(0, 40, 14,  0,0,0,  0,1,0 ) 
              ElseIf Key = #PB_Shortcut_Z
               glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_();
                gluLookAt_(0, 20, 30,  0,0,0,  0,1,0 )  
                                
            EndIf
               
    EndIf
   EndIf
   
   SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
   Delay(5)
Until Event = #PB_Event_CloseWindow Or quit = 1
For i=1 To 7
      glDeleteTextures_(1, @TexID(i))
Next
    
Procedure FillArray()
    ;xMin.f = -2 : yMin.f = -2: zMin.f = -2 : xMax.f = 2: yMax = 2 : zMax = 2
;xMin.f = -1 : yMin.f = -1: zMin.f = -1 : xMax.f = 1: yMax = 1 : zMax = 1
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
;xMin.f = -30 : yMin.f = -30: zMin.f = -30 : xMax.f = 30: yMax = 30 : zMax = 30
;xMin.f = -12 : yMin.f = -12: zMin.f = -12 : xMax.f = 12: yMax = 12 : zMax = 12
xMin.f = -20 : yMin.f = -20: zMin.f = -20 : xMax.f = 20: yMax = 20 : zMax = 20
;xMin.f = -10 : yMin.f = -10: zMin.f = -10 : xMax.f = 10: yMax = 10 : zMax = 10
  range.f = xMax - xMin
  step1.f = range / NbX
  x.f = xMin: z.f = zMin : y.f = yMin : tu.f: tv.f
    
  For b=0 To NbZ
   
    For a=0 To NbX
      
      ;y.f =5*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) 
      ;y.f = ATan ((z*z*z)/4 - (x*x))
      ;y.f = 1/(15*(x*x+z*z))
      ;y.f = Sin(5*x)*Cos(5*z)/5 ; hills
      ;y.f = 2/Exp((x*5)*(x*5)*(z*5)*(z*5)) ; like '+'
      ;y.f = Log(x*x+z*z)+0.6 ; horn
      ;y.f = Sin(10*(x*x+z*z))/5 ; like waves
      ;y.f = x * x
      ;y.f = 1/(x*x+z*z)
      ;y.f = Cos(x*x+z*z)
      ;y.f = (x*x+z*z)/6
      ;y.f =6*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) 
      y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f =Sqr(5*5-z*z-x*x); sphere real part; x2 + y2 + z2 = r2
      
      ;**********************************************************************            
      
      Point3D(a,b)\x = x*1
      Point3D(a,b)\y = y*1 ; just amplify the height
      Point3D(a,b)\z = z*1
      
      Point3D(a,b)\tu = a/NbX
      Point3D(a,b)\tv = b/NbZ     
      
      If y>=0.05 ; just to color the points above 0.05 in green
        Point3D(a,b)\r = 0.0 :Point3D(a,b)\g = 1.0 :Point3D(a,b)\b = 0 
        Else
        Point3D(a,b)\r = 1 :Point3D(a,b)\g = 1 :Point3D(a,b)\b = 1 
      EndIf
      
      x.f + step1
      
    Next a
    
    x = xMin
    z.f + step1
  Next b
  
   ;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
  
  Nb=NbX+1
  For b=0 To NbZ-1
    For a=0 To NbX-1
      
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1

      MeshDataInd(indx)\Index = P3
      ReDim MeshDataInd.PB_MeshFace(indx+2)
      MeshDataInd(indx+1)\Index = P4
      ReDim MeshDataInd.PB_MeshFace(indx+3)
      MeshDataInd(indx+2)\Index = P2
      ReDim MeshDataInd.PB_MeshFace(indx+4)
      MeshDataInd(indx+3)\Index = P1;P2
 
      indx+4
    Next
  Next
  indexsize = ArraySize(MeshDataInd()) + 1
    EndProcedure
    
  
using parametric equations, we use structured one dimensional array to fill the values
display a tear drop
Image

uncomment lines from 186 to 188 to see a sphere
change line 213 to While v <= 1 * #PI to get semi sphere or semi tear drop
**note: if you don't like the OpenGLGadget special keys (i don't like it also) then use the PB Ogre usual keys by loading the 3d engine together with openglGadget: look my previous example http://purebasic.fr/english/viewtopic.php?f=36&t=65658
tested in winxp/32 and ubunto/x64

Code: Select all

Structure Point3D
  x.f
  y.f
  z.f
  tu.f
  tv.f
  r.f
  g.f
  b.f
EndStructure

UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()

Declare FillArray()
Global.f txu, txv

Define event, quit

#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"
Dim *Buffer(7)

For i=1 To 7
  Select i
      Case 1
        LoadImage(i, #ImagePath+"axes.png")
        Case 2
          LoadImage(i, #ImagePath+"terrain_texture.jpg")
          Case 3
            LoadImage(i, #ImagePath+"ValetCoeur.jpg")
            Case 4
              LoadImage(i, #ImagePath+"MRAMOR6X6.jpg")
              Case 5
                LoadImage(i, #ImagePath+"Geebee2.bmp")
                Case 6
                  LoadImage(i, #ImagePath+"clouds.jpg")
                  Case 7
                  LoadImage(i, #ImagePath+"Wood.jpg")
   EndSelect 
   *Buffer(i) = EncodeImage(i) ; default is: #PB_ImagePlugin_BMP : encode the image in BMP 
Next

Dim TexID(7)

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press '+' to go to next texture, ..... Up/Down: zoom in/out... 'W': wire frame... 'A'/'Z': change Camera view")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

;- Generate textures
For i = 1 To 7
glGenTextures_(1, @TexID(i))
glBindTexture_(#GL_TEXTURE_2D, TexID(i))
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth(i), ImageHeight(i), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *Buffer(i)+57)
Next

For i=1 To 7
  FreeMemory(*Buffer(i))
Next

glEnable_(#GL_TEXTURE_2D)   ; Enable texture mapping 
glBindTexture_(#GL_TEXTURE_2D, TexID(1))

glLoadIdentity_();
gluPerspective_(45.0, DesktopWidth(0)/DesktopHeight(0), 1.0, 60.0)
glTranslatef_(0, 0, -5)
glEnable_(#GL_DEPTH_TEST)

Global NbX = 100
Global NbZ = 100

Global Dim Point3D.Point3D(0)
Global Dim MeshDataInd.PB_MeshFace(0)
Global indexsize ;= ArraySize(MeshDataInd()) + 1
;Debug indexsize

;FillArray()
FillArray()
  ;Debug VertexIndex  
 ;=================================================================================
rot.f = 1
;glPointSize_( 3 )  
;glTranslatef_(0.0, 0.0, -30)
SetActiveGadget(0) ; make the openGLgadget active

glPushMatrix_(); to store the current state
glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, WindowWidth(0)/WindowHeight(0), 1.0, 800.0)
glMatrixMode_(#GL_MODELVIEW)
glTranslatef_(0, 0, -1)
glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))

gluLookAt_( 0, 1, 1, ; the camera looking from position 0,0.3,0.5  to 0,0,0 from above
            0,  0, 0,
            0,  1,  0 ) 

glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
glPopMatrix_()
glPushMatrix_()
t=1: zz=30
;Debug indexsize
Repeat
  
  Event = WindowEvent()
  
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glClearColor_(0.9, 0.9, 0.9, 1)
  ;glClearColor_(0.3, 0.3, 0.3, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
    
  glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
  glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glRotatef_(rot/5, 0, 1, 0);
 
  glVertexPointer_(3, #GL_FLOAT,SizeOf(Point3D),@Point3D(0)\x)
  glColorPointer_(3, #GL_FLOAT, SizeOf(Point3D), @Point3D(0)\r)
  glTexCoordPointer_(2, #GL_FLOAT, SizeOf(Point3D), @Point3D(0)\tu)
  
  ;glDrawElements_(#GL_LINES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  ;glDrawElements_(#GL_POINTS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  ;glDrawElements_(#GL_TRIANGLES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  glDrawElements_(#GL_QUADS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  
  glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glDisableClientState_(#GL_COLOR_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY);
  
  If Event = #PB_Event_Gadget And EventGadget() = 0 
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
            If key = #PB_Shortcut_Add
               t+1: If t=8:t=1:EndIf ; go in round trip between textures 1 to 7
               glBindTexture_(#GL_TEXTURE_2D, 0)
               glBindTexture_(#GL_TEXTURE_2D, TexID(t))
               ElseIf key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
            
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE)
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL )
                fill ! 1
              EndIf
              ElseIf Key = #PB_Shortcut_Up
                glScalef_(1.05,1.05,1.05)
              ElseIf Key = #PB_Shortcut_Down
                glScalef_(0.95,0.95,0.95)
              ElseIf Key = #PB_Shortcut_A
                glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_()           ;
                gluLookAt_(0, 3, 1,  0,0,0,  0,1,0 ) 
              ElseIf Key = #PB_Shortcut_Z
               glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_();
                gluLookAt_(0, 1, 2,  0,0,0,  0,1,0 )  
                                
            EndIf
               
    EndIf
   EndIf
   
   SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
   Delay(5)
Until Event = #PB_Event_CloseWindow Or quit = 1
For i=1 To 7
      glDeleteTextures_(1, @TexID(i))
    Next
    

Macro Vertex(u, v, txu, txv)
  ;this produce very beautiful shape
  x.f = 0.5 * (1 - Cos(u)) * Sin(u) * Cos(v)
  y.f = 0.5 * (1 - Cos(u)) * Sin(u) * Sin(v)
  z.f = Cos(u)
  ;this produce a sphere shape
  ;x.f = 0.5 * Cos(u)* Sin(v)
  ;y.f = 0.5 * Sin(u)* Sin(v)
  ;z.f = 0.5 * Cos(v)
  
  ReDim Point3D.Point3D(a)
  Point3D(a)\x = x*1
  Point3D(a)\y = y*1
  Point3D(a)\z = z*1
  
  Point3D(a)\tu = txu
  Point3D(a)\tv = txv
  
  Point3D(a)\r = 1.0 :Point3D(a)\g = 1.0 :Point3D(a)\b = 1
  
  a+1
      
  
EndMacro

Procedure FillArray()
  
  Protected.f u, v, Delta = 4*#PI/NbX ; change 4 to 2 to get more quads
  Protected.f x, y, z
  txu.f : txv.f
  ;Debug delta  
  u = 0
  v = 0
  While v <= 2 * #PI
    
    While u <= 1 * #PI ; change 2 to 1 and will get half of the object
  
      Vertex(u, v, txu, txv)
      Vertex(u + Delta, v, txu+u/NbX*#PI, txv)
      Vertex(u + Delta, v + Delta, txu+u/NbX*#PI, txv+v/NbX*#PI)
      Vertex(u, v + Delta, txu, txv+v/NbX*#PI)
      txu = txu + u/NbX*#PI ; for texturing
      
      ReDim MeshDataInd.PB_MeshFace(VertexIndex+4)
      MeshDataInd(VertexIndex)\Index = VertexIndex   + 0
      MeshDataInd(VertexIndex+1)\Index = VertexIndex + 1
      MeshDataInd(VertexIndex+2)\Index = VertexIndex + 2
      MeshDataInd(VertexIndex+3)\Index = VertexIndex + 3

      VertexIndex + 4
            
      u + Delta
      
    Wend
    txu = 0
    txv = txv + v/NbX*1*#PI ; for texturing
    u = 0
    v + Delta
  Wend
  
  indexsize = ArraySize(MeshDataInd())
  ;Debug indexsize
    
  ;Debug VertexIndex
EndProcedure
    
  
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Quad Mesh, with cartesian and parametric equations

Post by Keya »

that is insanely cool!!!!! :)
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Quad Mesh, with cartesian and parametric equations

Post by IdeasVacuum »

That is excellent applePi - going into the realm of CAD. 8)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Quad Mesh, with cartesian and parametric equations

Post by applePi »

thank you Keya and IdeasVacuum
adding mobius strip and klein bottle with quad mesh and parametric equations . with OpenGLGadget
http://paulbourke.net/geometry/mobius/
http://paulbourke.net/geometry/klein/
mobius strip:
Image

Image

note that the vertices in order like in the figure, at the end we twist the strip 180 degree
vertex 0 is Point3D(0), vertex 1 is Point3D(1)... etc
while
MeshDataInd(0)\Index = 0
MeshDataInd(1)\Index = 1
MeshDataInd(2)\Index = 3
MeshDataInd(3)\Index = 2
means connect vertex 0 to ver 1 then vert 3 then vert 2 to form quad
and what determines the quad is the #GL_QUADS in this line while walking through MeshDataInd array :
glDrawElements_(#GL_QUADS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)

Code: Select all

Structure Point3D
  x.f
  y.f
  z.f
  tu.f
  tv.f
  r.f
  g.f
  b.f
EndStructure

UseJPEGImageDecoder()

Declare FillArray()
Global.f txu, txv, x,y,z, u,v

Define event, quit

#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"

LoadImage(0, #ImagePath+"Wood.jpg")
*Buffer = EncodeImage(0) ; default is: #PB_ImagePlugin_BMP : encode the image in BMP 
TexID = 0

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "keys Up/Down: zoom in/out......  'W': wire/solid frame...")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

;- Generate textures

glGenTextures_(1, @TexID)
glBindTexture_(#GL_TEXTURE_2D, TexID)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth(i), ImageHeight(i), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *Buffer+57)

FreeMemory(*Buffer)

glEnable_(#GL_TEXTURE_2D)   ; Enable texture mapping 
glBindTexture_(#GL_TEXTURE_2D, TexID)

glLoadIdentity_();
gluPerspective_(45.0, DesktopWidth(0)/DesktopHeight(0), 1.0, 60.0)
glTranslatef_(0, 0, -5)
glEnable_(#GL_DEPTH_TEST)

Global Dim Point3D.Point3D(0)
Global Dim MeshDataInd.PB_MeshFace(0)
Global indexsize 

FillArray()
;=================================================================================
rot.f = 1
;glPointSize_( 3 ) 
glLineWidth_(2)
;glTranslatef_(0.0, 0.0, -30)
SetActiveGadget(0) ; make the openGLgadget active

glPushMatrix_(); to store the current state
glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, WindowWidth(0)/WindowHeight(0), 1.0, 800.0)
glMatrixMode_(#GL_MODELVIEW)
;glTranslatef_(0, 0, -1)
glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))

gluLookAt_( 0, 2, 2.5, ; the camera looking from position 0,0.3,0.5  to 0,0,0 from above
            0,  0, 0,
            0,  1,  0 ) 

glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
glPopMatrix_()
glPushMatrix_()
glRotatef_(80, 1, 0, 0);

Repeat
  Event = WindowEvent()
  
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glClearColor_(0.6, 0.7, 0.6, 1)
  ;glClearColor_(0.3, 0.3, 0.3, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
    
  glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
  glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glRotatef_(rot/5, 0, 0, 1);
 
  glVertexPointer_(3, #GL_FLOAT,SizeOf(Point3D),@Point3D(0)\x)
  glColorPointer_(3, #GL_FLOAT, SizeOf(Point3D), @Point3D(0)\r)
  glTexCoordPointer_(2, #GL_FLOAT, SizeOf(Point3D), @Point3D(0)\tu)
    
  ;glDrawElements_(#GL_LINES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  ;glDrawElements_(#GL_POINTS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  ;glDrawElements_(#GL_TRIANGLES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  glDrawElements_(#GL_QUADS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  
  glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glDisableClientState_(#GL_COLOR_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY);
  
  If Event = #PB_Event_Gadget And EventGadget() = 0 
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
          
               If key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
            
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE)
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL )
                fill ! 1
              EndIf
              ElseIf Key = #PB_Shortcut_Up
                glScalef_(1.05,1.05,1.05)
              ElseIf Key = #PB_Shortcut_Down
                glScalef_(0.95,0.95,0.95)
              
            EndIf
               
    EndIf
   EndIf
   
   SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
   Delay(5)
Until Event = #PB_Event_CloseWindow Or quit = 1

glDeleteTextures_(1, @TexID)


Procedure FillArray()
x.f: y.f :z.f : u.f: v.f: r.f
a.l =0
v.f = -0.5 :  u.f=0 :txu.f : txv.f
While u <= 2*#PI
  
  While v<= 0.5
       x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) )
			 y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) )
			 z = v/2 * Sin(u/2)
			       
       ;Vertex(u, v, txu, txv)
	     ReDim Point3D.Point3D(a)
      ;MeshVertexPosition(x, y, z);			 
       Point3D(a)\x = x*1
       Point3D(a)\y = y*1
       Point3D(a)\z = z*1
  
       Point3D(a)\tu = txu
       Point3D(a)\tv = txv
  
       Point3D(a)\r = 1.0 :Point3D(a)\g = 1.0 :Point3D(a)\b = 1
       
       Select a ; just to color the first 4 vertices green 
           Case 0,1,2,3
         Point3D(a)\r = 0.0 :Point3D(a)\g = 1.0 :Point3D(a)\b = 0
       EndSelect

       a+1
       txv = txv + 1 ; texture coordinates
         
         v + 1
       Wend
       txv = 0
        txu = txu + 1/(2*#PI/0.1) ;texture coordinates
        v = -0.5
        u + 0.1
      Wend
      ;Debug a ; here 126 vertices from 0 to 125
      
      For j=0 To a-3 Step 2
        ReDim MeshDataInd.PB_MeshFace(Index+4)
        MeshDataInd(Index+0)\Index = j   + 0
        MeshDataInd(Index+1)\Index = j   + 1
        MeshDataInd(Index+2)\Index = j   + 3
        MeshDataInd(Index+3)\Index = j   + 2

        Index + 4
     
      Next
      
      ;connecting the first 2 vertices index with the last 2 vertices (twisted!!!)
        ReDim MeshDataInd.PB_MeshFace(Index+4)
        MeshDataInd(Index+0)\Index = 124
        MeshDataInd(Index+1)\Index = 125
        MeshDataInd(Index+2)\Index = 0
        MeshDataInd(Index+3)\Index = 1
        
      ;MeshFace(0,125,1)
      ;MeshFace(1,125,124)
  indexsize = ArraySize(MeshDataInd())
;Debug indexsize
EndProcedure
    
  


klein bottle:
Image
there is a problem with klein bottle, its wall intercept its handle in a way if we throw a ball will stuck at its mouth, look at it in wire mode, there should be other formula somewhere

Code: Select all

Structure Point3D
  x.f
  y.f
  z.f
  tu.f
  tv.f
  r.f
  g.f
  b.f
EndStructure

UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()

Declare FillArray()
Global.f txu, txv

Define event, quit

#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"

LoadImage(0, #ImagePath+"Wood.jpg")
*Buffer = EncodeImage(0) ; default is: #PB_ImagePlugin_BMP : encode the image in BMP 

TexID = 0

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "Up/Down: zoom in/out... 'W': wire frame ")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

;- Generate textures

glGenTextures_(1, @TexID)
glBindTexture_(#GL_TEXTURE_2D, TexID)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth(i), ImageHeight(i), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *Buffer+57)

FreeMemory(*Buffer)

glEnable_(#GL_TEXTURE_2D)   ; Enable texture mapping 
glBindTexture_(#GL_TEXTURE_2D, TexID)

glLoadIdentity_();
gluPerspective_(45.0, DesktopWidth(0)/DesktopHeight(0), 1.0, 60.0)
glTranslatef_(0, 0, -5)
glEnable_(#GL_DEPTH_TEST)


Global Dim Point3D.Point3D(0)
Global Dim MeshDataInd.PB_MeshFace(0)
Global indexsize 

FillArray()
 
 ;=================================================================================
rot.f = 1
;glPointSize_( 3 ) 
;glLineWidth_(2)
;glTranslatef_(0.0, 0.0, -30)
SetActiveGadget(0) ; make the openGLgadget active

glPushMatrix_(); to store the current state
glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, WindowWidth(0)/WindowHeight(0), 1.0, 800.0)
glMatrixMode_(#GL_MODELVIEW)
;glTranslatef_(0, 0, -1)
glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))

gluLookAt_( 0, 40, 50, ; the camera looking from position 0,0.3,0.5  to 0,0,0 from above
            0,  0, 0,
            0,  1,  0 ) 

;glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
glPopMatrix_()
glPushMatrix_()
glRotatef_(180, 1, 0, 0);

Repeat
  
  Event = WindowEvent()
  
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glClearColor_(0.6, 0.7, 0.6, 1)
  ;glClearColor_(0.3, 0.3, 0.3, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
    
  glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
  ;glEnableClientState_(#GL_NORMAL_ARRAY);
  glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glRotatef_(rot/5, 0, 1, 0);
 
  glVertexPointer_(3, #GL_FLOAT,SizeOf(Point3D),@Point3D(0)\x)
  glColorPointer_(3, #GL_FLOAT, SizeOf(Point3D), @Point3D(0)\r)
  glTexCoordPointer_(2, #GL_FLOAT, SizeOf(Point3D), @Point3D(0)\tu)
  ;glNormalPointer_(#GL_FLOAT,SizeOf(Point3D),@Point3D(0)\nx)
  
  ;glDrawElements_(#GL_LINES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  ;glDrawElements_(#GL_POINTS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  ;glDrawElements_(#GL_TRIANGLES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  glDrawElements_(#GL_QUADS,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  
  glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  ;glDisableClientState_(#GL_NORMAL_ARRAY)
  glDisableClientState_(#GL_COLOR_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY);
  
  If Event = #PB_Event_Gadget And EventGadget() = 0 
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
          
               If key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
            
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL)
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
                fill ! 1
              EndIf
              ElseIf Key = #PB_Shortcut_Up
                glScalef_(1.05,1.05,1.05)
              ElseIf Key = #PB_Shortcut_Down
                glScalef_(0.95,0.95,0.95)
              
            EndIf
               
    EndIf
   EndIf
   
   SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
   Delay(5)
Until Event = #PB_Event_CloseWindow Or quit = 1

glDeleteTextures_(1, @TexID)

Macro Vertex(u, v, txu, txv)

 r.f = 4 * (1 - (Cos(u)/2)) 
 If u <= #PI
     x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(u) * Cos (v)
     y = 16 * Sin(u) + r * Sin(u) * Cos(v)
 ElseIf u > #PI And u <=2*#PI   
     x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(v+#PI)
     y = 16 * Sin(u)
 EndIf
   
 z.f = r * Sin(v)
  
  ReDim Point3D.Point3D(a)
  Point3D(a)\x = x*1
  Point3D(a)\y = y*1
  Point3D(a)\z = z*1
  
  Point3D(a)\tu = txu
  Point3D(a)\tv = txv
  
  
  Point3D(a)\r = 1.0 :Point3D(a)\g = 1.0 :Point3D(a)\b = 1
  
  a+1
  
EndMacro

Procedure FillArray()
  NbX = 50
  NbZ = 50
  Nb=NbX
  Protected.f u, v, Delta = 2*#PI/NbX ; change 4 to 2 to get more quads
  Protected.f x, y, z
  txu.f : txv.f
  ;Debug delta  
    
      For i = 0 To NbX
        v = i * Delta
        For j = 0 To NbZ
          u = j * Delta
          
      Vertex(u, v, txu, txv)
      Vertex(u + Delta, v, txu+u/Nb, txv)
      Vertex(u + Delta, v + Delta, txu+u/Nb, txv+v/Nb)
      Vertex(u, v + Delta, txu, txv+v/Nb)
      txu = txu + u/Nb ; for texturing
      
      ReDim MeshDataInd.PB_MeshFace(VertexIndex+4)
      MeshDataInd(VertexIndex)\Index = VertexIndex   + 0
      MeshDataInd(VertexIndex+1)\Index = VertexIndex + 1
      MeshDataInd(VertexIndex+2)\Index = VertexIndex + 2
      MeshDataInd(VertexIndex+3)\Index = VertexIndex + 3

      VertexIndex + 4
    
    Next
  
    txu = 0
    txv = txv + v/Nb ; for texturing
 
  Next
 
  indexsize = ArraySize(MeshDataInd())

EndProcedure
    
  
Last edited by applePi on Wed May 25, 2016 9:39 am, edited 2 times in total.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Quad Mesh, with cartesian and parametric equations

Post by IdeasVacuum »

...yeah, the klein bottle is a sort of optical illusion. That geometry is not so easy to construct in CAD, but with CAD you can build portions at a time, trim surfaces where they intersect etc.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Quad Mesh, with cartesian and parametric equations

Post by applePi »

from practical viewpoint the following is a quad mesh in PB 3D engine .
in example MeshManual2.pb there is this code:

Code: Select all

 ;- Mesh Plane (using MeshIndex)
    CreateMesh(4, #PB_Mesh_LineStrip, #PB_Mesh_Static)
    ; Define vertex position of index 0..3
    MeshVertexPosition(-10, 0, -10) 
    MeshVertexPosition(-10, 0,  10) 
    MeshVertexPosition( 10, 0,  10) 
    MeshVertexPosition( 10, 0, -10)
    ; Define usage of vertices by referring To the indexes
    MeshIndex(0)
    MeshIndex(1)
    MeshIndex(2)
    MeshIndex(3)
    MeshIndex(0)
    FinishMesh(#False)
so there is other ways to weave the mesh, other than MeshFace() which accepts only 3 vertex indices to make a triangle or say a face.
in the Doc of MeshIndex(): It behaves like the command MeshFace(), but with an arbitrary number of vertices.
so why not to use this method to make a Quad Mesh ? : the following is an application of this method to create quad mesh terrain. and to make things more interesting i have added it to a compound entity, and then added a house. all the construction have physics body and rotating .
the only Sin of this method is that we can't extend the texture between the mesh lines since we have used CreateMesh(#terrain, #PB_Mesh_LineList, #PB_Mesh_Static)
in the usual triangular mesh we use #PB_Mesh_TriangleList to enable texturing. if there is something like #PB_Mesh_QuadList then we can texture the Quad mesh conveniently.
Image
Note: to display math function instead of a terrain uncomment line 171
y.f = Sin(Sqr(a*a+ b*b))*30 / Sqr(a*a + b*b)

works only in PB 5.50 because the addition of a compound entity
tested in windows xp/32
save this picture to the same folder as the code:
Image

Code: Select all

UsePNGImageDecoder()
UseJPEGImageDecoder()

Enumeration
  #Window
  #Camera
  #sphere
  #terrain
         
EndEnumeration

Global Dim MeshData.PB_MeshVertex(0)

#CameraSpeed = 1

Declare DrawMatrix()

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  
  Add3DArchive(".", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3D/Data/Models", #PB_3DArchive_FileSystem)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)

If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, " ....mouse+arrow keys for the camera ")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)
    
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 0, 110, 120, #PB_Absolute)
    CameraLookAt(#Camera,0,0,0)
    CameraBackColor(#Camera, RGB(254,236,186))
    
    LoadTexture(2, "Wood.jpg")
    CreateMaterial(1, LoadTexture(1, "Geebee2.bmp")) ;MRAMOR6X6
    MaterialCullingMode(1, #PB_Material_NoCulling)
    ;AddMaterialLayer(1, TextureID(2) , #PB_Material_Modulate) 
    
    CreateMaterial(0, LoadTexture(0, "terrain_texture.jpg"))
    ;CreateMaterial(0, LoadTexture(0, "white.jpg"))
    MaterialCullingMode(0, #PB_Material_NoCulling)
    CreateMaterial(3, LoadTexture(3, "nskingr.jpg"))
    CreateMaterial(6, LoadTexture(6, "fw12b.jpg"))
    MaterialCullingMode(6, #PB_Material_NoCulling)
    
    CreateLight(0, RGB(255, 255, 255), 100, 100, 0)
    AmbientColor(RGB(250, 250, 250))
  
  EndIf
EndIf
 
 ;*******************************************
Global terrain = CreateEntity(#PB_Any,0,0)

DrawMatrix() ; call the terrain mesh building proc

AddSubEntity(terrain, #terrain, #PB_Entity_StaticBody)

wireFrame = 1

CreateEntityBody(#terrain, #PB_Entity_StaticBody ,1,1,1)
;WorldShadows(#PB_Shadow_Modulative)
LoadMesh(9, "tudorhouse.mesh")
TransformMesh(9,20,15,-35, 0.01,0.01,0.01,0,0,0)
CreateEntity(9, MeshID(9),MaterialID(6))
AddSubEntity(terrain, 9, #PB_Entity_StaticBody)
CreateEntityBody(terrain, #PB_Entity_CompoundBody, 0, 1, 1)


CreateSphere(#sphere,2)
CreateEntity(#sphere, MeshID(#sphere), MaterialID(3), 10,35,0)
CreateEntityBody(#sphere, #PB_Entity_ConvexHullBody  ,1,0.5,1)
WorldGravity(-20) ; the gravity here is twice the normal

;WorldDebug( #PB_World_DebugEntity)
;WorldDebug(#PB_World_DebugBody)

Repeat
  Repeat 
  Until WindowEvent()=0
          
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
                
      If ExamineKeyboard()
           
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
                
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
            MaterialShadingMode(1, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
            MaterialShadingMode(1, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
            
      EndIf
      DisableEntityBody(#terrain, #False)
      DisableEntityBody(#sphere, #False)
            
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
      
      RotateEntity(terrain, 0,0.1,0, #PB_Relative)
      RenderWorld()
           
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End


Procedure DrawMatrix()

Dim TerrainData.l(100, 100) ; to fill it with red color values of the height map image.
LoadImage(0, "terrain.png")
ResizeImage(0, 100+1, 100+1) ; just for resizing images bigger than 100x100
StartDrawing(ImageOutput(0))
 For z=0 To 100
   For x=0 To 100
   colr=Point(x,z)
     TerrainData(x,z)=Red(colr)
   Next
 Next
 StopDrawing()
 
 ; now building the terrain mesh
  CreateMesh(#terrain, #PB_Mesh_LineList, #PB_Mesh_Static)
  Protected.l a, b, Nb
  Protected.w P1, P2, P3, P4
  TileSize = 1 ; the size of every square in the grid, make it bigger for less squares number in Nb, Nb
  ; as an example for Nb=10: Nb=10 let TileSize = 10 to get the same visual terrain size as before
    
  Nb = 100 ;; number of squares acroos x, and acroos z
  
  For b=-Nb/2 To Nb/2
      
      For a = -Nb/2 To Nb/2
      
      y.f = TerrainData(a+Nb/2,b+Nb/2)/10 ; divide by 10 is just a choice to make y smaller 
      ;y.f = Sin(Sqr(a*a+ b*b))*30 / Sqr(a*a + b*b)
      MeshVertexPosition(TileSize*a, y, TileSize*b )
      MeshVertexNormal(0,1,0) 
      MeshVertexTextureCoordinate((a+Nb/2)/Nb, (b+Nb/2)/Nb)
    
       
    Next
    Next
     
   ;Define usage of vertices by referring To the indexes
   ;ie weaving a quad mesh
    For b = 0 To Nb-1
      
      For a = 0 To Nb-1
        
        MeshIndex(ind) : MeshIndex(ind+1)
        MeshIndex(ind+1) : MeshIndex(ind+Nb+2)
        MeshIndex(ind+Nb+2) :MeshIndex(ind+Nb+1) 
        MeshIndex(ind+Nb+1) :MeshIndex(ind) 
        ind + 1 
        
      Next
      ind + 1
    Next
    
  ; at the end we have made a big grid deformed up and down according to y in line 149
  FinishMesh(#True)
  UpdateMeshBoundingBox(#terrain)
  SetMeshMaterial(#terrain, MaterialID(1))
    
  CreateEntity(#terrain, MeshID(#terrain), #PB_Material_None)
  
EndProcedure 
Post Reply