Социал-сычевист
Регистрация: 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.
|