Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для компьютеров > BlitzMax > 3D-программирование

3D-программирование miniB3D, OpenGL

Ответ
 
Опции темы
Старый 18.09.2013, 14:53   #1
Кирпи4
Социал-сычевист
 
Аватар для Кирпи4
 
Регистрация: 24.06.2011
Сообщений: 593
Написано 331 полезных сообщений
(для 1,295 пользователей)
MD2 Loader под MiniB3D

Сап булка.
Очень уж я подружился с максом, и ещё сильнее с minib3d. И тут народ захотел увидеть в SpriteBoy (а плеер под него написан именно на максе) модельки хотя бы в MD2. Ну а кто я такой, чтобы им отказать?

Лоадер был написан, но при загрузке и построении меша происходит какая то неведомость с текстурными координатами. Для примера сравните:

Блицевский LoadMD2


Моё творение


Как видно, на бошке, на левой бицухе и по бокам ног есть ошибка UV. Я обрыскал весь код вдоль и поперёк, проверил UV, но всё видимо в порядке. Очень надеюсь на вашу помощь.

Код загрузчика (минибздун для работы обязателен)
Rem
	bbdoc:Undocumented type
End Rem

Function MD2Interp:Float(x1:Float, x2:Float, trans:Float)
	Return x1 + ((x2-x1)*trans)
End Function

Type TMD2Vert
	Field x:Float, y:Float, z:Float
End Type

Type TMD2Tri
	Field vert:Int[3]
	Field tex:Int[3]
End Type

Type TMD2TexCoord
	Field u:Double
	Field v:Double
End Type

	
Type TMD2Frame
	Field Name:String
	Field Scale:Float[3]
	Field Trans:Float[3]
	Field Surf:TSurface
	Field Vertices:TMD2Vert[]
End Type

Const _MAGIC:Int = 0
Const _VERSION:Int = 1
Const _SKIN_WIDTH:Int = 2
Const _SKIN_HEIGHT:Int = 3
Const _FRAME_SIZE:Int = 4
Const _COUNT_SKIN:Int = 5
Const _COUNT_VERTEX:Int = 6
Const _COUNT_TEXCOORD:Int = 7
Const _COUNT_TRIS:Int = 8
Const _COUNT_OGLCOM:Int = 9
Const _COUNT_FRAME:Int = 10
Const _OFF_SKIN:Int = 11
Const _OFF_TEXCOORD:Int = 12
Const _OFF_TRIS:Int = 13
Const _OFF_FRAME:Int = 14
Const _OFF_OGLCOM:Int = 15
Const _OFF_EOF:Int = 16

Const MD2_UseInterpolation:Int = 1


Type TMD2' Extends TEntity
	Global md2s:TList = CreateList()

	Field file:TStream
	Field mesh:TMesh
	Field surf:TSurface
	Field header:Int[17]
	Field frames:TMD2Frame[]
	Field tris:TMD2Tri[]
	Field coords:TMD2TexCoord[]
	
	Field anim_mode:Int
	Field anim_bounds:Int[2]
	Field anim_spd:Float
	Field anim_pos:Float
	Field anim_interp:Float
	
	Method UpdateFrame()
		' Calculating interpolation
		Local interp:Float = Self.anim_pos - Floor(Self.anim_pos)
		Local fr1:Int = Floor(Self.anim_pos)
		If fr1 < Self.anim_bounds[0] fr1 = Self.anim_bounds[1]
		Local fr2:Int = fr1 + 1
		If fr2 > Self.anim_bounds[1] fr2 = Self.anim_bounds[0]
		If MD2_UseInterpolation
			For Local i:Int = 0 To Self.surf.CountVertices() - 1
				Local x:Float[2], y:Float[2], z:Float[2]
				x[0] = Self.frames[fr1].Vertices[i].x
				y[0] = Self.frames[fr1].Vertices[i].y
				z[0] = Self.frames[fr1].Vertices[i].z
				x[1] = Self.frames[fr2].Vertices[i].x
				y[1] = Self.frames[fr2].Vertices[i].y
				z[1] = Self.frames[fr2].Vertices[i].z
				Self.surf.VertexCoords(i, MD2Interp(x[0], x[1], interp), MD2Interp(y[0], y[1], interp), MD2Interp(z[0], z[1], interp))
			Next
		Else
			For Local i:Int = 0 To Self.surf.CountVertices() - 1
				Self.surf.VertexCoords(i, Self.frames[fr1].Vertices[i].x, Self.frames[fr1].Vertices[i].y, Self.frames[fr1].Vertices[i].z)
			Next
		EndIf
	End Method
	
	Method StartAnim(st:Int, en:Int, spd:Float, md:Int, trans:Float)
		Self.anim_bounds[0] = st
		Self.anim_bounds[1] = en
		Self.anim_pos = Self.anim_bounds[0]
		Self.anim_spd = spd
		Self.anim_mode = md
		Self.anim_interp = trans
	End Method
	
	' Funcs
	Function LoadMD2:TMD2(path:String, parent:TEntity = Null)
		Local f:TStream = ReadStream(path)
		If Not f Return Null
		Local m:TMD2 = New TMD2
		
		' Header
		For Local i:Int = 0 To 16
			m.header[i] = ReadInt(f)
		Next
		
		If m.header[_VERSION] <> 8
			CloseStream f
			Return Null
		EndIf
		
		' Frames
		
		SeekStream(f, m.header[_OFF_FRAME])
		m.frames = New TMD2Frame[m.header[_COUNT_FRAME]]
		For Local I:Int = 0 To m.header[_COUNT_FRAME] - 1
			Local Fr:TMD2Frame = New TMD2Frame
			Fr.Scale[0] = ReadFloat(f)
			Fr.Scale[1] = ReadFloat(f)
			Fr.Scale[2] = ReadFloat(f)
			Fr.Trans[0] = ReadFloat(f)
			Fr.Trans[1] = ReadFloat(f)
			Fr.Trans[2] = ReadFloat(f)
			Fr.Name = ReadString(f, 16)
			Fr.Vertices = New TMD2Vert[m.header[_COUNT_VERTEX] ]
			For Local V:Int = 0 To m.header[_COUNT_VERTEX] - 1
				Local Temp:TMD2Vert = New TMD2Vert
				Temp.x = Float((ReadByte(f) * Fr.Scale[0]) + Fr.Trans[0])
				Temp.y = Float((ReadByte(f) * Fr.Scale[1]) + Fr.Trans[1])
				Temp.z = Float((ReadByte(f) * Fr.Scale[2]) + Fr.Trans[2])
				ReadByte(f) ' Skip Normal Index
				Fr.Vertices[V] = Temp
			Next
			m.frames[i] = Fr
		Next
		
		' Triangles
		
		SeekStream(f, m.header[_OFF_TRIS])
		m.tris = New TMD2Tri[m.header[_COUNT_TRIS] ]
		For Local I:Int = 0 To m.header[_COUNT_TRIS] - 1
			Local T:TMD2Tri = New TMD2Tri
			T.vert[2] = ReadShort(f)
			T.vert[1] = ReadShort(f)
			T.vert[0] = ReadShort(f)
			T.tex[2] = ReadShort(f)
			T.tex[1] = ReadShort(f)
			T.tex[0] = ReadShort(f)
			'Print T.VIndex[0] + " : " + T.VINDEX[1] + " : " + T.Vindex[2] 
			m.tris[i] = T
		Next
		
		' Tex Coords
		
		SeekStream(f, m.header[_OFF_TEXCOORD])
		m.coords = New TMD2TexCoord[m.header[_COUNT_TEXCOORD] ]
		For Local I:Int = 0 To m.header[_COUNT_TEXCOORD] - 1
			Local T:TMD2TexCoord = New TMD2TexCoord
			T.U = Float(ReadShort(f)) / Float(m.header[_SKIN_WIDTH])
			T.V = Float(ReadShort(f)) / Float(m.header[_SKIN_HEIGHT])
			m.coords[i] = T
		Next
		
		' Building mesh
		m.mesh = CreateMesh(parent)
		m.mesh.EntityFX(3 + 8)
		Local surf:TSurface = m.mesh.CreateSurface()
		m.surf = surf
		For Local v:TMD2Vert = EachIn m.frames[0].Vertices
			surf.AddVertex(v.x, v.y, v.z)
		Next
		For Local fr:TMD2Frame = EachIn m.frames
			
			Local sr:TSurface = CreateSurface(m.mesh)
			For Local v:TMD2Vert = EachIn fr.Vertices
				sr.AddVertex(v.x, v.y, v.z)
			Next
		Next
		
		For Local t:TMD2Tri = EachIn m.tris
			surf.AddTriangle(t.vert[0], t.vert[1], t.vert[2])
			surf.VertexTexCoords(t.vert[0], m.coords[t.tex[0] ].u, m.coords[t.tex[0] ].v)
			surf.VertexTexCoords(t.vert[1], m.coords[t.tex[1] ].u, m.coords[t.tex[1] ].v)
			surf.VertexTexCoords(t.vert[2], m.coords[t.tex[2] ].u, m.coords[t.tex[2] ].v)
			
		Next
		
		
		md2s.AddLast(m)
		Return m
	EndFunction
	
	Function UpdateMD2(spd:Float = 1)
		Local m:TMD2
		For m = EachIn TMD2.md2s
			Local inview:Int = 0
			For Local c:TCamera = EachIn TCamera.cam_list
				If c.Hidden() = 0
					If c.EntityInView(m.mesh)
						inview = 1
						Exit
					End If
				End If
			Next
			If m.anim_mode > 0 And m.anim_spd <> 0 And inview
				m.UpdateFrame()
				If m.anim_interp <> 0
					
				Else
					m.anim_pos:+(spd * m.anim_spd)
					Select m.anim_mode
						Case 1
							If m.anim_spd < 0
								If m.anim_pos <= m.anim_bounds[0] m.anim_pos = m.anim_bounds[1]
							Else
								If m.anim_pos >= m.anim_bounds[1] m.anim_pos = m.anim_bounds[0]
							End If
						Case 2
							If m.anim_spd < 0
								If m.anim_pos < m.anim_bounds[0] m.anim_mode = 0
							Else
								If m.anim_pos > m.anim_bounds[1] m.anim_mode = 0
							End If
						
					End Select
				EndIf
			End If
		Next
	EndFunction
	
	
End Type
__________________
(Offline)
 
Ответить с цитированием
Старый 18.09.2013, 15:21   #2
Черный крыс
 
Сообщений: n/a
Ответ: MD2 Loader под MiniB3D

да бывает такое. Я тоже как то писал загрузчики md2/md3

Там нужно очень хитро передавать указатель. Пороюсь в мусорке, если найду - выложу полностью рабочий загрузчик.
 
Ответить с цитированием
Старый 18.09.2013, 15:33   #3
Кирпи4
Социал-сычевист
 
Аватар для Кирпи4
 
Регистрация: 24.06.2011
Сообщений: 593
Написано 331 полезных сообщений
(для 1,295 пользователей)
Ответ: MD2 Loader под MiniB3D

Если найдёшь - пожму руку

UPD: Хм, по-видимому с UV всё нормально, это они уже херово передаются в самого бздуна. Печаль века...
__________________
(Offline)
 
Ответить с цитированием
Старый 18.09.2013, 15:58   #4
Черный крыс
 
Сообщений: n/a
Ответ: MD2 Loader под MiniB3D

загрузчик остался в жостком который я снял....

Короче тама наскок я помню делал так :

1 ) закидывал в массив
2 ) передавал адрес указателя

вроде так :

Local uv#[2]

glTexCoords2fv(VarPtr Float Ptr(uv[0]), VarPtr Float Ptr(uv[1])) 
Или вроде так

glCoordsv(VarPtr Float Ptr(uv)) 
 
Ответить с цитированием
Старый 18.09.2013, 21:04   #5
Кирпи4
Социал-сычевист
 
Аватар для Кирпи4
 
Регистрация: 24.06.2011
Сообщений: 593
Написано 331 полезных сообщений
(для 1,295 пользователей)
Ответ: MD2 Loader под MiniB3D

Дьябло, ты извращенец =D

А если по теме: автэ оч сильно помог, практически указал на ошибку. Всё дело оказалось в том, что формат по несколько раз использует одни и те же вершины, задавая им разные UV. Так как в своё время ни VBO, ни каких то других фенечек не было, всё рисовалось через glBegin-glEnd. Собственно, вертексы в их существенном понимании отсутствовали и нигде не хранились, задаваясь каждый раз по новой. Поэтому пришлось немного подкостылить, заимев на каждый MD2-вертекс TList, который содержит реальные айди вершин-двойников этого вертекса.

Анимации ещё надо сильно допиливать.

Rem
	MD2 Loader
End Rem

Function MD2Interp:Float(x1:Float, x2:Float, trans:Float)
	Return x1 + ((x2-x1)*trans)
End Function

Type TMD2Vert
	Field x:Float, y:Float, z:Float
End Type

Type TMD2BlitzVert
	Field tris:TList
End Type

Type TMD2Tri
	Field vert:Int[3]
	Field tex:Int[3]
End Type

Type TMD2TexCoord
	Field u:Double
	Field v:Double
End Type

	
Type TMD2Frame
	Field Name:String
	Field Scale:Float[3]
	Field Trans:Float[3]
	Field Vertices:TMD2Vert[]
End Type

Const _MAGIC:Int = 0
Const _VERSION:Int = 1
Const _SKIN_WIDTH:Int = 2
Const _SKIN_HEIGHT:Int = 3
Const _FRAME_SIZE:Int = 4
Const _COUNT_SKIN:Int = 5
Const _COUNT_VERTEX:Int = 6
Const _COUNT_TEXCOORD:Int = 7
Const _COUNT_TRIS:Int = 8
Const _COUNT_OGLCOM:Int = 9
Const _COUNT_FRAME:Int = 10
Const _OFF_SKIN:Int = 11
Const _OFF_TEXCOORD:Int = 12
Const _OFF_TRIS:Int = 13
Const _OFF_FRAME:Int = 14
Const _OFF_OGLCOM:Int = 15
Const _OFF_EOF:Int = 16

Const MD2_UseInterpolation:Int = 1


Type TMD2' Extends TEntity
	Global md2s:TList = CreateList()

	Field file:TStream
	Field mesh:TMesh
	Field surf:TSurface
	Field header:Int[17]
	Field frames:TMD2Frame[]
	Field tris:TMD2Tri[]
	Field coords:TMD2TexCoord[]
	Field verts:TMD2BlitzVert[]
	Field skins:String[]
	
	Field anim_mode:Int
	Field anim_bounds:Int[2]
	Field anim_spd:Float
	Field anim_pos:Float
	Field anim_interp:Float
	
	Method UpdateFrame()
		' Calculating interpolation
		Local interp:Float = Self.anim_pos - Floor(Self.anim_pos)
		Local fr1:Int = Floor(Self.anim_pos)
		If fr1 < Self.anim_bounds[0] fr1 = Self.anim_bounds[1]
		Local fr2:Int = fr1 + 1
		If fr2 > Self.anim_bounds[1] fr2 = Self.anim_bounds[0]
		If MD2_UseInterpolation
			For Local i:Int = 0 To Self.header[_COUNT_VERTEX] - 1
				Local x:Float[2], y:Float[2], z:Float[2]
				x[0] = Self.frames[fr1].Vertices[i].x
				y[0] = Self.frames[fr1].Vertices[i].y
				z[0] = Self.frames[fr1].Vertices[i].z
				x[1] = Self.frames[fr2].Vertices[i].x
				y[1] = Self.frames[fr2].Vertices[i].y
				z[1] = Self.frames[fr2].Vertices[i].z
				Self.repositionVert(i, MD2Interp(x[0], x[1], interp), MD2Interp(y[0], y[1], interp), MD2Interp(z[0], z[1], interp))
			Next
		Else
			For Local i:Int = 0 To Self.header[_COUNT_VERTEX] - 1
				Self.repositionVert(i, Self.frames[fr1].Vertices[i].x, Self.frames[fr1].Vertices[i].y, Self.frames[fr1].Vertices[i].z)
			Next
		EndIf
	End Method
	
	Method StartAnim(st:Int, en:Int, spd:Float, md:Int, trans:Float)
		Self.anim_bounds[0] = st
		Self.anim_bounds[1] = en
		Self.anim_pos = Self.anim_bounds[0]
		Self.anim_spd = spd
		Self.anim_mode = md
		Self.anim_interp = trans
		If Self.anim_bounds[1] > Self.header[_COUNT_FRAME] - 1 Self.anim_bounds[1] = Self.header[_COUNT_FRAME] - 1
	End Method
	
	'========== Funcs =============
	'Quake2 MD2
	
	Function LoadMD2:TMD2(path:String, parent:TEntity = Null)
		Local f:TStream = ReadStream(path)
		If Not f Return Null
		Local m:TMD2 = New TMD2
		
		' Header
		For Local i:Int = 0 To 16
			m.header[i] = ReadInt(f)
		Next
		
		If m.header[_VERSION] <> 8
			CloseStream f
			Return Null
		EndIf
		
		' Frames
		
		SeekStream(f, m.header[_OFF_FRAME])
		m.frames = New TMD2Frame[m.header[_COUNT_FRAME] ]
		m.verts = New TMD2BlitzVert[m.header[_COUNT_VERTEX] ]
		For Local I:Int = 0 To m.header[_COUNT_FRAME] - 1
			Local Fr:TMD2Frame = New TMD2Frame
			Fr.Scale[0] = ReadFloat(f)
			Fr.Scale[1] = ReadFloat(f)
			Fr.Scale[2] = ReadFloat(f)
			Fr.Trans[0] = ReadFloat(f)
			Fr.Trans[1] = ReadFloat(f)
			Fr.Trans[2] = ReadFloat(f)
			Fr.Name = ReadString(f, 16)
			Fr.Vertices = New TMD2Vert[m.header[_COUNT_VERTEX] ]
			For Local V:Int = 0 To m.header[_COUNT_VERTEX] - 1
				m.verts[v] = New TMD2BlitzVert
				m.verts[v].tris = CreateList()
				Local Temp:TMD2Vert = New TMD2Vert
				Temp.z = Float((ReadByte(f) * Fr.Scale[0]) + Fr.Trans[0])
				Temp.x = Float((ReadByte(f) * Fr.Scale[1]) + Fr.Trans[1])
				Temp.y = Float((ReadByte(f) * Fr.Scale[2]) + Fr.Trans[2])
				ReadByte(f) ' Skip Normal Index
				Fr.Vertices[V] = Temp
			Next
			m.frames[i] = Fr
		Next
		
		' Triangles
		
		SeekStream(f, m.header[_OFF_TRIS])
		m.tris = New TMD2Tri[m.header[_COUNT_TRIS] ]
		For Local I:Int = 0 To m.header[_COUNT_TRIS] - 1
			Local T:TMD2Tri = New TMD2Tri
			T.vert[0] = ReadShort(f)
			T.vert[1] = ReadShort(f)
			T.vert[2] = ReadShort(f)
			T.tex[0] = ReadShort(f)
			T.tex[1] = ReadShort(f)
			T.tex[2] = ReadShort(f)
			m.tris[i] = T
		Next
		
		' Tex Coords
		
		SeekStream(f, m.header[_OFF_TEXCOORD])
		m.coords = New TMD2TexCoord[m.header[_COUNT_TEXCOORD] ]
		For Local I:Int = 0 To m.header[_COUNT_TEXCOORD] - 1
			Local T:TMD2TexCoord = New TMD2TexCoord
			T.U = Float(ReadShort(f)) / Float(m.header[_SKIN_WIDTH])
			T.V = Float(ReadShort(f)) / Float(m.header[_SKIN_HEIGHT])
			m.coords[i] = T
		Next
		
		' Skins
		
		SeekStream(f, m.header[_OFF_SKIN])
		m.skins = New String[m.header[_COUNT_SKIN] ]
		For Local I:Int = 0 To m.header[_COUNT_SKIN] - 1
			m.skins[i] = Trim(ReadString(f, 64))
		Next
		
		' Building mesh
		m.mesh = CreateMesh(parent)
		m.mesh.EntityFX(3 + 8)
		Local surf:TSurface = m.mesh.CreateSurface()
		m.surf = surf
		For Local t:TMD2Tri = EachIn m.tris
			Local vrt:Int[3]
			vrt[0] = m.addInternalVert(surf, t.vert[0], m.coords[t.tex[0] ].u, m.coords[t.tex[0] ].v)
			vrt[1] = m.addInternalVert(surf, t.vert[1], m.coords[t.tex[1] ].u, m.coords[t.tex[1] ].v)
			vrt[2] = m.addInternalVert(surf, t.vert[2], m.coords[t.tex[2] ].u, m.coords[t.tex[2] ].v)
			surf.AddTriangle(vrt[2], vrt[1], vrt[0])
		Next
		
		md2s.AddLast(m)
		Return m
	EndFunction
	
	Method addInternalVert:Int(surf:TSurface, vid:Int, u:Float, v:Float)
		Local vrt:Int = surf.AddVertex(Self.frames[0].Vertices[vid].x, Self.frames[0].Vertices[vid].y, Self.frames[0].Vertices[vid].z, u, v)
		Self.verts[vid].tris.AddLast(String(vrt))
		Return vrt
	EndMethod
	
	Method repositionVert(vid:Int, x:Float, y:Float, z:Float)
		For Local i:String = EachIn Self.verts[vid].tris
			Local st:Int = Int(i)
			Self.surf.VertexCoords(st, x, y, z)
		Next
	End Method
	
	Function UpdateMD2(spd:Float = 1)
		Local m:TMD2
		For m = EachIn TMD2.md2s
			Local inview:Int = 0
			For Local c:TCamera = EachIn TCamera.cam_list
				If c.Hidden() = 0
					If c.EntityInView(m.mesh)
						inview = 1
						Exit
					End If
				End If
			Next
			If m.anim_mode > 0 And m.anim_spd <> 0
				If inview m.UpdateFrame()
				If m.anim_interp <> 0
					
				Else
					m.anim_pos:+(spd * m.anim_spd)
					Select m.anim_mode
						Case 1
							If m.anim_spd < 0
								If m.anim_pos <= m.anim_bounds[0] m.anim_pos = m.anim_bounds[1]
							Else
								If m.anim_pos >= m.anim_bounds[1] m.anim_pos = m.anim_bounds[0]
							End If
						Case 2
							If m.anim_spd < 0
								If m.anim_pos < m.anim_bounds[0] m.anim_mode = 0
							Else
								If m.anim_pos > m.anim_bounds[1] m.anim_mode = 0
							End If
						
					End Select
				EndIf
			End If
		Next
	EndFunction
	
	
End Type
__________________
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо Кирпи4 за это полезное сообщение:
Gector (19.09.2013), St_AnGer (19.09.2013)
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 03:23.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com