Показать сообщение отдельно
Старый 21.09.2013, 01:42   #2
Кирпи4
Социал-сычевист
 
Аватар для Кирпи4
 
Регистрация: 24.06.2011
Сообщений: 611
Написано 342 полезных сообщений
(для 1,359 пользователей)
Ответ: OpenGL-загрузчики

Quake 2 MD2
Я у мамы кваколюб


Как юзать:
Лоадер умеет не только грузить, но и собственно рисовать модель, рисует через Immediate Mode (патамуша так рисовал сам Кармак, лол), секцию OGLCOM не использует.

Загрузка меша
; нам требуется переменная для собственно хранения меша и всех потрохов.
; она должна быть со структурой MD2Entity
myMD2.MD2Entity
; грузим меш. Первый параметр - ссылка на ваш объект, второй - путь.
LoadMD2(@myMD2, "tris.md2")
Отрисовка
; Параметры: ссылка на модель, кадр1, кадр2, интерполяция между ними (float от 0 до 1)
; следует помнить, что функция рисует модель относительно настоящей трансформации, по матрице MODELVIEW
; позиционирование - на вашей совести
; также, функция автоматически не играет анимацию, а лишь рисует интерполированную позицию между "кадр1" и "кадр2"
DisplayMD2(@myMD2, 1, 2, 0.3)
В исходнике ещё много разных функций, но они внутренние и их использование нежелательно.

Код:
; ===================================
; MD2 Loader and Drawer
; 2013 Kirpi4
; ===================================
; 
; Note: GLCCOM section not used


; Vertex
Structure MD2Vert
	x.f
	y.f
	z.f
	n.f
EndStructure

; Triangle
Structure MD2Tri
	Array vert.l(3)
	Array tex.l(3)
EndStructure

; Texture Coords
Structure MD2Coords
	u.f
	v.f
EndStructure

; Frame
Structure MD2Frame
	name.s
	Array trans.f(3)
	Array scale.f(3)
	Array verts.MD2Vert(0)
EndStructure

; Model
Structure MD2Entity
	Array header.l(18)
	Array frames.MD2Frame(0)
	Array tris.MD2Tri(0)
	Array coords.MD2Coords(0)
	Array skins.s(0)
	Array verts.MD2Vert(0)
EndStructure

Enumeration
	#MD2_MAGIC = 0
	#MD2_VERSION
	#MD2_SKIN_WIDTH
	#MD2_SKIN_HEIGHT
	#MD2_FRAME_SIZE
	#MD2_COUNT_SKIN
	#MD2_COUNT_VERTEX
	#MD2_COUNT_TEXCOORD
	#MD2_COUNT_TRIS
	#MD2_COUNT_OGLCOM
	#MD2_COUNT_FRAME
	#MD2_OFF_SKIN
	#MD2_OFF_TEXCOORD
	#MD2_OFF_TRIS
	#MD2_OFF_FRAME
	#MD2_OFF_OGLCOM
	#MD2_OFF_EOF
EndEnumeration

Procedure.s MD2BufferString(f.l,len.l)
	tmp.s = ""
	For i=0 To len-1
		tmp + Chr(ReadByte(f))
	Next
	ProcedureReturn tmp
EndProcedure

Procedure.f MD2Interpolate(x1.f,x2.f,interp.f)
	dlt.f = x2-x1
	ProcedureReturn x1 + (dlt*interp)
EndProcedure

Procedure.f MD2GetPos(pos1.l,scale.f,trans.f)
	oldps.f = (scale*pos1)+trans
	ProcedureReturn oldps
EndProcedure

Procedure.l MD2WrapByte(b.l)
	If b<0
		ProcedureReturn b+256
	Else
		ProcedureReturn b
	EndIf
EndProcedure

Procedure.l LoadMD2(*m.md2entity,file.s)

	f.l = ReadFile(-1,file)
	
	; Header
	For i=0 To 17
		*m\header(i) = ReadLong(f)
	Next
	
	; Frames
	FileSeek(f,*m\header(#MD2_OFF_FRAME))
	Dim *m\frames.MD2Frame(*m\header(#MD2_COUNT_FRAME))
	For i=0 To *m\header(#MD2_COUNT_FRAME)-1
		*m\frames(i)\scale(0) = ReadFloat(f)
		*m\frames(i)\scale(1) = ReadFloat(f)
		*m\frames(i)\scale(2) = ReadFloat(f)
		*m\frames(i)\trans(0) = ReadFloat(f)
		*m\frames(i)\trans(1) = ReadFloat(f)
		*m\frames(i)\trans(2) = ReadFloat(f)
		*m\frames(i)\name = Trim(MD2BufferString(f,16))
		Dim *m\frames(i)\verts.MD2Vert(*m\header(#MD2_COUNT_VERTEX))
		For j=0 To *m\header(#MD2_COUNT_VERTEX)-1
			With *m\frames(i)\verts(j)
				\x = MD2GetPos(MD2WrapByte(ReadByte(f)),*m\frames(i)\scale(0),*m\frames(i)\trans(0))
				\y = MD2GetPos(MD2WrapByte(ReadByte(f)),*m\frames(i)\scale(1),*m\frames(i)\trans(1))
				\z = MD2GetPos(MD2WrapByte(ReadByte(f)),*m\frames(i)\scale(2),*m\frames(i)\trans(2))
				\n = ReadByte(f)
			EndWith
		Next
	Next
	
	; Triangles
	FileSeek(f,*m\header(#MD2_OFF_TRIS))
	Dim *m\tris.MD2Tri(*m\header(#MD2_COUNT_TRIS))
	Dim *m\verts.MD2Vert(*m\header(#MD2_COUNT_VERTEX))
	For i=0 To *m\header(#MD2_COUNT_TRIS)-1
		With *m\tris(i)
			\vert(0) = ReadWord(f)
			\vert(1) = ReadWord(f)
			\vert(2) = ReadWord(f)
			\tex(0) = ReadWord(f)
			\tex(1) = ReadWord(f)
			\tex(2) = ReadWord(f)
		EndWith
	Next
	
	; Texture coords
	FileSeek(f,*m\header(#MD2_OFF_TEXCOORD))
	Dim *m\coords.MD2Coords(*m\header(#MD2_COUNT_TEXCOORD))
	For i=0 To *m\header(#MD2_COUNT_TEXCOORD)-1
		With *m\coords(i)
			cdx.f = ReadWord(f)
			cdy.f = ReadWord(f)
			divx.f = *m\header(#MD2_SKIN_WIDTH)
			divy.f = *m\header(#MD2_SKIN_HEIGHT)
			\u = cdx/divx
			\v = cdy/divy
		EndWith
	Next
	
	; Skins
	FileSeek(f,*m\header(#MD2_OFF_SKIN))
	Dim *m\skins.s(*m\header(#MD2_COUNT_SKIN))
	For i=0 To *m\header(#MD2_COUNT_SKIN)-1
		*m\skins(i) = Trim(MD2BufferString(f,64))
	Next
	
	
	
	CloseFile(f)
	
EndProcedure

Procedure DisplayMD2(*m.md2entity,frame1.l,frame2.l,trans.f)
	If frame1>=frame2
		Swap frame1, frame2
		trans = 1.0-trans
	EndIf
	glEnable_(#GL_CULL_FACE)
	For i=0 To *m\header(#MD2_COUNT_VERTEX)-1
		*m\verts(i)\x = MD2Interpolate(*m\frames(frame1)\verts(i)\x,*m\frames(frame2)\verts(i)\x,trans)
		*m\verts(i)\y = MD2Interpolate(*m\frames(frame1)\verts(i)\y,*m\frames(frame2)\verts(i)\y,trans)
		*m\verts(i)\z = MD2Interpolate(*m\frames(frame1)\verts(i)\z,*m\frames(frame2)\verts(i)\z,trans)
	Next
	glBegin_(#GL_TRIANGLES)
	For i=0 To *m\header(#MD2_COUNT_TRIS)-1
		For j = 0 To 2
			glTexCoord2f_(*m\coords(*m\tris(i)\tex(j))\u,*m\coords(*m\tris(i)\tex(j))\v)
			glVertex3f_(*m\verts(*m\tris(i)\vert(j))\y,*m\verts(*m\tris(i)\vert(j))\z,-*m\verts(*m\tris(i)\vert(j))\x)
		Next
	Next
	glEnd_()
	glDisable_(#GL_CULL_FACE)
EndProcedure
__________________



Последний раз редактировалось Кирпи4, 23.09.2013 в 01:40.
(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо Кирпи4 за это полезное сообщение:
ABTOMAT (21.09.2013), impersonalis (23.09.2013), St_AnGer (23.09.2013)