Creating a simple cube manually

Everything related to 3D programming
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Creating a simple cube manually

Post by mrw »

Hi,
I have tried to create a simple cube manually by using the CreateMesh and other Mesh-commands.
I want it to behave and look exactly as CreateCube when coding it as:

Code: Select all

CreateCube(0, 1)
CreateEntity(0, MeshID(0), #PB_Material_None)
My cube have the correct vertex-coordinates and faces but how should I set other things like normals?
I would prefer to only set the color and not have to use a Material and texture, if possible.

I have noticed that the cube created with CreateCube has 36 triangles, when my cube uses 12. Perhaps the desired effect is not possible with only 12 polygons? Or rather to use 24 vertices and 12 triangles?

In my attempts I have a light that travels around so I can see the shadows, and my cubes shadows look weird and "choppy". Not the same as cubes created with the code above.

Can anyone help me with how to do this?
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Creating a simple cube manually

Post by mrw »

Ok, I redid the cube using 24 vertices and 12 triangles.
But if I use NormalizeMesh() the cube goes completely dark without any light or shadows on it.
And if I set every vertex with MeshVertexNormal() I get some light and shadows, but they don´t look correct.
How should I calculate correct normals? Or what else needs to be done?
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Creating a simple cube manually

Post by mrw »

Well I´m apparently solving this myself as I go ;)

Now the light and shadows is correct.
My setup for the top side of the cube is:

Code: Select all

MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(0,1,0)
And then I create 2 faces facing out/up.
So what remains is to set the colors on each vertex. If I just add MeshVertexColor() to each vertex it doesn´t make any difference at all.
Any ideas?
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Creating a simple cube manually

Post by applePi »

mrw, to set color to each vertex. we must use something like this:
CreateMaterial(#texWhite, LoadTexture(#texWhite, "white.jpg"))
MaterialCullingMode(#texWhite, #PB_Material_NoCulling)
DisableMaterialLighting(#texWhite, #True)
ie the material should not be lighted

and since we have used for the mesh creation #PB_Mesh_TriangleList then every vertex color will be extended to the neighbors
note we have used
SetMeshMaterial(0, MaterialID(0))
CreateEntity(0, MeshID(0), #PB_Material_None , 0,-10,0)

this is to show you a demo using a plane (but copied to a mesh created with CreateMesh(0,...) the MeshVertexPosition/Color will act on that mesh) which i was testing 2 days ago, hope it is helpfull

Code: Select all

Enumeration
   
   #LIGHT
   #CAMERA
   #mainwin
   #Plane
  #sphere
  
EndEnumeration

Structure vector3d
  x.f
  y.f
  z.f
EndStructure

Structure vertex
  x.f
  y.f
  z.f
EndStructure


Define.f KeyX, KeyY, MouseX, MouseY

Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)

ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "press 'W' to toggle wire/solid frame, ... use mouse + Arrows to rotate + move Camera", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

Define.f KeyX, KeyY

Declare CreateMatrix()


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)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts",#PB_3DArchive_FileSystem)
    
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0), 0, 0, 0)
    
  
    CreateMaterial(0, LoadTexture(0, "White.jpg"))
    DisableMaterialLighting(0, #True)
    MaterialShadingMode(0, #PB_Material_Wireframe     )
    MaterialCullingMode(0, #PB_Material_NoCulling)
            
    CreateCamera(#camera, 0, 0, 100, 100)
    MoveCamera(#camera, 0, 5, 0.1, #PB_Absolute)
    CameraFOV(#camera, 70)
    CameraBackColor(#camera, RGB(100,100,100))
    CameraLookAt(#camera,0,0,0)
        
    CreateLight(0, RGB(255,255,255), 0, 20, 30)
    AmbientColor(RGB(200, 200, 200))
    
    CreateMatrix() ; call the plane generator
              
             
    Repeat
      Repeat
      Event = WindowEvent()
    Until Event = 0
    
        
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
      
          
      If ExamineKeyboard()
        
         If KeyboardReleased(#PB_Key_W)
          If wireFrame
          MaterialShadingMode(0, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
          MaterialShadingMode(0, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
      EndIf
         
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -0.5
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = 0.5
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -0.5
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = 0.5
        Else
          KeyY = 0
        EndIf
        
        
       If KeyboardReleased(#PB_Key_S)
          ;SaveMesh(0, "plane10x10.mesh")
        EndIf         
        EndIf
       
        rot.f+0.6
        RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
      
      RenderWorld()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End


Procedure CreateMatrix()
  CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
  ;CreateMesh(0, #PB_Mesh_PointList , #PB_Mesh_Dynamic)
  
  CreatePlane(1, 10,10,10,10,10,10)
  
  GetMeshData(1,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(1)-1)
  GetMeshData(1,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(1, 0)-1)
  ArrSize = ArraySize(MeshData())
  
   ;main mesh: the ground or the Table
   For c=0 To ArrSize
      
      x.f = MeshData(c)\x 
      y.f = MeshData(c)\y
      z.f = MeshData(c)\z
      MeshVertexPosition(x,y,z)
      MeshVertexColor(RGB(Random(255,10),Random(255,10),Random(255,10)))
      ;MeshVertexTextureCoordinate(MeshData(c)\u, MeshData(c)\v) 
         
   Next   
   
   ArrSizeInd = ArraySize(MeshDataInd()) 
   For i=0 To ArrSizeInd Step 3
     MeshFace(MeshDataInd(i)\Index, MeshDataInd(i+1)\Index,MeshDataInd(i+2)\Index)
   Next
   
   
  FinishMesh(#True)
  SetMeshMaterial(0, MaterialID(0))
    
  CreateEntity(0, MeshID(0), #PB_Material_None , 0,-10,0)
  
    
EndProcedure
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Creating a simple cube manually

Post by mrw »

Nice example! Thanks!

But what you basically are saying is that to be able to set vertexcolors(and to be able to see it..), I need to define and use a Material first?
Oh well, I guess I need to advance into OGRE scripts then.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Creating a simple cube manually

Post by applePi »

i suppose a theory that to color the vertex with MeshVertexColor(..) it has no effect until we assign a material to the mesh in which the vertex one of the mesh components. look example meshmanual2.pb in the examples. (i have a strong memory that there is an other way example (like you want), but can't find it, can't remember how it was successful once upon time for me, very strange)
to go the script way. i have a very little knowledge but i have found this little example which does not need any picture ( but it needs a script file :wink: )
save this as points.material (or any name with extension .material)

Code: Select all

material Just_Point
{
   receive_shadows off
   technique
   {
      pass
      {
         point_size 5
         lighting off
         diffuse vertexcolour
      }
   }
}
the material name here is: Just_Point
we need this material file to be in one of the 3d files path and here it is

Code: Select all

Add3DArchive(".", #PB_3DArchive_FileSystem)
Parse3DScripts()
"." searches the current folder of the code demo.
also we don't need DisableMaterialLighting(0, #True) because it is available in the lighting off in the script material

Code: Select all

ExamineDesktops()
If OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), " Big Points", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-10, 0, 0, 0)

InitKeyboard()
SetFrameRate(60)

Add3DArchive(".", #PB_3DArchive_FileSystem)
Parse3DScripts()

CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))

CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 2, 9)
CameraLookAt(0, 0, 2, 0)

RotateCamera(0, -15, 0, 0)
EndIf

CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Dynamic )

GetScriptMaterial(0, "Just_Point")
SetMeshMaterial(1, MaterialID(0))
;DisableMaterialLighting(0, #True)

Global Stars = CreateNode(#PB_Any)
AttachNodeObject(Stars, MeshID(1))

MeshVertexPosition(-0.175999999,0.0016000271,0.1156001091)
MeshVertexColor(RGB(0,255,0))
MeshVertexPosition(-0.4800000191,0.0239999294,-0.4963999987)
MeshVertexColor(RGB(255,255,0))
MeshVertexPosition(0.0624001026,-0.5196000338,-0.1699999571)
MeshVertexColor(RGB(255,0,0))
MeshVertexPosition(-0.1563999653,0.4960000515,-0.9924000502)
MeshVertexColor(RGB(0,255,0))
FinishMesh(#False)
;NormalizeMesh(1)

;Main loop
Repeat
  Repeat
      Event = WindowEvent()
  Until Event = 0 Or Event = #PB_Event_CloseWindow
  
    y + 1
   RotateNode(Stars, x, y, z)
   
   RenderWorld()
   FlipBuffers()

  ExamineKeyboard()
    
  Until KeyboardPushed(#PB_Key_Escape) Or Event = #PB_Event_CloseWindow
EDIT:: the same example above but with CreateEntity instead of the Node

Code: Select all

ExamineDesktops()
If OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), " Big Points", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-10, 0, 0, 0)

InitKeyboard()
SetFrameRate(60)

Add3DArchive(".", #PB_3DArchive_FileSystem)
Parse3DScripts()

CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))

CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 2, 9)
CameraLookAt(0, 0, 2, 0)

RotateCamera(0, -15, 0, 0)
EndIf

CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Static )

GetScriptMaterial(0, "Just_Point")
SetMeshMaterial(1, MaterialID(0))
;DisableMaterialLighting(0, #True)


MeshVertexPosition(-0.2,0.001,0.2)
MeshVertexColor(RGB(0,255,0))
MeshVertexPosition(-0.5,0.1,-0.6)
MeshVertexColor(RGB(255,255,0))
MeshVertexPosition(0.1,-0.5,-0.2)
MeshVertexColor(RGB(255,0,0))
MeshVertexPosition(-0.3,0.5,-1)
MeshVertexColor(RGB(0,255,0))
;NormalizeMesh(1) ; works here but not necessary
FinishMesh(#True)

CreateEntity(1, MeshID(1), #PB_Material_None)
;NormalizeMesh(1) using this here with entity made from mesh points will cause invalid memory access error
;CreateEntityBody(1, #PB_Entity_BoxBody,1,0.5,1 ) ; using this will give the entity a weight and will fall down
;Main loop
Repeat
  Repeat
      Event = WindowEvent()
  Until Event = 0 Or Event = #PB_Event_CloseWindow

   RotateEntity(1, 0, 1, 0, #PB_Relative )
   
   RenderWorld()
   FlipBuffers()

  ExamineKeyboard()
    
  Until KeyboardPushed(#PB_Key_Escape) Or Event = #PB_Event_CloseWindow
Edit2: if you don't want pictures or scripts, just the code, then
create immediate material:

Code: Select all

CreateTexture(0,32,32)
  StartDrawing(TextureOutput(0))
    Box(0,0,32,32,RGB(255,255,255))
  StopDrawing()
CreateMaterial(0,TextureID(0))
MaterialCullingMode(0, #PB_Material_NoCulling)
DisableMaterialLighting(0, #True)
then

Code: Select all

CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Static )
SetMeshMaterial(1, MaterialID(0))

MeshVertexPosition(-0.2,0.001,0.2)
MeshVertexColor(RGB(0,255,0))
.... etc
but note the points are small and not big like the one with script
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Creating a simple cube manually

Post by mrw »

Ok, thanks for all help. I think I got how to set vertexcolors.
So, switching to use a texture instead I ofcourse got problems.

My main issue is to get my manual meshcube to look exactly like CreateCube() which it doesn´t.

I have created a materialscript that loads a simple small texture.
I can easily apply that to both the CreateCube() and my own manual cube. But my mesh is not getting the texture but the CreateCube() does.
I assumed that I just needed to set the UV coordinates for the vertexes but no matter what I set I don´t get any texture.

So I must be missing something to make this work. I´m guessing in the manual mesh creation.
Can anyone tell my what I´m doing wrong?

My materialscript looks like this ATM:

Code: Select all

material Texture1
{
    receive_shadows on    
    technique
    {
       pass
        {
          ambient 0.8 0.8 0.8 1.0
          diffuse 0.64 0.64 0.64 1.0
          specular 0.5 0.5 0.5 1.0 12.5
          emissive 0.0 0.0 0.0 1.0
          lighting on
          shading gouraud
          transparent_sorting on
          texture_unit
          {
            texture texture1.png
            scale 1.0 1.0
            colour_op replace
            filtering none
          }
       }   
    }
 }
My world is set up with(not complete code but just some important settings):

Code: Select all

WorldShadows(#PB_Shadow_Additive)
AmbientColor(RGB(80, 80, 100))
CreateLight(#PB_Any, RGB(201, 226, 255), 0, 3000, 0)
CameraBackColor(0, RGB(70, 100, 182))
GetScriptMaterial(75, "Texture1")
And to create the builtin cube I have:

Code: Select all

CreateCube(0, 1)
CreateEntity(0, MeshID(0), MaterialID(75))
My own manual cube is 24 vertices and 12 triangles. Each side has its own 4 vertices. And It´s only on the 4 last vertices I have set UV and that is the top side of the cube

Code: Select all

CreateMesh(4)
  
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(0,0,-1) 
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(0,0,-1)
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(0,0,-1)
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(0,0,-1)
    
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(0,0,1) 
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(0,0,1)
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(0,0,1)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(0,0,1)
    
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(-1,0,0)
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(-1,0,0)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(-1,0,0)
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(-1,0,0)
    
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(1,0,0)  
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(1,0,0)
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(1,0,0) 
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(1,0,0)
    
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(0,1,0) 
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(0,1,0) 
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(0,1,0)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(0,1,0)
    
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(0,0)
    
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(1,0)
    
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(1,1)
    
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(0,1)
;
MeshFace(0, 2, 3)
MeshFace(0, 1, 2)
MeshFace(4, 6, 5)
MeshFace(4, 7, 6)
MeshFace(8, 10, 9)
MeshFace(8, 11, 10)
MeshFace(12, 14, 13)
MeshFace(13, 14, 15)
MeshFace(16, 17, 18)
MeshFace(16, 18, 19)
MeshFace(20, 23, 21)
MeshFace(21, 23, 22)
    
FinishMesh(#True)
    
BuildMeshShadowVolume(4)

CreateEntity(4, MeshID(4), MaterialID(75))
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Creating a simple cube manually

Post by applePi »

to texture a cube according to UV coordinates, here is an example using your vertices and meshfaces connections
i will texture every cube face with part of the texture which is this picture
Image
so save it to the code folder, togethor with your material script above http://purebasic.fr/english/viewtopic.p ... 34#p485570
the texture picture coordinates is going usualy from 0 to 1 horizontally and 0 to 1 vertically, so in the case of a cube we will divide it horizontally by 6. in fact we can texture the face top with number 3 at the nose of the smiley in the picture if we know exactly its positions and then dividing the positions by the hz and vrt dimensions of the picture to get the numbers for UV as fractions between 0 to 1

Code: Select all

Declare DrawCube()


Define.f keyX, keyY, MouseX, MouseY, CameraSpeed = 0.5

Enumeration
  #mesh
  #entity
  #light
  #camera
  #tex2
  
EndEnumeration

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

ExamineDesktops()

OpenWindow(0,0,0,DesktopWidth(0), DesktopHeight(0),"Cube ... press 'W' to toggle wire/solid frame ... move/rotate camera with arrows and mouse ",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,DesktopWidth(0), DesktopHeight(0),1,0,0,#PB_Screen_WaitSynchronization)

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

Global texture = GetScriptMaterial(#PB_Any, "Texture1")
MaterialCullingMode(texture, #PB_Material_NoCulling)

KeyboardMode(#PB_Keyboard_AllowSystemKeys)

CreateMaterial(#tex2, LoadTexture(#tex2, "Wood.jpg"))
MaterialCullingMode(#tex2, #PB_Material_NoCulling)

CreatePlane(500, 30, 30, 1, 1, 1, 1)
CreateEntity(500, MeshID(500), MaterialID(#tex2), 0,-10,0)

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

;Create Camera
CreateCamera(0,0,0,100,100)
MoveCamera(0,0,20, 50,#PB_Absolute)
CameraLookAt(0, 0, 0, 0)
CameraBackColor(0, RGB(0,200,200))

AmbientColor(RGB(100,100,100))

;-Mesh
DrawCube()

wireFrame = 1 : rot=1
;WorldShadows(#PB_Shadow_Additive)

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.f = -CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX.f = 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(texture, #PB_Material_Wireframe)
      
          wireFrame ! 1
        Else 
          MaterialShadingMode(texture, #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(0, 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 DrawCube()
CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
;back
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(0,0,-1) 
MeshVertexTextureCoordinate(1/6, 0)
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(0,0,-1)
MeshVertexTextureCoordinate(0,0)
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(0,0,-1)
MeshVertexTextureCoordinate(0,1)
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(0,0,-1)
MeshVertexTextureCoordinate(1/6, 1)
;front    
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(0,0,1) 
MeshVertexTextureCoordinate(1/6, 0)
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(0,0,1)
MeshVertexTextureCoordinate(2/6, 0)
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(0,0,1)
MeshVertexTextureCoordinate(2/6, 1)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(0,0,1)
MeshVertexTextureCoordinate(1/6, 1)
;left    
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(-1,0,0)
MeshVertexTextureCoordinate(4/6, 0)
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(-1,0,0)
MeshVertexTextureCoordinate(5/6, 0)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(-1,0,0)
MeshVertexTextureCoordinate(5/6, 1)
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(-1,0,0)
MeshVertexTextureCoordinate(4/6, 1)
;right    
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(1,0,0)
MeshVertexTextureCoordinate(4/6, 0)
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(1,0,0)
MeshVertexTextureCoordinate(4/6, 1)
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(1,0,0) 
MeshVertexTextureCoordinate(3/6, 0)
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(1,0,0)
MeshVertexTextureCoordinate(3/6, 1)
;bottom    
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(5/6, 1)
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(0,1,0) 
MeshVertexTextureCoordinate(6/6, 1)
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(6/6, 0)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(5/6, 0)
;top    
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(2/6,0)
    
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(3/6,0)
    
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(3/6,1)
    
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(2/6,1)

; connecting vertices together
MeshFace(0, 2, 3)
MeshFace(0, 1, 2)
MeshFace(4, 6, 5)
MeshFace(4, 7, 6)
MeshFace(8, 10, 9)
MeshFace(8, 11, 10)
MeshFace(12, 14, 13)
MeshFace(13, 14, 15)
MeshFace(16, 17, 18)
MeshFace(16, 18, 19)
MeshFace(20, 23, 21)
MeshFace(21, 23, 22)
      
FinishMesh(#True)
SetMeshMaterial(0, MaterialID(texture))      
      
CreateEntity(0, MeshID(0),  MaterialID(texture) ,0,0,0)
    
EndProcedure




another way to make a cube from submeshes here
http://purebasic.fr/english/viewtopic.p ... 27#p460831

Edit: extraction of the UV for the '3' on the nose of the smiley face. will display 3 on the cube top

Code: Select all

;top    
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(209/510, 32/74 )
    
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(219/510, 32/74)
    
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(219/510, 50/74)
    
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(209/510, 50/74)
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Creating a simple cube manually

Post by mrw »

Thanks to your code I got it to work!

I couldn´t see any significant different between your setup and mine, and when I simply copied your mesh-creation code(vertex, normal, uv) over mine the cube showed texture.
And the only difference in that code was that you defined UVs for EVERY vertex. I had only done the top side, which I assumed would be enough to display a texture on that side.
And strangely when I added the UVs to the back side, both the back side and the top showed. Which is correct but really weird that I had to add the back UV to get the top side texture to show.

Any explanation to this?
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Creating a simple cube manually

Post by applePi »

i have noticed now what you means, it seems to me that we should add the info about uv from top to bottom of vertices creation after the CreateMesh, so in the example above if we add the uv info for the back face (which is the first) then it will be textured even if it is assigned the uv numbers alone. if you want the top face (the last one in the code) to be textured alone then put it at the top after createMesh(...) but then you need to re make the MeshFace again.
in concise we must assign UV numbers to the first face then we can consider other faces
first face : is the one created immediately after CreateMesh
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Creating a simple cube manually

Post by mrw »

I´m guessing this has to do with the way PureBasic(or OGRE) works when creating meshes. It all starts from the first. If the creation was more dynamic and allowed the MeshVertexXXX(#vertexindex) some indexnumber so we could add the vertices and triangles in any order we like, then probably you could just add those UVs you want and skip the rest.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Creating a simple cube manually

Post by applePi »

it is possible to access and manipulate any part of the mesh after you make it first. you want to texture only the cube top using the uv numbers even it is the last defined cube face.
the cube top info described in this picture
Image
the solution is to copy the cube mesh to a special structured array with function GetMeshData, and in the structured array change anything (positions, uv, etc) and save it again to the mesh with function SetMeshData.
in the following we will manipulate the cube top : do these experiments:
1- press 'D' you will see the cube top go up 1 unit, press D again and again. look procedure deform() to see how it is done.
2- press 'U' all the faces textures will be textured white and then will texture again the top face as smiley face texture , look procedure change_uv()
other notes:
MeshDataInd(30)\Index refer to vertex 20. and we access vertex 20 y data either with:
MeshData(20)\y
or
MeshData(MeshDataInd(30)\Index)\y
the array MeshDataInd(..)\Index contains the vertices numbers sequence in which every triple of points define a triangle. it is a tricky concept but structured and working okay.
save this picture to same folder as the code
Image

Code: Select all

Declare DrawCube()
Declare triangle(num.l)
Declare change_uv()
Declare deform()

Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)

Define.f keyX, keyY, MouseX, MouseY, CameraSpeed = 0.5

Enumeration
  #mesh
  #entity
  #light
  #camera
  #tex2
  #cube
  #sphere
  
EndEnumeration

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

ExamineDesktops()

OpenWindow(0,0,0,DesktopWidth(0), DesktopHeight(0),"'W' toggle wire/solid .... 'U' call change_uv ...'D' deform cube top ... 'space' .. tell what triangle the sphere on .. arrows+mouse Cam ",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,DesktopWidth(0), DesktopHeight(0),1,0,0,#PB_Screen_WaitSynchronization)

Add3DArchive(".", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
Parse3DScripts()
Global monitor=CreateSprite(#PB_Any,120,40)

;Global texture = GetScriptMaterial(#PB_Any, "Texture1")
Global texture = CreateMaterial(#PB_Any, LoadTexture(222, "texture1.png"))
;MaterialShadingMode(texture, #PB_Material_Wireframe)
MaterialCullingMode(texture, #PB_Material_NoCulling)

KeyboardMode(#PB_Keyboard_AllowSystemKeys)

CreateMaterial(#tex2, LoadTexture(#tex2, "Wood.jpg"))
MaterialCullingMode(#tex2, #PB_Material_NoCulling)

CreatePlane(500, 30, 30, 1, 1, 1, 1)
CreateEntity(500, MeshID(500), MaterialID(#tex2), 0,-10,0)

CreateLight(0,RGB(255,255,255),6,13,0)

;Create Camera
CreateCamera(0,0,0,100,100)
MoveCamera(0,0,20, 50,#PB_Absolute)
CameraLookAt(0, 0, 0, 0)
CameraBackColor(0, RGB(0,200,200))

AmbientColor(RGB(255,255,255))
CreateSphere(#sphere, 0.5)
CreateEntity(#sphere, MeshID(#sphere),  #PB_Material_None  ,0,2,0)


;-Mesh
DrawCube()
GetMeshData(#mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Color | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Tangent , 0, MeshVertexCount(#Mesh)-1)
GetMeshData(#mesh,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(#mesh, 0)-1)
;Debug MeshIndexCount(#mesh)/3

wireFrame = 1 : rot=0
;WorldShadows(#PB_Shadow_Additive)
Global tri=0
triangle(tri)
      
SetMeshData(#mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Color | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Tangent, 0, MeshVertexCount(#mesh)-1)
UpdateMeshBoundingBox(#mesh)
    
Global deform = 0
    
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.f = -CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX.f = 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(texture, #PB_Material_Wireframe)
      
          wireFrame ! 1
        Else 
          MaterialShadingMode(texture, #PB_Material_Solid)

          wireFrame ! 1
        EndIf
      EndIf
      
      If KeyboardReleased(#PB_Key_D)
         deform()
        
       EndIf
       
       If KeyboardReleased(#PB_Key_U)
         change_uv()
        
      EndIf
      
      If KeyboardReleased(#PB_Key_Space)
          tri+1
          If tri*3 > MeshIndexCount(#mesh)-1
            tri=0
          EndIf
          
          triangle(tri)
                    
      EndIf
        
      
  
  RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
  MoveCamera  (0, KeyX, 0, KeyY)
  
  RenderWorld()
  StartDrawing(SpriteOutput(monitor))
  DrawText(5,5,"the ball in Triangle " )
  DrawText(5,20,"Triangle= " +"      ")
  DrawText(5,20,"Triangle= " +Str(tri))
  StopDrawing()
  DisplaySprite(monitor,0,0)
      
  
  FlipBuffers()

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

;main drawing routine
Procedure DrawCube()
CreateMesh(#mesh, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
;back
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(0,0,-1) 
MeshVertexTextureCoordinate(1/6, 0)
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(0,0,-1)
MeshVertexTextureCoordinate(0,0)
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(0,0,-1)
MeshVertexTextureCoordinate(0,1)
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(0,0,-1)
MeshVertexTextureCoordinate(1/6, 1)
;front    
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(0,0,1) 
MeshVertexTextureCoordinate(1/6, 0)
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(0,0,1)
MeshVertexTextureCoordinate(2/6, 0)
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(0,0,1)
MeshVertexTextureCoordinate(2/6, 1)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(0,0,1)
MeshVertexTextureCoordinate(1/6, 1)
;left    
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(-1,0,0)
MeshVertexTextureCoordinate(4/6, 0)
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(-1,0,0)
MeshVertexTextureCoordinate(5/6, 0)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(-1,0,0)
MeshVertexTextureCoordinate(5/6, 1)
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(-1,0,0)
MeshVertexTextureCoordinate(4/6, 1)
;right    
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(1,0,0)
MeshVertexTextureCoordinate(4/6, 0)
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(1,0,0)
MeshVertexTextureCoordinate(4/6, 1)
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(1,0,0) 
MeshVertexTextureCoordinate(3/6, 0)
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(1,0,0)
MeshVertexTextureCoordinate(3/6, 1)
;bottom    
MeshVertexPosition(-5, -5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(5/6, 1)
MeshVertexPosition(5, -5, -5)
MeshVertexNormal(0,1,0) 
MeshVertexTextureCoordinate(6/6, 1)
MeshVertexPosition(5, -5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(6/6, 0)
MeshVertexPosition(-5, -5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(5/6, 0)
;top    
MeshVertexPosition(-5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(2/6,0)
    
MeshVertexPosition(5, 5, -5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(3/6,0)
    
MeshVertexPosition(5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(3/6,1)
    
MeshVertexPosition(-5, 5, 5)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(2/6,1)

; connecting vertices together
MeshFace(0, 2, 3)
MeshFace(0, 1, 2)
MeshFace(4, 6, 5)
MeshFace(4, 7, 6)
MeshFace(8, 10, 9)
MeshFace(8, 11, 10)
MeshFace(12, 14, 13)
MeshFace(13, 14, 15)
MeshFace(16, 17, 18)
MeshFace(16, 18, 19)
MeshFace(20, 23, 21)
MeshFace(21, 23, 22)
      
FinishMesh(#True)
SetMeshMaterial(#mesh, MaterialID(texture))      
      
CreateEntity(#mesh, MeshID(#mesh),  MaterialID(texture) ,0,0,0)
    
EndProcedure

Procedure triangle(num.l)
    i = 3*num 
  
    x1.f = MeshData(MeshDataInd(i)\Index)\x
    y1.f = MeshData(MeshDataInd(i)\Index)\y
    z1.f = MeshData(MeshDataInd(i)\Index)\z
        
    x2.f = MeshData(MeshDataInd(i+1)\Index)\x
    y2.f = MeshData(MeshDataInd(i+1)\Index)\y
    z2.f = MeshData(MeshDataInd(i+1)\Index)\z
       
    x3.f = MeshData(MeshDataInd(i+2)\Index)\x 
    y3.f = MeshData(MeshDataInd(i+2)\Index)\y 
    z3.f = MeshData(MeshDataInd(i+2)\Index)\z 
    
    If deform ; to deform the triangle vertices or not
    MeshData(MeshDataInd(i)\Index)\z - 2
    MeshData(MeshDataInd(i+1)\Index)\z - 2
    MeshData(MeshDataInd(i+2)\Index)\z - 2
    EndIf
    
    SetMeshData(#mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Color | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Tangent, 0, MeshVertexCount(#mesh)-1)
    ;position a sphere at the center of the triangle 
    MoveEntity(#sphere, (x1+x2+x3)/3,(y1+y2+y3)/3,(z1+z2+z3)/3, #PB_Absolute)
  EndProcedure
  
  Procedure change_uv()
    i=0
    ;the uv numbers below refer to a white point on the texture, you can make it 0,0
    While  i<=32
    MeshData(MeshDataInd(i)\Index)\u = 180/510 
    MeshData(MeshDataInd(i)\Index)\v = 6/74 : i+1 
    MeshData(MeshDataInd(i)\Index)\u = 180/510  
    MeshData(MeshDataInd(i)\Index)\v = 6/74 : i+1
    MeshData(MeshDataInd(i)\Index)\u = 180/510   
    MeshData(MeshDataInd(i)\Index)\v = 6/74 : i+1
    MeshData(MeshDataInd(i)\Index)\u = 180/510  
    MeshData(MeshDataInd(i)\Index)\v = 6/74 : i+1
    Wend
;Debug MeshDataInd(34)\Index
 ;cube top 
MeshData(MeshDataInd(30)\Index)\u = 2/6
MeshData(MeshDataInd(30)\Index)\v = 0 
MeshData(MeshDataInd(33)\Index)\u = 3/6
MeshData(MeshDataInd(33)\Index)\v = 0 
MeshData(MeshDataInd(34)\Index)\u = 2/6
MeshData(MeshDataInd(34)\Index)\v = 1
MeshData(MeshDataInd(35)\Index)\u = 3/6
MeshData(MeshDataInd(35)\Index)\v = 1


   SetMeshData(#mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Color | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Tangent, 0, MeshVertexCount(#mesh)-1)

    
 EndProcedure
 
  
  Procedure deform()
   GetMeshData(#mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Color | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Tangent , 0, MeshVertexCount(#Mesh)-1)
   ;GetMeshData(#mesh,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(#mesh, 0)-1)
     
    MeshData(20)\y + 1 ; the same as: MeshData(MeshDataInd(30)\Index)\y + 1
    MeshData(21)\y + 1
    MeshData(22)\y + 1
    MeshData(23)\y + 1
        
    SetMeshData(#mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Color | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Tangent, 0, MeshVertexCount(#mesh)-1)
    
  EndProcedure
  
Last edited by applePi on Thu Mar 31, 2016 10:21 am, edited 1 time in total.
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Creating a simple cube manually

Post by mrw »

it is possible to access and manipulate any part of the mesh after you make it first.
Well, ofcourse. But that is not easier than to just know that you need to define UVs from the start. And everything in order.
I´m talking about removing the requirement to create the vertices in order. Or the problem really isn´t in defining the vertices but more that when setting normals, UVs, color and so on, on the vertices it would be much easier if I could just give the command a #vertexindex handle.

But as long as you are aware of what the requirements are it´s not a big problem. It´s just more complex than doing the same thing in BlitzBasic.. ;)
Post Reply