Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    5
  • comments
    10
  • views
    3627

About this blog

Buisness application developer by day - amatuer game developer by night.

Entries in this blog

 

Fire evacuation in Rancho Bernardo....

WOW. When they say evacuate - EVACUATE. Sunday night my wife and I went to sleep around 10:00PM with the fires 10 miles away. Throughout the night the air quality got worse and we kept waking up coughing. At 4:00AM we noticed an increase of emergency traffic (i.e. sirens). At 5:00AM we got a reverse 911 call - well, kind of - we never actually HEARD the message - our neighbor was banging on our door at 5:30AM.

So, after that we casually got our stuff together, got the dogs in the car, and pulled out into the heaviest traffic I have ever seen. We live on the intersection of Duenda and West Bernardo. As we turned onto West Bernardo into dead stop traffic we saw the flames burning a church. It took over an hour to get onto the highway - and our house is less than a mile away. I was very concerned with the fire catching up our car. The wind was horrible, too. Ash, leaves, branches, and embers were blowing over the hood of my car at 30-50 mph. It reminded me of a black snow storm. Visiblity was very poor.

We made it to the highway and to my parents house in Point Loma and have spent the last couple of days anxiously watching the television. My wife and I are lucky as our house is still standing - we saw it on a news broadcast during a helicopter fly over. Other than that we know very little. Hopefully we'll be able to return home sometime today.

In retrospect, fire is very real and travels at an incredible rate when fanned by the right type of winds. When you are told to evacuate get out as quickly as possible.




AtomicWedgie

AtomicWedgie

 

Extracting Mesh (.X) information without a Device

Previously, my game engine calculated boundry information from meshes as they were loaded by the Device. While re-working the engine I decided that this wasn't necessary and the information could be extracted directly from the .X file itself. Microsoft provides some bases classes that help with this in the Microsoft.DirectX.Direct3D assembly - the XFile and XFileManager classes.

I created the MeshInfo class which loads a .X file and extracts the vertices and faces of the mesh stored within it. Transformations are done where necessary if frames exist in the .X file.

This is the resource loader function used by MeshInfo.


///
/// Creates a resource stream. Checks both physical files and assemblies for the desired resource.
///
/// The name of the resource.
/// The search location. Checks both physical files and assemblies for the desired resource. If null or empty will search the current directory.
/// The stream.
static public System.IO.Stream CreateResourceStream(string resourceName, string searchPath)
{
// Default search path to the current directory...
if (string.IsNullOrEmpty(searchPath))
searchPath = System.IO.Directory.GetCurrentDirectory();

if (File.Exists(Path.Combine(searchPath, resourceName)))
{
#region Load from File

// Load from File ...

try
{
return new FileStream(Path.Combine(searchPath, resourceName), FileMode.Open, FileAccess.Read);
}
catch (Exception exe)
{
throw new Exception("An error occured while resource from file, \"" + Path.Combine(searchPath, resourceName) + "\".", exe);
}

#endregion
}
else
{
#region Load from Assembly

// Load from assembly...

Assembly asm;

// Browse all assemblies...
foreach (string assemblyPath in Directory.GetFiles(searchPath, "*.dll"))
{
asm = Assembly.LoadFile(assemblyPath);

// Browse all resources in assembly...
foreach (string assResourceName in asm.GetManifestResourceNames())
{
// Exists in the assembly?
if (assResourceName.ToLower().EndsWith(resourceName.ToLower()))
{
try
{
// Yes.
return asm.GetManifestResourceStream(assResourceName);
}
catch (Exception exe)
{
throw new Exception("An error occured while loading resource from assembly, \"" + assemblyPath + "\".", exe);
}
}
}
}

#endregion
}

// Resource not found...
throw new FileNotFoundException("The resource \"" + resourceName + "\" could not be found in \"" + searchPath + "\"!");
}



Here is the "face" structure used by the MeshInfo class.


using Microsoft.DirectX;
using System;

namespace GameEngine.Math.Structures
{
///
/// A Ray.
///
public struct Ray
{
#region variables
///
/// Ray direction.
///
public Vector3 origin;
///
/// Ray origin.
///
public Vector3 direction;
#endregion

#region properties
///
/// Retreives an empty ray.
///
static public Ray Empty
{
get
{
Ray result;

result = new Ray(Vector3.Empty,Vector3.Empty);

return result;
}
}
#endregion

#region constructors
///
/// Constructor.
///
/// Ray direction.
/// Ray origin.
public Ray (Vector3 direction, Vector3 origin)
{
this.direction = direction;
this.origin = origin;
}
#endregion

#region operators
public override string ToString()
{
return "Origin : " + this.origin + ", " + "Direction : " + this.direction;
}
public static bool operator == (Ray x, Ray y)
{
if (x.direction == y.direction)
if (x.origin == y.origin)
return true;

return false;
}
public static bool operator != (Ray x, Ray y)
{
return (!(x == y));
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode ();
}
#endregion
}

///
/// A Triangle
///
public struct Triangle
{
#region variables
///
/// 3 vertices that make up the triangle.
///
public Vector3 [] positions;
///
/// Normal of the triangle.
///
public Vector3 normal;
#endregion

#region properties
///
/// Retreives an empty triangle.
///
static public Triangle Empty
{
get
{
Triangle result;

result = new Triangle();
result.normal = Vector3.Empty;
result.positions = null;
return result;
}
}
#endregion

#region constructors
///
/// Constructor.
///
/// Vertex 1 of the Triangle.
/// Vertex 2 of the Triangle.
/// Vertex 3 of the Triangle.
/// Normal of the Triangle.
public Triangle (Vector3 pos1, Vector3 pos2, Vector3 pos3, Vector3 normal)
{
this.positions = new Vector3[3];
this.positions[0] = pos1;
this.positions[1] = pos2;
this.positions[2] = pos3;
this.normal = normal;
}
#endregion

#region methods
///
/// Returns the Plane that this Triangle creates.
///
///
/// The Plane that the Triangle creates.
///
public Plane GetPlane()
{
return Plane.FromPointNormal(this.positions[0],this.normal);
}
///
/// Returns a Transformed Triangle.
///
/// The Transformation Matrix to transform the Triangle by.
///
/// The Triangle transformed by the specified Transformation Matrix.
///
///
/// Source :
/// http://www.gignews.com/realtime020100.htm
///
public Triangle GetTransformedTriangle ( Matrix transformation )
{
Triangle triangle;
Vector3 triangleEdge1, triangleEdge2;

triangle.positions = new Vector3 [3];

// Transform the Positions of the Triangle.
for (int i = 0; i this.positions.Length; i++)
{
triangle.positions = Vector3.TransformCoordinate(this.positions,transformation);
}

// Transform the Normal of the Triangle.
// The Normal of the Triangle can be derived from the Cross Product of its Edges...
triangleEdge1 = triangle.positions[0] - triangle.positions[1];
triangleEdge2 = triangle.positions[0] - triangle.positions[2];
triangle.normal = Vector3.Cross(triangleEdge1,triangleEdge2);
triangle.normal.Normalize();

return triangle;
}
///
/// Returns the barycenter (center of gravity) of the triangle.
///
/// The barycenter of the triangle.
public Vector3 GetBarycenter()
{
float midX, midY, midZ;

midX = (this.positions[0].X + this.positions[1].X + this.positions[2].X) / 3.0f;
midY = (this.positions[0].Y + this.positions[1].Y + this.positions[2].Y) / 3.0f;
midZ = (this.positions[0].Z + this.positions[1].Z + this.positions[2].Z) / 3.0f;

return new Vector3(midX, midY, midZ);
}
///
/// Computes a normal for the triangle.
///
/// The normal of the triangle.
public Vector3 ComputeNormal ()
{
Vector3 triangleEdge1, triangleEdge2, result;

triangleEdge1 = this.positions[0] - this.positions[1];
triangleEdge2 = this.positions[2] - this.positions[1];
result = Vector3.Normalize(Vector3.Cross(triangleEdge2, triangleEdge1));

return result;
}
#endregion

#region operators
///
/// 06/06/2007 SV Now call IsEqual() when comparing positions. Rounds to Minimum Precision.
///
public static bool operator == (Triangle x, Triangle y)
{
if (Math.Library.IsEqual(x.normal,y.normal))
{
if ((x.positions == null) && (y.positions == null))
return true;

if (x.positions.Length != x.positions.Length)
return false;

for (int index=0 ; index if (!Math.Library.IsEqual(x.positions[index],y.positions[index]))
return false;

return true;
}

return false;

}
public static bool operator != (Triangle x, Triangle y)
{
return (!(x == y));
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode ();
}
public override string ToString()
{
if (this.positions == null)
return "";
else
return "\nv0: \n" + this.positions[0] + "\nv1: \n" + this.positions[1] + "\nv2: \n" + this.positions[2] + "\nnormal: \n" + this.normal;
}

#endregion
}

///
/// A Sphere.
///
public struct Sphere
{
#region variables
///
/// The Center of the Sphere.
///
public Vector3 center;
///
/// The Radius of the Sphere.
///
public float radius;
#endregion

#region properties
///
/// Retreives an empty sphere.
///
static public Sphere Empty
{
get
{
Sphere result;

result = new Sphere();
result.center = Vector3.Empty;
result.radius = 0;
return result;
}
}
#endregion

#region constructors
///
/// Constructor.
///
/// The center of the sphere.
/// The radius of the sphere.
public Sphere (Vector3 center, float radius)
{
this.center = center;
this.radius = radius;
}
///
/// Constructor.
///
/// The points the sphere should encapsulate.
public Sphere(Vector3[] points)
{
center = Vector3.Empty;
radius = 0.0f;

if (points != null ? points.Length > 0 : false)
{
// Find the center of the points.
center = Library.GetCenter(points);

// Now find the furthest point from the center. The distance of this point from the center
// will be the radius.
for (int index = 0; index {
radius = System.Math.Max(System.Math.Max(System.Math.Max(
radius,
System.Math.Abs(center.X - points[index].X)),
System.Math.Abs(center.Y - points[index].Y)),
System.Math.Abs(center.Z - points[index].Z));
}
}
}
#endregion

#region methods
///
/// Merge two spheres.
///
/// The first sphere.
/// The second sphere.
/// The encapsulating sphere.
static public Sphere Merge(Sphere sphereA, Sphere sphereB)
{
Vector3 center;
float radius;
float distCenterToSphereA;
float distCenterToSphereB;

center = new Vector3( (sphereA.center.X + sphereB.center.X) / 2,
(sphereA.center.Y + sphereB.center.Y) / 2,
(sphereA.center.Z + sphereB.center.Z) / 2);

distCenterToSphereA = Math.Library.GetDistance(center,sphereA.center);
distCenterToSphereB = Math.Library.GetDistance(center,sphereB.center);

radius = System.Math.Max(distCenterToSphereA + sphereA.radius,distCenterToSphereB + sphereB.radius);

return new Sphere(center,radius);
}
#endregion

#region operators
public static bool operator == (Sphere x, Sphere y)
{
if (x.center == y.center)
if (x.radius == y.radius)
return true;

return false;
}
public static bool operator != (Sphere x, Sphere y)
{
return (!(x == y));
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode ();
}
public override string ToString()
{
return "center = " + this.center.ToString() + ", radius = " + this.radius;
}
#endregion
}

///
/// A Cylinder.
///
public struct Cylinder
{
#region variables
///
/// The radius of the cylinder.
///
public float radius;
///
/// The center of endcap "p" of the cylinder.
///
public Vector3 p;
///
/// The center of endcap "q" of the cylinder.
///
public Vector3 q;
#endregion

#region properties
///
/// Returns an Empty Cylinder.
///
public Cylinder Empty
{
get
{
return new Cylinder(0,Vector3.Empty,Vector3.Empty);
}
}
#endregion

#region constructors
///
/// Constructor.
///
/// The radius of the cylinder.
/// The center of endcap "p" of the cylinder.
/// The center of endcap "q" of the cylinder.
public Cylinder( float radius, Vector3 p, Vector3 q )
{
this.radius = radius;
this.p = p;
this.q = q;
}
#endregion

#region operators
public static bool operator == (Cylinder x, Cylinder y)
{
if (x.radius == y.radius)
if (x.p == y.p)
if (x.q == y.q)
return true;

return false;

}
public static bool operator != (Cylinder x, Cylinder y)
{
return (!(x == y));
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode ();
}
public override string ToString()
{
return "radius = " + this.radius + ", p = " + this.p + ", q = " + this.q;
}
#endregion
}

///
/// A Capsule.
///
public struct Capsule
{
#region variables
///
/// The cylinder representing the capsule.
///
private Cylinder cylinder;
#endregion

#region properties
///
/// The radius of the capsule.
///
public float Radius
{
get
{
return this.cylinder.radius;
}
set
{
this.cylinder.radius = value;
}
}
///
/// The center the capsule's end sphere "p".
///
public Vector3 P
{
get
{
return this.cylinder.p;
}
set
{
this.cylinder.p = value;
}
}
///
/// The center the capsule's end sphere "q".
///
public Vector3 Q
{
get
{
return this.cylinder.q;
}
set
{
this.cylinder.q = value;
}
}
///
/// Returns an empty capsule.
///
public Capsule Empty
{
get
{
return new Capsule(0, Vector3.Empty, Vector3.Empty);
}
}
#endregion

#region constructors
///
/// Constructor.
///
/// The radius of the capsule.
/// The center the capsule's end sphere "p".
/// The center the capsule's end sphere "q".
public Capsule(float radius, Vector3 p, Vector3 q)
{
this.cylinder = new Cylinder(radius, p, q);
}
#endregion

#region operators
public static bool operator ==(Capsule x, Capsule y)
{
if (x.cylinder.radius == y.cylinder.radius)
if (x.cylinder.p == y.cylinder.p)
if (x.cylinder.q == y.cylinder.q)
return true;

return false;

}
public static bool operator !=(Capsule x, Capsule y)
{
return (!(x == y));
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override string ToString()
{
return "radius = " + this.cylinder.radius + ", p = " + this.cylinder.p + ", q = " + this.cylinder.q;
}
#endregion
}

///
/// An Axis-Aligned Box.
///
public struct AxisAlignedBox
{
#region variables
///
/// The Lower-Left Corner of the Axis-Aligned Box.
///
public Vector3 min;
///
/// The Upper-Right Corner of the Axis-Aligned Box.
///
public Vector3 max;
#endregion

#region properties
///
/// The X-Dimension of the Axis-Aligned Box.
///
public float DimX
{
get
{
return System.Math.Abs(this.max.X-this.min.X);
}
}
///
/// The Y-Dimension of the Axis-Aligned Box.
///
public float DimY
{
get
{
return System.Math.Abs(this.max.Y-this.min.Y);
}
}
///
/// The Z-Dimension of the Axis-Aligned Box.
///
public float DimZ
{
get
{
return System.Math.Abs(this.max.Z-this.min.Z);
}
}
///
/// The center of the axis-aligned box.
///
///
/// 06/04/2007 SV No longer adding min and max before dividing by 2. If min and max have components that are maximum and minimum will result in NaN.
/// 06/04/2007 SV Now handling situations where both max and min are +/- infinity. Was resulting in a NaN component for the resulting center.
///
public Vector3 Center
{
get
{
Vector3 center;

if (float.IsPositiveInfinity(this.max.X) && float.IsNegativeInfinity(this.min.X))
center.X = 0;
else
center.X = (this.max.X / 2.0f) + (this.min.X / 2.0F);

if (float.IsPositiveInfinity(this.max.Y) && float.IsNegativeInfinity(this.min.Y))
center.Y = 0;
else
center.Y = (this.max.Y / 2.0f) + (this.min.Y / 2.0F);

if (float.IsPositiveInfinity(this.max.Z) && float.IsNegativeInfinity(this.min.Z))
center.Z = this.max.Z = 0;
else
center.Z = (this.max.Z / 2.0f) + (this.min.Z / 2.0F);

return center;
}
}
///
/// The volume of the axis-aligned box.
///
public float Volume
{
get
{
return this.DimX * this.DimY * this.DimZ;
}
}
///
/// Retreives an empty Axis-Aligned Box.
///
static public AxisAlignedBox Empty
{
get
{
AxisAlignedBox result;

result = new AxisAlignedBox();
result.max = Vector3.Empty;
result.min = Vector3.Empty;
return result;
}
}
#endregion

#region constructors
///
/// Constructor.
///
/// The lower-left corner of the box.
/// The upper-right Corner of the box.
public AxisAlignedBox (Vector3 min, Vector3 max)
{
this.min = min;
this.max = max;
}
///
/// Constructor.
///
/// The center of the box.
/// The x-dimension of the box.
/// The y-dimension of the box.
/// The z-dimension of the box.
public AxisAlignedBox(Vector3 center, float dimX, float dimY, float dimZ)
{
if (float.IsNaN(dimX) || float.IsNaN(dimY) || float.IsNaN(dimZ))
throw new Exception("Can not create an invalid axis aligned box. The x-dimension, y-dimension, and z-dimensions of the box can not be NaN!");

this.min = new Vector3(center.X - (dimX / 2.0f), center.Y - (dimY / 2.0f), center.Z - (dimZ / 2.0f));
this.max = new Vector3(center.X + (dimX / 2.0f), center.Y + (dimY / 2.0f), center.Z + (dimZ / 2.0f));
}
///
/// Constructor.
///
/// The points the box should encapsulate.
public AxisAlignedBox(Vector3[] points)
{
this.min = Vector3.Empty;
this.max = Vector3.Empty;

if (points != null ? points.Length > 0 : false)
{
// Iterate through all of the points and find the maximum and minimum constraints for
// X, Y, and Z. These are the max and min of the AABB.
for (int index = 0; index {
// Maximum.
this.max.X = System.Math.Max(points[index].X, this.max.X);
this.max.Y = System.Math.Max(points[index].Y, this.max.Y);
this.max.Z = System.Math.Max(points[index].Z, this.max.Z);

// Minimum.
this.min.X = System.Math.Min(points[index].X, this.min.X);
this.min.Y = System.Math.Min(points[index].Y, this.min.Y);
this.min.Z = System.Math.Min(points[index].Z, this.min.Z);
}
}
}
#endregion

#region methods
///
/// Returns a transformed axis aligned box.
///
/// The transformation matrix to transform the box by.
///
/// The box transformed by the specified transformation matrix.
///
public AxisAlignedBox GetTransformedBox(Matrix transformation)
{
Vector3 transCenter;
float transDimX, transDimY, transDimZ;

// Transform the center of the box.
transCenter = Vector3.TransformCoordinate(this.Center, transformation);

// Transfom the dimensions of the box.
transDimX = this.DimX * transformation.M11;
transDimY = this.DimY * transformation.M22;
transDimZ = this.DimZ * transformation.M33;

return new AxisAlignedBox(
new Vector3(transCenter.X - (transDimX / 2.0f), transCenter.Y - (transDimY / 2.0f), transCenter.Z - (transDimZ / 2.0f)),
new Vector3(transCenter.X + (transDimX / 2.0f), transCenter.Y + (transDimY / 2.0f), transCenter.Z + (transDimZ / 2.0f)));
}
///
/// Merge two axis-aligned boxes.
///
/// The first box.
/// The second box.
/// The encapsulating box.
static public AxisAlignedBox Merge (AxisAlignedBox boxA, AxisAlignedBox boxB)
{
Vector3 max;
Vector3 min;

min = Vector3.Empty;
max = Vector3.Empty;

max = Vector3.Maximize(boxA.max,boxB.max);
min = Vector3.Minimize(boxA.min,boxB.min);

return new AxisAlignedBox(min,max);
}
#endregion

#region operators
///
/// 06/06/2007 SV Now call IsEqual() when comparing min/max of boxes. Rounds to Minimum Precision.
///
public static bool operator == (AxisAlignedBox x, AxisAlignedBox y)
{
if (Math.Library.IsEqual(x.min,y.min))
if (Math.Library.IsEqual(x.max,y.max))
return true;

return false;
}
public static bool operator != (AxisAlignedBox x, AxisAlignedBox y)
{
return (!(x == y));
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode ();
}
#endregion
}
}





Here is the MeshInfo class.


using GameEngine.Math.Structures;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text;

namespace GameEngine.Resources
{
///
/// Retreieves mesh info from a .X file. Does not load the mesh into graphics memory.
///
public class MeshInfo
{
#region support classes
///
/// Mesh list.
///
private class MeshList : List
{ }
///
/// Frame list.
///
private class FrameList : List
{ }
///
/// Represents a frame.
///
private class Frame
{
#region variables
///
/// Frame name.
///
internal string Name;
///
/// Parent frame.
///
internal Frame Parent;
///
/// Child frame(s).
///
internal FrameList Children;
///
/// Mesh(s).
///
internal MeshList Meshes;
///
/// Frame transformation.
///
internal Matrix Transformation;
#endregion

#region properties
///
/// Total vertices.
///
internal int TotalVertices
{
get
{
int result;

result = 0;

// Add vertices in the frame's meshes.
foreach (Mesh mesh in this.Meshes)
result += (mesh.Faces != null) ? mesh.Faces.Length * 3 : 0;

// Add vertices from the frame's children.
foreach (Frame child in this.Children)
result += child.TotalVertices;

return result;
}
}
///
/// Total faces.
///
internal int TotalFaces
{
get
{
int result;

result = 0;

// Add triangles in the frame's meshes.
foreach (Mesh mesh in this.Meshes)
result += (mesh.Faces != null) ? mesh.Faces.Length : 0;

// Add triangles from the frame's children.
foreach (Frame child in this.Children)
result += child.TotalFaces;

return result;
}
}
#endregion

#region constructors
///
/// Constructor.
///
internal Frame()
{
this.Name = "";
this.Parent = null;
this.Children = new FrameList();
this.Meshes = new MeshList();
this.Transformation = Matrix.Identity;
}
#endregion

#region methods
///
/// Gets the faces for the frame.
///
/// The transformation to apply to the faces.
/// The index to write to in the faces array.
/// The faces array.
private void GetTransformedFaces(Matrix transformation, int index, ref Triangle[] faces)
{
Matrix combinedTransform;

combinedTransform = this.Transformation * transformation;

// Add triangles in the frame's meshes.
foreach (Mesh mesh in this.Meshes)
foreach (Triangle tri in mesh.GetTransformedFaces(combinedTransform))
faces[index++] = tri;

// Add triangles from the frame's children.
foreach (Frame child in this.Children)
child.GetTransformedFaces(combinedTransform, index, ref faces);
}
///
/// Gets the vertices for the frame.
///
/// The transformation to apply to the vertices.
/// The index to write to in the vertice array.
/// The vertice array.
private void GetTransformedVertices(Matrix transformation, int index, ref Vector3[] vertices)
{
Matrix combinedTransform;

combinedTransform = this.Transformation * transformation;

// Add vertices in the frame's meshes.
foreach (Mesh mesh in this.Meshes)
foreach (Vector3 vert in mesh.GetTransformedVertices(combinedTransform))
vertices[index++] = vert;

// Add vertices from the frame's children.
foreach (Frame child in this.Children)
child.GetTransformedVertices(combinedTransform, index, ref vertices);
}
///
/// Gets the faces for the frame.
///
/// The transformation to apply to the faces.
/// The frame's faces.
internal Triangle[] GetTransformedFaces(Matrix transformation)
{
Triangle[] result;

result = new Triangle[this.TotalFaces];

this.GetTransformedFaces(transformation, 0, ref result);

return result;
}

///
/// Get the vertices for the frame.
///
/// The frame.
/// The transformation to apply to the vertices.
/// The frame's vertices.
internal Vector3[] GetTransformedVertices(Matrix transformation)
{
Vector3[] result;

result = new Vector3[this.TotalVertices];

this.GetTransformedVertices(transformation, 0, ref result);

return result;
}
#endregion
}
/// &l

AtomicWedgie

AtomicWedgie

 

Spinning off the graphics engine...

So, I am revisiting the core framework for Epiphany and have realized that my graphics engine should be spun off from the game engine. Why? Well for one, the code is looking more and more speghettish ;) The other reason is that the graphics engine and game engine perform very unique tasks...

Ideallty, it the game engine should be a "hub". As such, it should implement the game loop and the scene graph. During each iteration of the game loop the game engine should process each game entity by making requests against the graphics engine (and other engines).

The graphics engine should be responsible for loading, rendering, and disposing of game entities AND recovering itself (if necessary). The graphics engine should also maintain resource pools for the loading (and sharing) of graphics resources such as Fonts, Meshes, Textures, and Shaders.

Previously the game engine was handling all of these tasks - and as such it was getting more and more difficult to maintain.

AtomicWedgie

AtomicWedgie

 

It's time for 3D sound...

This weekend I enabled 3D sound in Epiphany. I followed three good articles on DirectSound implementation using Managed DirectX 1.1...

http://www.riemers.net/eng/Tutorials/DirectX/Csharp/Series2/tut15.php
http://www.pluralsight.com/wiki/default.aspx/Craig.DirectX/DirectSoundTutorialIndex.html
http://blogs.msdn.com/coding4fun/archive/2006/11/06/999786.aspx

After getting everything working on my laptop I decided to test it against my wife's desktop. This is where I ran into problems. Although sound played fine on my laptop - sound on my wife's desktop either was not played or was not played in 3D. Very odd.

After searching MSDN and these forums and trying various things I came across a solution. When creating the SecondaryBuffer for the sound if I explicitly set the "LocateInSoftware" flag to "true" 3D sound worked flawlessly!

According to an MSDN article http://msdn2.microsoft.com/en-us/library/bb280909.aspx, this forces sound mixing to be performed by software and not the sound card hardware.

So, apparently not all sound cards are created equal...

Until next time....




AtomicWedgie

AtomicWedgie

 

So, I had an epiphany moment...

So, 2 years ago I was 29 and came to a realization. Although I was working as a software developer and programming buisness software - I realized that I kind of lost sight of what got me interested in programming in the first place. Yeah, you got it - games.

Call it an epiphany.

So, I picked up some books on Managed DirectX development (thank you Tom Miller), discovered this site, and started coding, and refactoring, and coding...

Almost two years later I have something presentable. It's a multiplayer mech FPS shooter based upon a framework/engine that I designed. I wrote it using C#, .Net 2.0, and Managed DirectX 1.1.

Am I done? Heck no. There's so much that I still want to do! But for now here are some screenshots...


















AtomicWedgie

AtomicWedgie

Sign in to follow this  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!