Page 1 of 1

mesh clockwise & anticlockwise, and the shadow

Posted: Fri Jan 09, 2015 6:07 pm
by applePi
not too much but may interest someone .
this is to show that clockwise and anticlockwise have an effect on the shadow. in ogre it should be anticlockwise. ... how to look at the 3D scene http://purebasic.com/documentation/engine3d/index.html
look at this:
the default shadow is Modulative, now we can use 'W' key to toggle wire frame or solid frame
now uncomment line 45 : WorldShadows(#PB_Shadow_Additive ) and we can't use the 'W" key any more. even we can show the wire frame if we added MaterialShadingMode(#tex, #PB_Material_Wireframe ) before the Repeat loop

also i have noticed that we should add NormalizeMesh(..) before FinishMesh(#True) and not after it.
Image

Code: Select all

Declare CreateMatrix()

#CameraSpeed = 0.3
Define.f KeyX, KeyY, MouseX, MouseY

Enumeration
  #mesh
  #entity
  #tex
  #light
  #camera
  #material
EndEnumeration

InitEngine3D(#PB_Engine3D_DebugLog)
InitSprite()
InitKeyboard()
InitMouse()

ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)
OpenWindow(0, 0, 0, DesktopW, DesktopH, "press 'W' wire/solid Frame ....'Space': stop rotation .....mouse+arrow keys for the camera ")
  OpenWindowedScreen(WindowID(0), 0, 0, DesktopW, DesktopH, 0, 0, 0)
    

Add3DArchive(".", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)

KeyboardMode(#PB_Keyboard_AllowSystemKeys)

CreateMaterial(#material, LoadTexture(#material, "MRAMOR6X6.jpg"))
CreatePlane(500, 30, 30, 5, 5, 2, 2)
CreateEntity(500, MeshID(500), MaterialID(#material), 0,-16,0)

CreateLight(0,RGB(245,245,205),19,13,0)

;Create Camera
CreateCamera(0,0,0,100,100)
MoveCamera(0,0,12,-35,#PB_Absolute)
CameraLookAt(0, 0, -13, 0)

AmbientColor(RGB(100,100,100))

CreateMaterial(#tex, LoadTexture(#tex, "Geebee2.bmp"))
MaterialCullingMode(#tex, #PB_Material_NoCulling)
;MaterialShadingMode(#tex, #PB_Material_Wireframe  )

WorldShadows(#PB_Shadow_Modulative  , -1, RGB(100, 100, 100))
;WorldShadows(#PB_Shadow_Additive )

;-Mesh
CreateMatrix()


wireFrame = 1 : rot=1
Repeat
  Repeat
  Until WindowEvent()=0
  
  If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.2
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.2
      EndIf
  ShowCursor_(0)
    
; Use arrow keys and mouse to rotate camera and fly in/out
  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(#tex, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
            MaterialShadingMode(#tex, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
        
      If KeyboardReleased(#PB_Key_Space) ;press key to toggle the rotation of the object
    rot ! 1
  EndIf
    
  
  RotateEntity(#entity, 0, rot, 0,#PB_Relative)
  
  RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
  MoveCamera  (0, KeyX, 0, KeyY)
  
  RenderWorld()
  
  FlipBuffers()

Until KeyboardPushed(#PB_Key_Escape) Or WindowEvent() = #PB_Event_CloseWindow

;main drawing routine
Procedure DrawMatrix()
  
      MeshVertexPosition(-5, 0, 6)
      MeshVertexNormal(0,1,0) 
      MeshVertexTextureCoordinate(0, 0)
      
      MeshVertexPosition(5, 0, 6)
      MeshVertexNormal(0,1,0)
      MeshVertexTextureCoordinate(1, 0)
      
      MeshVertexPosition(5, 0, -6)
      MeshVertexNormal(0,1,0) 
      MeshVertexTextureCoordinate(1, 1)
      
      MeshVertexPosition(2, 0, -6)
      MeshVertexNormal(0,1,0) 
      MeshVertexTextureCoordinate(1, 1)
      
      MeshVertexPosition(-8, 0, -6)
      MeshVertexNormal(0,1,0) 
      MeshVertexTextureCoordinate(0, 1)
      
      MeshVertexPosition(-8, 0, 6)
      MeshVertexNormal(0,1,0) 
      MeshVertexTextureCoordinate(0, 0)
     
      
      MeshFace(0, 1, 2)
      MeshFace(3, 4, 5)
      
      ;MeshFace(2, 1, 0)
      ;MeshFace(5, 4, 3)
      
  
EndProcedure 

Procedure CreateMatrix()
  
  CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
  DrawMatrix()
  NormalizeMesh(0) ; works
  FinishMesh(#True)
  ;NormalizeMesh(0) ; does not work
  
  SetMeshMaterial(0, MaterialID(#tex))
  CreateEntity(#entity, MeshID(0), MaterialID(#tex),0,-10,0)
      
EndProcedure


Re: mesh clockwise & anticlockwise, and the shadow

Posted: Fri Jan 09, 2015 7:10 pm
by Samuel
applePi wrote: this is to show that clockwise and anticlockwise have an effect on the shadow. in ogre it should be anticlockwise. ... how to look at the 3D scene http://purebasic.com/documentation/engine3d/index.html

also i have noticed that we should add NormalizeMesh(..) before FinishMesh(#True) and not after it.
I wonder if you have found a bug with the shadows. Because the face direction only sets which side of the triangle is to be rendered. Anticlockwise is towards you and clockwise should be away.
In your example though the mesh can completely disappear leaving only a small shadow that doesn't even match the objects scale.

The part that should affect the shadows is the normals. The normals set which direction each vertex is to receive light and the shadows need this in order to render correctly. But your mesh has normals, although in order for it to work you had to move NormalizeMesh() before the FinishMesh() command. Which I can't figure out why that works.

I made another little example for testing. I created two custom planes each anticlockwise and I normalized each after mesh creation. The shadows are rendered correctly which seems to be the opposite affect your example has when you move your NormalizeMesh() outside the FinishMesh().
Also try rendering the smaller plane clockwise. It should disappear because only the backside can be rendered, but it doesn't leave any shadow artifacts behind.

Code: Select all

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

Enumeration
  #Window
  #Camera
  #Light
  #Texture
  #Material
  #Plane
  #Mesh
  #Entity1
  #Entity2
EndEnumeration

#Clockwise     = 0
#AntiClockwise = 1

Declare CustomMesh(Size.d, Direction.i)

ExamineDesktops()
WinW = DesktopWidth(0)
WinH = DesktopHeight(0)

If OpenWindow(#Window, 0, 0, WinW, WinH, "Custom Mesh with shadows")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, WinW, WinH)

    CreateTexture(#Texture, 128, 128)
    StartDrawing(TextureOutput(#Texture))
      Box( 0,  0, 64, 64, RGB(200,200,200))
      Box(64,  0, 64, 64, RGB(0,200,200))
      Box(64, 64, 64, 64, RGB(200,200,200))
      Box( 0, 64, 64, 64, RGB(0,200,200))
    StopDrawing()
    CreateMaterial(#Material, TextureID(#Texture))
    
    Handle = CustomMesh(5, #AntiClockwise)
    If IsMesh(Handle) <> 0
      CreateEntity(#Entity1, MeshID(Handle), MaterialID(#Material), 0, 0, 0)
    EndIf
    
    
    ;Try setting this one to #Clockwise.
    ;It will be invisible because it's rendering the backside only.
    Handle = CustomMesh(1, #AntiClockwise)
    ;Handle = CustomMesh(1, #Clockwise)
    If IsMesh(Handle) <> 0
      CreateEntity(#Entity2, MeshID(Handle), MaterialID(#Material), 0, 1, 0)
    EndIf
    
    CreateLight(#Light, RGB(255,255,255), 10, 10, 10)
    
    CreateCamera   (#Camera, 0, 0, 100, 100)
    MoveCamera     (#Camera, 0, 10, 10)
    CameraLookAt   (#Camera, 0, 0, 0)
    CameraBackColor(#Camera, RGB(30,30,30))
    
    WorldShadows(#PB_Shadow_Modulative, 1000, RGB(100, 100, 100))
    
    ;CameraRenderMode(#Camera, #PB_Camera_Wireframe)
    
    Repeat
  
      Event = WindowEvent()
  
      ExamineKeyboard()
      
      RotateEntity(#Entity2, 0, 1, 0, #PB_Relative)
      
      FlipBuffers()
      RenderWorld()
  
    Until Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)

  EndIf
EndIf
End

Procedure CustomMesh(Size.d, Direction.i)
  
  MeshHandle = CreateMesh(#PB_Any)

    MeshVertexPosition(-Size, 0, -Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(0, 0)
      
    MeshVertexPosition(Size, 0, -Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(1, 0)
    
    MeshVertexPosition(-Size, 0, Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(0, 1)
    
    MeshVertexPosition(Size, 0, Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(1, 1)
    
    If Direction = #Clockwise
      
      MeshFace(0, 1, 2)
      MeshFace(1, 3, 2)
      
    ElseIf Direction = #AntiClockwise
      
      MeshFace(0, 2, 1)
      MeshFace(1, 2, 3)
      
    EndIf
    
  FinishMesh(#True)
    
  NormalizeMesh(MeshHandle)
  
  ProcedureReturn MeshHandle

EndProcedure

Re: mesh clockwise & anticlockwise, and the shadow

Posted: Fri Jan 09, 2015 9:29 pm
by applePi
thanks Samuel for the valuable example which have many tips, i find it very usefull .
i have used your plane procedure to cast the shadow over it, but for a strange reason it disappears unless we write the NormalizeMesh(MeshHandle) before FinishMesh(#True) .
if we disabled the shadow then the plane will appear again. and there is no difference (in my example if we use for the ground plane a clockwise or anticlockwise regarding this issue.

Code: Select all

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

Declare CreateMatrix()
Declare CustomMesh(Size.d, Direction.i)

#CameraSpeed = 1
#Clockwise     = 0
#AntiClockwise = 1

Enumeration
  #mesh
  #entity
  #tex
  #Light
  #Camera
  #Texture
  #Material
  #Entity1
  
EndEnumeration

;InitEngine3D(#PB_Engine3D_DebugLog)
;InitSprite()
;InitKeyboard()
InitMouse()

OpenWindow(0,0,0,1024,768,"about shadow")
OpenWindowedScreen(WindowID(0),0,0,1024,768)

Add3DArchive(".", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)

KeyboardMode(#PB_Keyboard_AllowSystemKeys)


CreateLight(0,RGB(245,245,205),19,13,0)

;Create Camera
CreateCamera(0,0,0,100,100)
MoveCamera(0,0,12,35,#PB_Absolute)
CameraLookAt(0, 0, -16, 0)

AmbientColor(RGB(100,100,100))

CreateMaterial(#tex, LoadTexture(#tex, "Geebee2.bmp"))
MaterialCullingMode(#tex, #PB_Material_NoCulling)
;MaterialShadingMode(#tex, #PB_Material_Wireframe  )

;WorldShadows(#PB_Shadow_Modulative  , -1, RGB(100, 100, 100))
WorldShadows(#PB_Shadow_Modulative, 1000, RGB(100, 100, 100))
;WorldShadows(#PB_Shadow_Additive )

;-Mesh
CreateMatrix() ;create the smaller plane

CreateTexture(#Texture, 128, 128)
    StartDrawing(TextureOutput(#Texture))
      Box( 0,  0, 64, 64, RGB(200,200,200))
      Box(64,  0, 64, 64, RGB(0,200,200))
      Box(64, 64, 64, 64, RGB(200,200,200))
      Box( 0, 64, 64, 64, RGB(0,200,200))
    StopDrawing()
CreateMaterial(#Material, TextureID(#Texture))
MaterialCullingMode(#Material, #PB_Material_NoCulling)

    Handle = CustomMesh(15, #AntiClockwise)
    If IsMesh(Handle) <> 0
       CreateEntity(#Entity1, MeshID(Handle), MaterialID(#Material), 0, -16, 0)
    EndIf

wireFrame = 1
Repeat
  WindowEvent()
  
  If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.2
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.2
      EndIf
  ShowCursor_(0)
    
; Use arrow keys and mouse to rotate camera and fly in/out
  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(#tex, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
            MaterialShadingMode(#tex, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
        
      If KeyboardReleased(#PB_Key_Space) ;press key to toggle the rotation of the object
    temp ! 1
  EndIf
    
  
  RotateEntity(#entity, 0, 1, 0,#PB_Relative)
  
  RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
  MoveCamera  (0, KeyX, 0, KeyY)
  
  RenderWorld()
  
  FlipBuffers()

Until KeyboardPushed(#PB_Key_Escape) Or WindowEvent() = #PB_Event_CloseWindow

;main drawing routine
Procedure DrawMatrix()
  
      MeshVertexPosition(-5, 0, 6)
      MeshVertexNormal(0,0,0) 
      MeshVertexTextureCoordinate(0, 0)
      
      MeshVertexPosition(5, 0, 6)
      MeshVertexNormal(0,0,0)
      MeshVertexTextureCoordinate(1, 0)
      
      MeshVertexPosition(5, 0, -6)
      MeshVertexNormal(0,0,0) 
      MeshVertexTextureCoordinate(1, 1)
      
      MeshVertexPosition(2, 0, -6)
      MeshVertexNormal(0,0,0) 
      MeshVertexTextureCoordinate(1, 1)
      
      MeshVertexPosition(-8, 0, -6)
      MeshVertexNormal(0,0,0) 
      MeshVertexTextureCoordinate(0, 1)
      
      MeshVertexPosition(-8, 0, 6)
      MeshVertexNormal(0,0,0) 
      MeshVertexTextureCoordinate(0, 0)
     
      
      MeshFace(0, 1, 2)
      MeshFace(3, 4, 5)
      
      ;MeshFace(2, 1, 0)
      ;MeshFace(5, 4, 3)
      
  
EndProcedure 

Procedure CreateMatrix()
  
  CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
  DrawMatrix()
  NormalizeMesh(0) ; works
  FinishMesh(#True)
  ;NormalizeMesh(0) ; does not work
  
  SetMeshMaterial(0, MaterialID(#tex))
  CreateEntity(#entity, MeshID(0), MaterialID(#tex),0,-10,0)
      
EndProcedure
;1024,768
Procedure CustomMesh(Size.d, Direction.i)
  
  MeshHandle = CreateMesh(#PB_Any)

    MeshVertexPosition(-Size, 0, -Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(0, 0)
      
    MeshVertexPosition(Size, 0, -Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(1, 0)
    
    MeshVertexPosition(-Size, 0, Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(0, 1)
    
    MeshVertexPosition(Size, 0, Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(1, 1)
    
    If Direction = #Clockwise
      
      MeshFace(0, 1, 2)
      MeshFace(1, 3, 2)
      
    ElseIf Direction = #AntiClockwise
      
      MeshFace(0, 2, 1)
      MeshFace(1, 2, 3)
      
    EndIf
  NormalizeMesh(MeshHandle)  
  FinishMesh(#True)
    
  ;NormalizeMesh(MeshHandle)
  
  ProcedureReturn MeshHandle

EndProcedure

Re: mesh clockwise & anticlockwise, and the shadow

Posted: Fri Jan 09, 2015 10:08 pm
by Samuel
I think I found the bug. If the shadows are turned on before mesh creation the entities are invisible, but if you turn them on afterwards everything works like it should.
I altered my code to show it. Just change the variable ShadowTime from #Before to #After to see the differences.

Code: Select all

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

Enumeration
  #Window
  #Camera
  #Light
  #Texture
  #Material
  #Plane
  #Mesh
  #Entity1
  #Entity2
EndEnumeration

#Clockwise     = 0
#AntiClockwise = 1

#Before = 0
#After  = 1

Declare CustomMesh(Size.d, Direction.i)

ExamineDesktops()
WinW = DesktopWidth(0)
WinH = DesktopHeight(0)

; Try #After to make the shadows and the entities appear.
ShadowTime = #Before

If OpenWindow(#Window, 0, 0, WinW, WinH, "Custom Mesh with shadows")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, WinW, WinH)
    
    ; BUG!!! If you activate the worldshadows before mesh creation the entities will not be visible,
    ; It needs to be moved below the mesh creation.
    If ShadowTime = #Before
      WorldShadows(#PB_Shadow_Modulative, 1000, RGB(100, 100, 100))
    EndIf
      
    CreateTexture(#Texture, 128, 128)
    StartDrawing(TextureOutput(#Texture))
      Box( 0,  0, 64, 64, RGB(200,200,200))
      Box(64,  0, 64, 64, RGB(0,200,200))
      Box(64, 64, 64, 64, RGB(200,200,200))
      Box( 0, 64, 64, 64, RGB(0,200,200))
    StopDrawing()
    CreateMaterial(#Material, TextureID(#Texture))
    
    Handle = CustomMesh(5, #AntiClockwise)
    If IsMesh(Handle) <> 0
      CreateEntity(#Entity1, MeshID(Handle), MaterialID(#Material), 0, 0, 0)
    EndIf
    
    
    ;Try setting this one to #Clockwise.
    ;It will be invisible because it's rendering the backside only.
    Handle = CustomMesh(1, #AntiClockwise)
    ;Handle = CustomMesh(1, #Clockwise)
    If IsMesh(Handle) <> 0
      CreateEntity(#Entity2, MeshID(Handle), MaterialID(#Material), 0, 1, 0)
    EndIf
    
    CreateLight(#Light, RGB(255,255,255), 10, 10, 10)
    
    CreateCamera   (#Camera, 0, 0, 100, 100)
    MoveCamera     (#Camera, 0, 10, 10)
    CameraLookAt   (#Camera, 0, 0, 0)
    CameraBackColor(#Camera, RGB(30,30,30))
    
    ; The shadows will work when enabled after the mesh creation.
    If ShadowTime = #After
      WorldShadows(#PB_Shadow_Modulative, 1000, RGB(100, 100, 100))
    EndIf
    
    ;CameraRenderMode(#Camera, #PB_Camera_Wireframe)
    
    Repeat
  
      Event = WindowEvent()
  
      ExamineKeyboard()
      
      RotateEntity(#Entity2, 0, 1, 0, #PB_Relative)
      
      FlipBuffers()
      RenderWorld()
  
    Until Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)

  EndIf
EndIf
End

Procedure CustomMesh(Size.d, Direction.i)
  
  MeshHandle = CreateMesh(#PB_Any)

    MeshVertexPosition(-Size, 0, -Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(0, 0)
      
    MeshVertexPosition(Size, 0, -Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(1, 0)
    
    MeshVertexPosition(-Size, 0, Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(0, 1)
    
    MeshVertexPosition(Size, 0, Size)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTextureCoordinate(1, 1)
    
    If Direction = #Clockwise
      
      MeshFace(0, 1, 2)
      MeshFace(1, 3, 2)
      
    ElseIf Direction = #AntiClockwise
      
      MeshFace(0, 2, 1)
      MeshFace(1, 2, 3)
      
    EndIf
    
  FinishMesh(#True)
    
  NormalizeMesh(MeshHandle)
  
  ProcedureReturn MeshHandle

EndProcedure