1
1
Fork 0
mirror of https://github.com/QB64Official/qb64.git synced 2024-07-05 08:50:25 +00:00
qb64/programs/samples/open_gl/3d_model_viewer.bas

712 lines
23 KiB
QBasic

CHDIR "programs\samples\open_gl"
' This example shows how models with textures or materials can be displayed with OpenGL using QB64
'
'IMPORTANT:
' Whilst the .X file loader is optimized for speed, it is very incomplete:
' -only .X files in text file format
' -only one object, not a cluster of objects
' -if using a texture, use a single texture which will be applied to all materials
' -all the 3D models in this example were exported from Blender, a free 3D creation tool
' Blender tips: CTRL+J to amalgamate objects, select object to export first, in the UV/image-editor
' window you can export the textures built into your .blend file, apply the decimate
' modifier to reduce your polygon count to below 10000, preferably ~3000 or less
' This program is not a definitive guide to OpenGL in any way
' The GLH functions are something I threw together to stop people crashing their code by making
' calls to OpenGL with incorrectly sized memory regions. The GLH... prefixed commands are not mandatory or
' part of QB64, nor do they represent a complete library of helper commands.
' Lighting is not this example's strongest point, there's probably some work to do on light positioning
' and vertex normals
'
'Finally, I hope you enjoy this program as much as I enjoyed piecing it together,
' Galleon
'###################################### GLH SETUP #############################################
'Used to manage textures
TYPE DONT_USE_GLH_Handle_TYPE
in_use AS _BYTE
handle AS LONG
END TYPE
'Used by GLH RGB/etc helper functions
DIM SHARED DONT_USE_GLH_COL_RGBA(1 TO 4) AS SINGLE
REDIM SHARED DONT_USE_GLH_Handle(1000) AS DONT_USE_GLH_Handle_TYPE
'.X Format Model Loading Data
TYPE VERTEX_TYPE
X AS DOUBLE
Y AS DOUBLE
Z AS DOUBLE
NX AS DOUBLE
NY AS DOUBLE
NZ AS DOUBLE
END TYPE
REDIM SHARED VERTEX(1) AS VERTEX_TYPE
DIM SHARED VERTICES AS LONG
TYPE FACE_CORNER_TYPE
V AS LONG 'the vertex index
TX AS SINGLE 'texture X coordinate
TY AS SINGLE 'texture Y coordinate
END TYPE
TYPE FACE_TYPE
V1 AS FACE_CORNER_TYPE
V2 AS FACE_CORNER_TYPE
V3 AS FACE_CORNER_TYPE
Material AS LONG
Index AS LONG
END TYPE
REDIM SHARED FACE(1) AS FACE_TYPE
DIM SHARED FACES AS LONG
TYPE MATERIAL_RGBAI_TYPE
R AS SINGLE
G AS SINGLE
B AS SINGLE
A AS SINGLE
Intensity AS SINGLE
END TYPE
TYPE MATERIAL_TYPE
Diffuse AS MATERIAL_RGBAI_TYPE 'regular col
Specular AS MATERIAL_RGBAI_TYPE 'hightlight/shine col
Texture_Image AS LONG 'both an image and a texture handle are held
Texture AS LONG 'if 0, there is no texture
END TYPE
REDIM SHARED MATERIAL(1) AS MATERIAL_TYPE
DIM SHARED MATERIALS AS LONG
'##############################################################################################
DIM SHARED AllowSubGL
SCREEN _NEWIMAGE(1024, 768, 32)
backdrop = _LOADIMAGE("backdrop_tron.png")
DIM SHARED rot1
DIM SHARED rot2, rot3
DIM SHARED scale: scale = 1
'Load (default) model
GLH_Load_Model_Format_X "marty.x", "marty_tmap.png"
'draw backdrop
_PUTIMAGE , backdrop: _DONTBLEND: LINE (200, 200)-(500, 500), _RGBA(0, 255, 255, 0), BF: _BLEND
AllowSubGL = 1
DO
'This is our program's main loop
_LIMIT 100
LOCATE 1, 1
PRINT "Mouse Input:"
PRINT "{Horizonal Movement}Spin"
PRINT "{Vertical Movement}Flip"
PRINT "{Wheel}Scale"
PRINT
PRINT "Keyboard comands:"
PRINT "Switch rendering order: {1}GL behind, {2}GL on top, {3}GL only, good for speed"
PRINT "Switch/Load model: {A}Zebra, {B}Pig, {C}Car"
k$ = INKEY$
IF k$ = "1" THEN _GLRENDER _BEHIND
IF k$ = "2" THEN _GLRENDER _ONTOP
IF k$ = "3" THEN _GLRENDER _ONLY
PRINT "Angles:"; rot1, rot2, rot3
IF UCASE$(k$) = "A" THEN
AllowSubGL = 0
GLH_Load_Model_Format_X "marty.x", "marty_tmap.png"
_PUTIMAGE , backdrop: _DONTBLEND: LINE (200, 200)-(500, 500), _RGBA(0, 255, 255, 0), BF: _BLEND
AllowSubGL = 1
END IF
IF UCASE$(k$) = "B" THEN
AllowSubGL = 0
GLH_Load_Model_Format_X "piggy_mini3.x", ""
_PUTIMAGE , backdrop: _DONTBLEND: LINE (200, 200)-(500, 500), _RGBA(0, 255, 255, 0), BF: _BLEND
AllowSubGL = 1
END IF
IF UCASE$(k$) = "C" THEN
AllowSubGL = 0
GLH_Load_Model_Format_X "gasprin.x", "gasprin_tmap.png"
_PUTIMAGE , backdrop: _DONTBLEND: LINE (200, 200)-(500, 500), _RGBA(0, 255, 255, 0), BF: _BLEND
AllowSubGL = 1
END IF
DO WHILE _MOUSEINPUT
scale = scale * (1 - (_MOUSEWHEEL * .1))
rot1 = _MOUSEX
rot2 = _MOUSEY
LOOP
IF k$ = "." THEN rot3 = rot3 + 1
IF k$ = "," THEN rot3 = rot3 - 1
LOOP UNTIL k$ = CHR$(27)
END
'this specially named sub "_GL" is detected by QB64 and adds support for OpenGL commands
'it is called automatically whenever the underlying software deems an update is possible
'usually/ideally, this is in sync with your monitor's refresh rate
SUB _GL STATIC
'STATIC was used above to make all variables in this sub maintain their values between calls to this sub
IF AllowSubGL = 0 THEN EXIT SUB 'we aren't ready yet!
'timing is everything, we don't know how fast the 3D renderer will call this sub to we use timers to smooth things out
T# = TIMER(0.001)
IF ETT# = 0 THEN ETT# = T#
ET# = T# - ETT#
ETT# = T#
IF sub_gl_called = 0 THEN
sub_gl_called = 1 'we only need to perform the following code once
'...
END IF
'These settings affect how OpenGL will render our content
'!!! THESE SETTINGS ARE TO SHOW HOW ALPHA CAN WORK, BUT IT IS 10x FASTER WHEN ALPHA OPTIONS ARE DISABLED !!!
'*** every setting must be reset because SUB _GL cannot guarantee settings have not changed since last time ***
_glMatrixMode _GL_PROJECTION 'Select The Projection Matrix
_glLoadIdentity 'Reset The Projection Matrix
_gluPerspective 45, _WIDTH(0) / _HEIGHT(0), 1, 100 'QB64 internally supports this GLU command for convenience sake, but does not support GLU
_glEnable _GL_TEXTURE_2D
_glEnable _GL_BLEND
_glBlendFunc _GL_SRC_ALPHA, _GL_ONE_MINUS_SRC_ALPHA 'how alpha values are interpretted
_glEnable _GL_DEPTH_TEST 'use the zbuffer
_glDepthMask _GL_TRUE
_glAlphaFunc _GL_GREATER, 0.5 'dont do anything if alpha isn't greater than 0.5 (or 128)
_glEnable _GL_ALPHA_TEST
_glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
_glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR
'**************************************************************************************************************
_glMatrixMode _GL_MODELVIEW 'Select The Modelview Matrix
_glLoadIdentity 'Reset The Modelview Matrix
'setup our light
_glEnable _GL_LIGHTING
_glEnable _GL_LIGHT0
_glLightfv _GL_LIGHT0, _GL_DIFFUSE, GLH_RGB(.8, .8, .8)
_glLightfv _GL_LIGHT0, _GL_AMBIENT, GLH_RGB(0.1, 0.1, 0.1)
_glLightfv _GL_LIGHT0, _GL_SPECULAR, GLH_RGB(0.3, 0.3, 0.3)
light_rot = light_rot + ET#
_glLightfv _GL_LIGHT0, _GL_POSITION, GLH_RGBA(SIN(light_rot) * 20, COS(light_rot) * 20, 20, 1)
_glTranslatef 0, 0, -20 'Translate Into The Screen
_glRotatef rot1, 0, 1, 0
_glRotatef rot2, 1, 0, 0
_glRotatef rot3, 0, 0, 1
current_m = -1
FOR F = 1 TO FACES
m = FACE(F).Material
IF m <> current_m THEN 'we don't switch materials unless we have to
IF current_m <> -1 THEN _glEnd 'stop rendering triangles so we can change some settings
current_m = m
IF MATERIAL(m).Texture_Image THEN
_glEnable _GL_TEXTURE_2D
_glDisable _GL_COLOR_MATERIAL
_glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR 'seems these need to be respecified
_glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR
IF MATERIAL(m).Texture = 0 THEN
MATERIAL(m).Texture = GLH_Image_to_Texture(MATERIAL(m).Texture_Image)
END IF
GLH_Select_Texture MATERIAL(m).Texture
_glMaterialfv _GL_FRONT, _GL_DIFFUSE, GLH_RGBA(1, 1, 1, 1)
ELSE
'use materials, disable textures
_glDisable _GL_TEXTURE_2D
_glDisable _GL_COLOR_MATERIAL
mult = MATERIAL(m).Diffuse.Intensity 'otherwise known as "power"
r = MATERIAL(m).Diffuse.R * mult
g = MATERIAL(m).Diffuse.G * mult
b = MATERIAL(m).Diffuse.B * mult
' _glColor3f r, g, b
_glMaterialfv _GL_FRONT, _GL_DIFFUSE, GLH_RGBA(r, g, b, 1)
mult = MATERIAL(m).Specular.Intensity
r = MATERIAL(m).Specular.R * mult
g = MATERIAL(m).Specular.G * mult
b = MATERIAL(m).Specular.B * mult
_glMaterialfv _GL_FRONT, _GL_SPECULAR, GLH_RGBA(r, g, b, 1)
END IF
_glBegin _GL_TRIANGLES
END IF
FOR s = 1 TO 3
IF s = 1 THEN v = FACE(F).V1.V
IF s = 2 THEN v = FACE(F).V2.V
IF s = 3 THEN v = FACE(F).V3.V
v = v + 1
'vertex
x = (VERTEX(v).X + 0) * scale
y = (VERTEX(v).Y + 0) * scale
z = (VERTEX(v).Z + 0) * scale
'normal direction from vertex
nx = VERTEX(v).NX: ny = VERTEX(v).NY: nz = VERTEX(v).NZ
'corner's texture coordinates
IF MATERIAL(m).Texture THEN
IF s = 1 THEN tx = FACE(F).V1.TX: ty = FACE(F).V1.TY
IF s = 2 THEN tx = FACE(F).V2.TX: ty = FACE(F).V2.TY
IF s = 3 THEN tx = FACE(F).V3.TX: ty = FACE(F).V3.TY
_glTexCoord2f tx, ty
END IF
_glNormal3d nx, my, nz
_glVertex3f x, y, z
NEXT
NEXT
_glEnd
END SUB
'QB64 OPEN-GL HELPER MACROS (aka. GLH macros) #######################################################################
SUB GLH_Select_Texture (texture_handle AS LONG) 'turn an image handle into a texture handle
IF texture_handle < 1 OR texture_handle > UBOUND(DONT_USE_GLH_HANDLE) THEN ERROR 258: EXIT FUNCTION
IF DONT_USE_GLH_Handle(texture_handle).in_use = 0 THEN ERROR 258: EXIT FUNCTION
_glBindTexture _GL_TEXTURE_2D, DONT_USE_GLH_Handle(texture_handle).handle
END SUB
FUNCTION GLH_Image_to_Texture (image_handle AS LONG) 'turn an image handle into a texture handle
IF image_handle >= 0 THEN ERROR 258: EXIT FUNCTION 'don't allow screen pages
DIM m AS _MEM
m = _MEMIMAGE(image_handle)
DIM h AS LONG
h = DONT_USE_GLH_New_Texture_Handle
GLH_Image_to_Texture = h
_glBindTexture _GL_TEXTURE_2D, DONT_USE_GLH_Handle(h).handle
_glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH(image_handle), _HEIGHT(image_handle), 0, &H80E1&&, _GL_UNSIGNED_BYTE, m.OFFSET
_MEMFREE m
END FUNCTION
FUNCTION DONT_USE_GLH_New_Texture_Handle
handle&& = 0
_glGenTextures 1, _OFFSET(handle&&)
DONT_USE_GLH_New_Texture_Handle = handle&&
FOR h = 1 TO UBOUND(DONT_USE_GLH_Handle)
IF DONT_USE_GLH_Handle(h).in_use = 0 THEN
DONT_USE_GLH_Handle(h).in_use = 1
DONT_USE_GLH_Handle(h).handle = handle&&
DONT_USE_GLH_New_Texture_Handle = h
EXIT FUNCTION
END IF
NEXT
REDIM _PRESERVE DONT_USE_GLH_Handle(UBOUND(DONT_USE_GLH_HANDLE) * 2) AS DONT_USE_GLH_Handle_TYPE
DONT_USE_GLH_Handle(h).in_use = 1
DONT_USE_GLH_Handle(h).handle = handle&&
DONT_USE_GLH_New_Texture_Handle = h
END FUNCTION
SUB GLH_Load_Model_Format_X (Filename$, Optional_Texture_Filename$)
_AUTODISPLAY 'so loading messages can be seen
DEFLNG A-Z
IF LEN(Optional_Texture_Filename$) THEN
texture_image = _LOADIMAGE(Optional_Texture_Filename$, 32)
IF texure_image = -1 THEN texure_image = 0
END IF
'temporary arrays
DIM SIDE_LIST(10000) AS LONG 'used for wrangling triangle-fans/triangle-strips
REDIM TEXCO_TX(1) AS SINGLE
REDIM TEXCO_TY(1) AS SINGLE
REDIM POLY_FACE_INDEX_FIRST(1) AS LONG
REDIM POLY_FACE_INDEX_LAST(1) AS LONG
'buffer file
fh = FREEFILE: OPEN Filename$ FOR BINARY AS #fh: file_data$ = SPACE$(LOF(fh)): GET #fh, , file_data$: CLOSE #fh
file_x = 1
file_data$ = UCASE$(file_data$)
ASC_COMMA = 44
ASC_SEMICOLON = 59
ASC_LBRAC = 123
ASC_RBRAC = 125
ASC_SPACE = 32
ASC_TAB = 9
ASC_CR = 13
ASC_LF = 10
ASC_FSLASH = 47
ASC_DOT = 46
ASC_MINUS = 45
DIM WhiteSpace(255) AS LONG
WhiteSpace(ASC_LF) = -1
WhiteSpace(ASC_CR) = -1
WhiteSpace(ASC_SPACE) = -1
WhiteSpace(ASC_TAB) = -1
DIM FormattingCharacter(255) AS LONG
FormattingCharacter(ASC_COMMA) = -1
FormattingCharacter(ASC_SEMICOLON) = -1
FormattingCharacter(ASC_LBRAC) = -1
FormattingCharacter(ASC_RBRAC) = -1
DIM Numeric(255) AS LONG
FOR a = 48 TO 57
Numeric(a) = -1
NEXT
Numeric(ASC_DOT) = -1
Numeric(ASC_MINUS) = -1
PRINT "Loading model:"
DO
skip_comment:
'find start of element
x1 = -1
FOR x = file_x TO LEN(file_data$)
IF WhiteSpace(ASC(file_data$, x)) = 0 THEN x1 = x: EXIT FOR
NEXT
IF x1 = -1 THEN EXIT DO 'no more data
a = ASC(file_data$, x1)
IF a = ASC_FSLASH THEN 'commend
IF ASC(file_data$, x1 + 1) = ASC_FSLASH THEN
FOR x = x1 TO LEN(file_data$)
a = ASC(file_data$, x)
IF a = ASC_CR OR a = ASC_LF THEN file_x = x + 1: GOTO skip_comment '//.....
NEXT
END IF
END IF
'find end of element
x2 = x1
FOR x = x1 TO LEN(file_data$)
a = ASC(file_data$, x)
IF WhiteSpace(a) THEN
IF a = ASC_CR OR a = ASC_LF THEN EXIT FOR 'it is the end
ELSE
'not whitespace
IF FormattingCharacter(a) THEN EXIT FOR
x2 = x
END IF
NEXT
file_x = x2 + 1
a2$ = MID$(file_data$, x1, x2 - x1 + 1)
IF LEN(skip_until$) THEN
IF a2$ <> skip_until$ THEN GOTO skip_comment
skip_until$ = ""
END IF
a = ASC(a2$)
IF Numeric(a) AND a <> ASC_DOT THEN 'faster than VAL, value conversion
v = 0
dp = 0
div = 1
IF a = ASC_MINUS THEN neg = 1: x1 = 2 ELSE neg = 0: x1 = 1
FOR x = x1 TO LEN(a2$)
a2 = ASC(a2$, x)
IF a2 = ASC_DOT THEN
dp = 1
ELSE
v = v * 10 + (a2 - 48)
IF dp THEN div = div * 10
END IF
NEXT
IF dp = 1 THEN
v# = v
div# = div
IF neg THEN value# = (-v#) / div# ELSE value# = v# / div#
ELSE
IF neg THEN value# = -v ELSE value# = v
END IF
END IF
IF face_input THEN
IF face_input = 3 THEN
IF a2$ = ";" THEN
IF last_a2$ = ";" THEN face_input = 0
SLI = SLI + 1
ELSEIF a2$ = "," THEN
face_input = 2
polygon = polygon + 1
ELSE
SIDE_LIST(SLI) = value#
IF SLI >= 3 THEN
FACES = FACES + 1
IF FACES > UBOUND(FACE) THEN REDIM _PRESERVE FACE(UBOUND(FACE) * 2) AS FACE_TYPE
FACE(FACES).V1.V = SIDE_LIST(1)
FACE(FACES).V2.V = SIDE_LIST(SLI - 1)
FACE(FACES).V3.V = SIDE_LIST(SLI)
IF POLY_FACE_INDEX_FIRST(polygon) = 0 THEN POLY_FACE_INDEX_FIRST(polygon) = FACES
POLY_FACE_INDEX_LAST(polygon) = FACES
FACE(FACES).Index = polygon
END IF
file_x = file_x + 1: a2$ = ";": a = ASC_SEMICOLON: SLI = SLI + 1
END IF
GOTO done
END IF
IF face_input = 2 THEN
SIDES = value#
SLI = 0
face_input = 3
GOTO done
END IF
IF face_input = 1 THEN
POLYGONS = value#
REDIM _PRESERVE FACE(POLYGONS * 4) AS FACE_TYPE 'estimate triangles in polygons
REDIM POLY_FACE_INDEX_FIRST(POLYGONS) AS LONG
REDIM POLY_FACE_INDEX_LAST(POLYGONS) AS LONG
polygon = 1
face_input = 2
FACES = 0
GOTO done
END IF
END IF
IF mesh_input THEN
IF mesh_input = 5 THEN
IF a = ASC_SEMICOLON THEN
mesh_input = 0: face_input = 1
IF normals_input = 1 THEN
face_input = 0 'face input is unrequired on 2nd pass
skip_until$ = "MESHMATERIALLIST"
END IF
END IF
GOTO done
END IF
IF mesh_input = 4 THEN
IF a = ASC_SEMICOLON THEN
'ignore
ELSEIF a = ASC_COMMA THEN
vertex = vertex + 1
ELSE
IF normals_input = 1 THEN
IF plane = 1 THEN VERTEX(vertex).NX = value#
IF plane = 2 THEN VERTEX(vertex).NY = value#
IF plane = 3 THEN VERTEX(vertex).NZ = value#
ELSE
IF plane = 1 THEN VERTEX(vertex).X = value#
IF plane = 2 THEN VERTEX(vertex).Y = value#
IF plane = 3 THEN VERTEX(vertex).Z = value#
END IF
plane = plane + 1
IF plane = 4 THEN
plane = 1
IF vertex = VERTICES THEN mesh_input = 5
END IF
file_x = file_x + 1 'skip next character (semicolon)
END IF
GOTO done
END IF
IF mesh_input = 3 THEN
IF a2$ = ";" THEN mesh_input = 4
GOTO done
END IF
IF mesh_input = 2 THEN
VERTICES = value#
IF normals_input = 0 THEN
REDIM VERTEX(VERTICES) AS VERTEX_TYPE
REDIM TEXCO_TX(VERTICES) AS SINGLE
REDIM TEXCO_TY(VERTICES) AS SINGLE
END IF
mesh_input = 3
GOTO done
END IF
IF mesh_input = 1 THEN
IF a2$ = "{" THEN mesh_input = 2: plane = 1: vertex = 1
GOTO done
END IF
GOTO done
END IF
IF matlist_input THEN
IF matlist_input = 6 THEN
IF a2$ = "," THEN
'do nothing
ELSEIF a2$ = ";" THEN
matlist_input = 0
ELSE
polygon = polygon + 1: m = value#
FOR f = POLY_FACE_INDEX_FIRST(polygon) TO POLY_FACE_INDEX_LAST(polygon)
FACE(f).Material = m + 1
NEXT
END IF
GOTO done
END IF
IF matlist_input = 5 AND a2$ = ";" THEN matlist_input = 6: polygon = 0: face_search_start = 1: GOTO done
IF matlist_input = 4 THEN matlist_input = 5: GOTO done
IF matlist_input = 3 AND a2$ = ";" THEN matlist_input = 4: GOTO done
IF matlist_input = 2 THEN MATERIALS = value#: REDIM MATERIAL(MATERIALS) AS MATERIAL_TYPE: matlist_input = 3: GOTO done
IF matlist_input = 1 AND a2$ = "{" THEN matlist_input = 2: GOTO done
GOTO done
END IF
IF material_input THEN
IF material_input = 2 THEN
IF a2$ = ";" THEN
'do nothing
ELSEIF a2$ = "}" THEN
material_input = 0
ELSE
N = material_n
IF N = 1 THEN MATERIAL(MATERIAL).Diffuse.R = value#
IF N = 2 THEN MATERIAL(MATERIAL).Diffuse.G = value#
IF N = 3 THEN MATERIAL(MATERIAL).Diffuse.B = value#
IF N = 4 THEN MATERIAL(MATERIAL).Diffuse.A = value#
IF N = 5 THEN MATERIAL(MATERIAL).Diffuse.Intensity = value# / 100
IF N = 6 THEN MATERIAL(MATERIAL).Specular.R = value#
IF N = 7 THEN MATERIAL(MATERIAL).Specular.G = value#
IF N = 8 THEN MATERIAL(MATERIAL).Specular.B = value#
IF N = 9 THEN MATERIAL(MATERIAL).Specular.A = value#
IF N = 10 THEN MATERIAL(MATERIAL).Specular.Intensity = MATERIAL(MATERIAL).Diffuse.Intensity
'if texture_image
material_n = N + 1
END IF
GOTO done
END IF
IF material_input = 1 AND a2$ = "{" THEN material_input = 2: material_n = 1: GOTO done
GOTO done
END IF
IF texco_input THEN
IF texco_input = 4 THEN
IF a2$ = ";" THEN
IF last_a2$ = ";" THEN
texco_input = 0
GOTO finished
END IF
plane = plane + 1: IF plane = 3 THEN plane = 1
ELSEIF a2$ = "," THEN
vertex = vertex + 1
ELSE
IF plane = 1 THEN
TEXCO_TX(vertex) = value#
ELSE
TEXCO_TY(vertex) = value#
END IF
END IF
GOTO done
END IF
IF texco_input = 3 THEN
IF a2$ = ";" THEN texco_input = 4: plane = 1: vertex = 1
GOTO done
END IF
IF texco_input = 2 THEN
'vertices already known
texco_input = 3
GOTO done
END IF
IF texco_input = 1 THEN
IF a2$ = "{" THEN texco_input = 2
GOTO done
END IF
GOTO done
END IF
'mode switch?
IF a2$ = "MESHTEXTURECOORDS" THEN texco_input = 1: PRINT "[Texture Coordinates]";: GOTO done
IF a2$ = "MESHNORMALS" THEN normals_input = 1: mesh_input = 1: face_input = 0: PRINT "[Normals]";: GOTO done
IF a2$ = "MESH" THEN mesh_input = 1: PRINT "[Mesh Vertices & Faces]";: GOTO done
IF a2$ = "MESHMATERIALLIST" THEN matlist_input = 1: PRINT "[Face Material Indexes]";: GOTO done
IF LEFT$(a2$, 9) = "MATERIAL " THEN
material_input = 1: MATERIAL = MATERIAL + 1
MATERIAL(MATERIAL).Texture = 0: MATERIAL(MATERIAL).Texture_Image = texture_image
PRINT "[Material]";: GOTO done
END IF
done:
progress = progress + 1: IF progress > 5000 THEN PRINT ".";: progress = 0
IF a = ASC_SEMICOLON THEN
last_a2$ = a2$
ELSE
IF LEN(last_a2$) THEN last_a2$ = ""
END IF
LOOP
finished:
'change texture coords (with are organised per vertex to be organised by face side
'that way one vertex can share multiple materials without duplicating the vertex
PRINT "[Attaching Texture Coordinates to Face Cornders]";
f = 1
DO UNTIL f > FACES
v = FACE(f).V1.V + 1: FACE(f).V1.TX = TEXCO_TX(v): FACE(f).V1.TY = TEXCO_TY(v)
v = FACE(f).V2.V + 1: FACE(f).V2.TX = TEXCO_TX(v): FACE(f).V2.TY = TEXCO_TY(v)
v = FACE(f).V3.V + 1: FACE(f).V3.TX = TEXCO_TX(v): FACE(f).V3.TY = TEXCO_TY(v)
f = f + 1
LOOP
PRINT
PRINT "Model loaded!"
DEFSNG A-Z
END SUB
FUNCTION GLH_RGB%& (r AS SINGLE, g AS SINGLE, b AS SINGLE)
DONT_USE_GLH_COL_RGBA(1) = r
DONT_USE_GLH_COL_RGBA(2) = g
DONT_USE_GLH_COL_RGBA(3) = b
DONT_USE_GLH_COL_RGBA(4) = 1
GLH_RGB = _OFFSET(DONT_USE_GLH_COL_RGBA())
END FUNCTION
FUNCTION GLH_RGBA%& (r AS SINGLE, g AS SINGLE, b AS SINGLE, a AS SINGLE)
DONT_USE_GLH_COL_RGBA(1) = r
DONT_USE_GLH_COL_RGBA(2) = g
DONT_USE_GLH_COL_RGBA(3) = b
DONT_USE_GLH_COL_RGBA(4) = a
GLH_RGBA = _OFFSET(DONT_USE_GLH_COL_RGBA())
END FUNCTION