
ç§ã¯åã
ã§Quake Worldã®ãœãŒã¹ã³ãŒãã®ç ç©¶ã«æ²¡é ããç§ãçè§£ãããã¹ãŠãèšäºã§æŠèª¬ããŸããã ãããæŽçããã人ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã ãã®èšäºã¯4ã€ã®ããŒãã«åãããŠããŸãã
- 建ç¯
- ãããã¯ãŒã¯
- äºæž¬
- å¯èŠå
建ç¯
Quake Client
Quakeã®åŠç¿ã¯ã
qwcl
ïŒã¯ã©ã€ã¢ã³ãïŒãããžã§ã¯ãããå§ãã䟡å€ããããŸãã
WinMain
ãšã³ããª
WinMain
ã¯
sys_win.cã«ãããŸãã èŠããã«ãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
WinMain { while (1) { newtime = Sys_DoubleTime (); time = newtime - oldtime; Host_Frame (time) { setjmp Sys_SendKeyEvents IN_Commands Cbuf_Execute CL_ReadPackets CL_SendCmd CL_SetUpPlayerPrediction(false) CL_PredictMove CL_SetUpPlayerPrediction(true) CL_EmitEntities SCR_UpdateScreen } oldtime = newtime; } }
ããã§ã¯ãQuake Worldã®3ã€ã®äž»èŠãªèŠçŽ ã匷調ã§ããŸãã
- ãããã¯ãŒã¯
CL_ReadPackets
ããã³CL_SendCmd
- äºæž¬
CL_SetUpPlayerPrediction
ã CL_PredictMove
ããã³CL_EmitEntities
- èŠèŠå
SCR_UpdateScreen
ãããã¯ãŒã¯å±€ïŒããããã£ã³ãã«ãšãåŒã°ããŸãïŒã¯ã
frames
æ
å ±ïŒ
frame_t
é
åïŒã«ã¯ãŒã«ãæ
å ±ãåºåããŸãã ãããã¯
äºæž¬ã¬ã€ã€ãŒã«è»¢éããã
cl_visedicts
è¡çªãåŠçãããããŒã¿ã¯å¯èŠæ§é åïŒPOVïŒã®å®çŸ©ãšãšãã«å¯èŠæ§è¡šç€ºïŒ
cl_visedicts
ïŒã®åœ¢åŒã§è¡šç€ºãããŸãã VisEdictã¯ãPOV倿°ïŒ
cl.sim*
ïŒãšãšãã«èŠèŠåã¬ã€ã€ãŒã§äœ¿çšãããã·ãŒã³ãã¬ã³ããªã³ã°ããŸãã

setjmp
ïŒ
ã³ãŒãã«äžéç¹ãèšå®ããŠãäœãæªãããšãèµ·ãã£ãå Žåãããã°ã©ã ã¯ããã«æ»ããŸãã
Sys_SendKeyEvents
ïŒ
Windows OSã¡ãã»ãŒãžã®åä¿¡ããŠã£ã³ããŠã®æå°åãªã©ã ãšã³ãžã³å€æ°ã®å¯Ÿå¿ããæŽæ°ïŒããšãã°ããŠã£ã³ããŠãæå°åãããŠããå Žåãã¯ãŒã«ãã¯ã¬ã³ããªã³ã°ãããŸããïŒã
IN_Commands
ïŒ
ãžã§ã€ã¹ãã£ãã¯ã®ãšã³ããªã«é¢ããæ
å ±ãååŸããŸãã
Cbuf_Execute
ïŒ
ã²ãŒã ã®åãµã€ã¯ã«ã§ãã³ãã³ãã¯ãããã¡ãŒã§å®è¡ãããŸãã ã³ãã³ãã¯äž»ã«ã³ã³ãœãŒã«ãä»ããŠçæãããŸããããµãŒããŒãŸãã¯ããŒã¹ãããŒã¯ãããçæã§ããŸãã
ã²ãŒã ã¯ãã³ãã³ããããã¡ãŒã®
exec quake.rc
ããéå§ããŸãã
CL_ReadPackets
ããã³
CL_SendCmd
ïŒ
ãšã³ãžã³ã®
ãããã¯ãŒã¯éšåã®åŠçã
CL_SendCmd
ã¯ãããŠã¹ãšããŒããŒãã®å
¥åãã€ã³ã¿ãŒã»ããããã³ãã³ããçæããŠéä¿¡ããŸãã
Quake Worldã¯UDPã䜿çšããŠãããããnetChannelãã±ããããããŒã«èšå®ãããã·ãŒã±ã³ã¹/ sequenceACKã«ãã£ãŠäŒéã®ä¿¡é Œæ§ãä¿èšŒãããŸããã ããã«ãæåŸã®ã³ãã³ãã¯äœç³»çã«åéãããŸããã ã¯ã©ã€ã¢ã³ãåŽã§ã¯ãããã±ãŒãžã®è»¢éã«å¶éã¯ãªããæŽæ°ã¯å¯èœãªéãé »ç¹ã«éä¿¡ãããŸããã ãµãŒããŒåŽã§ã¯ããã±ãããåä¿¡ãããéä¿¡é床ãåŠçé床ãããé
ãå Žåã«ã®ã¿ãã¡ãã»ãŒãžãã¯ã©ã€ã¢ã³ãã«éä¿¡ãããŸããã ãã®å¶éã¯ã¯ã©ã€ã¢ã³ãã«ãã£ãŠèšå®ããããµãŒããŒã«éä¿¡ãããŸããã
ããããã¯ãŒã¯ãã»ã¯ã·ã§ã³å
šäœããã®ãããã¯å°çšã§ãã
CL_SetUpPlayerPrediction
ã
CL_PredictMove
ããã³
CL_EmitEntities
ïŒ
ãšã³ãžã³ã§ã®
äºæž¬ãšè¡çªã®èšç®ãå®è¡ããŸããã ãããã¯äž»ã«ããããã¯ãŒã¯äžã®äŒéé
å»¶ã«å¯ŸåŠããããã«èšèšãããŠããŸãã
ãã®ãããã¯ã¯ããäºæž¬ãã»ã¯ã·ã§ã³å
šäœã§èª¬æãããŠããŸãã
SCR_UpdateScreen
ïŒ
ãšã³ãžã³ã§ã®
èŠèŠå ã ãã®éšåã§ã¯ãBSP / PVSãç©æ¥µçã«äœ¿çšãããŸãã ããã§
include
/
define
åºã¥ããŠã³ãŒããåå²ã
define
ã Quakeãšã³ãžã³ã¯ãããã°ã©ã ã§ããŸãã¯ããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ã§äžçãã¬ã³ããªã³ã°ã§ããŸãã
ãèŠèŠåãã»ã¯ã·ã§ã³ã¯ããã«å®å
šã«å°å¿µããŠããŸãã
zipã¢ãŒã«ã€ããéããŠã³ã³ãã€ã«ãã
zipãéãïŒq1sources.zipã¢ãŒã«ã€ãã«ã¯ã
QW
ãš
WinQuake
ãšãã2ã€ã®ãã©ã«ããŒ/ 2ã€ã®Visual Studioãããžã§ã¯ãããã
WinQuake
ã
WinQuake
ã¯ãã¯ã©ã€ã¢ã³ããšãµãŒããŒãçµã¿åããããã³ãŒãã§ãããåäžã®ããã»ã¹ãšããŠåäœããŸãïŒDOSã§ãµããŒããããŠããå Žåããããã¯2ã€ã®å¥åã®ããã»ã¹ã§ããããšãçæ³çã§ãïŒã ãããã¯ãŒã¯ãã¬ã€ã¯LANäžã§ã®ã¿å¯èœã§ãããQW
ã¯ããµãŒããŒãšã¯ã©ã€ã¢ã³ããå¥ã
ã®ãã·ã³ã§å®è¡ããå¿
èŠã®ããQuake Worldãããžã§ã¯ãã§ãïŒã¯ã©ã€ã¢ã³ãWinMain
ã¯WinMain
ïŒ sys_win.c
ïŒã§ããããµãŒããŒãšã³ããªãã€ã³ãã¯main
ïŒ sys_win.c
ïŒã§ããããšã«sys_win.c
ããŠsys_win.c
ïŒ ã
OpenGLã¬ã³ããªã³ã°ã§Quake WorldãåŠã³ãŸããã ãã®ãããžã§ã¯ãã«ã¯4ã€ã®ãµããããžã§ã¯ãããããŸãã
gas2asm
ã¢ã»ã³ãã©ã³ãŒããGNU ASMããx86 ASMã«ç§»æ€ããããã®ãŠãŒãã£ãªãã£qwcl
-Quakeã¯ã©ã€ã¢ã³ãåŽQWFwd
-QuakeãµãŒããŒã®åã«ãããããã·qwsv
-Quake qwsv
ã³ã³ãã€ã«ïŒWindowsãšDirectX SDKãã€ã³ã¹ããŒã«ããåŸãVisual Studio 2008ã§ã®ã³ã³ãã€ã«ã§1ã€ã®ãšã©ãŒãæ€åºãããŸãã
.\net_wins.c(178) : error C2072: '_errno' : initialization of a function
_errno
ã¯çŸåšãä»ã®äœãã«äœ¿çšãããMicrosoftãã¯ãã§ãã ãããã®ãšã©ãŒãä¿®æ£ããã«ã¯ã倿°åã
_errno
眮ãæããŸãïŒäŸïŒ
qerrno
ã
net_wins.c
if (ret == -1) { int qerrno = WSAGetLastError(); if (qerrno == WSAEWOULDBLOCK) return false; if (qerrno == WSAEMSGSIZE) { Con_Printf ("Warning: Oversize packet from %s\n", NET_AdrToString (net_from)); return false; } Sys_Error ("NET_GetPacket: %s", strerror(qerrno)); }
ãªã³ã«ã¯ãqwclãããžã§ã¯ãã®LIBC.libã«ã€ããŠæå¥ãèšããŸãã ç¡èŠãããã©ã€ãã©ãªãIgnored Libraryãã®ãªã¹ãã«è¿œå ããã ãã§ã4ã€ã®ãããžã§ã¯ãã®ã¢ã»ã³ããªãå®äºããŸãã
ããŒã«
Visual Studio ExpressïŒããªãŒãŠã§ã¢ïŒã¯IDEãšããŠæé©ã§ããã BSP / PVSãId Softwareãããã³Quakeã«åºã¥ããŠãšã³ãžã³ãããããçè§£ãããå Žåã¯ãããã€ãã®æ¬ãèªãããšããå§ãããŸãã




Quake Source Codeé±éã®æ¬æ£ã¯æ¬¡ã®ããã«ãªããŸããã

ãããã¯ãŒã¯
QuakeWorldã®ãããã¯ãŒã¯ã¢ãŒããã¯ãã£ã¯ããã€ãŠçŽ æŽããã驿°ãšèŠãªãããŠããŸããã åŸç¶ã®ãã¹ãŠã®ãããã¯ãŒã¯ã²ãŒã ã¯åãã¢ãããŒãã䜿çšããŸããã
ãããã¯ãŒã¯ã¹ã¿ãã¯
Quakeã®æ
å ±äº€æã®åºæ¬åäœã¯
ã§ããã ãããã¯ãäœçœ®ãæ¹åãå¥åº·ããã¬ãŒã€ãŒãžã®ãã¡ãŒãžãªã©ãæŽæ°ããããã«äœ¿çšãããŸãã TCP / IPã«ã¯ããªã¢ã«ã¿ã€ã ã·ãã¥ã¬ãŒã·ã§ã³ïŒéä¿¡å¶åŸ¡ãä¿¡é Œæ§ã®é«ãé
ä¿¡ããã±ããé åºã®ä¿åïŒã«åœ¹ç«ã€å€ãã®åªããæ©èœããããŸããããã®ãããã³ã«ã¯Quake Worldãšã³ãžã³ã§ã¯äœ¿çšã§ããŸããïŒå
ã®Quakeã§äœ¿çšãããŠããŸããïŒã äžäººç§°ã·ã¥ãŒãã£ã³ã°ã²ãŒã ã§ã¯ãæééãã«åä¿¡ãããªãã£ãæ
å ±ã¯åéãã䟡å€ããããŸããã ãããã£ãŠãUDP / IPãéžæãããŸããã ä¿¡é Œæ§ã®é«ãé
ä¿¡ãä¿èšŒãããã±ããã®é åºãç¶æããããã«ãæœè±¡åã®ãããã¯ãŒã¯å±€ã
NetChannel
ããäœæããŸããã
OSIã®èгç¹ããèŠããšã
NetChannel
UDPã®äžã«äŸ¿å©ã«é
眮ãããŠããŸãã

èŠçŽãããšããšã³ãžã³ã¯äž»ã«
æ©èœã
ã ããŒã¿ãéåä¿¡ããå¿
èŠãããå Žåã圌ã¯ãã®ã¿ã¹ã¯ã
Netchan_Transmit
ããã³
Netchan_Process
ã«
netchan.c
ïŒãããã®ã¡ãœããã¯ã¯ã©ã€ã¢ã³ããšãµãŒããŒã§åãã§ãïŒã
NetChannelããããŒ
NetChannelããããŒã®æ§é ã¯æ¬¡ã®ãšããã§ãã
ããããªãã»ãã | ããã0-15 | 16-31 |
---|
0 | ã·ãŒã±ã³ã¹ |
32 | ACKã·ãŒã±ã³ã¹ |
64 | Qport | ããŒã |
94 | ... |
- ã·ãŒã±ã³ã¹ã¯ãéä¿¡è
ã«ãã£ãŠåæåããããã±ãããéä¿¡ããããã³ã«1ãã€å¢å ãã
int
çªå·ã§ãã Sequence
å€ãã®ç®çã§äœ¿çšãããŸãããæãéèŠãªã¿ã¹ã¯ã¯ãåä¿¡è
ã«å€±ããã/éè€ãã/ç°åžžãªUDPãã±ãããèªèããæ©èœãæäŸããããšã§ãã ãã®æŽæ°ã®æäžäœãããã¯ã·ãŒã±ã³ã¹ã®äžéšã§ã¯ãªããïŒ
ïŒã«ä¿¡é Œã§ããããŒã¿ãå«ãŸããŠãããã©ããã瀺ããã©ã°ã§ãïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒã - ACKã·ãŒã±ã³ã¹ã
int
ã§ãæåŸã«åä¿¡ããã·ãŒã±ã³ã¹çªå·ãšåãã§ãã 圌ã®ãããã§ãNetChannelã®å察åŽã¯ãã±ããã倱ãããããšãçè§£ã§ããŸãã - QPortã¯NATã«ãŒã¿ãŒã®åé¿çã§ãïŒè©³çްã«ã€ããŠã¯ããã®ã»ã¯ã·ã§ã³ã®æåŸãåç
§ããŠãã ããïŒã ãã®å€ã¯ãã¯ã©ã€ã¢ã³ãã®èµ·åæã«èšå®ãããä¹±æ°ã§ãã
- ã³ãã³ãïŒéèŠãªããŒã¿ãéä¿¡ãããŸããã
ä¿¡é Œã§ããã¡ãã»ãŒãž
ä¿¡é Œã§ããªãã³ãã³ãã¯UDPãã±ããã«ã°ã«ãŒãåãããæåŸã®çºä¿¡ã·ãŒã±ã³ã¹çªå·ã§ããŒã¯ãããŠéä¿¡ãããŸããéä¿¡è
ã«ãšã£ãŠã倱ããããã©ããã¯é¢ä¿ãããŸããã ä¿¡é Œã§ããã³ãã³ãã®åŠçæ¹æ³ã¯ç°ãªããŸãã äž»ãªããšã¯ãéä¿¡è
ãšåä¿¡è
ã®éã«æªç¢ºèªã®ä¿¡é Œã§ããUDPãã±ããã1ã€ããååšã§ããªãããšãçè§£ããããšã§ãã
åã²ãŒã ãµã€ã¯ã«ã§ã¯ãæ°ããä¿¡é Œã§ããããŒã ãçæãããšãã«ã
message_buf
é
åã«è¿œå ãããŸãïŒ
message
倿°ã§å¶åŸ¡ãããŸãïŒïŒ
1 ïŒã ä¿¡é Œã§ããã³ãã³ãã®ã»ããã¯ã
message
ãã
reliable_buf
ïŒ
2 ïŒé
åã«ç§»åãã
message
ã ããã¯ã
reliable_buf
空ã®å Žåã«ã®ã¿çºçããŸãïŒç©ºã§ãªãå Žåãå¥ã®ã³ãã³ãã»ããã以åã«éä¿¡ãããåä¿¡ããŸã 確èªãããŠããªãããšãæå³ããŸãïŒã
次ã«ãæçµçãªUDPãã±ããã圢æãããŸããNetChannelïŒ
3 ïŒããããŒã远å ãããæ¬¡ã«trusted_bufã®å
容ãšçŸåšã®
reliable_buf
ã³ãã³ãïŒååãªã¹ããŒã¹ãããå ŽåïŒã远å ãããŸãã
åä¿¡åŽã§ã¯ãUDPã¡ãã»ãŒãžãè§£æãããçä¿¡
sequence
çªå·ãçºä¿¡
sequence ACK
ïŒ
4 ïŒã«éä¿¡ãã
sequence ACK
ïŒãã±ããã«ä¿¡é Œã§ããããŒã¿ãå«ãŸããŠããããšã瀺ãããããã©ã°ãšå
±ã«ïŒã
次ã«åãåãã¡ãã»ãŒãžïŒ
- ä¿¡é Œæ§ããããã©ã°ãtrueã®å ŽåãUDPãã±ããã¯åä¿¡è
ã«é
ä¿¡ãããŠããŸãã NetChannelã¯ã
reliable_buf
ïŒ 5 ïŒãã¯ãªã¢ã§ããæ°ããã³ãã³ãã»ãããéä¿¡ããæºåãã§ããŠããŸãã - ä¿¡é Œæ§ããããã©ã°ãfalseã®å ŽåãUDPãã±ããã¯åä¿¡è
ã«å°éããŠããŸããã NetChannelã¯ã
reliable_buf
ã®å
容ã®éä¿¡ãå詊è¡ããŸãã æ°ããã³ãã³ãã¯message_buf
èç©ãmessage_buf
ãŸãã é
åããªãŒããŒãããŒãããšãã¯ã©ã€ã¢ã³ãã¯ãªã»ãããããŸãã

ãã©ã³ã¹ããã·ã§ã³å¶åŸ¡
ç§ãçè§£ããŠããããã«ãéä¿¡å¶åŸ¡ã¯ãµãŒããŒåŽã§ã®ã¿å®è¡ãããŸãã ã¯ã©ã€ã¢ã³ãã¯ãå¯èœãªéãé »ç¹ã«ã¹ããŒã¿ã¹ã®æŽæ°ãéä¿¡ããŸãã
ãµãŒããŒäžã§ã®ã¿ã¢ã¯ãã£ããªäŒéå¶åŸ¡ã®æåã®ã«ãŒã«ïŒãã±ãããã¯ã©ã€ã¢ã³ãããåä¿¡ãããå Žåã«ã®ã¿ãã±ãããéä¿¡ããŸãã 2çªç®ã®ã¿ã€ãã®äŒéå¶åŸ¡ã¯ããã§ãŒã¯ãã§ããããã¯ãã¯ã©ã€ã¢ã³ããã³ã³ãœãŒã«ã³ãã³ã
rate
èšå®ãããã©ã¡ãŒã¿ãŒã§ãã ãµãŒããŒã¯æŽæ°ã¡ãã»ãŒãžãã¹ãããããŠãã¯ã©ã€ã¢ã³ãã«éä¿¡ãããããŒã¿ã®éãåæžã§ããŸãã
éèŠãªã³ãã³ã
ã³ãã³ãã«ã¯ã
ã«æ ŒçŽãããã¿ã€ãã³ãŒããšãããã«ç¶ãæçšãªã³ãã³ãæ
å ±ãå«ãŸããŸãã ããããæãéèŠãªã®ã¯ãã²ãŒã ã®ç¶æ
ã«é¢ããæ
å ±ãæäŸããã³ãã³ãïŒ
frame_t
ïŒã§ãã
svc_packetentities
ããã³svc_deltapacketentities
ïŒããµã€ã«ãã¬ãŒã¹ãççºãããŒãã£ã¯ã«ãªã©ã®ãªããžã§ã¯ããæŽæ°ããŸããsvc_playerinfo
ïŒãã¬ãŒã€ãŒã®äœçœ®ãæåŸã®ããŒã ãããã³ããŒã ã®ç¶ç¶æéã«é¢ããæŽæ°ãããªç§åäœã§svc_playerinfo
ããŸãã
qportã®è©³çްãèªã
ãšã©ãŒãä¿®æ£ããããã«ãQportãNetChannelããããŒã«è¿œå ãããŸããã qportã®åã«ãQuakeãµãŒããŒã¯ããªã¢ãŒãIPã¢ãã¬ã¹ããªã¢ãŒãUDPããŒããã®çµã¿åããã䜿çšããŠã¯ã©ã€ã¢ã³ããèå¥ããŸããã ã»ãšãã©ã®å Žåãããã¯ããŸãæ©èœããŸããããäžéšã®NATã«ãŒã¿ãŒã¯ããŒã倿ã¹ããŒã ïŒãªã¢ãŒãUDPããŒãïŒãä»»æã«å€æŽã§ããŸãã UDPããŒãã¯ä¿¡é Œã§ããªããªããJohn Carmackã¯ãããªã¢ãŒãIPã¢ãã¬ã¹ãNetChannelããããŒã®Qportãã«ãã£ãŠã¯ã©ã€ã¢ã³ããèå¥ããããšã«ãããšèª¬æããŸããã ããã«ãããšã©ãŒãä¿®æ£ããããµãŒããŒã¯å®å
UDPå¿çããŒããå³åº§ã«å€æŽã§ããŸããã
é
å»¶èšç®
Quakeãšã³ãžã³ã¯ã
frame_t
ãšãšãã«ãæè¿éä¿¡ããã64åã®ã³ãã³ãïŒ
frame_t
ïŒ
frames
é
åïŒã
senttime
ãŸãã ãããã¯ãéä¿¡ã«äœ¿çšãããã·ãŒã±ã³ã¹çªå·ïŒ
outgoing_sequence
ïŒã«ãã£ãŠçŽæ¥ã¢ã¯ã»ã¹ã§ããŸãã
frame = &cl.frames[cls.netchan.outgoing_sequence & UPDATE_MASK]; frame->senttime = realtime;
ãµãŒããŒãã確èªãåãåã£ãåŸãã³ãã³ããéä¿¡ããæéã¯
sequenceACK
ããååŸãã
sequenceACK
ã é
å»¶ã¯æ¬¡ã®ããã«èšç®ãããŸãã
ãšã¬ã¬ã³ããªãœãªã¥ãŒã·ã§ã³
é
åã€ã³ããã¯ã¹ã®ã«ãŒããšã³ãžã³ã®ãããã¯ãŒã¯éšåã«ã¯ãæåŸã«åä¿¡ãã64åã®UDPãã±ãããæ ŒçŽãããŸãã é
åãã«ãŒãããåçŽãªè§£æ±ºçã¯ãæŽæ°é€ç®ã®å°äœæŒç®åã䜿çšããããšã§ãã
arrayIndex = (oldArrayIndex+1) % 64;
代ããã«ãUPDATE_MASKã®ãã€ããªANDæŒç®ã䜿çšããŠæ°ããå€ãèšç®ãããŸãã UPDATE_MASKã¯64-1ã§ãã
arrayIndex = (oldArrayIndex+1) & UPDATE_MASK;
å®éã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
frame_t *newpacket; newpacket = &frames[cls.netchan.incoming_sequence&UPDATE_MASK];
æŽæ°ïŒããã¯ãå°äœé€ç®æäœã®æé©åã«é¢ããŠãã£ãŒããªããEppããåãåã£ãã³ã¡ã³ãã§ãã , "". : file.c: unsigned int modulo(unsigned int x) { return x % 64; } unsigned int and(unsigned int x) { return x & 63; } gcc -S file.c file.s. , , ! "" << 5 *32. , , , << 5 & 63 "", *32 %64 . --Dietrich .globl modulo .type modulo, @function modulo: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax andl $63, %eax popl %ebp ret .size modulo, .-modulo .globl and .type and, @function and: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax andl $63, %eax popl %ebp ret .size and, .-and
äºæž¬
ãããã¯ãŒã¯éä¿¡ã®ããã®NetChannelæœè±¡åãèŠãŸããã æ¬¡ã«ãé
å»¶ãäºæž¬ã«ãã£ãŠã©ã®ããã«çžæ®ºããããã調ã¹ãŸãã åŠç¿ããè³æã¯æ¬¡ã®ãšããã§ãã
- ãžã§ã³ã»ã«ãŒããã¯èªèº«ã«ããèšäº ã
- Half-lifeãšã³ãžã³ã«ã€ããŠèª¬æããå¥ã®Valveã®èšäº ïŒ ã¢ãŒã«ã€ã ïŒïŒHalf-lifeã¯Quakeãšã³ãžã³ã䜿çšïŒã
äºæž¬
äºæž¬ã¯ãããããQuake Worldãšã³ãžã³ã®äžã§æãé£ãããææžåãããŠããããæãéèŠãªéšåã§ãã äºæž¬ã®ç®çã¯ãåŸ
ã¡æéãç¡å¹ã«ããããšãã€ãŸããæ
å ±ãéä¿¡ããããã«åªäœãå¿
èŠãšããé
å»¶ãè£åããããšã§ãã äºæž¬ã¯ã¯ã©ã€ã¢ã³ãåŽã§å®è¡ãããŸãã ãã®ããã»ã¹ã¯ãã¯ã©ã€ã¢ã³ãåŽäºæž¬ããšåŒã°ããŸãã ãµãŒããŒåŽã§ã¯ãé
å»¶è£æ£ææ³ã¯é©çšãããŸããã
åé¡ïŒ

ã芧ã®ãšãããã²ãŒã ã®ç¶æ
ã¯ã¬ã€ãã³ã·ã®ååã®å€ã ããå€ããç¶æ
ã§ãã ããŒã ãéä¿¡ããæéã远å ããå Žåãã¢ã¯ã·ã§ã³ã®çµæã確èªããããã«ãã«ãµã€ã¯ã«ïŒåŸ
æ©æéïŒãåŸ
ã€å¿
èŠããããŸãã

Quakeã®äºæž¬ã·ã¹ãã ãçè§£ããã«ã¯ãNetChannelã
frames
倿°ïŒarray
frame_t
ïŒãã©ã®ããã«åã蟌ãããçè§£ããå¿
èŠããããŸãã

ãµãŒããŒã«éä¿¡ãããåã³ãã³ãã¯ã
netchannel.outgoingsequence
ã€ã³ããã¯ã¹ã§
senttime
ãšãšãã«
frames
ã«ä¿åãããŸãã
ãµãŒããŒã
sequenceACK
ã䜿çšããŠã³ãã³ãã®åä¿¡ã確èªãããšãéä¿¡ãããã³ãã³ããåãå
¥ããŠåŸ
æ©æéãèšç®ã§ããŸãã
latency = senttime-receivedtime;
ãã®æ®µéã§ã¯ã
é
å»¶/ 2ç§åã®äžçãããããŸãã NATã§ã¯ãåŸ
ã¡æéã¯éåžžã«çãïŒ<50ããªç§ïŒããã€ã³ã¿ãŒãããã§ã¯éåžžã«å€§ããïŒ> 200ããªç§ïŒã
çŸåšã®äžçã®ç¶æ
ãã·ãã¥ã¬ãŒãããã«ã¯äºæž¬ãå¿
èŠã§ãã ãã®ããã»ã¹ã¯ãããŒã«ã«ãã¬ãŒã€ãŒãšä»ã®ãã¬ãŒã€ãŒã§ç°ãªãæ¹æ³ã§å®è¡ãããŸãã
ããŒã«ã«ãã¬ã€ã€ãŒ
ããŒã«ã«ãã¬ãŒã€ãŒã®å ŽåããµãŒããŒã®ç¶æ
ãæšå®ãããããã¬ã€ãã³ã·ã¯ã»ãŒ0ã«æžå°ããŸãã ããã¯ããµãŒããŒããåä¿¡ããæåŸã®ã¹ããŒã¿ã¹ã䜿çšããŠããã®ç¬éããéä¿¡ããããã¹ãŠã®ã³ãã³ãããåçãããŸãã

ãããã£ãŠãã¯ã©ã€ã¢ã³ãã¯ããµãŒããŒäžã®ãã®äœçœ®ãæét +é
å»¶/ 2ã«ãªããšäºæž¬ããŸãã
ã³ãŒãã®èгç¹ãããããã¯
CL_PredictMove
ã¡ãœããã䜿çšããŠè¡ãããŸãã ãŸããQuakeãšã³ãžã³ã¯ãåçå¯èœãªãã³ãã³ãã®ã»ã³ãã¡ã³ãå¶éãéžæããŸãã
cl.time = realtime - cls.latency - cl_pushlatency.value*0.001;
æ³šïŒ cl_pushlatency
ã¯ãå€ãã¯ã©ã€ã¢ã³ãåŽã§èšå®ãããã³ã³ãœãŒã«å€æ°ïŒcvarïŒã§ãã ããã¯ãããªç§åäœã®ã¯ã©ã€ã¢ã³ãã®è² ã®é
å»¶ã«çžåœããŸãã ããããã
cl.time = realtime
ãšçµè«ä»ããã®ã¯ç°¡åã§ãã
ãã®åŸãä»ã®ãã¹ãŠã®ãã¬ãŒã€ãŒã¯
CL_SetSolidPlayers (cl.playernum);
å®çŸ©ãã
CL_SetSolidPlayers (cl.playernum);
ïŒè¡çªããã¹ãã§ããããã«ããããïŒãœãªãããªããžã§ã¯ããšããŠãæåŸã«åä¿¡ããç¶æ
ãããã®ç¬éã«éä¿¡ããããåçãã³ãã³ãïŒ
cl.time <= to->senttime
ïŒè¡çªã¯
CL_PredictUsercmd
ã䜿çšããŠåå埩ã§ãã¹ããããŸãïŒã
ä»ã®ãã¬ã€ã€ãŒ
ä»ã®ãã¬ã€ã€ãŒã®å ŽåãQuakeãšã³ãžã³ã«ã¯ãéä¿¡æžã¿ã§ããããŸã 確èªãããŠããªãããŒã ãããªãããã代ããã«è£éã䜿çšãããŸãã æåŸã®æ¢ç¥ã®äœçœ®ããéå§ããŠã
cmd
çµæã®äœçœ®ãäºæž¬ããããã«è£éãããŸãã è§å転ãªãã§äœçœ®ã®ã¿ãäºæž¬ãããŸãã
Quake Worldã§ã¯ãä»ã®ãã¬ã€ã€ãŒã®ã¬ã€ãã³ã·ãèæ
®ãããŸãã åãã¬ã€ã€ãŒã®ã¬ã€ãã³ã·ãŒã¯ãã¯ãŒã«ãã®æŽæ°ãšãšãã«éä¿¡ãããŸãã
ã³ãŒã
è¡çªäºæž¬ããã³èšç®ã³ãŒãã¯ã次ã®ããã«èŠçŽã§ããŸãã
CL_SetUpPlayerPrediction(false) CL_PredictMove | | CL_SetSolidPlayers | | CL_PredictUsercmd | | PlayerMove | CL_SetUpPlayerPrediction(true) CL_EmitEntities CL_LinkPlayers | | | | CL_SetSolidPlayers | | CL_PredictUsercmd | | PlayerMove CL_LinkPacketEntities CL_LinkProjectiles CL_UpdateTEnts
Quake Worldã¯ãã¬ã€ã€ãŒã®äºæž¬ãå®è¡ããã ãã§ãªããäºæž¬ã«åºã¥ããŠè¡çªãèªèããããããã®éšåã¯è€éã§ãã
CL_SetUpPlayerPrediction(false)
æåã®åŒã³åºãã¯äºæž¬ãå®è¡ããããµãŒããŒããåä¿¡ããäœçœ®ã«ãã¬ã€ã€ãŒãé
眮ããã ãã§ãïŒã€ãŸããtã¬ã€ãã³ã·/ 2ã®é
å»¶ã§ïŒã
CL_PredictMove()
ããã¯ãããŒã«ã«ãã¬ãŒã€ãŒãç§»åããå Žæã§ãã
- æ¹åã¯è£éãããããªã¢ã«ã¿ã€ã ã§å®å
šã«å®è¡ãããŸãã
- äœçœ®ãšé床ïŒçŸåšãŸã§ã«éä¿¡ããããã¹ãŠã®ã³ãã³ãïŒ
cl.time <= to->senttime
ïŒã¯ããµãŒããŒããåä¿¡ããæåŸã®äœçœ®/é床ã«é©çšãããŸãã
äœçœ®ãšéåºŠã®æŽæ°ã®è©³çްïŒ
- æåã«ãä»ã®ãã¬ã€ã€ãŒã¯
CL_SetUpPlayerPrediction(false)
ã䜿çšããŠã CL_SetUpPlayerPrediction(false)
èšå®ãããæåŸã®æ¢ç¥ã®äœçœ®ã§ïŒãœãªãããªããžã§ã¯ãã«CL_SetSolidPlayers
ãŸãã - ãšã³ãžã³ã¯ãéä¿¡ããããã¹ãŠã®ã³ãã³ããç¹°ãè¿ããè¡çªããã§ãã¯ãã
CL_PredictUsercmd
ã䜿çšããŠäœçœ®ãäºæž¬ãCL_PredictUsercmd
ã è¡çªã¯ãä»ã®ãã¬ãŒã€ãŒã§ããã¹ããããŸãã - çµæã®äœçœ®ãšé床ã¯
cl.sim*
ä¿åããcl.sim*
ã ãããã¯åŸã§èŠç¹ã調æŽããããã«äœ¿çšãããŸãã
CL_SetUpPlayerPrediction(true)
2çªç®ã®ãµãŒããŒåŽã®åŒã³åºãã§ã¯ãçŸåšã®æç¹ã§ã®ä»ã®ãã¬ãŒã€ãŒã®äœçœ®ãäºæž¬ãããŸãïŒãã ããç§»åã¯ãŸã å®è¡ãããŠããŸããïŒã äœçœ®ã¯ãæåŸã®æ¢ç¥ã®ããŒã ãšæåŸã®æ¢ç¥ã®äœçœ®ã«åºã¥ããŠæšå®ãããŸãã
泚ïŒããã§å°ããªåé¡ãçºçããŸããValveã¯ïŒ
cl_pushlatency
ïŒãµãŒããŒåŽã®ããŒã«ã«ãã¬ãŒã€ãŒã®ã¹ããŒã¿ã¹ãt +ã¬ã€ãã³ã·/ 2ã§äºæž¬ããããšãæšå¥šããŸãã ãã ããä»ã®ãã¬ãŒã€ãŒã®äœçœ®ã¯ãæétã§ãµãŒããŒåŽã§äºæž¬ãããŸãã ãããããQWã®
cl_pushlatency
ã®æé©ãªå€ã¯-latency / 2ã§ãããïŒ
CL_EmitEntities
å¯èŠæ§ã¬ã€ãã©ã€ã³ã¯ããã§çæãããŸãã æ¬¡ã«ãã¬ã³ãã©ãŒã«æž¡ãããŸãã
- CL_LinkPlayersïŒä»ã®ãã¬ã€ã€ãŒãåããŠãããä»ã®ãã¬ã€ã€ãŒããœãªãããªããžã§ã¯ãã«å€ãããäºæž¬ãããäœçœ®ã«å¯ŸããŠè¡çªæ€åºãå®è¡ãããŸãã
- CL_LinkPacketEntitiesPacketïŒãµãŒããŒããåä¿¡ããæåŸã®ç¶æ
ã®ãªããžã§ã¯ããäºæž¬ãããå¯èŠæ§ã¬ã€ãã©ã€ã³ã«é¢é£ä»ããããŸãã ã ãããæã¡äžãããããã±ããã«ã¯é
ãããããŸãã
- CL_LinkProjectilesïŒéããã³ãã®ä»ã®ã·ã§ã«ã®åŠçã
- CL_UpdateTEntsïŒå
ç·ãšãªããžã§ã¯ãã®æšæºæŽæ°ã
å¯èŠå
ãªãªãžãã«ã®ã²ãŒã ãéçºãããšããã»ãšãã©ã®åªåã¯Quakeã¬ã³ãã©ãŒã¢ãžã¥ãŒã«ã«è²»ããããŸããã ããã«ã€ããŠã¯ãMichael Abrashã®æ¬ãšJohn Carmackã®.planãã¡ã€ã«ã«è©³ãã説æãããŠããŸãã
å¯èŠå
ã·ãŒã³ã®èŠèŠåããã»ã¹ã¯ãBSPã«ãŒããšå¯æ¥ã«ãªã³ã¯ããŠããŸãã ãŠã£ãããã£ã¢ã®ãã€ããªã¹ããŒã¹ããŒãã£ã·ã§ã³åå²ã«ã€ããŠè©³ããèªãããšããå§ãããŸãã èŠããã«ãQuakeã«ãŒãã¯å€ãã®ååŠçãçµãŸããã ããªã¥ãŒã ã¯æ¬¡ã®ããã«ååž°çã«ã«ãããããŸããã

ãã®ããã»ã¹ã«ããããªãŒããå«ãBSPãäœæãããŸããïŒäœæã«ãŒã«ã¯æ¬¡ã®ãšããã§ããæ¢åã®ããªãŽã³ãåæé¢ãšããŠéžæããããå°ãªãããªãŽã³ãåæããã»ãã¬ãŒã¿ãéžæããŸãïŒã BSPãäœæããåŸãPVSïŒæœåšçã«å¯èŠã®ã»ãããæœåšçã«å¯èŠã®ã»ããïŒãåã·ãŒãã«å¯ŸããŠèšç®ãããŸããã äŸïŒã·ãŒã4ã¯ããªãŒã7ããã³9ãæœåšçã«èŠãããšãã§ããŸãã

ãã®ã·ãŒãã®æçµPVSã¯ããããã¯ãã«ãšããŠä¿åãããŸããã
Id èã£ã± | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
---|
ã·ãŒã4ã®PVS | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
---|
çµæã¯ããµã€ãºãçŽ5MBã®ã°ããŒãã«PVSã§ãã 1996幎ã®PCã«ã¯å€§ããããŸããã ãããã£ãŠãPVSã¯é·ãã®å·®ã®å§çž®ã«ãã£ãŠå§çž®ãããŸããã
ã·ãŒã4ã®å§çž®PVS | 3 | 2 | 1 | 7 |
---|
ãšã³ã³ãŒããããPVSã«ã¯ããŠãããéã®ãŒãã®æ°ã®ã¿ãå«ãŸããŠããŸããã
ããã¯éåžžã«å¹æçãªå§çž®æè¡ã®ããã«ã¯èŠããŸãããã倿°ã®èïŒ32767ïŒãšéåžžã«éãããå¯èŠã®èã®ã»ãããçµã¿åãããããšã§ãPVSå
šäœã®ãµã€ãºã20KBã«çž®å°ãããŸãããã¢ã¯ã·ã§ã³ã®ååŠç
äºåã«èšç®ãããBPSããã³PVSãååšããããããšã³ãžã³ã§ããããèŠèŠåããããã»ã¹ã¯ç°¡åã§ããã- BSPããã€ãã¹ããŠãã«ã¡ã©ãæããŠããã·ãŒããå€å¥ããŸãã
- ãã®ã·ãŒãã®PVSãæœåºããŠå±éããPVSãå埩åŠçããŠãBSPã§ãªãŒãã«ããŒã¯ãä»ããŸãã
- è¿ãããé ããŸã§BSPããã€ãã¹ããŸãã
- ããŒãïŒããŒãïŒãããŒã¯ãããŠããªãå Žåãã¹ããããããŸãã
- ã«ã¡ã©ã®å¯èŠæ§ã®ãã©ãããå
ã®ååšã«ã€ããŠãããŒãã®å¢çå
šäœããã¹ãããŸãã
- çŸåšã®ã·ãŒããèŠèŠåãªã¹ãã«è¿œå ããŸãã
æ³šïŒ BSPã¯è€æ°å䜿çšãããŸããããšãã°ãããããæãè¿ããã€ã³ãããåã¢ã¯ãã£ããªå
æºã®è·é¢ã«ãã€ãã¹ãããããäžã®ããªãŽã³ã«ããŒã¯ãä»ããå Žåãæ³š2ïŒãœãããŠã§ã¢ã¬ã³ããªã³ã°ã§ã¯ãBSPããªãŒã¯é ããã€ã³ãããæãè¿ããã€ã³ããŸã§ãã©ããŒã¹ãããŸãããã³ãŒãåââæ
ã€ãŸããèŠèŠåã³ãŒãã¯æ¬¡ã®ããã«è¡šãããšãã§ããŸãã SCR_UpdateScreen { GL_BeginRendering SCR_SetUpToDrawConsole V_RenderView | R_Clear | R_RenderScene | | R_SetupFrame | | Mod_PointInLeaf | | R_SetFrustum | | R_SetupGL | | R_MarkLeaves | | | Mod_LeafPVS | | | Mod_DecompressVis | | R_DrawWorld | | | R_RecursiveWorldNode | | | DrawTextureChains | | | | R_RenderBrushPoly | | | | DrawGLPoly | | | R_BlendLightmaps | | S_ExtraUpdate | | R_DrawEntitiesOnList | | GL_DisableMultitexture | | R_RenderDlights | | R_DrawParticles | R_DrawViewModel | R_DrawAliasModel | R_DrawWaterSurfaces | R_PolyBlend GL_Set2D SCR_TileClear V_UpdatePalette GL_EndRendering }
SCR_UpdateScreenåŒã³åºãïŒGL_BeginRendering
ïŒglx,gly,glwidth,glheight
åŸã§R_SetupGL
ãã¥ãŒããŒããšæåœ±è¡åãèšå®ããããã«äœ¿çšããã倿°ïŒïŒã®å€ãèšå®ããŸãïŒSCR_SetUpToDrawConsole
ïŒã³ã³ãœãŒã«ã®é«ããæ±ºå®ããŸãïŒ2Dã«é¢é£ããéšåã§ã¯ãªãããªãããã«ããã®ã§ããïŒïŒïŒV_RenderView
ïŒ3Dã·ãŒã³ã¬ã³ããªã³ã°ïŒGL_Set2D
ïŒæ£å°åœ±ãžã®åãæ¿ãïŒ2DïŒïŒSCR_TileClear
ïŒå€ãã®2Dãªããžã§ã¯ããã³ã³ãœãŒã«ãFPSã¡ããªãã¯ãªã©ã®è¿œå ã¬ã³ããªã³ã°ïŒV_UpdatePalette
ïŒååã¯ãœãããŠã§ã¢ã¬ã³ãã©ãŒã«å¯Ÿå¿ããŸããopenGLã§ã¯ãã¡ãœããã¯åãåã£ããã¡ãŒãžãŸãã¯ã¢ã¯ãã£ããªããŒãã¹ã«å¿ããŠããã·ã³ã°ã¢ãŒããèšå®ããç»é¢ãèµ€ãããããæãããããããŸããïŒå€ã¯ã«æ ŒçŽãããŸãv_blend
GL_EndRendering
ïŒãããã¡ã¹ã€ããã³ã°ïŒããã«ãããã¡ãªã³ã°ïŒïŒïŒ
V_RenderViewåŒã³åºãïŒV_CalcRefdef
ïŒãã¿ãŸãããç§ã¯ãã®éšåãçè§£ããŠããŸããã§ããïŒR_PushDlights
åå
æºã§ããªãŽã³ãããŒã¯ããŠã广ãé©çšããŸãïŒæ³šãåç
§ïŒR_RenderView
æ³šïŒ R_PushDlightsã¯ãååž°ã¡ãœããïŒR_MarkLights
ïŒãåŒã³åºããŸããBSPã䜿çšããŠãå
æºã®åœ±é¿ãåããããªãŽã³ãïŒæŽæ°ããããã¯ãã«ã䜿çšããŠïŒããŒã¯ããŸããBSPã¯ïŒå
æºã®èгç¹ããïŒè¿ãç¹ããé ãç¹ã«ç§»åããŸãããã®ã¡ãœããã¯ãå
æºãã¢ã¯ãã£ãã§æã®å±ãç¯å²ã«ãããã©ããã確èªããŸãããã®æ¹æ³ã¯R_MarkLights
ç¹ã«æ³šç®ã«å€ããŸãããªããªããããã§ã¯ãã€ã³ããšãã¬ãŒã³éã®è·é¢ã«é¢ããMichael Abrashã«ããèšäºã®çŽæ¥çãªå®è£
ãèŠãããããã§ãïŒãåç
§ãã¬ãŒã ãdist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
ïŒïŒïŒïŒãR_RenderViewã®åŒã³åºãïŒR_Clear
ïŒå¿
èŠã§ããã°GL_COLOR_BUFFER_BITããã³/ãŸãã¯GL_DEPTH_BUFFER_BITã®ã¯ãªãŒãã³ã°ïŒR_RenderScene
R_DrawViewModel
ïŒãªãã¶ãŒããŒã¢ãŒãã§ã®ãã¬ãŒã€ãŒã¢ãã«ã®ã¬ã³ããªã³ã°ïŒR_DrawWaterSurfaces
ïŒGL_BEND / GL_MODULATEã¢ãŒãã«åãæ¿ããŠæ°ŽãåŒããå€åœ¢ã¯ãã«ãã¯ã¢ããããŒãã«sinããã³cosã䜿çšããŠå®è¡ãããŸãgl_warp.c
ïŒR_PolyBlend
ïŒV_UpdatePalette
倿°ã«èšå®ãããå€ã䜿çšããŠç»é¢å
šäœãæ··åããŸãv_blend
ãããã¯ããã¡ãŒãžãåããïŒèµ€ïŒãæ°Žäžã«ããããŸãã¯ããŒãã¹ãé©çšããããšã瀺ãããã«äœ¿çšãããŸãïŒ
R_RenderSceneåŒã³åºãïŒR_SetupFrame
ïŒã«ã¡ã©ãé
眮ãããŠããBSPã·ãŒããæœåºãã倿°ãr_viewleafãã«ä¿åããŸãïŒR_SetFrustum
ïŒã€ã³ã¹ããŒã« mplane_t[4]
ãè¿ããšé ãé£è¡æ©ãªããR_SetupGL
ïŒGL_PROJECTIONãGL_MODELVIEWãglCullFaceã®ãã¥ãŒããŒããšåŽé¢ã®èšå®ãããã³Y軞ãšZ軞ã®å転ãQuakeã®X軞ãšZ軞ã¯openGLãšã¯ç°ãªãäœçœ®ã«ãããããïŒR_MarkLeaves
R_DrawWorld
S_ExtraUpdate
ïŒããŠã¹ã®äœçœ®ããªã»ãããããªãŒãã£ãªã®åé¡ã解決ããŸãïŒR_DrawEntitiesOnList
ïŒãªã¹ãå
ã®ãªããžã§ã¯ãã®æç»ïŒGL_DisableMultitexture
ïŒãã«ããã¯ã¹ãã£ãªã³ã°ãç¡å¹ã«ããïŒR_RenderDlights
ïŒã©ã€ããã¡ã€ã³ãšç
§æå¹æïŒR_DrawParticles
ïŒççºãç«ã黿°ãªã©ïŒ
R_SetupFrameè峿·±ãè¡ïŒ r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel);
ãã®äžã§ãQuakeãšã³ãžã³ã¯ãã«ã¡ã©ãçŸåšæããŠããBSPã®ã·ãŒã/ããŒããååŸããŸããMod_PointInLeafã¯model.cã«ãããBSPãä»ããŠå®è¡ãããŸãïŒBSPããªãŒã®ã«ãŒãã¯model->ããŒãã«ãããŸãïŒãåããŒãã«å¯ŸããŠïŒ- ããŒããããã«ã¹ããŒã¹ãåæããªãå Žåãããã¯ã·ãŒããªã®ã§ãçŸåšã®ããŒãã®äœçœ®ãšããŠæ»ããŸãã
- ãã以å€ã®å ŽåãBSPã®æ£å²é¢ã¯çŸåšã®äœçœ®ã«ã€ããŠãã§ãã¯ããïŒéåžžã®ã¹ã«ã©ãŒç©ã䜿çšããŠãããã¯BSPããªãŒããã©ããŒã¹ããæšæºçãªæ¹æ³ã§ãïŒã察å¿ããåã¯ãã€ãã¹ãããŸãã
R_MarkLeaves BSPã®ã«ã¡ã©ã®å Žæã倿°r_viewleaf
ïŒã«ååŸR_SetupFrame
ïŒã«æ ŒçŽããæœåšçãªå¯èŠã»ããïŒPVSïŒãæ€çŽ¢ïŒMod_LeafPVS
ïŒãããã³è§£åïŒMod_DecompressVis
ïŒããŸããæ¬¡ã«ãããããã¯ãã«ãå埩åŠçããæœåšçã«è¡šç€ºãããBSPããŒããããŒã¯ããŸãïŒnode-> visframe = r_visframecountãR_DrawWorldã®èª²é¡ïŒR_RecursiveWorldNode
ïŒBSPã¯ãŒã«ããåããåŸãã«èµ°æ»ãã以åã«ããŒã¯ãããŠããªãããŒããã¹ããããïŒc R_MarkLeaves
ïŒãcl.worldmodel->textures[]->texturechain
é©åãªããªãŽã³ã§ãªã¹ãã«å
¥åããŸããïŒDrawTextureChains
ïŒtexturechainã«ä¿åãããŠããããªãŽã³ã®ãªã¹ããæç»ããïŒcl.worldmodel-> textures []ãå埩åŠçããŸããããã«ããããããªã¢ã«ãžã®ã¹ã€ããã1ã€ã ãååŸã§ããŸããæªãã¯ãããŸãããïŒR_BlendLightmaps
ïŒãã¬ãŒã ãããã¡ãŒã§ã©ã€ãããããæ··åããããã«äœ¿çšããã2çªç®ã®ãã¹ïŒã
泚ïŒãã®éšåã§ã¯ãæªåé«ãopenGLã®ãã€ããã£ãšã€ãã¢ãŒããã¢ãŒãã䜿çšãããŸãããã®ã¢ãŒãã¯ãæè¡ã®æåŸã®èšèããšèŠãªãããŠããŸãããã§R_RecursiveWorldNode
ã¯ãªããã³ã°è¡šé¢ã®ã»ãšãã©ã®æäœãå®è¡ãããŸããæ¬¡ã®å ŽåãããŒãã¯åæãããŸãã- ãã®å
容ã¯åºäœãªããžã§ã¯ãã§ãã
- ã·ãŒãã¯PVSã§ããŒã¯ãããŠããŸããïŒ
node->visframe != r_visframecount
ïŒ - èã¯å¯èŠæ§ã®ãã©ãããã«æ²¿ã£ãŠã¯ãªããã³ã°ãããŸããã

MDL圢åŒ
MDL圢åŒã¯ãåºå®ãã¬ãŒã ã®ã»ããã§ããQuakeãšã³ãžã³ã¯ãé ç¹ã®äœçœ®ãè£éããŠã¢ãã¡ãŒã·ã§ã³ãæ»ããã«ããŸããïŒãããã£ãŠããã¬ãŒã ã¬ãŒããé«ããŠãã¢ãã¡ãŒã·ã§ã³ã¯æ¹åãããŸããïŒããšã¬ã¬ã³ããªãœãªã¥ãŒã·ã§ã³
ãšã¬ã¬ã³ããªãªãŒãã¿ã®ã³ã°ã¬ã³ããªã³ã°ã®ããã®BSP ãªãŒãã¿ã®ã³ã°ã®çŽ æŽãªã¢ãããŒãã¯ãããŒã«å€æ°ã䜿çšããããšã§ãisMarkedVisible
ãåãã¬ãŒã ã®åã«å¿
èŠãªãã®ïŒ- ãã¹ãŠã®ããŒã«å€æ°ã®å€ãfalseã«èšå®ããŸãã
- PVSãç¹°ãè¿ããã€ãã¹ãã衚瀺ãããŠããåã·ãŒãã«trueãæå®ããŸãã
- 次ã«ãã·ãŒãããã¹ãããŸã
if (leave.isMarkedVisible)
代ããã«ãQuakeãšã³ãžã³ã¯æŽæ°ã䜿çšããŠãã¬ã³ããªã³ã°ããããã¬ãŒã ïŒr_visframecount
倿°ïŒã®æ°ãèšç®ããŸããããã«ãããæåã®ã¹ããããåãé€ãããšãã§ããŸãã- å埩PVSãã©ããŒãµã«ããã³å¯èŠã·ãŒãã»ããããš
leaf.visframe = r_visframecount
- 次ã«ãã·ãŒãããã¹ãããŸã
if (leaf.visframe == r_visframecount)
ååž°ãåãé€ãã«ã¯R_SetupFrame
代ããã«BSPã®ããã®ãéã«åããããã©ããŒãµã«ååž°ãå®è¡ããªãããµã€ã¯ã«ãå©çšããŠçŸåšäœçœ®ãååŸããŸãã node = model->nodes; while (1) { if (node->contents < 0) return (mleaf_t *)node; plane = node->plane; d = DotProduct (p,plane->normal) - plane->dist; if (d > 0) node = node->children[0]; else node = node->children[1]; }
ãã¯ã¹ãã£ã®åãæ¿ãã®æå°åopenGLã§ã¯ãïŒglBindTexture(GL_TEXTURE_2D,id)
ïŒã䜿çšãããã¯ã¹ãã£ã®åãæ¿ãã¯éåžžã«é«äŸ¡ã§ãããã¯ã¹ãã£ã®åãæ¿ãåæ°ãæå°éã«æãããããã¬ã³ããªã³ã°çšã«ããŒã¯ãããåããªãŽã³ã¯ãããªãŽã³ãã¯ã¹ãã£ãããªã¢ã«ã«ãã£ãŠã€ã³ããã¯ã¹ä»ããããé
åã®ãã§ãŒã³ã«æ ŒçŽãããŸãã cl.worldmodel->textures[textureId]->texturechain[]
ã¯ãªããã³ã°ãå®äºãããšããã¯ã¹ãã£ãã§ãŒã³ãé çªã«æç»ãããŸãããããã£ãŠãåèšNåã®ãã¯ã¹ãã£ã¹ã€ãããå®è¡ãããŸããããã§ãNã¯å¯èŠãã¯ã¹ãã£ã®ç·æ°ã§ãã int i; for ( i = 0; i < cl.worldmodel->textures_num ; i ++) DrawTextureChains(i);