Last active
August 14, 2017 19:05
-
-
Save shibbo/2ddd754add51f858570444c6bc4695bb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Drawing; | |
using System.IO; | |
using System.Windows.Forms; | |
using OpenTK; | |
using OpenTK.Graphics.OpenGL; | |
using DouBOLDash.Rendering; | |
namespace DouBOLDash | |
{ | |
public partial class MainWindow : Form | |
{ | |
public string PROGRAM_NAME = "DouBOL Dash "; | |
public string VERSION = "v0.2 "; | |
private const float k_FOV = (float)((70f * Math.PI) / 180f); | |
private const float k_zNear = 0.01f; | |
private const float k_zFar = 1000f; | |
public bool isSelectionMode = false; | |
private float m_AspectRatio; | |
private Vector2 m_CamRotation; | |
private Vector3 m_CamPosition; | |
private Vector3 m_CamTarget; | |
private float m_CamDistance; | |
private bool m_UpsideDown; | |
private Matrix4 m_CamMatrix, m_SkyboxMatrix; | |
private RenderInfo m_RenderInfo; | |
private MouseButtons m_MouseDown; | |
private Point m_LastMouseMove, m_LastMouseClick; | |
private float m_PixelFactorX, m_PixelFactorY; | |
private const float CUBESIZE = 50f; | |
bool loaded = false; | |
private Point FormCenter | |
{ | |
get | |
{ | |
return new Point(this.Location.X + this.Width / 2, this.Location.Y + this.Height / 2); | |
} | |
} | |
TrackObject.TrackObject selectedObject; | |
int MapGLList = 0; | |
int MapSkyGLList = 0; // this sometimes isn't used. | |
int CourseObjectGLList = 0; | |
Bmd map; | |
Bmd sky; | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
courseView = new GLControl(); | |
courseView.Dock = DockStyle.Fill; | |
courseView.Load += new System.EventHandler(courseView_Load); | |
courseView.Paint += new PaintEventHandler(courseView_Paint); | |
//this.courseView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.courseView_KeyDown); | |
//this.courseView.KeyUp += new System.Windows.Forms.KeyEventHandler(this.courseView_KeyUp); | |
courseView.MouseDown += new MouseEventHandler(courseView_MouseDown); | |
courseView.MouseMove += new MouseEventHandler(courseView_MouseMove); | |
courseView.MouseUp += new MouseEventHandler(courseView_MouseUp); | |
courseView.Resize += new EventHandler(courseView_Resize); | |
panel1.Controls.Add(courseView); | |
if (Properties.Settings.Default.basePath == "") | |
doFolderChoose(); | |
exfs = new ExternalFilesystem(Properties.Settings.Default.basePath); | |
setupUI(); | |
} | |
public void setupUI() | |
{ | |
collisionSetting = new CheckBox(); | |
collisionSetting.Text = "Collision Setting:"; | |
collisionSetting.TextAlign = ContentAlignment.MiddleLeft; | |
collisionSetting.CheckAlign = ContentAlignment.MiddleRight; | |
courseSettings.Controls.Add(collisionSetting); | |
Label lapLbl = new Label(); | |
lapLbl.Text = "Lap Count:"; | |
courseSettings.Controls.Add(lapLbl); | |
lapCount = new NumericUpDown(); | |
lapCount.Minimum = 1; | |
lapCount.Maximum = 9; | |
lapCount.Increment = 1; | |
courseSettings.Controls.Add(lapCount); | |
Label lightXLbl = new Label(); | |
lightXLbl.Text = "Light Position X:"; | |
courseSettings.Controls.Add(lightXLbl); | |
lightX = new NumericUpDown(); | |
lightX.DecimalPlaces = 2; | |
courseSettings.Controls.Add(lightX); | |
Label lightYLbl = new Label(); | |
lightYLbl.Text = "Light Position Y:"; | |
courseSettings.Controls.Add(lightYLbl); | |
lightY = new NumericUpDown(); | |
lightY.DecimalPlaces = 2; | |
courseSettings.Controls.Add(lightY); | |
Label lightZLbl = new Label(); | |
lightZLbl.Text = "Light Position Z:"; | |
courseSettings.Controls.Add(lightZLbl); | |
lightZ = new NumericUpDown(); | |
lightZ.DecimalPlaces = 2; | |
courseSettings.Controls.Add(lightZ); | |
} | |
public void LoadCourse(string name) | |
{ | |
string newname = name.Replace(".arc", ""); | |
string lowResName = ""; | |
if (newname == "Luigi2L" || newname == "Luigi2") | |
return; | |
if (newname.EndsWith("L")) | |
{ | |
newname = newname.Remove(newname.Length - 1); | |
lowResName = name.Replace(".arc", "").ToLower(); | |
rarc = new RarcFilesystem(exfs.OpenFile("/Course/" + name)); | |
course = new Course(rarc.OpenFile("/" + lowResName + "/" + newname.ToLower() + "_course.bol")); | |
courseName = newname.ToLower(); | |
course.GetCourseInfo(newname); | |
} | |
else | |
{ | |
rarc = new RarcFilesystem(exfs.OpenFile("/Course/" + name)); | |
course = new Course(rarc.OpenFile("/" + newname + "/" + newname + "_course.bol")); | |
courseName = newname.ToLower(); | |
course.GetCourseInfo(newname); | |
} | |
// first we check to see if we can even load the course model or the sky model | |
if (rarc.FileExists("/" + courseName + "/" + courseName + "_course.bmd")) | |
map = new Bmd(rarc.OpenFile("/" + courseName + "/" + courseName + "_course.bmd")); | |
if (rarc.FileExists("/" + courseName + "/" + courseName + "_sky.bmd")) | |
sky = new Bmd(rarc.OpenFile("/" + courseName + "/" + courseName + "_sky.bmd")); | |
// now we set up our GL lists | |
MapGLList = GL.GenLists(1); | |
MapSkyGLList = GL.GenLists(1); | |
GL.NewList(MapGLList, ListMode.Compile); | |
if (map != null) | |
DrawBMD(map); | |
GL.EndList(); | |
GL.NewList(MapSkyGLList, ListMode.Compile); | |
if (sky != null) | |
DrawBMD(sky); | |
GL.EndList(); | |
} | |
private void doFolderChoose() | |
{ | |
FolderBrowserDialog fbd = new FolderBrowserDialog(); | |
if (fbd.ShowDialog() == DialogResult.OK) | |
if (Directory.Exists(fbd.SelectedPath + "/Course/")) | |
{ | |
Properties.Settings.Default.basePath = fbd.SelectedPath; | |
Properties.Settings.Default.Save(); | |
} | |
else | |
{ | |
if (Properties.Settings.Default.basePath != "") | |
{ | |
MessageBox.Show("Failed to set new path. The current path is unchanged."); | |
return; | |
} | |
else | |
{ | |
Properties.Settings.Default.basePath = ""; | |
Properties.Settings.Default.Save(); | |
MessageBox.Show("Failed to get folder. This can happen by it not existing, or it is missing the /Course directory."); | |
return; | |
} | |
} | |
} | |
ExternalFilesystem exfs; | |
private void selectCourseToolStripMenuItem_Click(object sender, EventArgs e) | |
{ | |
CourseSelector cs = new CourseSelector(); | |
cs.GetFiles(exfs.GetFiles("/Course")); | |
cs.Show(); | |
} | |
private void courseView_Resize(object sender, EventArgs e) | |
{ | |
courseView.MakeCurrent(); | |
UpdateViewport(); | |
} | |
private void courseView_Load(object sender, EventArgs e) | |
{ | |
courseView.MakeCurrent(); | |
GL.Enable(EnableCap.DepthTest); | |
GL.ClearDepth(1f); | |
GL.FrontFace(FrontFaceDirection.Cw); | |
m_CamPosition = new Vector3(0f, 0f, 0f); | |
m_CamRotation = new Vector2(0.0f, 0.0f); | |
m_CamDistance = 1f; | |
m_RenderInfo = new RenderInfo(); | |
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); | |
loaded = true; | |
Console.WriteLine("loaded"); | |
courseView.Invalidate(); | |
} | |
private void courseView_Paint(object sender, PaintEventArgs e) | |
{ | |
if (!loaded) | |
return; | |
courseView.MakeCurrent(); | |
GL.DepthMask(true); | |
// bg color | |
GL.ClearColor(0f, 0f, 0.125f, 1f); | |
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); | |
// set our matrix modes and load it | |
GL.MatrixMode(MatrixMode.Modelview); | |
GL.LoadMatrix(ref m_CamMatrix); | |
GL.Disable(EnableCap.Texture2D); | |
GL.CallList(MapGLList); | |
GL.CallList(MapSkyGLList); | |
GL.Begin(PrimitiveType.Lines); | |
GL.Color4(1f, 0f, 0f, 1f); | |
GL.Vertex3(0f, 0f, 0f); | |
GL.Vertex3(100000f, 0f, 0f); | |
GL.Color4(0f, 1f, 0f, 1f); | |
GL.Vertex3(0f, 0f, 0f); | |
GL.Vertex3(0, 100000f, 0f); | |
GL.Color4(0f, 0f, 1f, 1f); | |
GL.Vertex3(0f, 0f, 0f); | |
GL.Vertex3(0f, 0f, 100000f); | |
GL.End(); | |
GL.Color4(1f, 1f, 1f, 1f); | |
courseView.SwapBuffers(); | |
UpdateCamera(); | |
} | |
private void UpdateViewport() | |
{ | |
if (courseView.Height == 0 || courseView.Width == 0) | |
Console.WriteLine("we no update view"); | |
else | |
{ | |
GL.Viewport(courseView.ClientRectangle); | |
m_AspectRatio = (float)courseView.Width / (float)courseView.Height; | |
GL.MatrixMode(MatrixMode.Projection); | |
Matrix4 projmtx = Matrix4.CreatePerspectiveFieldOfView(k_FOV, m_AspectRatio, k_zNear, k_zFar); | |
GL.LoadMatrix(ref projmtx); | |
m_PixelFactorX = ((2f * (float)Math.Tan(k_FOV / 2f) * m_AspectRatio) / (float)(courseView.Width)); | |
m_PixelFactorY = ((2f * (float)Math.Tan(k_FOV / 2f)) / (float)(courseView.Height)); | |
} | |
} | |
private void UpdateCamera() | |
{ | |
Vector3 up; | |
if (Math.Cos(m_CamRotation.Y) < 0) | |
{ | |
m_UpsideDown = true; | |
up = new Vector3(0.0f, -1.0f, 0.0f); | |
} | |
else | |
{ | |
m_UpsideDown = false; | |
up = new Vector3(0.0f, 1.0f, 0.0f); | |
} | |
m_CamPosition.X = m_CamDistance * (float)Math.Cos(m_CamRotation.X) * (float)Math.Cos(m_CamRotation.Y); | |
m_CamPosition.Y = m_CamDistance * (float)Math.Sin(m_CamRotation.Y); | |
m_CamPosition.Z = m_CamDistance * (float)Math.Sin(m_CamRotation.X) * (float)Math.Cos(m_CamRotation.Y); | |
Vector3 skybox_target; | |
skybox_target.X = -(float)Math.Cos(m_CamRotation.X) * (float)Math.Cos(m_CamRotation.Y); | |
skybox_target.Y = -(float)Math.Sin(m_CamRotation.Y); | |
skybox_target.Z = -(float)Math.Sin(m_CamRotation.X) * (float)Math.Cos(m_CamRotation.Y); | |
Vector3.Add(ref m_CamPosition, ref m_CamTarget, out m_CamPosition); | |
m_CamMatrix = Matrix4.LookAt(m_CamPosition, m_CamTarget, up); | |
m_SkyboxMatrix = Matrix4.LookAt(Vector3.Zero, skybox_target, up); | |
m_CamMatrix = Matrix4.Mult(Matrix4.CreateScale(0.0001f), m_CamMatrix); | |
} | |
private void BuildRender() | |
{ | |
} | |
private void courseView_MouseMove(object sender, MouseEventArgs e) | |
{ | |
// moves the camera around the scene | |
float xdelta = (float)(e.X - m_LastMouseMove.X); | |
float ydelta = (float)(e.Y - m_LastMouseMove.Y); | |
m_LastMouseMove = e.Location; | |
if (m_MouseDown != MouseButtons.None) | |
{ | |
if (m_MouseDown == MouseButtons.Right) | |
{ | |
if (m_UpsideDown) | |
xdelta = -xdelta; | |
m_CamRotation.X -= xdelta * 0.002f; | |
m_CamRotation.Y -= ydelta * 0.002f; | |
} | |
else if (m_MouseDown == MouseButtons.Left) | |
{ | |
xdelta *= 0.005f; | |
ydelta *= 0.005f; | |
m_CamTarget.X -= xdelta * (float)Math.Sin(m_CamRotation.X); | |
m_CamTarget.X -= ydelta * (float)Math.Cos(m_CamRotation.X) * (float)Math.Sin(m_CamRotation.Y); | |
m_CamTarget.Y += ydelta * (float)Math.Cos(m_CamRotation.Y); | |
m_CamTarget.Z += xdelta * (float)Math.Cos(m_CamRotation.X); | |
m_CamTarget.Z -= ydelta * (float)Math.Sin(m_CamRotation.X) * (float)Math.Sin(m_CamRotation.Y); | |
} | |
UpdateCamera(); | |
} | |
courseView.Refresh(); | |
} | |
private void courseView_MouseUp(object sender, MouseEventArgs e) | |
{ | |
if (e.Button != m_MouseDown) return; | |
m_MouseDown = MouseButtons.None; | |
m_LastMouseMove = e.Location; | |
courseView.Invalidate(); | |
} | |
private void courseView_MouseDown(object sender, MouseEventArgs e) | |
{ | |
if (m_MouseDown != MouseButtons.None) return; | |
m_MouseDown = e.Button; | |
m_LastMouseMove = m_LastMouseClick = e.Location; | |
courseView.Invalidate(); | |
} | |
public void DrawBMD(Bmd model, RenderMode rnd = RenderMode.Opaque) | |
{ | |
RenderInfo ri = new RenderInfo(); | |
ri.Mode = rnd; | |
BmdRenderer br = new BmdRenderer(model); | |
br.Render(ri); | |
} | |
GLControl courseView; | |
Course course; | |
RarcFilesystem rarc; | |
string courseName; | |
CheckBox collisionSetting; | |
NumericUpDown lapCount; | |
ComboBox music; | |
ComboBox ambientColor; | |
ComboBox lightColor; | |
NumericUpDown lightX; | |
NumericUpDown lightY; | |
NumericUpDown lightZ; | |
NumericUpDown fogType; | |
NumericUpDown fogStartZ; | |
NumericUpDown fogEndZ; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment