[3D-Model Loader] for *.OBJ-Files

Previous topic - Next topic

Schranz0r

Hi, here a *.OBJ-File (Wavefront OBJ file) loader for GLBasic.

See attachment

sourcecode:
Code (glbasic) Select
// --------------------------------- //
// Project: OBJ Loader
// Start: Sunday, September 02, 2012
// IDE Version: 10.283


TYPE TVector3
x#;y#;z# // position
ENDTYPE

TYPE TVector2
x#;y#
ENDTYPE

TYPE TFace
vertex[3] AS TVector3
tex_coord[3] AS TVector2
vertex_norm[3] AS TVector3
ENDTYPE


TYPE TObj

filename$
texturename$

vertex[] AS TVector3
tex_coord[] AS TVector2
vertex_norm[] AS TVector3
faces[] AS TFace

filehandle%
tex_handle%
XObj_handle%

FUNCTION LOAD: name$

self.filehandle = GENFILE() // set the filehandle
self.filename$ = name$  //set filename

// if file exist

IF DOESFILEEXIST(self.filename$) AND OPENFILE(self.filehandle, self.filename$, 1)
//DEBUG "All OK, file exist!\n"

WHILE ENDOFFILE(self.filehandle) = 0
LOCAL tmp$, check$, splt$[]

READLINE self.filehandle, tmp$
check$ = MID$(tmp$, 0, 2)

SELECT check$
CASE "v "
SPLITSTR(tmp$,splt$[]," ")
//DEBUG "->"+splt$[1]+" : "+splt$[2]+" : "+splt$[3]+"<-\n"
LOCAL v AS TVector3

v.x = splt$[1]
v.y = splt$[2]
v.z = splt$[3]

DIMPUSH self.vertex[], v

CASE "vt"
SPLITSTR(tmp$,splt$[]," ")
//DEBUG "->"+splt$[1]+" : "+splt$[2]+"<-\n"
LOCAL v AS TVector2

v.x = splt$[1]
v.y = splt$[2]

DIMPUSH self.tex_coord[], v
CASE "vn"
SPLITSTR(tmp$,splt$[]," ")
//DEBUG "->"+splt$[1]+" : "+splt$[2]+" : "+splt$[3]+"<-\n"
LOCAL v AS TVector3

v.x = splt$[1]
v.y = splt$[2]
v.z = splt$[3]

DIMPUSH self.vertex_norm[], v
CASE "us"
SPLITSTR(tmp$,splt$[]," ")
self.texturename$ = splt$[1]
//DEBUG self.texturename$+"\n"
CASE "f "
LOCAL s$[]
SPLITSTR(tmp$,splt$[]," ")

LOCAL t AS TFace

FOR i = 1 TO 3
SPLITSTR(splt$[i],s$[],"/")
//DEBUG "->"+s$[0]+" : "+s$[1]+" : "+s$[2]+"<-\n"
LOCAL v=s$[0] , vt=s$[1], vn=s$[2]

t.vertex[i-1] = self.vertex[v-1]
t.tex_coord[i-1] = self.tex_coord[vt-1]
t.vertex_norm[i-1] = self.vertex_norm[vn-1]

NEXT

DIMPUSH self.faces[], t
ENDSELECT

WEND

// free some memory!
REDIM self.vertex[0]
REDIM self.tex_coord[0]
REDIM self.vertex_norm[0]

self.tex_handle = GENSPRITE()
LOADSPRITE self.texturename$, self.tex_handle

self.XObj_handle = GENX_OBJ()

X_OBJSTART self.XObj_handle
FOREACH t IN self.faces[]
X_OBJNEWGROUP
FOR i = 0 TO 2
X_OBJADDVERTEX t.vertex[i].x, t.vertex[i].y, t.vertex[i].z, t.tex_coord[i].x, t.tex_coord[i].y, RGB(0xff, 0xff, 0xff)
NEXT
NEXT
X_OBJEND

ENDIF
ENDFUNCTION

FUNCTION DRAW:
X_SETTEXTURE self.tex_handle, -1
X_DRAWOBJ self.XObj_handle, 0
ENDFUNCTION

ENDTYPE


[attachment deleted by admin]
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Slim


Marmor


Schranz0r

thx, but it's not perfect...
there are to many different versions from *.obj out there :/

It's just a "basic"-loader :D
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

mentalthink

Very interesting info and Code... Thanks for sharing!!! :nw: :nw:

jestermon

That source code takes me way back - to an obj loader I wrote about 10 years ago for Vpython. Interesting how similar the code looks - I guess the basics never change :)
http://jestermon.weebly.com/uploads/1/6/2/1/1621282/objloader.zip

erico

Quote from: Schranz0r on 2012-Sep-03
...
there are to many different versions from *.obj out there :/
...

Yeah there are.

Current lightwave 3d obj struggles with the obj->ddd converter. It also struggles on a couple 3d apps around.
Strangely, if I send the obj to blender and save it again, it works fine

I´m tempted in giving this a try to see the results.
I wonder if it will preserve surfaces name or a vertex normal map (ie for the smooth/flat polys).

Gud job!