Draw Ogre mesh with OpenGL glDrawElements()
Posted: Sun May 08, 2016 7:32 am
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
with random colors for each vertex
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
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
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