Skip to content

Instantly share code, notes, and snippets.

@shibbo
Last active August 14, 2017 19:05
Show Gist options
  • Save shibbo/2ddd754add51f858570444c6bc4695bb to your computer and use it in GitHub Desktop.
Save shibbo/2ddd754add51f858570444c6bc4695bb to your computer and use it in GitHub Desktop.
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