Page 1 of 1

Draw Ogre mesh with OpenGL glDrawElements()

Posted: Sun May 08, 2016 7:32 am
by applePi
use GetMeshData() function to get data from Ogre mesh (*.mesh) and store it in an array and then straightforward draw the array with glDrawElements() opengl function

works only for meshes with one submesh (SubMeshCount(#Mesh) gives the number of submeshes). for displaying the models with several submeshes i am thinking of copying the many submeshes data to a big flat one submesh suitable for glDrawElements().

here is other 12 meshes which works with this program, some of them don't have normals nor UV so they appears black with textures but they are useful for vertex coloring and for exercises to add normals and uv to it.
http://www.mediafire.com/file/br1iz2bq3 ... meshes.rar

note: for UV coordinates we flip it vertically by subtracting from 1, since the UV(0,0) in Ogre located at the top left , while in OpenGL it is at the bottom left

with textures
Image

Code: Select all

Enumeration
  #mesh
  #cube
  #sphere
  
EndEnumeration

UseJPEGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageDecoder()

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

Global MeshNo = 0: Global zoom.f=1

Declare LoadOgreMesh(MeshNo)

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

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

Dim TexID(6)

InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

OpenWindow(0, 0, 0, 800, 600, "'Space': next mesh ...Up/Down keys: zoom ....A/Z: move up/down .... 'W': toggle wireFrame ")
SetWindowColor(0, RGB(200,220,200))
OpenWindowedScreen(WindowID(0),790,20,20, 20,1,0,0,#PB_Screen_WaitSynchronization)
OpenGLGadget(0, 20, 10, WindowWidth(0)-40 , WindowHeight(0)-20)

;- Generate textures
For i = 0 To 6
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=0 To 6
  FreeMemory(*Buffer(i))
Next


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()

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

LoadOgreMesh(3) ; begin to display mesh 3

Global indexsize = ArraySize(MeshDataInd()) + 1

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, 50, ; the camera looking from position 0,0.3,0.5  to 0,0,0 from above
            0,  0, 0,
            0,  1,  0 ) ;change this vector to 0,-1,0 and we will look from below

rot.f = 0.5
glPopMatrix_()
glPushMatrix_()
Repeat
  Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
  Until event = 0 Or quit = #True
      
  ExamineKeyboard()
  If KeyboardReleased (#PB_Key_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
    
  EndIf
  If KeyboardPushed (#PB_Key_Up)
    
    glScalef_(1.05,1.05,1.05)
  ElseIf KeyboardPushed (#PB_Key_Down)
    glScalef_(0.95,0.95,0.95)
  EndIf
  If KeyboardPushed (#PB_Key_Z)
    glTranslatef_(0, -0.2, 0)
    ElseIf KeyboardPushed (#PB_Key_A)
    glTranslatef_(0, 0.2, 0)
  EndIf
  If KeyboardReleased (#PB_Key_Space)
    glPopMatrix_() ; restore the original state
    glPushMatrix_(); to store the current state

    ReDim MeshData.PB_MeshVertex(0)
    ReDim MeshDataInd.PB_MeshFace(0)
    FreeMesh(#mesh)
    glBindTexture_(#GL_TEXTURE_2D, #False)
    glBindTexture_(#GL_TEXTURE_2D, TexID(t))
    t+1: If t=7:t=0: EndIf ;; go in round trip between textures 0 to 6
    LoadOgreMesh(MeshNo)
    MeshNo+1
    If MeshNo > 6: MeshNo = 0: EndIf
    indexsize = ArraySize(MeshDataInd()) + 1
  EndIf
  
  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_TEXTURE_COORD_ARRAY)
  
  glVertexPointer_(3, #GL_FLOAT,SizeOf(PB_MeshVertex),@MeshData(0)\x)
  glTexCoordPointer_(2, #GL_FLOAT, SizeOf(PB_MeshVertex), @MeshData(0)\u) 
  
  glRotatef_(rot, 0, 1, 0)
   
  glDrawElements_(#GL_TRIANGLES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
   
  glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY)
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)

Until KeyboardPushed(#PB_Key_Escape) Or  quit = #True
;glPopMatrix_()
For i=0 To 6
      glDeleteTextures_(1, @TexID(i))
Next
 
 

Procedure LoadOgreMesh(MeshNo)

  Select MeshNo
      Case 0
       
         LoadMesh(#mesh, "tudorhouse.mesh")
       Case 1
         CreateSphere(#mesh, 5)
       Case 2 
         CreateCube(#mesh, 8)
       Case 3
         LoadMesh(#mesh, "Barrel.mesh")
         
       Case 4
         LoadMesh(#mesh, "axes.mesh")
       Case 5
         LoadMesh(#mesh, "PureBasic.mesh")
       Case 6
         LoadMesh(#mesh, "robot.mesh")
       
     EndSelect
;Debug SubMeshCount(#mesh)
     
radius.f = MeshRadius(#mesh)
TransformMesh(#mesh, 0, 0, 0, 16/radius, 16/radius, 16/radius, 0, 0, 0)
UpdateMeshBoundingBox(#mesh)

GetMeshData(#mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Color | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(#mesh)-1)
GetMeshData(#mesh,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(#mesh, 0)-1)
GetMeshData(#mesh,0, MeshData2(), #PB_Mesh_Vertex | #PB_Mesh_Color | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(#mesh)-1)
GetMeshData(#mesh,0, MeshDataInd2(), #PB_Mesh_Face, 0, MeshIndexCount(#mesh, 0)-1)

For i=0 To MeshVertexCount(#mesh)-1
  ;MeshData(i)\u =  MeshData(i)\u
  MeshData(i)\v =  1-MeshData(i)\v 
  ;flip the uv verticaly , since in opengl the uv(0,0) located ...
  ;at the bottom left, while in Ogre it is located at top left

Next

EndProcedure

  

with random colors for each vertex
Image

Code: Select all

Structure Color
  r.f ;red
  g.f ;green
  b.f ;blue
EndStructure

Enumeration
  #mesh
  #cube
  #sphere
  
EndEnumeration

Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)
Global Dim VertexColor.Color(0)
Global MeshNo = 0

Declare LoadOgreMesh(MeshNo)

InitEngine3D() ; we need it only: to use Ogre GetMeshData function
InitKeyboard()
InitSprite()
InitMouse()

OpenWindow(0, 0, 0, 800, 600, "'Space': next mesh ...Up/Down keys: zoom ....A/Z: move up/down .... 'W': toggle wireFrame ")
SetWindowColor(0, RGB(200,220,200))
OpenWindowedScreen(WindowID(0),790,20,20, 20,1,0,0,#PB_Screen_WaitSynchronization)
OpenGLGadget(0, 20, 10, WindowWidth(0)-40 , WindowHeight(0)-20)

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()

CreateMaterial(0, LoadTexture(0, "Geebee2.bmp"))
MaterialCullingMode(0, #PB_Material_NoCulling)

LoadOgreMesh(3)
Global indexsize = ArraySize(MeshDataInd()) + 1

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, 50, ; the camera looking from position 0,0.3,0.5  to 0,0,0 from above
            0,  0, 0,
            0, 1,  0 ) ;change this vector to 0,-1,0 and we will look from below

rot.f = 0.5
glPopMatrix_()
glPushMatrix_()

Repeat
  Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
  Until event = 0 Or quit = #True
      
  ExamineKeyboard()
  If KeyboardReleased (#PB_Key_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
    
  EndIf
  If KeyboardPushed (#PB_Key_Up)
    glScalef_(1.05,1.05,1.05)
    ElseIf KeyboardPushed (#PB_Key_Down)
    glScalef_(0.95,0.95,0.95)
  EndIf
  If KeyboardPushed (#PB_Key_Z)
    glTranslatef_(0, -0.2, 0)
    ElseIf KeyboardPushed (#PB_Key_A)
    glTranslatef_(0, 0.2, 0)
  EndIf
  If KeyboardReleased (#PB_Key_Space)
    glPopMatrix_() ; restore the original state
    glPushMatrix_(); to store the current state
    
    ReDim MeshData.PB_MeshVertex(0)
    ReDim MeshDataInd.PB_MeshFace(0)
    FreeMesh(#mesh)
    LoadOgreMesh(MeshNo)
    MeshNo+1
    If MeshNo > 6: MeshNo = 0: EndIf
    indexsize = ArraySize(MeshDataInd()) + 1
  EndIf
  
  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)
  
  glVertexPointer_(3, #GL_FLOAT,SizeOf(PB_MeshVertex),@MeshData(0)\x)
  glColorPointer_(3, #GL_FLOAT, SizeOf(Color), @VertexColor(0)\r) 
  ;glPointSize_(10) ; used if you choose #GL_POINTS
  ;glLineWidth_(2)  ; make lines thick when mesh displayed in wirefarem (when press 'W')
  glRotatef_(rot, 0, 0.6, 0)
  glDrawElements_(#GL_TRIANGLES,indexsize,#GL_UNSIGNED_INT, @MeshDataInd(0)\Index)
  glDisableClientState_(#GL_COLOR_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY)
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)

Until KeyboardPushed(#PB_Key_Escape) Or  quit = #True

Procedure LoadOgreMesh(MeshNo)

  Select MeshNo
      Case 0
       CreateCube(#mesh, 10)
       Case 1
         CreateSphere(#mesh, 5)
       Case 2 
         LoadMesh(#mesh, "robot.mesh")
       Case 3
         LoadMesh(#mesh, "Barrel.mesh")
       Case 4
         LoadMesh(#mesh, "axes.mesh")
       Case 5
         LoadMesh(#mesh, "PureBasic.mesh")
       Case 6
         LoadMesh(#mesh, "tudorhouse.mesh")
       
     EndSelect
     
  
radius.f = MeshRadius(#mesh)
TransformMesh(#mesh, 0, 0, 0, 16/radius, 16/radius, 16/radius, 0, 0, 0)
UpdateMeshBoundingBox(#mesh)

GetMeshData(#mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Color, 0, MeshVertexCount(#mesh)-1)
GetMeshData(#mesh,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(#mesh, 0)-1)
numOfVertices = MeshVertexCount(#mesh)-1
Dim VertexColor.Color(numOfVertices) 
Define event, quit

For i=0 To MeshVertexCount(#mesh)-1 ; number of vertices
  
  VertexColor(i)\r = Random(1,0) 
  VertexColor(i)\g = Random(1,0) 
  VertexColor(i)\b = Random(1,0) 

Next
EndProcedure