ãã®èšäºã§ã¯ãOpenGLäžã§ã«ãŒããã¯ãã¥ãŒããšãã¥ã¬ãŒã¿ãäœæããæ¹æ³ã«ã€ããŠèª¬æããŸãã
ç«æ¹äœã¯3Dã«ãªããããŠã¹ã§å転ãããããšãã§ããç¢å°ãã¯ãªãã¯ããŠé¢ãå転ãããããšãã§ããŸãã ããã«ãèŠèŽè ã«æãè¿ã端ã«ç¢å°ã衚瀺ãããŸãã
CïŒã§ã®ã«ãŒããã¯ãã¥ãŒããšãã¥ã¬ãŒã¿ãŒã®äœæã«ã€ããŠèª¬æããŸããOpenGLã§ã¯OpenTKã©ã€ãã©ãªã䜿çšããŸãã ããŠã³ããŒãããŠãVisual Studioã§ãã®ã©ã€ãã©ãªãžã®ãªã³ã¯ãäœæããå¿ èŠããããŸãã
3Dãã¢ãŒ
3Dã«ã€ããŠå°ã説æããŸãã 3Dã®ãªããžã§ã¯ãã«ã¯3ã€ã®åº§æšxãyãzããããã¢ãã¿ãŒç»é¢ã«ã¯2ã€ã®åº§æšãããããŸããã åœç¶ãæ圱ã¯ã¢ãã¿ãŒç»é¢ã«è¡šç€ºããå¿ èŠããããŸãã
ãã ããåŸãã®ãªããžã§ã¯ãã暪åãã®ãªããžã§ã¯ãã¯æ圱ããªãã§ãã ããã ãŸããé ããããããžã§ã¯ããæ圱ããã¹ãã§ã¯ãããŸããã ïŒã¬ãŒã¹ã§ã¯ãæ¥è¿ãå§ãããšé ãã®ãªããžã§ã¯ããã©ã®ããã«è¡šç€ºãããããèŠããŠãããŠãã ããïŒã
ãããã£ãŠã衚瀺ã§ãããã®ãå¶éããå¿ èŠããããŸãã
ãã®ãããªåé ãã©ãããã¯FrustrumïŒFrustRumïŒãšåŒã°ãããªããžã§ã¯ããç»é¢ã«è¡šç€ºããããã«ããããFrustrumã«åãŸããã©ãããå€æãïŒåãŸããªãéšåã¯åãåãããŸãïŒãç»é¢ã«æ圱ããŸãã ãããã¯ãã¹ãŠOpenGLã«ãã£ãŠè¡ãããŸãã
ãã§ã¶ãŒãã¹ã
OpenTKã©ã€ãã©ãªãããŠã³ããŒãããŸã ã ãã¡ã€ã«ãå®è¡ããã©ã€ãã©ãªã解åããŸãã
ãããžã§ã¯ããäœæããOpenTK.dllãã¡ã€ã«ãžã®ãªã³ã¯ãè¿œå ããŸãã ãŸããã«ãŒããã¯ãã¥ãŒãã衚瀺ãããGLControlã³ã³ãããŒã«ã䜿çšãããããOpenTK.GLControl.dllãžã®ãªã³ã¯ãè¿œå ããŸãã
OpenTKã«ã¯System.Drawing.dllãžã®ãªã³ã¯ãå¿ èŠãªã®ã§ãããäžåºŠãªã³ã¯ãè¿œå ããããã®ã€ã³ã¿ãŒãã§ã€ã¹ã«ç§»åãã[ãNet]ã¿ããéžæããŠSystem.Drawingãæ¢ããŠè¿œå ããŸãã
OpenTKã©ã€ãã©ãªã®è¿œå
éåžžã®GUIããã°ã©ã å ã§OpenGLã䜿çšããŸãã ãããã£ãŠããã¶ã€ã³ã¢ãŒãã§ã¯ãããŒã«ããŒãå³ã¯ãªãã¯ããŠ[èŠçŽ ã®éžæ]ãéžæãã[ãNET Frameworkã®ã³ã³ããŒãã³ã]ã¿ãã«ç§»åããŠãOpenTK.GLControl.dllãã¡ã€ã«ãéžæããŸãã æ°ããGLControlèŠçŽ ããªã¹ãã«è¡šç€ºããããã®åã«ãã§ãã¯ããŒã¯ãä»ããŸãã ããã£ã æ°ããGLControlã¢ã€ãã ãããŒã«ããŒã«è¡šç€ºãããŸãã ããããã©ãŒã ã«è»¢éãããã©ãŒã å šäœã«åŒã䌞ã°ããŸãã
GLControlã³ã³ãããŒã«ïŒãã£ã³ãã¹ããã£ã³ãã¹ïŒã®è¿œå
GLControlèŠçŽ ã«ã¯Loadã€ãã³ããããããã®èŠçŽ ãèªã¿èŸŒãŸãããšèµ·åããŸãã
ïŒã¯ãªãã¯ããŠãã³ãã©ãŒã®æ¬äœãåãããšãglControl1_Loadã¡ãœããã衚瀺ãããŸãïŒ
OpenTKã®äœæè ã¯ãèµ·ååã«GLControlã§äœæ¥ãéå§ããããšãæšå¥šããŠããªããããGLControlãèµ·åãããã©ããã«é¢ä¿ãªãå€ãæ ŒçŽããå€æ°ãèµ·åããå¿ èŠããããŸãã
ã³ãŒã
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; namespace habr { public partial class Form1 : Form { bool loaded = false;//<-------------------------------------- public Form1() { InitializeComponent(); } private void glControl1_Load(object sender, EventArgs e) { loaded = true;//<-------------------------------------- } private void glControl1_Paint(object sender, PaintEventArgs e) { if (!loaded)//<-------------------------------------- return;//<-------------------------------------- } } }
glControl1_Load-Loadã€ãã³ããåŠçããã¡ãœãã
glControl1_Paint-Paintã€ãã³ããåŠçããã¡ãœãããããšãã°ããŠã£ã³ããŠãé衚瀺ã«ããŠããåã³éãããšãããŸãã¯ãŠã£ã³ããŠã®ãµã€ãºãå€æŽãããšãã«èµ·åããŸãã
å®éã«ç«æ¹äœãæããŸãã
å°ããªç«æ¹äœãæãã³ãŒã
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; namespace habr { public partial class Form1 : Form { bool loaded = false; public Form1() { InitializeComponent(); } private void glControl1_Load(object sender, EventArgs e) { loaded = true; GL.ClearColor(Color.SkyBlue); GL.Enable(EnableCap.DepthTest); Matrix4 p = Matrix4.CreatePerspectiveFieldOfView((float)(80 * Math.PI / 180), 1, 20, 500); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref p); Matrix4 modelview = Matrix4.LookAt(70, 70, 70, 0, 0, 0, 0, 1, 0); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref modelview); } private void glControl1_Paint(object sender, PaintEventArgs e) { if (!loaded) return; GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); float width = 20; /**/ GL.Color3(Color.Red); GL.Begin(BeginMode.Polygon); GL.Vertex3(0, 0, 0); GL.Vertex3(width, 0, 0); GL.Vertex3(width, width, 0); GL.Vertex3(0, width, 0); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 0, width); GL.Vertex3(0, width, width); GL.Vertex3(0, width, 0); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 0, width); GL.Vertex3(width, 0, width); GL.Vertex3(width, 0, 0); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(0, width, 0); GL.Vertex3(0, width, width); GL.Vertex3(width, width, width); GL.Vertex3(width, width, 0); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(0, 0, width); GL.Vertex3(width, 0, width); GL.Vertex3(width, width, width); GL.Vertex3(0, width, width); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(width, 0, 0); GL.Vertex3(width, 0, width); GL.Vertex3(width, width, width); GL.Vertex3(width, width, 0); GL.End(); /**/ GL.Color3(Color.Black); GL.Begin(BeginMode.LineLoop); GL.Vertex3(0, 0, 0); GL.Vertex3(0, width, 0); GL.Vertex3(width, width, 0); GL.Vertex3(width, 0, 0); GL.End(); GL.Begin(BeginMode.LineLoop); GL.Vertex3(width, 0, 0); GL.Vertex3(width, 0, width); GL.Vertex3(width, width, width); GL.Vertex3(width, width, 0); GL.End(); GL.Begin(BeginMode.LineLoop); GL.Vertex3(0, 0, width); GL.Vertex3(width, 0, width); GL.Vertex3(width, width, width); GL.Vertex3(0, width, width); GL.End(); GL.Begin(BeginMode.LineLoop); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 0, width); GL.Vertex3(0, width, width); GL.Vertex3(0, width, 0); GL.End(); glControl1.SwapBuffers(); } } }
OpenTKã䜿çšã -Matrix4ã¯ã©ã¹ã«å¿ èŠïŒ4x4ãããªãã¯ã¹ïŒ
OpenTK.Graphics.OpenGLã䜿çšããŸãã -GLãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ããããã«å¿ èŠã§ãã
GLã¯ãOpenGLã³ãã³ããå®éã«åŒã³åºãããã®ãªããžã§ã¯ãã§ãã
GL.ClearColorïŒColor.SkyBlueïŒ; -éã§å¡ãã€ã¶ã
GL.EnableïŒEnableCap.DepthTestïŒ; -é ãèŠçŽ ãæãè¿ãèŠçŽ ãšéãªãããã«ããã®è¡ãå¿ èŠã§ãã
Matrix4 p = Matrix4.CreatePerspectiveFieldOfView((float)(80 * Math.PI / 180), 1, 20, 500); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref p);
ããã§ãéå°ã®åå ãšãªãè¡åãèšå®ããŸãã
1ïŒèŠéè§80床
2ïŒé·ããšé«ãã®æ¯-1
3ïŒæåã®é¡ãŸã§ã®è·é¢-20
4ïŒå察åŽãŸã§ã®è·é¢-500
æ圱ã¢ãŒãã«ç§»åããŠããã®ãããªãã¯ã¹ãèšå®ããŸãã ã¢ãŒãã«ã€ããŠã¯åŸã§èª¬æããŸãã
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
ColorBufferBitããã³DepthBufferãåæåãã
ColorBuffer ã«ã©ãŒãããã¡ã ç»é¢äžã®åãã¯ã»ã«ã«ã¯ãã«ã©ãŒãããã¡ãŒã«èšé²ãããŠããã«ã©ãŒå€ããããŸãã ãã®å ŽåãGL.ClearïŒClearBufferMask.ColorBufferBitïŒãåŒã³åºããšããŠã£ã³ããŠã空è²ïŒäžèšåç §ïŒã§å¡ãã€ã¶ãããŸãã
DepthBufferã 圌ã¯Z-Bufferã§ãã 深床ãããã¡ã å®éã«ã¯ã3D空éã®2ã€ã®ãã€ã³ããã¹ã¯ãªãŒã³äžã®1ã€ã®ãã€ã³ãã«æ圱ã§ããŸãã è¿ç¹ãé ç¹ãšéãªãããšãå¿ èŠã§ãã ãããè¡ãã«ã¯ããã€ã³ãã®ãæ·±ãããèšç®ãïŒå€ã¯ã«ã¡ã©ãããã€ã³ããŸã§ã®è·é¢ã«åæ¯äŸããŸãïŒããã®å€ããããã¡ãŒïŒãã¯ã»ã«ãªã©ã深床ãªã©ïŒã«èšé²ããå¿ èŠããããŸãã
次ã®ãã€ã³ããåããã¯ã»ã«ã«æ圱ãããå Žåãæ°ãããã€ã³ãã®ãæ·±ãããšèšé²ããã深床ãããã¡ãæ¯èŒããå¿ èŠããããŸãã æ°ãããã€ã³ãããããæµ ããïŒã«ã¡ã©ã«è¿ãïŒå Žåããã®æ圱ã¯æ¢åã®æ圱ãšéãªãã¯ãã§ããããã§ãªãå Žåã¯ããã¹ãŠããã®ãŸãŸã«ããŸãã
ãã¥ãŒãã®ã¬ã³ããªã³ã°ã®éå§æã«ãDepth-Bufferãã¯ãªã¢ããå¿ èŠããããŸãã
Matrix4 modelview = Matrix4.LookAt(70, 70, 70, 0, 0, 0, 0, 1, 0); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref modelview);
ããã§ã¯ãã«ã¡ã©ããã€ã³ãïŒ30ã70ã80ïŒã座æšç³»ã®äžå¿ã®èŠç·æ¹åïŒ0ã0ã0ïŒã«èšå®ããŸãã åãã¯ãOY軞ãäžãåããããªãã®ã§ãã
ãããããªã
Matrix4 modelview = Matrix4.LookAt(30, 70, 80, 0, 0, 0, 1, 1, 0);
次ã«ãé ãå·Šã«45床åŸããããã«ãç«æ¹äœãæãã«èŠãŸãã
次ã«ããã¥ãŒãèªäœãå®éã«æç»ãããŸããæåã¯é¢ãèµ€ã§ã次ã«ãšããžãé»ã§ã
次ã«ãã³ãã³ããåŒã³åºãããŸã
glControl1.SwapBuffers();
äºå®ãããã©ã«ãã§ã¯ãOpenTKã®OpenGLã¯ããã«ãããã¡ãŒã§ããåãããã¡ãŒïŒColorBufferãDepthBufferãããã³ç§ãèšåããªãã£ãä»ã®ãããã¡ãŒïŒã¯è€è£œãããŸãã ç»åãæç»ãããšãã¯ããããã¡ã®ã¿ã䜿çšããŸãã ãã®ãšããç»é¢ã«ã¯ä»ã®ãããã¡ããååŸããç»åã衚瀺ãããŸãã
GlControl1.SwapBuffersïŒïŒ; ãã€ã³ããããããã¡ã䜿çšããŠç»åã衚瀺ããŸãã
ã¡ãªã¿ã«ãåããŠã«ã©ãŒãããã¡ãŒãã¯ãªã¢ããå Žåã¯
bool b = true; private void glControl1_Paint(object sender, PaintEventArgs e) { if (!loaded) return; GL.Clear(ClearBufferMask.DepthBufferBit); if (b) { GL.Clear(ClearBufferMask.ColorBufferBit); } b = false; âŠ
ã€ãŸãã1ã€ã®ã«ã©ãŒãããã¡ãŒã®ã¿ãã¯ãªã¢ãïŒå®éã«ã¯ãéè²ã§å¡ãã€ã¶ããŸãïŒãããäžæ¹ã¯ã¯ãªã¢ããŸããã ãããŠããŠã£ã³ããŠãæå°å/æ倧åããŸãã ãã®èæ¯è²ã¯éããé»ã«å€ãããŸãã ïŒç¢ºãã«ããŠã£ã³ããŠã®ãµã€ãºãå€æŽãããšããŠã£ã³ããŠã¯åžžã«é»ã«ãªããŸãïŒãµã€ãºãå€æŽãããšãäž¡æ¹ã®ãããã¡ããªã»ãããããŸãïŒã
ã¢ãŒãã«ã€ããŠ
ãªããžã§ã¯ãã¯3次å 座æšã§æå®ãããŸãã ãããã®åº§æšã¯ãªããžã§ã¯ã座æšãšåŒã°ããŸãã åãªããžã§ã¯ãã¯ããªããžã§ã¯ã座æšã§å®çŸ©ã§ããŸãã ç°ãªãäœçœ®ã«äºãã«é¢é£ããç°ãªã3Dãªããžã§ã¯ãã®äžçãæ§ç¯ããã«ã¯ã
åãªããžã§ã¯ãã®ãªããžã§ã¯ã座æšã«å¯Ÿå¿ããã¢ãã«ãããªãã¯ã¹ ïŒã¢ãã«ãããªãã¯ã¹ïŒãæããå¿ èŠããããŸãã 次ã«ãæ°ããå ±éã¯ãŒã«ã空éã§åãªããžã§ã¯ãã®æ°ãã座æšãååŸããŸãã
åæã«ãç°ãªãåŽé¢ãããªããžã§ã¯ãã®äžçãèŠãããšãã§ããã«ã¡ã©ãã²ã£ããè¿ãããªããžã§ã¯ãã«è¿ã¥ããããããé¢ããããšãã§ããŸãã ãªããžã§ã¯ãã®åº§æšïŒã¯ãŒã«ã空éã®åº§æšïŒã«ãã¥ãŒå€æã®å¯Ÿå¿ãããããªãã¯ã¹ïŒãã¥ãŒãããªãã¯ã¹ïŒãä¹ç®ããŠãåãªããžã§ã¯ãã®ãã¥ãŒåº§æšãååŸããŸãã
OpenGLã§ã¯ãã¢ãã«å€æãããªãã¯ã¹ã¯ãã¥ãŒå€æãããªãã¯ã¹ãšçµã¿åããããŠ1ã€ã«ãªããŸãïŒmodelView MatrixïŒã ïŒçµå±ã2ã€ã®æ¹æ³ã§ãªããžã§ã¯ããé ãããããšãã§ããŸããã¯ãŒã«ã座æšãå€æŽããïŒãªããžã§ã¯ããé ãããïŒããŸãã¯ã«ã¡ã©ããªããžã§ã¯ãããé ãããïŒæ°ãããã¥ãŒåº§æšãååŸïŒïŒã
次ã«ã座æšã«æ圱ãããªãã¯ã¹ïŒæ圱ãããªãã¯ã¹ïŒãæããŸããããã«ããããã©ã¹ãã¬ãŒã·ã§ã³ïŒéèŠæ圱ïŒãèšå®ãããŸãã
ãŸãã¯ãæ£å°åœ±ãèšå®ããŸãã
ãã¥ãŒåº§æšã«æ圱è¡åãä¹ç®ãããšãåãæšãŠããã座æšïŒã¯ãªãã座æšïŒãååŸãããŸãã å座æšïŒxãyãzïŒãÏã®å€ã§4ã§å²ããšãããã€ã¹ã®æ£èŠåããã座æšïŒNormalize Device CoordinatesãNDCïŒãåŸãããŸããããããã®åº§æšã¯-1ãã1ã§ãZ軞ã¯æ¢ã«å±éãããŠããŸãïŒã€ãŸããFrustrumã¯æ¬è³ªçã«ç«æ¹äœã«ãªããç§ãã¡ãã180床å転ããŸãïŒ
ããã«ã座æšã¯ã·ããããããŠã£ã³ããŠåº§æšã«ã¹ã±ãŒãªã³ã°ãããŸãããŠã£ã³ããŠåº§æšã¯ãæçµçã«ç»é¢äžã®2Dç»åã®æ§ç¯ã«é¢äžããŸãã
æ圱ãããªãã¯ã¹å¶åŸ¡ã¢ãŒãã«åãæ¿ããã«ã¯ãMatrixMode.Projectionãã©ã¡ãŒã¿ãŒãæå®ããŠGL.MatrixModeé¢æ°ãåŒã³åºãå¿ èŠããããŸãã
GL.MatrixModeïŒMatrixMode.ProjectionïŒ;
ã¢ãã«ãã¥ãŒå€æãããªãã¯ã¹å¶åŸ¡ã¢ãŒãã«åãæ¿ããã«ã¯ãMatrixMode.Modelvewãã©ã¡ãŒã¿ãŒãæå®ããŠGL.MatrixModeé¢æ°ãåŒã³åºãå¿ èŠããããŸãã
GL.MatrixModeïŒMatrixMode.ModelViewïŒ;
軞OXãOYãOZãæãã³ãŒããglControl1_Paintã«è¿œå ããŸãã
GL.Color3(Color.Black); GL.Begin(BeginMode.Lines); GL.Vertex3(0, 0, 0); GL.Vertex3(50, 0, 0); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 50, 0); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 0, 50); GL.End();
ãŸãããã©ãŒã ãã¶ã€ããŒã§ãKeyDownã€ãã³ãã®ãã³ãã©ãŒãè¿œå ããå¿ èŠããããŸããglControl1_KeyDowné¢æ°ã衚瀺ãããŸãã 次ã®ã³ãŒããå ¥åããŸãã
private void glControl1_KeyDown(object sender, KeyEventArgs e) { if (!loaded) return; if (e.KeyCode == Keys.A) { GL.MatrixMode(MatrixMode.Projection); GL.Rotate(30, 0, 0, 1); } if (e.KeyCode == Keys.B) { GL.MatrixMode(MatrixMode.Modelview); GL.Rotate(30, 0, 0, 1); } glControl1.Invalidate(); }
ã€ãŸããããŒããŒãã®AããŒãæŒããšãæ圱ã¢ãŒãã«ãªããOZ軞ãäžå¿ã«åæèšåãã«30床å転ããŸãã
ãŸããBããŒãæŒããšãOZ軞ãäžå¿ãšããå転ãå®è¡ãããŸããããã§ã«ã¢ãã«åºæã®å€æã¢ãŒãã«ãªã£ãŠããŸãã
ããã«å®å šãªã³ãŒãã瀺ããŸãïŒ
AãšBãæŒããšå転ããå°ããªç«æ¹äœ
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; namespace habr { public partial class Form1 : Form { float width = 20; bool loaded = false; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void glControl1_Load(object sender, EventArgs e) { loaded = true; GL.ClearColor(Color.SkyBlue); GL.Enable(EnableCap.DepthTest); Matrix4 p = Matrix4.CreatePerspectiveFieldOfView((float)(80 * Math.PI / 180), 1, 20, 500); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref p); Matrix4 modelview = Matrix4.LookAt(70, 70, 70, 0, 0, 0, 0, 1, 0); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref modelview); } private void glControl1_KeyDown(object sender, KeyEventArgs e) { if (!loaded) return; if (e.KeyCode == Keys.A) { GL.MatrixMode(MatrixMode.Projection); GL.Rotate(30, 0, 0, 1); } if (e.KeyCode == Keys.B) { GL.MatrixMode(MatrixMode.Modelview); GL.Rotate(30, 0, 0, 1); } glControl1.Invalidate(); } private void glControl1_Paint(object sender, PaintEventArgs e) { if (!loaded) return; GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit); /**/ GL.Color3(Color.Red); GL.Begin(BeginMode.Polygon); GL.Vertex3(0, 0, 0); GL.Vertex3(width, 0, 0); GL.Vertex3(width, width, 0); GL.Vertex3(0, width, 0); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 0, width); GL.Vertex3(0, width, width); GL.Vertex3(0, width, 0); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 0, width); GL.Vertex3(width, 0, width); GL.Vertex3(width, 0, 0); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(0, width, 0); GL.Vertex3(0, width, width); GL.Vertex3(width, width, width); GL.Vertex3(width, width, 0); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(0, 0, width); GL.Vertex3(width, 0, width); GL.Vertex3(width, width, width); GL.Vertex3(0, width, width); GL.End(); /**/ GL.Begin(BeginMode.Polygon); GL.Vertex3(width, 0, 0); GL.Vertex3(width, 0, width); GL.Vertex3(width, width, width); GL.Vertex3(width, width, 0); GL.End(); GL.Color3(Color.Black); GL.Begin(BeginMode.LineLoop); GL.Vertex3(0, 0, 0); GL.Vertex3(0, width, 0); GL.Vertex3(width, width, 0); GL.Vertex3(width, 0, 0); GL.End(); GL.Begin(BeginMode.LineLoop); GL.Vertex3(width, 0, 0); GL.Vertex3(width, 0, width); GL.Vertex3(width, width, width); GL.Vertex3(width, width, 0); GL.End(); GL.Begin(BeginMode.LineLoop); GL.Vertex3(0, 0, width); GL.Vertex3(width, 0, width); GL.Vertex3(width, width, width); GL.Vertex3(0, width, width); GL.End(); GL.Begin(BeginMode.LineLoop); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 0, width); GL.Vertex3(0, width, width); GL.Vertex3(0, width, 0); GL.End(); GL.Color3(Color.Black); GL.Begin(BeginMode.Lines); GL.Vertex3(0, 0, 0); GL.Vertex3(50, 0, 0); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 50, 0); GL.Vertex3(0, 0, 0); GL.Vertex3(0, 0, 50); GL.End(); glControl1.SwapBuffers(); } } }
ããŒããŒãã§æåAãæŒããšãç»é¢äžã®2Dç»åãå転ããŸãã
ãããã£ãŠãé è¿æ³åº§æšã§ã¯ãOZ軞ã¯Froustrum軞ã§ããããŸãã
ããŒããŒãã§BãæŒããšã座æšç³»ã¯OZ軞ãäžå¿ã«å転ããŸãã
ã³ãŒã
GL.MatrixMode(MatrixMode.Projection); GL.Rotate(30, 0, 0, 1);
åãæåã§ããã«çœ®ãæããããšãã§ããŸãïŒ
Matrix4d projection_matrix;// 4x4, double GL.GetDouble(GetPName.ProjectionMatrix, out projection_matrix);// projection_matrix // OZ double cos = Math.Cos(-30 * Math.PI / 180); double sin = Math.Sin(-30 * Math.PI / 180); Matrix4d rotating_matrix = new Matrix4d( cos, -sin, 0, 0, sin, cos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); projection_matrix *= rotating_matrix;// GL.MatrixMode(MatrixMode.Projection);// GL.LoadMatrix(ref projection_matrix);//
ModelViewãããªãã¯ã¹ã®äžã«ããåãã³ãŒãã¯åãçµæã«ãªããŸãã
å®éã«ãããããããŠã³ããŒãã§ããã«ãŒããã¯ãã¥ãŒããšãã¥ã¬ãŒã¿ããã°ã©ã ã®èª¬æã«ç§»ããŸããããhttpïŒ//trukoding.rf/files/opengl.zip
ã€ãã«
ããããã®ããã¹ããããã®ã§ãç§ã¯ãã¹ãŠã説æããŸããã ããŒãã€ã³ãã«ã€ããŠèª¬æããŸãã
äž»èŠãªããŒã¿æ§é
1ïŒã«ãŒããã¯ãã¥ãŒãããšããžã3ã€ã®ãã¥ãŒãã§æ§æããã27åã®å°ããªãã¥ãŒãã§æ§æãããŠããŸãã
ã«ãŒããã¯ãã¥ãŒãïŒKRïŒã®é¢ãå転ããããšãå°ããªãã¥ãŒãã®äœçœ®ãå€ãããŸãã CRã®é¢ãå転ãããããã»ã¹ã§ã¯ãå転ããå°ããªç«æ¹äœãç¥ãå¿ èŠããããŸãïŒçµå±ãç°ãªãç«æ¹äœãé¢ã«çŸããå¯èœæ§ããããŸãïŒããŸããCRã®é¢ã®æ¬¡ã®å転ã®åŸãç«æ¹äœãåéããããã©ããã確èªããå¿ èŠããããŸãã
ãããã¯ã®äœçœ®ã远跡ããããã«ãäœçœ®ã®é åãé©çšããŸããïŒ
int []äœçœ®;
圌ã®éµã¯ç«æ¹äœã®æ°ãšäœçœ®ã®æ°ã®å€ã§ãã
ãšããã§ãç§ã¯æ¬¡ã®ããã«ããžã·ã§ã³ãæå®ããŸããã
2ïŒ CDé¢ãå転ããããšã察å¿ããå°ããªç«æ¹äœã®äœçœ®ãå€ããã ãã§ãªããå察åŽã§å転ããŸãã ãšããžã1å転ïŒ90床ïŒãããšã
次ã«ããã¥ãŒãã®æ°ããç¶æ ã2ã€ã®æ¹æ³ã§ååŸã§ããŸãã
1ïŒç¹å®ã®è»žãäžå¿ã«å¯Ÿå¿ãããã¥ãŒãã90床å転ããŸãïŒå転æã«è¡ãããŸããïŒ
2ïŒãã¥ãŒããæ°ããå Žæã«åé 眮ããåãã¥ãŒãããã®è»žãäžå¿ã«90床å転ããŸãã
次ã®ã¯ã©ã¹ã¯ã空éå ã®ãã¥ãŒããèšè¿°ããããã«äœ¿çšãããŸãã
public class angleXYZ { public angleXYZ() { this.X = 0; this.Y = 0; this.Z = 0; } public int X { get; set; } public int Y { get; set; } public int Z { get; set; } }
ãã£ãŒã«ãXãYãZã¯ã軞OXãOYãOZã«å¯Ÿããè§åºŠã§ãã
é¢ãå転ããããšã察å¿ãããã¥ãŒãã®å¯Ÿå¿ããè§åºŠãå€åããŸãã
å転ãå®äºãããããããã®è§åºŠããªã»ãããããã¥ãŒããæ°ããäœçœ®ã«ç§»åãïŒã€ãŸããããã«å¿ããŠäœçœ®é åãå€æŽãïŒã軞ãäžå¿ã«ãã¥ãŒããå転ããŸãïŒãã®æå³ã説æããŸãïŒã ãŠãŒã¶ãŒã«ã¯å転èªäœã®ã¿ã衚瀺ãããŸãã
åãã¥ãŒãã«ã¯angleXYZã¯ã©ã¹ã®ãªããžã§ã¯ãããããanglesã³ã¬ã¯ã·ã§ã³ã«ä¿åãããŸãã
List<angleXYZ> angles = new List<angleXYZ>();
3ïŒåãã¥ãŒãã«ã¯8ã€ã®ã³ãŒããŒãã€ã³ããå«ãŸããŠããŸãã ãããã®ç¹ãç¥ã£ãŠããã°ããã¥ãŒããæãããšã¯åé¡ã§ã¯ãããŸããã
ãã€ã³ãã®åº§æšã¯ããšããžã®3次å é åã«æ ŒçŽãããŸãã ïŒå ç®ãšä¹ç®ã§ã¯ãªãïŒä¹ç®æŒç®ã®ã¿ã䜿çšããŠåº§æšã転éããã³å転ããã«ã¯ã座æšã«1x4è¡åãã転éããã³ä¹ç®è¡åã«4x4è¡åã䜿çšããŸãã
4x4è¡åã䜿çšãããšãä¹ç®æŒç®ãšè»¢éè¡åãããã³å転ãçµã¿åãããããšãã§ããŸãã ãããã£ãŠã2ã€ã®äºæã1ã€ã®ä¹ç®æŒç®ã§å®è¡ã§ããŸãïŒè»¢éãšä¹ç®ã®äž¡æ¹ã
float[][][] edges; ⊠// edges = new float[n][][];//n - (27, 3x3x3) ⊠for (int i = 0; i < n; i++) { float[][] vectors = new float[8][] { //w- new float[4] { 0, 0, 0, 1 }, new float[4] { 0, 0, w, 1 }, new float[4] { 0, w, 0, 1 }, new float[4] { 0, w, w, 1 }, new float[4] { w, 0, 0, 1 }, new float[4] { w, 0, w, 1 }, new float[4] { w, w, 0, 1 }, new float[4] { w, w, w, 1 }, }; edges[i] = vectors; ⊠// List<int> data = getOffsets(i); int offset_x = data[0]; int offset_z = data[1]; int offset_y = data[2]; for (int j = 0; j < edges[i].Length; j++) { //w - , spacing - //( ) edges[i][j][0] += offset_x * (w + spacing); edges[i][j][1] += offset_y * (w + spacing); edges[i][j][2] += offset_z * (w + spacing); } }
çµã¿ç«ãŠãããCRã®ãŒãäœçœ®ã«å¯Ÿãã次ã®å°ããªãã¥ãŒãïŒã«ãŒããã¯ãã¥ãŒããå«ãŸããïŒã®ãªãã»ãããèŠã€ããããã«ãç¹å¥ãªé¢æ°getOffsetsãäœæããŸãããããã¯ããã¥ãŒãã®æ°ãååŸããå軞ã«æ²¿ã£ãŠåŸéããå¿ èŠããããã¥ãŒãã®æ°ãè¿ããŸãã
4ïŒèŸæžintersect_planesããããŸãã
èŸæžããŒã¯è»žïŒè»žåæãªããžã§ã¯ãïŒãããªãã¯åæ軞Axis {XãYãZ};ïŒïŒã
å€ã¯å¯Ÿå¿ãã軞ã®é¢ãç§ã®ã¯ã©ã¹ã®å¹³é¢ïŒå¹³é¢ïŒã®ãªããžã§ã¯ãã§ãã
public enum Axis { X, Y, Z }; Dictionary<Axis, Plane[]> intersect_planes = new Dictionary<Axis,Plane[]>();
Planeã¯ã©ã¹ã¯ãåé¢ã®ã³ãŒããŒãã€ã³ãã®ãã€ã³ãã®åº§æšãæ ŒçŽããããã«å¿ èŠã§ãã
side = N * w + (N - 1) * spacing;// - // Vector3 p1 = new Vector3(0, side, side);//<---- Vector3 p2 = new Vector3(side, 0, side); Vector3 p3 = new Vector3(side, side, side);//<---- Vector3 p4 = new Vector3(side, 0, 0); Vector3 p5 = new Vector3(0, 0, 0); Vector3 p6 = new Vector3(0, side, 0);//<---- Vector3 p7 = new Vector3(0, 0, side); Vector3 p8 = new Vector3(side, side, 0); intersect_planes[Axis.X] = new Plane[2] { new Plane(p2, p3, p8),// 2, 5, 8, 11, 14, 17, 23, 20, 26 X new Plane(p1, p7, p5)// 0, 3, 6, 9, 12, 15, 18, 21, 24 X }; intersect_planes[Axis.Y] = ... âŠ.
Planeã¯ã©ã¹ã®ãªããžã§ã¯ãã¯3ç¹ã®åº§æšãåã«ä¿åãããã®ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ããããç°ãªãããšã確èªããŸãã ããããå¥ã®ã¯ã©ã¹ãéå§ããããšã¯ã§ããŸããã§ãããã2次å ã®é åã§ããŸãããããšãã§ããŸããã
intersect_planes[Axis.X] = new Vector3[2][] { new Vector3[]{p2, p3, p8},// 2, 5, 8, 11, 14, 17, 23, 20, 26 X new Vector3[]{p1, p7, p5},// 0, 3, 6, 9, 12, 15, 18, 21, 24 X };
ããããäžé£ã®è§æ¬åŒ§ãä»ããŠé åèŠçŽ ã«ã¢ã¯ã»ã¹ããã®ã¯é¢åã§ãã
ãã®ãã£ã¯ã·ã§ããªã¯ãå¹³é¢ããããŠã¹ã§ã¯ãªãã¯ããé¢ããããã決å®ããããã«å¿ èŠã§ãããã«ãŒããã¯ãã¥ãŒãã®ã©ã®éšåãå転ãããå¿ èŠããããŸãã ããŠã¹ã§ç¢å°ãã¯ãªãã¯ããå¹³é¢ã®å®çŸ©ã¯ãåŸã§èšè¿°ãããŸãã
5ïŒ vpã¯ã©ã¹ViewPointã®éèŠãªãªããžã§ã¯ãã
ViewPoint vp = new ViewPoint();
ã«ãŒããã¯ãã¥ãŒãã®èŠç¹ã®åº§æšã®å€ãæ ŒçŽããŸããå®éãã«ãŒããã¯ãã¥ãŒããããŠã¹ã§å転ããããšãèŠç¹ã®äœçœ®ãå®éã«å€ãããç«æ¹äœãéæ¢ããŸãã
ãã¥ãŒãã€ã³ãã«æãè¿ã軞ãååŸããã«ã¯ãViewPointã¯ã©ã¹ãå¿ èŠã§ãïŒgetNearestAxisã¡ãœããïŒã ããã¯ãç¢å°ã衚瀺ãããé¢ãã€ãŸããããŠã¹ãã¯ãªãã¯ããããšãã«å転ããéšåã決å®ããããã«å¿ èŠã§ãã
èŠç¹ã¯çäœã®ã«ãŒããã¯ãã¥ãŒããäžå¿ã«å転ããããã軞OXã«å¯Ÿããè§åºŠïŒè§åºŠÎ±ïŒãšocããã³OYã«å¯Ÿããè§åºŠïŒè§åºŠÎ²ïŒã§æäœãããšäŸ¿å©ã§ãã
vpãªããžã§ã¯ãã«ã¯ãsetterããããã£angle_view_alphaãšangle_view_betaããããããããä»ããŠè§åºŠÎ±ãšè§åºŠÎ²ãå€åããŸããã»ãã¿ãŒã®æ¬äœã§ã¯ããããã®è§åºŠããã«ã¡ã©åº§æšïŒèŠç¹ïŒãèšç®ãããŸãã
ãã®ã¯ã©ã¹ã«ã¯ãã«ã¡ã©ãéããŸã«ãªã£ãŠãããã©ãããç¹å®ã®è»žã®ã©ã¡ãåŽã§ãã¥ãŒããèŠãŠããããå€æããããã«äœ¿çšã§ããã²ãã¿ãŒããããã£ããããŸãïŒããšãã°ãæ£ã®Xå€ã®åŽããããŸãã¯è² ã®Zå€ã®åŽããïŒã
ããã¯ãã«ãŒããã¯ãã¥ãŒãã®ãšããžããããæ¹åãæ£ãã決å®ããããã«å¿ èŠã§ãã ã«ãŒããã¯ãã¥ãŒãèªäœã¯ããã®äžå¿ãåç¹ã®äžå¿ã«ãªãããã«é 眮ãããŠããŸãã
ã³ãŒãã«ç§»ããŸããã
ããŒãã€ã³ãã®ã¿ã説æããŸãããã以å€ã®å Žåã¯éåžžã«é·ããªããŸãã ç§ã¯ãã§ã«ã¬ãªã»ãã³ã©ãšãŽã£ãããæããŠããŸãã
ã¬ã³ããªã³ã°æ¹æ³
ã«ãŒããã¯ãã¥ãŒãèªäœãæç»ããŠããã®äžå¿ãåç¹ã®äžå¿ãšäžèŽããããã«ãããã®ã§ãModelViewãããªãã¯ã¹ã¢ãŒãã«åãæ¿ãããšã座æšç³»ããã¹ãŠã®è»žã«æ²¿ã£ãŠã«ãŒããã¯ãã¥ãŒãã®ååã®é·ãã«è»¢éããŸãã
double offset0 = this.w * N + (N - 1) * spacing;// w - , N - (3), spacing - . double offset = offset0 / 2; GL.Translate( -offset, -offset, -offset );
次ã«ããã¥ãŒãã®æ°ïŒ27åïŒã§ããã¥ãŒãé¢æ°ãåŒã³åºãããŸãããã®é¢æ°ã¯ãCDã®äžå¿ã«ããããšãé€ããŠå°ããªãã¥ãŒããæç»ããŸãã
ãã¥ãŒãé¢æ°
ãŸããOpenGLãæäŸããã¹ã¿ãã¯ã«çŸåšã®ModelViewãããªãã¯ã¹ãä¿åããŸãã
GL.PushMatrix();
ãããŠæåŸã«ãã¹ã¿ãã¯ãããã®ãããªãã¯ã¹ã埩å ããŸãïŒ
GL.PopMatrix();
ããã¯ã1ã€ã®ãã¥ãŒãã®ModelViewãããªãã¯ã¹ïŒå転ã転éïŒãå€æŽããŠãä»ã®ãã¥ãŒãã®ãããªãã¯ã¹ã«åœ±é¿ããªãããã«ããããã«å¿ èŠã§ãã ã€ãŸãã1ã€ã®å°ããªç«æ¹äœããããå Žåãä»ã®ç«æ¹äœã¯å転ããªãã¯ãã§ãã
é¢ã®ã¹ã¯ããŒã«ãã¢ãã¡ãŒã·ã§ã³åããããã«ã軞ã®1ã€ãäžå¿ã«å転ããŸãã
float offset = (w * N + (N - 1) * spacing) / 2;// GL.Translate( offset, offset, offset ); GL.Rotate(angle.X, Vector3.UnitX); GL.Rotate(angle.Y, Vector3.UnitY); GL.Rotate(angle.Z, Vector3.UnitZ); GL.Translate( -offset, -offset, -offset );
ã³ãŒãã¯ãè§åºŠangle.Xãangle.Yãangle.Zã®ãããã1ã€ã ããäžåºŠã«ãŒã以å€ã«ãªãããã«èšè¿°ãããŠãããããããã§ã¯1ã€ã®è»žã®åšãã§ã®ã¿å転ãããããŸã£ããå®è¡ãããŸããã
ãããã座æšç³»ãã·ããããããšã念é ã«çœ®ããŠããŸããã®åº§æšç³»ãå ã®å Žæã«æ»ããæ¹åãå€ããåã³é転éãè¡ãå¿ èŠããããŸãã
次ã«ã edgesé åã䜿çšããŠç«æ¹äœãæç»ããç«æ¹äœã®é¢ã®è²ãç«æ¹äœã®æ°ãã決å®ããŸããããã¯ãç«æ¹äœé¢æ°ã«æž¡ãããŸãã
ç¢å°
GL.Translateã䜿çšããäžå¿åº§æšç³»ã¯ãå ã®å Žæã«æ»ããŸãã
次ã«ãViewPointã¯ã©ã¹ã®vpã䜿çšããŠãã«ã¡ã©ã«æãè¿ã座æšç³»ã®è»žãšãã©ã¡ãã®åŽãã決å®ãããŸãã察å¿ããå転ã¯GL.Rotateã䜿çšããŠè¡ãããGL.Translateã¡ãœããã¯ç¢å°ãæãè¿ãé¢ã«æç»ãããããã«ãã®ãããªè»¢éãè¡ããŸãã
ã©ã®ç¢å°ãã¯ãªãã¯ããããå€æããã«ã¯ããŸãããŠã¹ã¯ãªãã¯ã®å ŽæããçŽç·ã決å®ãã次ã«ç«æ¹äœã®é¢ãå«ãæãè¿ãå¹³é¢ãšã®äº€ç¹ã決å®ãã次ã«å°ããªç«æ¹äœã®ãµã€ãºãšãããã®éã®è·é¢ãç¥ãå¿ èŠããããŸããã©ã®ç¢å°ã決å®ããã®ã¯é£ãããããŸããã¯ãªãã¯ããŸããã
ãã®ãããªçŽç·ã®2ç¹ã決å®ããã«ã¯ãããã€ã¹ïŒäžèšã®NDCïŒã®æ£èŠåããã座æšãèŠã€ããModelViewè¡åãšæ圱ãä¹ç®ããŠåŸãããéè¡åãä¹ç®ããå¿ èŠããããŸãã
ãã®çµæãFroustrumã®æãè¿ãå¹³é¢ãšé ãå¹³é¢ã«ãã2ã€ã®ç¹ã®åº§æšãååŸããŸãã
System.Windows.Forms.MouseEventArgs me = (e as System.Windows.Forms.MouseEventArgs); double y = me.Y; double x = me.X; int w = glControl1.Width; int h = glControl1.Height; float xpos = (float)(2 * (x / w) - 1); float ypos = (float)(2 * (1 - y / h) - 1); Vector4 startRay = new Vector4(xpos, ypos, 1, 1); Vector4 endRay = new Vector4(xpos, ypos, -1, 1); // Reverse Project Matrix4 modelview = new Matrix4(); Matrix4 projection = new Matrix4(); GL.GetFloat(GetPName.ModelviewMatrix, out modelview); GL.GetFloat(GetPName.ProjectionMatrix, out projection); Matrix4 trans = modelview * projection; trans.Invert(); startRay = Vector4.Transform(startRay, trans); endRay = Vector4.Transform(endRay, trans); sr = startRay.Xyz / startRay.W; er = endRay.Xyz / endRay.W;
å床Renderã¡ãœããã«æ»ããŸã
æ¥è¿ããŠããé¢ãšç·ã®2ç¹ãç¥ããšãç·ãšç§ãã¡ã«æãè¿ãã«ãŒããã¯ãã¥ãŒãã®é¢ãããé¢ã®äº€å·®ç¹ãèŠã€ããŸãïŒã€ãŸããé¢ã®ç¹ãå«ããintersect_planesèŸæžãäœçšããŸãïŒã
ã°ãŒã°ã«ã§äº€å·®ç¹ã®å®çŸ©ã決å®ããæ©èœãããã«ãã³ãŒãã§ã¯ãã¯ãªãã¯ããé¢ïŒç¢å°ã®æ¹åïŒãšãé¢ã®åŽé¢ãŸãã¯äžããäžã®ãããããã¯ãªãã¯ããŸããããã¥ãŒãèªäœã¯ç§»åããããã®åŽé¢ã¯XOYãXOZãYOZå¹³é¢ã«å¹³è¡ã§ãããããããã¯ãã¹ãŠç°¡åã§ãïŒã€ãŸãããã¹ãŠã亀ç¹ã®å°ãªã/å€ã座æšãš4ã€ã®ã³ãŒããŒãã€ã³ãã®åº§æšãæ¯èŒããããšã§æ±ºå®ãããŸãïŒã
ããã§ã¯ãé¡ãå転ãããããã»ã¹ãéå§ããŸãã
é¡ã®å転
é¡ã®å転ãã¢ãã¡ãŒã·ã§ã³åããããã«ãSystem.Timers.Timerããç¶æ¿ããEasingTimerã¯ã©ã¹ãäœæããã·ã³ã°ã«ãã³ãã¶ã€ã³ãã¿ãŒã³ã䜿çšããŠããã®ã¯ã©ã¹ã®èŠçŽ ã1ã€ã ãäœæã§ããŸããå¶ç¶ã«2ã€ã®é¢ãåæã«å転ããªãããã«ããããè¡ããŸããããŸããå転ããã»ã¹ãå®è¡ãããŠãããã©ããã決å®ããå®è¡å€æ°ããããæ°ããå転ããã»ã¹ã¯åã®ããã»ã¹ãçµäºãããŸã§éå§ãããŸããã
EasingTimerã¯ã©ã¹ã®ãªããžã§ã¯ãã®durationããããã£ã¯ãå転ã®æç¶æéãããªç§åäœã§èšå®ããŸãã
å転èªäœã¯æ¬¡ã®ããã«è¡ãããŸãã
- åææéãä¿åãããŸã
- ã¿ã€ããŒã¯ã100ããªç§ããšã«éå§ãããŸãã
- , rotatePart , angles . , .
public class angleXYZ { public angleXYZ() { this.X = 0; this.Y = 0; this.Z = 0; } public int X { get; set; } public int Y { get; set; } public int Z { get; set; } }
, X, Y, Z,
100 , , , .
, glControl1.Invalidate();, Render , cube , angles , . , .
- rotatePart , duration .
, ( Render , , ).
positions ( , , ), . â , , .
, :
ãããã£ãŠãèŠçŽ ã¯ãå転ããå°ããªç«æ¹äœã®8ç¹ã®åº§æšãå«ããšããžã®é åã§ããã察å¿ããå転è¡åãä¹ç®ãããŸãã
ãã®åŸãåã³glControl1.InvalidateïŒïŒãåŒã³åºããŸãã Renderã¡ãœãããåŒã³åºãããŸããããã«ããããã¥ãŒãã¡ãœãããåŒã³åºããããã¥ãŒããæ°ããââå Žæã«è¡šç€ºãããããã«å¿ããŠå転ããŸãã
次ã«ãpositionsé åãçºæãããçç±ã説æããŸããããã¯ããã¥ãŒããã©ã®äœçœ®ã«äŸ¡å€ããããã瀺ããŸãïŒ27åã®ãã€ã¹ã27åã®äœçœ®ïŒãå®éãã«ãŒããã¯ãã¥ãŒãã®é¢ãå転ãããããã»ã¹ã§ã¯ãå°ããªç«æ¹äœã®äœçœ®ã絶ããå€åãããããããã¥ãŒã3ãX軞ã®åšãã«90床å転ããªã©ã®ã³ãã³ãã§ã¯ãªãããç«æ¹äœãå転ããªã©ã®ã³ãã³ãã§æäœããå¿ èŠããããŸãäœçœ®3ã§ãX軞ã®åšãã«90床ã
次ã«ã空éå ã§ãã¥ãŒããå転ãããè§åºŠé åã®èŠçŽ ããŒãã«ãªã»ããããçç±ã説æããŸããå®éã«ã¯ãé çªã®é çªãéèŠã§ãã X軞ã®åšãã®å転ãY軞ã®åšãã®å転ã¯ãY軞ã®åšãã®å転ããããŠX軞ã®åšãã®å転ãšåãã§ã¯ãããŸããã
ãã¥ãŒãã®å転è§åºŠããªã»ããããªãå Žåãå転ã¢ãã¡ãŒã·ã§ã³ãå®è£ ãããã¥ãŒãã¡ãœããã®æ¬¡ã®ã³ãŒã
ã¯æåã®3åã®å転ãããã«ã¯ããããããã®é åºã§ããå ŽåïŒXåšããYåšããZåšã
GL.Rotate(angle.X, Vector3.UnitX); GL.Rotate(angle.Y, Vector3.UnitY); GL.Rotate(angle.Z, Vector3.UnitZ);
åãã¥ãŒãã®å転ã®é åºãå¿ èŠãªã¿ãŒã³ã®ç¹å®ã®ãã¬ãŒã¹ãèŠããŠããå¿ èŠããããŸãããšããžé åã«ã¯ãå°ããªç«æ¹äœã®ã³ãŒããŒãã€ã³ãã®åº§æšãå«ãŸããŠãããç«æ¹äœã®åº§æšã«å¯Ÿå¿ããå転è¡åãæãããã³ã«ããã®ç«æ¹äœã®ãã¹ãŠã®å転ã®å±¥æŽãä¿åãããŸãããšããžé åã®èŠçŽ ãèªã¿åãã察å¿ãããã¥ãŒãã衚瀺ããã ãã§ãã
ã«ãŒããã¯ãã¥ãŒãå šäœã®å転
ã«ãŒããã¯ãã¥ãŒãå šäœã®å転ã¯ãèŠç¹ãå€æŽããããšã«ãã£ãŠã®ã¿çºçããŸããããã¯ããã³ãã©ãŒMouseDownãMouseMoveãMouseUpã§å®è£ ãããŸããããŠã¹ãããã°ã©ã ãŠã£ã³ããŠã®åšå²ãã©ãã ã移åããããåçŽã«èšç®ãããã®ç§»åã察å¿ããå転è§åºŠïŒåçŽããã³æ°Žå¹³ïŒã«å€æããŸãã
X軞ãšY軞ããã®è§åºŠãæ åœããViewPointã¯ã©ã¹ã®vpãªããžã§ã¯ãã®å¯Ÿå¿ããããããã£ãå€æŽããïŒäžã®å³ãåç §ïŒãViewPointã¯ã©ã¹ã®ã¡ãœããå ã§ãã«ã¡ã©ã®æ°ãã座æšã決å®ãããäžäžãéã«ãªããæ°ããModelViewãããªãã¯ã¹ãäœæãããŸãïŒ
G_modelview = Matrix4.LookAt(vp.viewX, vp.viewY, vp.viewZ, 0, 0, 0, 0, vp.orintation_y, 0);
æåã®3ã€ã®èŠçŽ ã¯ã«ã¡ã©ã®åº§æšãæå®ãã
2çªç®ã®3ã€ã®èŠçŽ ã¯ã«ã¡ã©ã座æšç³»ã®äžå¿ã«åããããããšãæå®ããŸãã
æåŸã®3ã€ã®èŠçŽ
ã¯ãããã§ã«ã¡ã©ã®å転æ¹æ³ãæå®ããvp.orintation_y == 1ã®å Žåã¯Y軞ãäžã«åããvp.orintation_y == -1ã®å Žåã¯äžã«åãããã
ã«æå®ããŸãã
ä»ã®ãã¹ãŠãç§ã¯ãããæå³ãèŠãã®ã§ã¯ãªãããããã¯é·ãéã§ãããæž èŽããããšãããããŸããããããããããžã§ã¯ããããŠã³ããŒãã§ããŸãïŒhttpïŒ//xn--c1abmgrdmpk4e.xn--p1ai/files/opengl.zip