Best way to get Blender objects to OpenGL/C++
Moderators: jesterKing, stiv
Best way to get Blender objects to OpenGL/C++
What's the easiest/best way to take models from blender and "export" them so I can use them in C++ OpenGL code, so that I can create a walk through.
Thanks
Carmen
Thanks
Carmen
-
- Posts: 233
- Joined: Sun Oct 13, 2002 7:37 pm
- Location: University of Minnesota (USA)
- Contact:
There is also this openGL exporter:
http://www.geocities.com/dway_designer/ ... ter1.0.htm
http://www.geocities.com/dway_designer/ ... ter1.0.htm
opengl has a native format?mjordan wrote:Why not an OpenGL exporter in Bleder?
I find quite ridicolous an OpenGL app has a DirectX exporter and not an OpenGL one ...
there is an opengl call to load a model in a standard well documented format?!?!
yeah, I didn't think so. someone could write an exporter which generated the code to render the model [what about loading the textures?], but interactive mode is slow... so then someone would want the exported code to render the model using a vertex buffer [still, what about loading the textures?]... and, how do we load a different model at runtime? So then say someone writes an exporter/importer combo... then essentially haven't they written the most primal parts of a graphics engine? what if someone wants skeletal animation? what if someone wants glsl? ...
why not just use ogre and their importer/exporter?
No need to bother. I was just asking something like BOGLE (Blender OpenGL Exporter) directly integrated into Blender, for the simple reason this kind of scripts become obsolete very soon.z3r0_d wrote:opengl has a native format?mjordan wrote:Why not an OpenGL exporter in Bleder?
I find quite ridicolous an OpenGL app has a DirectX exporter and not an OpenGL one ...
there is an opengl call to load a model in a standard well documented format?!?!
yeah, I didn't think so. someone could write an exporter which generated the code to render the model [what about loading the textures?], but interactive mode is slow... so then someone would want the exported code to render the model using a vertex buffer [still, what about loading the textures?]... and, how do we load a different model at runtime? So then say someone writes an exporter/importer combo... then essentially haven't they written the most primal parts of a graphics engine? what if someone wants skeletal animation? what if someone wants glsl? ...
why not just use ogre and their importer/exporter?
Loading different models at runtime is an app job, not a Blender job. I'm asking for a script that dumps the model's coordinates into an array, not a development environment.
Regards,
Renato Perini
-
You can't live with women, you can't live without women.
Fuzzy logic example.
Renato Perini
-
You can't live with women, you can't live without women.
Fuzzy logic example.
simple export, public domainmjordan wrote:Loading different models at runtime is an app job, not a Blender job. I'm asking for a script that dumps the model's coordinates into an array, not a development environment.
Code: Select all
import struct
import Blender
def save(filename):
objs = Blender.Object.GetSelected()
if not len(objs) and objs[0].getType() == "mesh":
Blender.Draw.PupMenu("active object must be a mesh")
return
obj = objs[0]
mesh = obj.getData()
f = open(filename, "wb")
f.write(struct.pack("i",len(mesh.verts))) # vert count, as int
vertDict = {} # used to speed finding vertex indicies
index = 0
for vert in mesh.verts:
f.write(
struct.pack("6f", # write each vert floats for coord [xyz] and normal [xyz]
vert.co[0],vert.co[1],vert.co[2],
vert.no[0],vert.no[1],vert.no[2]
))
vertDict[vert] = index
index += 1
# I don't know how many faces there are
# since I will export only triangles I will now count them
numfaces = 0
for face in mesh.faces:
if len(face.v) == 4:
numfaces += 2
elif len(face.v) == 3:
numfaces += 1
f.write(struct.pack("i",numfaces)) # vert count, as int
# here I actually export the faces
# a face is written as for each vert: int index to each vert, followed by two floats (uv)
for face in mesh.faces:
if len(face.v) == 4:
# write face for 0 1 2, and face for 0 2 3
f.write(struct.pack("iff iff iff",
vertDict[face.v[0]], face.uv[0][0], face.uv[0][1],
vertDict[face.v[1]], face.uv[1][0], face.uv[1][1],
vertDict[face.v[2]], face.uv[2][0], face.uv[2][1]))
f.write(struct.pack("iff iff iff",
vertDict[face.v[0]], face.uv[0][0], face.uv[0][1],
vertDict[face.v[2]], face.uv[2][0], face.uv[2][1],
vertDict[face.v[3]], face.uv[3][0], face.uv[3][1]))
elif len(face.v) == 3:
f.write(struct.pack("iff iff iff",
vertDict[face.v[0]], face.uv[0][0], face.uv[0][1],
vertDict[face.v[1]], face.uv[1][0], face.uv[1][1],
vertDict[face.v[2]], face.uv[2][0], face.uv[2][1]))
f.close()
print "### SIMPLE EXPORT COMPLETE ###"
Blender.Window.FileSelector(save, "Simple Export")
#save("E:\\Blender\\temp\\simple.exp")
Code: Select all
import struct
import Blender
def load(filename):
f = open(filename, "rb")
mesh = Blender.NMesh.New()
numverts = struct.unpack("i",f.read(struct.calcsize("i")))[0] # vert count, as int
print "%d verts"%numverts
i = 0
while i < numverts:
i += 1
vert = struct.unpack("6f",f.read(struct.calcsize("6f")))
newvert = Blender.NMesh.Vert(*vert[:3])
#newvert.no = list(vert[3:]) ## gets an error I'm too lazy to debug
mesh.verts.append(newvert)
numfaces = struct.unpack("i",f.read(struct.calcsize("i")))[0] # face count, as int
print "%d faces"%numfaces
i = 0
while i < numfaces:
i += 1
face = struct.unpack("iff iff iff",f.read(struct.calcsize("iff iff iff")))
newface = Blender.NMesh.Face(
[mesh.verts[face[0]],mesh.verts[face[3]],mesh.verts[face[6]]])
newface.uv = [
(face[1],face[2]),(face[4],face[5]),(face[7],face[8]) ]
mesh.faces.append(newface)
mesh.update()
# perhaps revise this to not have blender recalculate normals
Blender.NMesh.PutRaw(mesh)
f.close()
print "### SIMPLE IMPORT COMPLETE ###"
Blender.Window.FileSelector(load, "Simple Import")
#load("E:\\Blender\\temp\\simple.exp")
Shouldn't be good to have this nicely integrated into Blender? I think this scripts could be very handy sometimes. Expecially if they are well maintained along with Blender releases (read changes, here).z3r0_d wrote:simple export, public domainmjordan wrote:Loading different models at runtime is an app job, not a Blender job. I'm asking for a script that dumps the model's coordinates into an array, not a development environment.simple import, public domainCode: Select all
import struct import Blender def save(filename): objs = Blender.Object.GetSelected() if not len(objs) and objs[0].getType() == "mesh": Blender.Draw.PupMenu("active object must be a mesh") return obj = objs[0] mesh = obj.getData() f = open(filename, "wb") f.write(struct.pack("i",len(mesh.verts))) # vert count, as int vertDict = {} # used to speed finding vertex indicies index = 0 for vert in mesh.verts: f.write( struct.pack("6f", # write each vert floats for coord [xyz] and normal [xyz] vert.co[0],vert.co[1],vert.co[2], vert.no[0],vert.no[1],vert.no[2] )) vertDict[vert] = index index += 1 # I don't know how many faces there are # since I will export only triangles I will now count them numfaces = 0 for face in mesh.faces: if len(face.v) == 4: numfaces += 2 elif len(face.v) == 3: numfaces += 1 f.write(struct.pack("i",numfaces)) # vert count, as int # here I actually export the faces # a face is written as for each vert: int index to each vert, followed by two floats (uv) for face in mesh.faces: if len(face.v) == 4: # write face for 0 1 2, and face for 0 2 3 f.write(struct.pack("iff iff iff", vertDict[face.v[0]], face.uv[0][0], face.uv[0][1], vertDict[face.v[1]], face.uv[1][0], face.uv[1][1], vertDict[face.v[2]], face.uv[2][0], face.uv[2][1])) f.write(struct.pack("iff iff iff", vertDict[face.v[0]], face.uv[0][0], face.uv[0][1], vertDict[face.v[2]], face.uv[2][0], face.uv[2][1], vertDict[face.v[3]], face.uv[3][0], face.uv[3][1])) elif len(face.v) == 3: f.write(struct.pack("iff iff iff", vertDict[face.v[0]], face.uv[0][0], face.uv[0][1], vertDict[face.v[1]], face.uv[1][0], face.uv[1][1], vertDict[face.v[2]], face.uv[2][0], face.uv[2][1])) f.close() print "### SIMPLE EXPORT COMPLETE ###" Blender.Window.FileSelector(save, "Simple Export") #save("E:\\Blender\\temp\\simple.exp")
I wrote these just now, they're incredibly simple and might be adequate. If nothing else they should give you some idea what to do to write your own exporter for meshesCode: Select all
import struct import Blender def load(filename): f = open(filename, "rb") mesh = Blender.NMesh.New() numverts = struct.unpack("i",f.read(struct.calcsize("i")))[0] # vert count, as int print "%d verts"%numverts i = 0 while i < numverts: i += 1 vert = struct.unpack("6f",f.read(struct.calcsize("6f"))) newvert = Blender.NMesh.Vert(*vert[:3]) #newvert.no = list(vert[3:]) ## gets an error I'm too lazy to debug mesh.verts.append(newvert) numfaces = struct.unpack("i",f.read(struct.calcsize("i")))[0] # face count, as int print "%d faces"%numfaces i = 0 while i < numfaces: i += 1 face = struct.unpack("iff iff iff",f.read(struct.calcsize("iff iff iff"))) newface = Blender.NMesh.Face( [mesh.verts[face[0]],mesh.verts[face[3]],mesh.verts[face[6]]]) newface.uv = [ (face[1],face[2]),(face[4],face[5]),(face[7],face[8]) ] mesh.faces.append(newface) mesh.update() # perhaps revise this to not have blender recalculate normals Blender.NMesh.PutRaw(mesh) f.close() print "### SIMPLE IMPORT COMPLETE ###" Blender.Window.FileSelector(load, "Simple Import") #load("E:\\Blender\\temp\\simple.exp")
Code: Select all
#!BPY
"""
Name: 'BOGLE (Blender/OpenGL exporter)'
Blender: 232
Group: 'Misc'
Tooltip: 'Exportador de objetos a codigo C usando openGL'
"""
# By: cNavarro <irc://cralost@irc.cl><carlos.ns NOSPAM_IN g_m_a_i_l DOT c_o_m>
#
#Este fichero esta basada en una utilidad para la libreria TDLIB.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
import Blender
from Blender import Draw, BGL
from Blender import Types, Object, NMesh, Camera, Lamp
import sys
MESHEXP_RAWTRIANGLE = 0
MESHEXP_DOEXPORT= 0
MESHEXP_EXPFILE=""
ACCION_EXPORT = 1
ACCION_EXPORTARMESH=1
ACCION_EXPORTARESC=0
OBJETO_SELECCIONADO=""
CONF_MESHPATH=""
def __MSG(MSG):
print MSG
Blender.Draw.PupMenu("%s" % MSG)
def DefinirEXPFILE(valor):
global MESHEXP_EXPFILE
MESHEXP_EXPFILE=valor
def __EsValido(nobjeto):
OBJETO_REF=0
if len(nobjeto)!=0:
OBJETO_REF = nobjeto[0].name
if OBJETO_REF!="":
return 1
else:
return 0
def __GetTipo(nobjeto):
if __EsValido(nobjeto):
return nobjeto[0].getType()
def __ExportarMesh(nfichero, nmesh):
global MESHEXP_EXPFILE
CONTA=0
if (__GetTipo(nmesh)!="Mesh" or len(MESHEXP_EXPFILE)<1):
if(__GetTipo(nmesh)!="Mesh"):
__MSG("Error: Solo objetos tipo Mesh soportados")
if(len(MESHEXP_EXPFILE)<1):
__MSG("Error: No hay nombre de fichero")
else:
mshobj = Blender.NMesh.GetRaw(nmesh[0].data.name)
faces = mshobj.faces
vertices = mshobj.verts
fichero = open(MESHEXP_EXPFILE, "wb")
stdout_pipe=sys.stdout
sys.stdout=fichero
print "/*"
print "Este fichero fue generado con BOGLE"
print "*/"
print "#include <GL/gl.h>"
print ""
print "void _BL_draw%s(int OPT)" % nmesh[0].data.name
print "//nombre mesh: %s" % nmesh[0].data.name
print "{"
for fcount in mshobj.faces:
CONTA=CONTA+1
if fcount.smooth:
print("\tglShadeModel(GL_SMOOTH);")
else:
print("\tglShadeModel(GL_FLAT);")
if len(fcount.v) ==3:
print "\tglBegin(GL_TRIANGLES);"
print "\tglNormal3f(%f, %f, %f);" % (fcount.v[0].no.x ,fcount.v[0].no.z ,fcount.v[0].no.y)
print "\tglVertex3f( %f, %f, %f);" % (fcount.v[0].co.x , fcount.v[0].co.z , fcount.v[0].co.y)
print "\tglNormal3f(%f, %f, %f);" % (fcount.v[1].no.x ,fcount.v[1].no.z ,fcount.v[1].no.y)
print "\tglVertex3f( %f, %f, %f);" % (fcount.v[1].co.x , fcount.v[1].co.z , fcount.v[1].co.y)
print "\tglNormal3f(%f, %f, %f);" % (fcount.v[2].no.x ,fcount.v[2].no.z ,fcount.v[2].no.y)
print "\tglVertex3f( %f, %f, %f);" % (fcount.v[2].co.x , fcount.v[2].co.z , fcount.v[2].co.y)
print "\tglEnd();"
if len(fcount.v) ==4:
print "\tglBegin(GL_QUADS);"
print "\tglNormal3f(%f, %f, %f);" % (fcount.v[0].no.x ,fcount.v[0].no.z ,fcount.v[0].no.y)
print "\tglVertex3f( %f, %f, %f);" % (fcount.v[0].co.x , fcount.v[0].co.z , fcount.v[0].co.y)
print "\tglNormal3f(%f, %f, %f);" % (fcount.v[1].no.x ,fcount.v[1].no.z ,fcount.v[1].no.y)
print "\tglVertex3f( %f, %f, %f);" % (fcount.v[1].co.x , fcount.v[1].co.z , fcount.v[1].co.y)
print "\tglNormal3f(%f, %f, %f);" % (fcount.v[2].no.x ,fcount.v[2].no.z ,fcount.v[2].no.y)
print "\tglVertex3f( %f, %f, %f);" % (fcount.v[2].co.x , fcount.v[2].co.z , fcount.v[2].co.y)
print "\tglNormal3f(%f, %f, %f);" % (fcount.v[3].no.x ,fcount.v[3].no.z ,fcount.v[3].no.y)
print "\tglVertex3f( %f, %f, %f);" % (fcount.v[3].co.x , fcount.v[3].co.z , fcount.v[3].co.y)
print "\tglEnd();"
print "}"
sys.stdout=stdout_pipe
fichero.close()
__MSG("Mesh exportado con exito!")
def ExisteText(nfichero):
retval = 0
iii = 0
ContenedoresTextos = Blender.Text.Get()
nTextos = len(ContenedoresTextos)
while iii< nTextos:
if ContenedoresTextos[iii]==nfichero:
retval = 1
iii = iii+1
return retval
def GetConf(nombreconf):
retval = ""
if ExisteText("% s.conf" % nombreconf):
FicheroConf = Blender.Text.Get("% s.conf" % nombreconf)
if FicheroConf:
if FicheroConf.getNLines()==1:
valorconf = FicheroConf.asLines()
retval = valorconf[0]
return retval
def HandleAccion():
global ACCION_EXPORT, ACCION_EXPORTARMESH, ACCION_EXPORTAESC
if ACCION_EXPORT == 1:
ACCION_EXPORTARMESH=1
else:
ACCION_EXPORTARMESH=0
if ACCION_EXPORT == 2:
ACCION_EXPORTARESC=1
else:
ACCION_EXPORTARARM=0
if ACCION_EXPORT == 3:
ACCION_EXPORTARPOSE=1
else:
ACCION_EXPORTARPOSE=0
def DibujarGUI():
global MESHEXP_RAWTRIANGLE
global ACCION_EXPORT, ACCION_EXPORTARMESH, ACCION_EXPORTARARM, ACCION_EXPORTARPOSE
global OBJETO_SELECCIONADO
TipoDeObjeto = ""
BGL.glClearColor(0.2,0.3,0.2,1)
BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
BGL.glColor3f(1,1,1)
BGL.glRasterPos2i(20, 250)
Draw.Text("BOGLE v0.1(Blender/OpenGL Exporter)")
BGL.glColor3f(0,.2,0)
BGL.glRasterPos2i(20, 240)
Draw.Text("Este script es parte de el proyecto tdlib", "small")
BGL.glColor3f(1,1,1)
Draw.Toggle("Exportar Mesh", 11, 110, 5, 130, 20, ACCION_EXPORTARMESH,"Exportacion de mallas para uso con tdlib")
Draw.Toggle("Exportar Escena", 12, 240, 5, 130, 20, ACCION_EXPORTARESC,"Exportacion de armatures para aplicacion de esqueletos")
Draw.Button("Salir", 99, 5, 5, 100, 20,"Haz click aqui para salir")
if ACCION_EXPORT==1:
Draw.Button("Exportar a codigo C/C++", 14, 320, 50, 170, 50, "Haga click aqui para realizar la exportacion")
ObjetoSeleccionado = Blender.Object.GetSelected()
if __EsValido(ObjetoSeleccionado):
OBJETO_SELECCIONADO = ObjetoSeleccionado[0].getName()
else:
OBJETO_SELECCIONADO = "[NINGUNO]"
if __GetTipo(ObjetoSeleccionado)=="Mesh":
BGL.glColor3f(1,1,1)
else:
BGL.glColor3f(1,0,0)
BGL.glRasterPos2i(20, 180)
Draw.Text("Objeto Seleccionado '% s'" % OBJETO_SELECCIONADO)
BGL.glRasterPos2i(120, 155)
Draw.Text("Fichero: '%s'" % MESHEXP_EXPFILE)
Draw.Button("examinar>>", 16, 20, 150, 90, 20, "Haga click aqui para realizar la exportacion")
def EventosGUI(evento, valor):
global ARM_CONSERVAR_NAMES
global OBJETO_SELECCIONADO
ObjetoSeleccionado2 = Blender.Object.GetSelected()
if ObjetoSeleccionado2:
if OBJETO_SELECCIONADO!=ObjetoSeleccionado2[0].name:
Draw.Redraw(1)
def EventosAPP(evento):
global MESHEXP_RAWTRIANGLE
global ACCION_EXPORT
if evento==99:
print "*>> Salida activada por usuario."
Draw.Exit()
if evento==10:
if MESHEXP_RAWTRIANGLE:
MESHEXP_RAWTRIANGLE=0
else:
MESHEXP_RAWTRIANGLE=1
Draw.Redraw(1)
if evento==14:
__ExportarMesh("",Blender.Object.GetSelected())
if evento==16:
Blender.Window.FileSelector(DefinirEXPFILE, "Export Mesh")
if evento==11:
ACCION_EXPORT = 1
HandleAccion()
Draw.Redraw(1)
if evento==12:
ACCION_EXPORT = 2
HandleAccion()
Draw.Redraw(1)
print GetConf("MESHPATH")
Draw.Register(DibujarGUI, EventosGUI, EventosAPP)
Regards,
Renato Perini
-
You can't live with women, you can't live without women.
Fuzzy logic example.
Renato Perini
-
You can't live with women, you can't live without women.
Fuzzy logic example.
if I run this script I get:
is there a solution to fix it??
Code: Select all
IndentationError: expected an indented block
File "blend2opengl.py.txt", line 46
print MSG
^
is there a solution to fix it??
http://www.web-play-3d.de
German site with Blender Tutorials
German site with Blender Tutorials
Bogle new version (in english)
a new version of bogle tested in blender 2.42a
Download the zipped file from:
http://es.geocities.com/carlost_ns/bogle.zip
or visit:
http://stumbecker.blogspot.com/2006/07/ ... e-v01.html
Download the zipped file from:
http://es.geocities.com/carlost_ns/bogle.zip
or visit:
http://stumbecker.blogspot.com/2006/07/ ... e-v01.html
Last edited by krlost on Sat Nov 03, 2007 3:37 pm, edited 2 times in total.
Re: Bogle new version (in english)
Thank you.krlost wrote:a new version of bogle tested in blender 2.42a
Download the zipped file http://es.geocities.com/carlost_ns/camline.zip
or see http://stumbecker.blogspot.com/2006/07/ ... e-v01.html
Regards,
Renato Perini
-
You can't live with women, you can't live without women.
Fuzzy logic example.
Renato Perini
-
You can't live with women, you can't live without women.
Fuzzy logic example.